Coffee Farm Model

Coffee Farm Model preview image

1 collaborator

Default-person Steve Railsback (Author)

Tags

netlogocon2026 

Tagged by Steve Railsback 3 days ago

Visible to everyone | Changeable by everyone
Model was written in NetLogo 7.0.4 • Viewed 38 times • Downloaded 0 times • Run 0 times
Download the 'Coffee Farm Model' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


WHAT IS IT?

This is the Coffee Farm Model of Railsback and Johnson (2011, 2014; citations below). It simulates bird foraging on the Coffee Berry Borer pest insect ("CBB") and other insects ("bugs") in a coffee farm modeled on those of the Blue Mountains of Jamaica. The model was designed to predict and understand how different areas and arrangement of several habitat types, especially low- and high-sun coffee, affect both bird abundance and production of uninfested coffee.

This model also provides a reusable method for generating artificial landscapes in which the user can control the relative area and number of clusters of several habitat types. See the procedures create-landscape and create-clumps-for.

HOW IT WORKS

On each simulated day, birds forage for up to 12 hours, stopping when they meet their daily food requirement. They forage by selecting the patch, from their current patch and its 8 neighbors, that provides highest intake of either CBB or bugs. See the publications cited below for full details.

HOW TO USE IT

Before using setup, you must either create a new landscape or load an existing one. One of five landscapes can be chosen via the chooser landscape-scenario. Choose a landscape and then either (a) click the load button if the landscape has already been created, or otherwise (b) click the create and save landscape button. If the landscape has been created already, it will exist as a file named cbb-landscape-1.csv (etc). (The landscapes are saved via export-world.) If the landscape does not already exist, you can watch it be created.

After creating or loading a landscape, click setup and go as usual. The model runs for 151 ticks, but the View is updated as birds forage within each tick. You can re-set-up and re-start the model without reloading the landscape.

The area in each habitat type, and the number of clumps of each, are controlled by parameter values set in the procedure set-parameters.

THINGS TO NOTICE

On each tick, one bird is selected randomly to put its pen down; its black trace indicates where the bird foraged over the day.

CREDITS AND REFERENCES

The first version of this model, and the "pattern-oriented modeling" process for designing it, is documented by:

Railsback, S. F., and M. D. Johnson. 2011. Pattern-oriented modeling of bird foraging and pest control in coffee farms. Ecological Modelling 222:3305-3319.

The calibration used to produce this version, and analyses of the model's results, are documented in this publication and its supplementary material:

Railsback, S. F., and M. D. Johnson. 2014. Effects of land use on bird populations and pest control services on coffee farms. Proceedings of the National Academy of Sciences of the United States of America 111:6109-6114.

These publications and additional information on models developed at Cal Poly Humboldt are at: https://www.humboldt.edu/ecological-modeling

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

globals
[
  ; Output file name
  output-file-name

  ; Spatial and temporal scale parameters
  space-width   ; The width of the square space, in m
  cell-size     ; The width of each square cell (patch), in m
  cell-area     ; The area of a cell, m2 (calculated from cell-size
  clump-spacing ; The minimum distance among where clumps are started, in m
  simulation-duration ; The number of days simulated

  forage-time-step     ; Time step length, hrs
  current-time         ; Current time, hrs since daily foraging started

  ; Bird parameters
  initial-bird-density    ; initial density (birds/ha)
  max-forage-hrs-per-day  ; max number of hours of foraging
  forage-radius       ; foraging radius in meters
  daily-min-intake    ; minimum intake to avoid starvation

  ; CBB parameters
  CBB-I-initial-high-shade  ; Initial CBB infestation rate in high-shade coffee
  CBB-I-initial-low-shade   ; Initial CBB infestation rate in low-shade coffee
  CBB-I-r-high-shade        ; Infestation growth rate in high-shade coffee
  CBB-I-r-low-shade         ; Infestation growth rate in low-shade coffee
  CBB-I-K-high-shade-mean        ; Infestation max rate in high-shade coffee
  CBB-I-K-high-shade-SD        ; Infestation max rate in high-shade coffee
  CBB-I-K-low-shade-mean         ; Infestation max rate in low-shade coffee
  CBB-I-K-low-shade-SD         ; Infestation max rate in low-shade coffee
  CBB-berry-dens-high-shade ; Coffee berry density (/m2) in high-shade coffee
  CBB-berry-dens-low-shade  ; Coffee berry density (/m2) in low-shade coffee
  CBB-borer-wt              ; Weight of female borer (g)

  ; Parameters for landuse areas
  frac-forest  ; The fraction of the landscape that is forest
  frac-high-shade ; The fraction of the landscape that is predominantly high-shade coffee
  frac-low-shade  ; The fraction of the landscape that is predominantly low-shade coffee
  frac-unusable   ; The fraction of the landscape that is farmland unusable by birds (e.g., pasture)
  frac-trees      ; The fraction of *non-forest area* that is overlain by trees (small forest patches)
  ; frac-other      ; The fraction that is other land uses (e.g., residential) - assumed all other land

  ; Parameters for number of landuse clumps
  num-forest-clumps
  num-high-shade-clumps
  num-low-shade-clumps
  num-unusable-clumps
  num-trees-clumps

  ; patch sets for landuse types
  forest-patches
  high-shade-patches
  low-shade-patches
  unusable-patches
  trees-patches
  other-patches
  coffee-patches    ; combination of high- and low-shade patches

  ; Colors for landuse types
  forest-color
  high-shade-color
  low-shade-color
  unusable-color
  trees-color
  other-color

  ; Bug parameters
  ; bug-prod-knob ; A multiplier for controlling total bug production, on Interface

  forest-bug-prod
  high-shade-bug-prod
  low-shade-bug-prod
  unusable-bug-prod
  trees-bug-prod
  other-bug-prod

  forest-bug-catchability
  high-shade-bug-catchability
  low-shade-bug-catchability
  unusable-bug-catchability
  trees-bug-catchability
  other-bug-catchability
  CBB-catchability

  ; Output variables for foraging hours
  forage-hrs-forest
  forage-hrs-high-shade
  forage-hrs-low-shade
  forage-hrs-high-shade-CBB
  forage-hrs-low-shade-CBB
  forage-hrs-unusable
  forage-hrs-trees
  forage-hrs-other

  ; Output variables for biomass consumed
  mass-eaten-forest
  mass-eaten-high-shade
  mass-eaten-low-shade
  mass-eaten-unusable
  mass-eaten-trees
  mass-eaten-other
  mass-eaten-CBB

  CBB-I-high-shade-exclosure
  CBB-I-low-shade-exclosure

  ; Virtual survey output variables
  survey-file-name     ; separate output file for bird surveys
  survey-plot-radius   ; radius of survey plot, meters
  survey-frequency     ; days between virtual bird surveys
  is-survey-day?       ; boolean for whether it is a survey day
  survey-num-plots     ; number of survey plots
  survey-spacing       ; minimum distance between plot centers, m
  survey-border-dist   ; maximum distance between plot centers and space border, m
  survey-patches       ; agentset of patches that are survey plot centers

  ; Bug irruption variables
  bug-irruption-patches  ; agentset of patches where irruption occurs
  irruption-end-time         ; last tick of irruption
  irruption-file-name    ; name of output file for irruption results

  ; Move distance output variables
  time-since-last-loc-obs  ; time (h) since last time bird locations were observed
  observed-move-dists-list   ; a list of distances between location observations - over all birds, all hours

]


patches-own
[
  bug-production    ; local copy of land-use-dependent parameter
  bug-catchability  ; local copy of land-use-dependent parameter
  bug-availability  ; total grams bugs available for whole patch

  CBB-I             ; Current infestation rate
  CBB-availability       ; g CBB available as prey in patch
  daily-start-CBB-availability  ; CBB before bird consumption; used to calculate bird consumption
  CBB-I-K  ; Now a patch variable

  distance-to-trees ; Used for virtual bird survey plots
]

turtles-own
[
  home-patch  ; home patch
  daily-intake ; daily grams food consumed
  daily-hours-foraged       ; number of hours that bird actually foraged
  I-ate-CBB?   ; for tracking what birds eat
  times-ate-CBB-today  ; for tracking how many times CBB were eaten

  ; Move distance output variables
  patch-at-last-obs          ; patch where bird was at last hourly location observation
]

to set-parameters

  ; Output file name-
  set output-file-name (word "CoffeeOutput-LS" landscape-scenario ".csv")
  ; Spatial and temporal scale parameters
  set space-width 1000 ; The width of the square space, in m
  set cell-size  5     ; The width of each square cell (patch), in m
  set cell-area (cell-size * cell-size)
  set clump-spacing 200 ; The minimum distance among clump starts, in m
  set simulation-duration 151 ; The number of days simulated - Dec 1 to Apr 30

  set forage-time-step 3 / 60   ; 20 moves per hr  -- Calibrated value

  ; Bird parameters
  set initial-bird-density 30    ; Birds / ha
  set max-forage-hrs-per-day 12
  set forage-radius 9        ; Forage only in adjacent patches
  set daily-min-intake 5.0

  ; Parameters for landuse areas
  set frac-forest        0.1
  set frac-high-shade    0.28
  set frac-low-shade     0.28
  set frac-unusable      0.28
  set frac-trees         0.2
  ; set frac-other         0.1

  let total-land-types (frac-forest + frac-high-shade + frac-low-shade + frac-unusable)

  if total-land-types > 1.001
    [user-message (word "Land use types sum to " total-land-types)]

  ; Parameters for number of landuse clumps
  set num-high-shade-clumps   20
  set num-low-shade-clumps    20
  set num-unusable-clumps     10
  set num-trees-clumps      1000

  ; Set colors for landuse types
  set forest-color      green
  set high-shade-color  grey
  set low-shade-color   yellow
  set unusable-color    brown
  set trees-color       lime
  set other-color       orange

  ; Set bug parameters -- from September 2012 re-calibration. 9/10/2012
  set forest-bug-prod     0.032
  set high-shade-bug-prod 0.022
  set low-shade-bug-prod  0.0085
  set unusable-bug-prod   0.00077
  set trees-bug-prod      0.026
  set other-bug-prod      0.0020

  set forest-bug-catchability      15
  set high-shade-bug-catchability  38
  set low-shade-bug-catchability   71
  set unusable-bug-catchability    15
  set trees-bug-catchability       29
  set other-bug-catchability       15
  set CBB-catchability           1100

  ; Set CBB parameters
  set CBB-I-initial-high-shade  0.05  ; Initial CBB infestation rate in high-shade coffee
  set CBB-I-initial-low-shade   0.05  ; Initial CBB infestation rate in low-shade coffee
  set CBB-I-r-high-shade        0.05  ; Infestation growth rate in high-shade coffee
  set CBB-I-r-low-shade         0.05  ; Infestation growth rate in low-shade coffee
  set CBB-I-K-high-shade-mean      0.20  ; Mean infestation max rate in high-shade coffee
  set CBB-I-K-high-shade-SD        0.05  ; SD of infestation max rate in high-shade coffee
  set CBB-I-K-low-shade-mean       0.40  ; Mean infestation max rate in low-shade coffee
  set CBB-I-K-low-shade-SD         0.10  ; SD of infestation max rate in low-shade coffee
  set CBB-berry-dens-high-shade 220   ; Coffee berry density (/m2) in high-shade coffee
  set CBB-berry-dens-low-shade  270   ; Coffee berry density (/m2) in low-shade coffee
  set CBB-borer-wt            0.00049 ; Weight of female borer (g)

  ; Virtual survey output variables
  set survey-file-name (word "VirtualSurvey-LS" landscape-scenario ".csv")
  set survey-plot-radius 11.3        ; radius of survey plot, meters
  set survey-frequency 30            ; days between virtual bird surveys
  set survey-num-plots 30            ; number of survey plots
  set survey-spacing 10              ; minimum distance between plot centers, m
  set survey-border-dist 10          ; maximum distance between plot centers and space border, m
  set survey-patches patch-set nobody  ; agentset of patches that are survey plot centers

  ; Bug irruption variables
  set bug-irruption-patches patch-set nobody  ; agentset of patches where irruption occurs

  ; Move distance output variables
  set time-since-last-loc-obs 0.0  ; time (h) since last time bird locations were observed
end 

to load-landscape

  clear-all

  ; set parameter values, in a separate procedure
  set-parameters

  ; Temporarily store any globals defined on the interface because "import-world" overwrites them
  ; let temp-initial-bird-density initial-bird-density

  ; size the world
  let max-cor ((space-width / cell-size) - 1)
  resize-world 0 max-cor 0 max-cor
  set-patch-size 2.5     ; Controls size of world display

  ; Load a landscape file or have user create one
  let landscape-file (word "cbb-landscape-" landscape-scenario ".csv")
  ifelse file-exists? landscape-file
  [
    show (word "Loading landscape file " landscape-file)
    import-world landscape-file
  ]
  [
    user-message (word "Please create landscape file for scenario " landscape-scenario)
    stop
  ]

  ; And we need to restore any globals defined on the interface because "import-world" overwrites them
  ; set initial-bird-density temp-initial-bird-density
end 

to setup

  ; Clean up manually -- Cannot clear-all because it would destroy landscape
  ask turtles [die]
  ask patches [set plabel ""]
  reset-ticks
  clear-all-plots

  ; Now we unfortunately need to set the parameters again because loading the world
  ; un-sets them
  set-parameters

  ; Set a new random seed because "import-world" restores an old one
  random-seed 100161 ; new-seed

  ; initial agentsets of land use patches
  set forest-patches patches with [pcolor = forest-color]
  set high-shade-patches patches with [pcolor = high-shade-color]
  set low-shade-patches patches with [pcolor = low-shade-color]
  set unusable-patches patches with [pcolor = unusable-color]
  set trees-patches patches with [pcolor = trees-color]
  set other-patches patches with [pcolor = other-color]
  set coffee-patches (patch-set high-shade-patches low-shade-patches)

  ; Some defensive programming...make sure we loaded a landscape
  if (count forest-patches) + (count high-shade-patches) + (count low-shade-patches) + (count other-patches) = 0
  [
    user-message "You need to load a landscape before running Setup"
    stop
  ]

  ; Initialize static patch variables
  ask forest-patches [set bug-production forest-bug-prod]
  ask high-shade-patches [set bug-production high-shade-bug-prod]
  ask low-shade-patches [set bug-production low-shade-bug-prod]
  ask unusable-patches [set bug-production unusable-bug-prod]
  ask trees-patches [set bug-production trees-bug-prod]
  ask other-patches [set bug-production other-bug-prod]

  ask forest-patches [set bug-catchability forest-bug-catchability]
  ask high-shade-patches [set bug-catchability high-shade-bug-catchability]
  ask low-shade-patches [set bug-catchability low-shade-bug-catchability]
  ask unusable-patches [set bug-catchability unusable-bug-catchability]
  ask trees-patches [set bug-catchability trees-bug-catchability]
  ask other-patches [set bug-catchability other-bug-catchability]

  ; Initialize CBB rates
  ask patches [set CBB-availability 0]
  ask high-shade-patches
  [
    set CBB-I CBB-I-initial-high-shade
    set CBB-I-K random-normal CBB-I-K-high-shade-mean CBB-I-K-high-shade-SD
    if CBB-I-K < CBB-I [set CBB-I-K CBB-I]   ; The max infestation rate can't be less than starting rate
    if CBB-I-K > 1.0 [set CBB-I-K 1.0]
  ]
  ask low-shade-patches
  [
    set CBB-I CBB-I-initial-low-shade
    set CBB-I-K random-normal CBB-I-K-low-shade-mean CBB-I-K-low-shade-SD
    if CBB-I-K < CBB-I [set CBB-I-K CBB-I]   ; The max infestation rate can't be less than starting rate
    if CBB-I-K > 1.0 [set CBB-I-K 1.0]
  ]
  do-CBB-dynamics

  ; And globals representing exclosures
  set CBB-I-high-shade-exclosure CBB-I-initial-high-shade
  set CBB-I-low-shade-exclosure CBB-I-initial-low-shade

  ; And tracking movement distances
  set observed-move-dists-list (list)


  ; Initialize birds. "initial-bird-density" is sometimes a slider; birds per ha over the whole space.
  ; In Vers. 2, home patches must be tree or forest patches.
  let potential-home-patches (patch-set forest-patches trees-patches)
  crt initial-bird-density * (count patches * cell-area) / 10000 ; m2 / ha
  [
    set size 2
    move-to one-of potential-home-patches
    set home-patch patch-here

    set patch-at-last-obs patch-here
  ]

  ; Open the main output file
  ; Do not delete it instead of appending to it because we could be doing multiple model run experiments
  ; Instead- print headers only if the file is new, and put date and time
  ; as separator between model runs

  ; Commented out for production runs

  ifelse (file-exists? output-file-name)
  [
    file-open output-file-name
    ; Print a header between model runs
    file-type date-and-time
    file-type (word ",Landscape:," landscape-scenario)
    file-type (word ",Total area:," (count patches * cell-area))
    file-type (word ",Fraction forest:," (count forest-patches / count patches))
    file-type (word ",Fraction high-shade:," (count high-shade-patches / count patches))
    file-type (word ",Fraction low-shade:," (count low-shade-patches / count patches))
    file-type (word ",Fraction unusable:," (count unusable-patches / count patches))
    file-type (word ",Fraction trees:," (count trees-patches / count patches))
    file-print (word ",Fraction other:," (count other-patches / count patches))
  ]
  [
    file-open output-file-name
    file-print date-and-time
    file-type ","

    file-type "day,"
    file-type "bird-abundance,"
    file-type "hrs-foraged,"
    file-type "cbb-rate-high-shade,"
    file-type "cbb-rate-low-shade,"
    file-type "cbb-rate-high-shade-exclosure,"
    file-type "cbb-rate-low-shade-exclosure,"
    file-type "bird-density-forest,"
    file-type "bird-density-high-shade,"
    file-type "bird-density-low-shade,"
    file-type "bird-density-high-shade-CBB,"
    file-type "bird-density-low-shade-CBB,"
    file-type "bird-density-unusable,"
    file-type "bird-density-trees,"
    file-type "bird-density-other,"
    file-type "mass-eaten-forest,"
    file-type "mass-eaten-high-shade,"
    file-type "mass-eaten-low-shade,"
    file-type "mass-eaten-unusable,"
    file-type "mass-eaten-trees,"
    file-type "mass-eaten-other,"
    file-type "mass-eaten-CBB,"
    file-print "CBB-cons-events"
  ]
  file-close

;  initialize-virtual-surveys
end 

to go

  tick
  if ticks > simulation-duration [stop]

  ; First, re-set daily bug availability
  ask patches [set bug-availability (bug-production *  cell-area)]

  ; Second, model CBB infestation and prey density
  do-CBB-dynamics

  ; Third, reset daily variables
  reset-daily-variables

  ; Optional test output file -- NOTE file is over-written each time step! It's big
  ;if file-exists? "Forage-Test-Output.csv" [file-delete "Forage-Test-Output.csv"]
  ;file-open "Forage-Test-Output.csv"
  ;file-print "Turtle,time,pxcor,pycor,pcolor,bug-availability,bug-catchability,CBB-availability,CBB-catchability,Intake/h"

  ; Fourth, birds forage repeatedly
  ; Number of moves each day = hrs / (hrs/move) (truncates to integer)
  repeat (max-forage-hrs-per-day / forage-time-step)
  [
    set current-time current-time + forage-time-step
    ask turtles [forage]
  ;  if is-survey-day? [ do-bird-survey ]         ; Commented out for production runs
    update-irruption
  ;  do-location-surveys         ; Commented out for production runs
  ]


  ; Close the optional test output file
  ; file-close

  ; Fifth, birds go back home at night.
  ask turtles [move-to home-patch]

  ; Sixth, birds die if they could not eat enough
  ask turtles
  [
    if daily-intake < daily-min-intake [if random-float 1.0 < 0.2 [die]] ; 1/5 of starving birds die, to weed out excess
  ]

  ; Finally, update outputs
   update-output
end 

to reset-daily-variables

  ; Reset bird foraging variables
    ask turtles
  [
    set daily-intake 0
    set daily-hours-foraged 0
    set times-ate-CBB-today 0
  ]

  set forage-hrs-forest 0
  set forage-hrs-high-shade 0  ; So BehaviorSpace reports total over run
  set forage-hrs-low-shade 0
  set forage-hrs-high-shade-CBB 0
  set forage-hrs-low-shade-CBB 0
  set forage-hrs-unusable 0
  set forage-hrs-trees 0
  set forage-hrs-other 0
  set observed-move-dists-list (list)

  ; Have one turtle trace its path, after erasing previous traces
  ask turtles [pu]
  clear-drawing
  if any? turtles
  [ask one-of turtles
    [
      set color black
      pd
    ]
  ]  ; if any? turtles

  ; Determine if it is a bird census day
  ifelse (remainder ticks survey-frequency) = 0
  [set is-survey-day? true]
  [set is-survey-day? false]

  ; Reset time-of-day counter
  set current-time 0.0
end 

to forage   ; a turtle procedure for selecting habitat and feeding, repeated within day

  if daily-intake > daily-min-intake [stop]

  set I-ate-CBB? false

  move-to max-one-of patches in-radius (forage-radius / cell-size) [food-intake-rate]
  feed
  set daily-hours-foraged (daily-hours-foraged + forage-time-step)

  ; Update output variables
  if I-ate-CBB? [ set times-ate-CBB-today times-ate-CBB-today + 1 ]
  ifelse pcolor = forest-color [set forage-hrs-forest forage-hrs-forest + forage-time-step]
  [ ifelse pcolor = high-shade-color [ifelse I-ate-CBB?
                                          [set forage-hrs-high-shade-CBB forage-hrs-high-shade-CBB + forage-time-step]
                                          [set forage-hrs-high-shade forage-hrs-high-shade + forage-time-step] ]
    [ ifelse pcolor = low-shade-color [ifelse I-ate-CBB?
                                          [set forage-hrs-low-shade-CBB forage-hrs-low-shade-CBB + forage-time-step]
                                          [set forage-hrs-low-shade forage-hrs-low-shade + forage-time-step] ]
      [ ifelse pcolor = unusable-color [set forage-hrs-unusable forage-hrs-unusable + forage-time-step]
        [ ifelse pcolor = trees-color [set forage-hrs-trees forage-hrs-trees + forage-time-step]
          [ ifelse pcolor = other-color [set forage-hrs-other forage-hrs-other + forage-time-step]
              [user-message "Invalid patch type in forage"]
          ]
        ]
      ]
    ]
  ]
end 

to-report food-intake-rate  ; a patch reporter; intake rate in g / hr
                            ; The reporter depends on a valid value of catchability to keep birds from having
                            ; intake higher than the total food available in the patch.

  ; Test output
  ; file-type (word [who] of myself "," current-time "," pxcor "," pycor "," pcolor "," bug-availability "," bug-catchability "," CBB-availability "," CBB-catchability)
  ifelse CBB-availability <= 0.0
  [
  ;  file-print (word "," ((bug-availability / cell-area) * bug-catchability))
    report  (bug-availability / cell-area) * bug-catchability
  ]
  [
    let bug-intake (bug-availability / cell-area) * bug-catchability
    let CBB-intake (CBB-availability / cell-area) * CBB-catchability

    ifelse bug-intake > CBB-intake
    [
   ;   file-print (word "," bug-intake)
      report bug-intake
    ]
    [
   ;   file-print (word "," CBB-intake)
      report CBB-intake
    ]
  ]
end 

to feed   ; a bird procedure that uses variables of the bird's patch
          ; Revised 22 Feb 2012 so birds do not consume more than available.

 ; let intake ([food-intake-rate] of patch-here) * forage-time-step
 ; set daily-intake (daily-intake + intake)

  let bug-intake (bug-availability / cell-area) * bug-catchability * forage-time-step
  let CBB-intake (CBB-availability / cell-area) * CBB-catchability * forage-time-step

  ifelse bug-intake > CBB-intake
    [
      if bug-intake > bug-availability [set bug-intake bug-availability]
      set bug-availability (bug-availability - bug-intake)
      set daily-intake (daily-intake + bug-intake)
    ]
    [
      set I-ate-CBB? true
      if CBB-intake > CBB-availability [set CBB-intake CBB-availability]
      set CBB-availability (CBB-availability - CBB-intake)
      set daily-intake (daily-intake + CBB-intake)
    ]
end 

to do-CBB-dynamics  ; High and low shade patches use the same methods but different parameters

  ask high-shade-patches
  [
    ; First re-calculate yesterday's change in inf. rate to reflect bird consumption
    ; then update the infestation rate
    let dI CBB-availability / (CBB-berry-dens-high-shade * CBB-borer-wt * cell-area)
    set CBB-I CBB-I + dI

    ; Second, update infestation rate for logistic increase
    set dI CBB-I-r-high-shade * CBB-I * (1 - (CBB-I / CBB-I-K))

    ; Third, update CBB biomass exposed to bird predation
    set CBB-availability dI * CBB-berry-dens-high-shade * CBB-borer-wt * cell-area
    set daily-start-CBB-availability CBB-availability

  ]

  ask low-shade-patches
  [
    ; First re-calculate yesterday's change in inf. rate to reflect bird consumption
    ; then update the infestation rate
    let dI CBB-availability / (CBB-berry-dens-low-shade * CBB-borer-wt * cell-area)
    set CBB-I CBB-I + dI

    ; Second, update infestation rate for logistic increase
    set dI CBB-I-r-low-shade * CBB-I * (1 - (CBB-I / CBB-I-K))

    ; Third, update CBB biomass exposed to bird predation
    set CBB-availability dI * CBB-berry-dens-low-shade * CBB-borer-wt * cell-area
    set daily-start-CBB-availability CBB-availability

  ]
end 

to create-landscape

  ;; (for this model to work with NetLogo's new plotting features,
  ;; __clear-all-and-reset-ticks should be replaced with clear-all at
  ;; the beginning of your setup procedure and reset-ticks at the end
  ;; of the procedure.)
  __clear-all-and-reset-ticks

  ; set parameter values, in a separate procedure
  set-parameters

  ; size the world
  let max-cor ((space-width / cell-size) - 1)
  resize-world 0 max-cor 0 max-cor
  set-patch-size 4     ; Controls size of world display

  random-seed landscape-scenario   ; "scenario" is chosen on interface; provides discrete number of landscapes

  show (word "Creating landscape scenario " landscape-scenario)

  create-forest

  create-clumps-for frac-unusable num-unusable-clumps unusable-color

  create-clumps-for frac-high-shade num-high-shade-clumps high-shade-color

  create-clumps-for frac-low-shade num-low-shade-clumps low-shade-color

  create-sprinkles-for frac-trees num-trees-clumps trees-color

  ; Set remaining patches to "other" color - the default land use
  ask patches with [pcolor = black] [set pcolor other-color]


  random-seed new-seed
end 

to create-forest

  let num-forest-patches frac-forest * count patches

  ; To save time, first create a solid strip of half the forest
  ask patches with [pxcor > (max-pxcor * (1 - (frac-forest / 2)))]  [set pcolor forest-color]


  ; Now add patches randomly to the strip to create a ragged edge
  while [count patches with [pcolor = forest-color] < num-forest-patches]

  [
    ; get rid of isolated patches of non-forest
    ask patches with [pcolor != forest-color and count neighbors with [pcolor = forest-color] > 6]
      [ set pcolor forest-color]

    ask one-of patches with [pcolor != forest-color and any? neighbors with [pcolor = forest-color] ]
    ; For smoother boundary, replace "any?" with "count neighbors with [pcolor = forest-color] > 1" etc.
    [
      set pcolor forest-color
    ]

  ]
end 

to create-clumps-for [frac-area num-clumps a-color]  ; Observer method to create clumps of a habitat type

  let tries 0
  let successes 0

  while [tries < 1000]
  [
    let seed-patch one-of patches with [pcolor = black]
    ask seed-patch
    [
      ifelse any? patches in-radius (clump-spacing / cell-size) with [pcolor = a-color]
      [stop]
      [
        set successes successes + 1
        set pcolor a-color
        ; ask neighbors with [pcolor = black] [set pcolor a-color] This makes clump a little rounder
      ]
    ]
    set tries tries + 1
    if successes >= num-clumps [set tries 1000]

  ] ; while [tries < 1000]


  let num-patches-to-use count patches * frac-area
  while [count patches with [pcolor = a-color] < num-patches-to-use]
  [
    let avail-patches patches with [pcolor = a-color and any? neighbors with [pcolor = black]]
    ifelse any? avail-patches
    [
      ask one-of avail-patches
        [
          ask neighbors with [pcolor = black] [set pcolor a-color]
        ]
    ]
    [
      user-message (word "Not enough black patches available for landuse color " a-color)
      stop
    ]

  ] ; while [count patches with [pcolor = a-color]
end 

to create-sprinkles-for [frac-area num-clumps a-color]

  if frac-area <= 0 [stop]

  let mean-size (frac-area * count patches) / num-clumps ; mean area, in patches, of tree sprinkles
  ; show mean-size

  repeat num-clumps
  [
    let sprinkle patch-set one-of patches with [pcolor != forest-color and pcolor != a-color]
    ask one-of sprinkle [set pcolor a-color]
    let sprinkle-size round (random-exponential mean-size)
    ; show sprinkle-size

    while [count sprinkle < sprinkle-size]
    [
      let a-patch one-of sprinkle with [any? neighbors with [pcolor != forest-color and pcolor != a-color]]
      ifelse a-patch = nobody ; patch is isolated in forest so grab another
      [
        set sprinkle patch-set one-of patches with [pcolor != forest-color and pcolor != a-color]
        ask one-of sprinkle [set pcolor a-color]
      ]
      [
        ask a-patch
        [
          ask one-of neighbors with [pcolor != forest-color and pcolor != a-color]
          [
            set pcolor a-color
            set sprinkle (patch-set sprinkle self)
          ]
        ]
      ]

    ]
  ]
end 

to initialize-virtual-surveys

  ifelse (file-exists? survey-file-name)
  [
    file-open survey-file-name
    ; Print a header between model runs
    file-print date-and-time
  ]
  [
    file-open survey-file-name
    file-print date-and-time
    file-type ","

    file-type "day,"
    file-type "time,"
    file-type "plot-center-XY,"
    file-type "plot-area,"
    file-type "distance-to-trees,"
    file-print "bird-count"
  ]

  file-close

  let tries 0
  let successes 0
  let border-dist survey-border-dist / cell-size
  let possible-patches coffee-patches with
  [
    (pxcor - min-pxcor > border-dist) and
    (max-pxcor - pxcor > border-dist) and
    (pycor - min-pycor > border-dist) and
    (max-pycor - pycor > border-dist)
  ]
  ; show count possible-patches

  while [tries < 1000]
  [
    let seed-patch one-of possible-patches
    ask seed-patch
    [
      ifelse any? survey-patches in-radius (survey-spacing / cell-size)
      [stop]
      [
        set successes successes + 1
        set survey-patches (patch-set survey-patches seed-patch)
        set plabel "S"
      ]
    ]
    set tries tries + 1
    if successes >= survey-num-plots [set tries 1000]
  ]

  ; Now calculate the distance to forest or trees
  let forest+tree-patches (patch-set forest-patches trees-patches)
  ask survey-patches
  [
    set distance-to-trees cell-size * (distance min-one-of forest+tree-patches [distance myself])
  ]
end 

to do-bird-survey

  file-open survey-file-name

  ask survey-patches
  [
    file-type "," ; Blank column for separator between runs
    file-type (word ticks ",")
    file-type (word current-time ",")
    file-type (word pxcor "x" pycor ",")
    file-type (word ((count patches in-radius (survey-plot-radius / cell-size)) * cell-area) ",")
    file-type (word distance-to-trees ",")
    file-print count (turtles-on (patches in-radius survey-plot-radius)) with [daily-intake < daily-min-intake]
  ]

  file-close
end 

to start-irruption   ; a patch procedure for bug irruptions, executed from an Agent Monitor

  ; First, you can't start one irruption if another is under way (messes up output)
  if count bug-irruption-patches > 0
  [
    user-message "An irruption is already underway; you cannot start another now"
    stop
  ]

  set bug-irruption-patches patches in-radius (25 / cell-size)  ; irruptions occur over 25-m radius
  ask bug-irruption-patches [set plabel "I"]

  set irruption-end-time (ticks + 30)   ; irruptions last 10 days

  set irruption-file-name (word "BugIrruptionAtTick" ticks ".csv")

  file-open irruption-file-name  ; File is always appended, with new header line
  file-print (word date-and-time "," "Coordinates of irruption center:" "," pxcor "," pycor)
  file-type ","

  file-type "day,"
  file-type "time,"
  file-type "bug production,"
  file-type "irruption-area,"
  file-print "bird-count"

  file-close
end 

to update-irruption   ; an observer procedure to execute bug irruptions, once they are started

  ; Stop if there is no irruption
  if count bug-irruption-patches = 0 [stop]


  ; First see if it's time to increase bug production - 10 days after start
  if (irruption-end-time - ticks = 20) and (current-time <= forage-time-step)
  [
    ask bug-irruption-patches [set bug-production (bug-production * 5)]  ; irruptions increase bugs x 5
  ]

  ; Next see if it's time to reset bug production - 20 days after start
  if (irruption-end-time - ticks = 10) and (current-time <= forage-time-step)
  [
    ask bug-irruption-patches [set bug-production (bug-production / 5)]  ; irruptions increase bugs x 5
    ; Re-calculate daily bug availability to avoid triggering "user message" in update-output
    ask patches [set bug-availability (bug-production *  cell-area)]
  ]

  ; Then, see if it's over
  if ticks >= irruption-end-time
  [
    ask bug-irruption-patches [set plabel ""]
    set bug-irruption-patches patch-set nobody
    stop
  ]


  file-open irruption-file-name  ; File is always appended, with new header line
  file-type ","

  file-type (word ticks ",")
  file-type (word current-time ",")
  file-type (word (mean [bug-production] of bug-irruption-patches) ",")
  file-type (word (count bug-irruption-patches * cell-area) ",")
  file-print count (turtles-on bug-irruption-patches) with [daily-intake < daily-min-intake]

  file-close
end 

to do-location-surveys     ; observer procedure to observe bird locations and movement distances hourly

  ifelse time-since-last-loc-obs < 1.0
  [
    set time-since-last-loc-obs time-since-last-loc-obs + forage-time-step
  ]
  [
    set time-since-last-loc-obs forage-time-step  ; re-set the timer
    ask turtles with [daily-intake < daily-min-intake]
    [
      set observed-move-dists-list fput (cell-size * distance patch-at-last-obs) observed-move-dists-list
      set patch-at-last-obs patch-here
    ]
  ]
end 

to update-output
  ;
  ; First calculate outputs
  ;
  ; Bird densities by habitat type
  let bird-density-forest         (forage-hrs-forest / max-forage-hrs-per-day) / (count forest-patches * cell-area / 10000)
  let bird-density-high-shade     (forage-hrs-high-shade / max-forage-hrs-per-day) / (count high-shade-patches * cell-area / 10000)
  let bird-density-low-shade      (forage-hrs-low-shade / max-forage-hrs-per-day) / (count low-shade-patches * cell-area / 10000)
  let bird-density-high-shade-CBB (forage-hrs-high-shade-CBB / max-forage-hrs-per-day) / (count high-shade-patches * cell-area / 10000)
  let bird-density-low-shade-CBB  (forage-hrs-low-shade-CBB / max-forage-hrs-per-day) / (count low-shade-patches * cell-area / 10000)
  let bird-density-unusable       (forage-hrs-unusable / max-forage-hrs-per-day) / (count unusable-patches * cell-area / 10000)
  let bird-density-trees          (forage-hrs-trees / max-forage-hrs-per-day) / (count trees-patches * cell-area / 10000)
  let bird-density-other          (forage-hrs-other / max-forage-hrs-per-day) / (count other-patches * cell-area / 10000)

  ; Calculate daily food consumption by habitat type
  set mass-eaten-forest 0
  set mass-eaten-high-shade 0
  set mass-eaten-low-shade 0
  set mass-eaten-unusable 0
  set mass-eaten-trees 0
  set mass-eaten-other 0
  set mass-eaten-CBB 0

  ; First some defensive programming
  ask patches
  [
    if (bug-production < 0.0) or (bug-availability < 0.0) or (bug-production * cell-area < bug-availability)
    [
      user-message (word "Bug production error at patch " pxcor " " pycor
        " Production: " bug-production " Availability: " bug-availability)
    ]
  ]  ; ask patches

  ask coffee-patches
  [
    if (daily-start-CBB-availability < 0.0) or (CBB-availability < 0.0) or (daily-start-CBB-availability < CBB-availability)
    [
      user-message (word "CBB production error at patch " pxcor " " pycor
        " Starting avail: " daily-start-CBB-availability " Ending avail: " CBB-availability)
    ]
  ]  ; ask coffee-patches

  ; Each patch increases total consumption by the difference between its production and
  ; the biomass left at the end of the day
  ask forest-patches [set mass-eaten-forest (mass-eaten-forest + (bug-production * cell-area) - bug-availability)]
  ask high-shade-patches [set mass-eaten-high-shade (mass-eaten-high-shade + (bug-production * cell-area) - bug-availability)]
  ask low-shade-patches [set mass-eaten-low-shade (mass-eaten-low-shade + (bug-production * cell-area) - bug-availability)]
  ask unusable-patches [set mass-eaten-unusable (mass-eaten-unusable + (bug-production * cell-area) - bug-availability)]
  ask trees-patches [set mass-eaten-trees (mass-eaten-trees + (bug-production * cell-area) - bug-availability)]
  ask other-patches [set mass-eaten-other (mass-eaten-other + (bug-production * cell-area) - bug-availability)]
  ask high-shade-patches [set mass-eaten-CBB (mass-eaten-CBB + daily-start-CBB-availability - CBB-availability)]
  ask low-shade-patches [set mass-eaten-CBB (mass-eaten-CBB + daily-start-CBB-availability - CBB-availability)]

  ; Calculate CBB infestation rates for exclosures (rates with no bird consumption)
  let dI CBB-I-r-high-shade * CBB-I-high-shade-exclosure * (1 - (CBB-I-high-shade-exclosure / CBB-I-K-high-shade-mean))
  set CBB-I-high-shade-exclosure (CBB-I-high-shade-exclosure + dI)
  set dI CBB-I-r-low-shade * CBB-I-low-shade-exclosure * (1 - (CBB-I-low-shade-exclosure / CBB-I-K-low-shade-mean))
  set CBB-I-low-shade-exclosure (CBB-I-low-shade-exclosure + dI)

  ;
  ; Now write file output
  ;
  file-open output-file-name
  file-type "," ; Blank column for separator between runs
  file-type (word ticks ",")
  file-type (word (count turtles) ",")
  file-type (word (mean [daily-hours-foraged] of turtles) ",")
  file-type (word (mean [CBB-I] of high-shade-patches) ",")
  file-type (word (mean [CBB-I] of low-shade-patches) ",")
  file-type (word CBB-I-high-shade-exclosure ",")
  file-type (word CBB-I-low-shade-exclosure ",")

  file-type (word bird-density-forest ",")
  file-type (word bird-density-high-shade ",")
  file-type (word bird-density-low-shade ",")
  file-type (word bird-density-high-shade-CBB ",")
  file-type (word bird-density-low-shade-CBB ",")
  file-type (word bird-density-unusable ",")
  file-type (word bird-density-trees ",")
  file-type (word bird-density-other ",")

  file-type (word mass-eaten-forest ",")
  file-type (word mass-eaten-high-shade ",")
  file-type (word mass-eaten-low-shade ",")
  file-type (word mass-eaten-unusable ",")
  file-type (word mass-eaten-trees ",")
  file-type (word mass-eaten-other ",")
  file-type (word mass-eaten-CBB ",")
  file-print sum [ times-ate-CBB-today ] of turtles
  file-close

  ;
  ; Plot outputs
  ;
  set-current-plot "Foraging hours histogram"
  histogram [daily-hours-foraged] of turtles

  ; Plot foraging densities: birds / day / ha
  set-current-plot "Bird density"

  set-current-plot-pen "Forest"
  plot bird-density-forest

  set-current-plot-pen "High shade"
  plot bird-density-high-shade

  set-current-plot-pen "Low shade"
  plot bird-density-low-shade

  set-current-plot-pen "High shade CBB"
  plot bird-density-high-shade-CBB

  set-current-plot-pen "Low shade CBB"
  plot bird-density-low-shade-CBB

  set-current-plot-pen "Unusable"
  plot bird-density-unusable

  set-current-plot-pen "Trees"
  plot bird-density-trees

  set-current-plot-pen "Other"
  plot bird-density-other

  ; Plot CBB availability
  set-current-plot "CBB availability"
  histogram [CBB-availability] of coffee-patches

  ; Plot daily food consumption by habitat type
  set-current-plot "Bug consumption"
  set-current-plot-pen "Forest"
  plot mass-eaten-forest

  set-current-plot-pen "High shade"
  plot mass-eaten-high-shade

  set-current-plot-pen "Low shade"
  plot mass-eaten-low-shade

  set-current-plot-pen "Unusable"
  plot mass-eaten-unusable

  set-current-plot-pen "Trees"
  plot mass-eaten-trees

  set-current-plot-pen "Other"
  plot mass-eaten-other

  set-current-plot-pen "CBB"
  plot mass-eaten-CBB

  ; Update histogram of movement distances
  set-current-plot "Hourly move distance histogram"
  histogram observed-move-dists-list
end 

There is only one version of this model, created 4 days ago by Steve Railsback.

Attached files

File Type Description Last updated
Coffee Farm Model.png preview Preview for 'Coffee Farm Model' 4 days ago, by Steve Railsback Download

This model does not have any ancestors.

This model does not have any descendants.