07 EffLab_V5.07 NL

07 EffLab_V5.07 NL preview image

1 collaborator

121210_portrait_of_garvin Garvin Boyle (Author)

Tags

(This model has yet to be categorized with any tags)
Model group Sustainability | Visible to everyone | Changeable by everyone
Model was written in NetLogo 5.0.5 • Viewed 298 times • Downloaded 20 times • Run 0 times
Download the '07 EffLab_V5.07 NL' modelDownload this modelEmbed this model

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


Info tab cannot be displayed because of an encoding error

Comments and Questions

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

Click to Run Model

;;-----------------------------------------------------------------------------|
;; SECTION A – AUTHOR IDENTIFICATION AND CODE ABSTRACT
;;-----------------------------------------------------------------------------|
;;
;; File Name: EffLab_I_V5.06.nlogo
;; By Orrery Software
;; Dated: 2019-10-06
;; Author contact:
;;   Garvin H Boyle
;;   orrery@rogers.com
;;   http://orrery-software.webs.com

;; As the author, I welcome questions, discussion of issues and suggestions
;;   for improvements.

;;-----------------------------------------------------------------------------|
;; This EffLab app is a laboratory in which students can study aspects 
;;   of the phenomenon of efficiency as described in my 
;;   associated diary notes.

;; In this model, nrg arrives in a steady stream from the Sun and is captured
;;   in plants that produce fruit, which appears randomly in dales in the 
;;   forest.  Nomadic seekers roaming the forest according to their own 
;;   heuristic strategy seek the dales currently having food, and harvest it.
;;   The strategies start as ineffective bland heuristics, and evolve to be 
;;   much more sophisticated. In the most simple scenario, all actions are 
;;   instinctive.  The efficiency is calculated for individual seekers, as well
;;   as for the trophic level (seekers) as a whole.

;;-----------------------------------------------------------------------------|
;; SECTION B – INITIAL DECLARATIONS OF GLOBALS AND BREEDS
;;-----------------------------------------------------------------------------|
;;
;;-----------------------------------------------------------------------------|
;; This program was developed on NetLogo Version 5.0.5
;;

;;-----------------------------------------------------------------------------|
;; code-determined global variables
globals
[
  ;; The version should be coded in this global variable to be included in
  ;;   output files.
  gs-Version
  
  ;; Note: Some global variables are declared inside of switches, sliders and 
  ;;   choosers when the interface is constructed and are not declared here.
  ;;   For the sake of clarity and completeness, they are noted here.
  
  ;; There are several uses of global variables:
  ;;  - Toggles (switches), and choosers which enable or disable features;
  ;;  - Numbers (in variables or sliders) which act as parameters;
  ;;  - Numbers (in variables) which collect data.
  ;;
  ;; Those marked as 'native Boolean' have values of true or false.
  ;; Those marked as 'numeric Boolean' have values of 1 or 0.
   
  ;;---------------------
  ;; MODELING ENVIRONMENT
  ;;---------------------
  
  ;; Assumed “Model Settings” on startup
  ;; horizontal wrap: on
  ;; vertical wrap: on
  ;; location of origin: centre
  ;; patch size: 10 pixels
  ;;-------------------------------------------------------------------------|
  ;; Implicit global variables due to model settings – patch locations
  ;; min-pxcor  -45
  ;; max-pxcor   45
  ;; min-pycor  -20
  ;; max-pycor   20
  ;; So, the arena is 41 x 91 cells.
  
  ;;----------------------------
  ;; SCENARIO SELECTION CONTROLS
  ;;----------------------------
  
  ;; gs-scenario         ;; Chooser, string converts to a scenario number
  g-scenario-number      ;; scenario no.; 0; interp. of gs-scenario
  ;; Glogal enumeration variables - There is only 1 scenario possible.
  ge-scenario-zero       ;; scenario 0, Small Beginnings
  ge-scenario-one        ;; scenario 1, At Carrying Capacity
  ;; g-seekers-at-start  ;; For Scenario 0, [1,1,100,10]
  
  ;; To halt a scenario at a pre-determined tick.
  ;; g-halt-at-tick      ;; Has it's own input box

  ;; Initialize the Pseudo Random Number Generator (PRNG).
  ;; g-use-this-seed     ;; Slider [1,1,100,7]

  ;;-----------------------------------------------
  ;; BIOPHYSICAL SUB-SYSTEM CONTROLS AND PARAMETERS
  ;;-----------------------------------------------

  ;; Biophyscial life function parameters, seekers.
  ;; g-c2-dat-parm  ;; The death age threshold
  ;; g-c2-det-parm  ;; The death nrg threshold
  ;; g-c2-rat-parm  ;; The reproductive age threshold
  ;; g-c2-ret-parm  ;; The reproductive nrg threshold
  ;; g-c2-epm-parm  ;; The nrg per move
  ;; g-c2-epa-parm  ;; The maximum nrg an agent may hold
  
  ;; The global list of possible heading deltas for moves.
  gl-heading-list  ;; List of heading deltas.
  gl-index-list    ;; List of numbers 0-7 in order
  gl-base-factors  ;; List of factors, used to mutate bases
  
  ;; Nrg control variables
  ;; g-nrg-per-deposit  ;; Nrg deposited per Dale [1,1,100,40]
  ;; g-prob-of-deposit  ;; Prob nrg will be deposited [0,.001,1,.05]
  ;; g-heuristic-delta  ;; Amount added to heuristic on success [0,.001,2,1]
  ;; g-prob-of-mutation ;; As it says [0,.001,1,0.95]
  ;; g-dt-for-ind-stats      ;; Delta time, used for EROI [40,40,400,200]

  ;; Nrg accounting variables
  g-nrg-in-fruit        ;; Nrg held in the fruit.
  g-nrg-in-agents       ;; Nrg held in the agents.
  g-nrg-in-system       ;; Total nrg in the system.
  g-sun-takeup-actual   ;; As measured

  ;; Global enumeration (ge-) codes for cause of death.
  ge-cod-none
  ge-cod-fission
  ge-cod-hunger
  ge-cod-oldage

  ;; List to hold counts of cause of death.
  gl-causes-of-death-per-tick
  gl-causes-of-death-cumulative

  ;;-------------------------------------
  ;; END OF MODEL PARAMETERS AND CONTROLS
  ;;-------------------------------------
  
  ;;-------------------------------------
  ;; DATA COLLECTION AND DISPLAY CONTROLS
  ;;-------------------------------------
  
  ;; The following global variables are not model controls or paramaters, 
  ;;   but, rather, are variables used to collect data about the model 
  ;;   for display in the user interface, in some fashion (monitors or plots),
  ;;   or used to manage all of the debug routines and output.
  
  ;; Global enumeration (ge-) codes.
  ge-sinktype-discard   ;; Discarded sunlight
  ge-sinktype-move-EPM  ;; Seekers EPM
  ge-sinktype-die-DET   ;; Remaining nrg of seeker on death.
  ge-sinktype-die-DAT   ;; Remaining nrg of seeker on death.
  ge-sinktype-repro-RET ;; Nrg passed mother to daughter, NOT A HEAT SINK.

  ;; SYSTEM-WIDE AGGREGATES
  ;; System of nrg sinks.
  gl-sinks-per-tick
  gl-sinks-cumulative

  ;;---------------------------------------------------------------------------|
  ;; The following agent sets, counts and averages are for data collection 
  ;;   and display in monitors and plots.
  
  ;; Global counts
  g-no-of-patches          ;; count of all patches
  g-no-of-dales            ;; count of all dales with fruit
  g-no-of-empty-patches    ;; count of all empty patches
  g-no-of-seekers          ;; count of all seekers
  g-carrying-capacity      ;; sustainable load of seekers
  
  ;; Global EROI/ETA system-wide calculations.
  g-sys-nrg-returned      ;; Gross nrg returned (er) within delta T.
  g-sys-nrg-invested      ;; Gross nrg invested (ei) within delta T.
  g-sys-nrg-benefits      ;; Net nrg returned or benefits (er-ei) within delta T.
  gl-sys-nrg-returned     ;; List of changes.
  gl-sys-nrg-invested     ;; List of changes.
  g-sys-eroi              ;; System-wide EROI, per tick =(I/C).
  g-sys-eta               ;; System-wide ETA, per tick  =(B/I).

  ;; Global lists for EROI/ETA for death by repro/hunger.
  g-dbr-stat-count        ;; Count of agents included in lists
  g-dbh-stat-count        ;; Count of agents included in lists
  g-dbo-stat-count        ;; Count of agents included in lists
  ;; g-max-for-lte-stats  ;; Maximum agents included [40,40,5000,5000]
  gl-lte-eroi-dbr         ;; List of EROI for death by repro
  gl-lte-eroi-dbh         ;; List of EROI for death by hunger
  gl-lte-eroi-dbo         ;; List of EROI for death by old age
  gl-lte-eroi-all         ;; List of EROI for death by all causes
  gl-lte-eta-dbr          ;; List of ETA for death by repro
  gl-lte-eta-dbh          ;; List of ETA for death by hunger
  gl-lte-eta-dbo          ;; List of ETA for death by old age
  gl-lte-eta-all          ;; List of ETA for death by all causes
  g-lte-eta-min           ;; Used to set min value for histograms
  g-lte-eroi-max          ;; Used to set max value for histograms
  
  ;; Other histogram limits
  g-hist-epm-max          ;; Max value for EPM histogram
  g-hist-epm-min          ;; Min value for EPM histogram
  g-hist-epa-max          ;; Max value for EPA histogram
  g-hist-epa-min          ;; Min value for EPA histogram

  ;; Averages for seekers
  g-ave-age               ;; age of seekers
  g-ave-nrg               ;; nrg of seekers
  g-ind-min-eroi          ;; min eroi of individual seekers = (B/C)
  g-ind-ave-eroi          ;; ave eroi of individual seekers = (B/C)
  g-ind-max-eroi          ;; max eroi of individual seekers = (B/C)
  g-ind-min-eta           ;; min eta of individual seekers  = (B/I)
  g-ind-ave-eta           ;; ave eta of individual seekers  = (B/I)
  g-ind-max-eta           ;; max eta of individual seekers  = (B/I)

  g-ave-C1-b0             ;; c1, base character, gene-0
  g-ave-C1-b1             ;; c1, base character, gene-1
  g-ave-C1-b2             ;; c1, base character, gene-2
  g-ave-C1-b3             ;; c1, base character, gene-3
  g-ave-C1-b4             ;; c1, base character, gene-4
  g-ave-C1-b5             ;; c1, base character, gene-5
  g-ave-C1-b6             ;; c1, base character, gene-6
  g-ave-C1-b7             ;; c1, base character, gene-7

  g-ave-c1-e0             ;; c1, exponent character, gene-0
  g-ave-c1-e1             ;; c1, exponent character, gene-1
  g-ave-c1-e2             ;; c1, exponent character, gene-2
  g-ave-c1-e3             ;; c1, exponent character, gene-3
  g-ave-c1-e4             ;; c1, exponent character, gene-4
  g-ave-c1-e5             ;; c1, exponent character, gene-5
  g-ave-c1-e6             ;; c1, exponent character, gene-6
  g-ave-c1-e7             ;; c1, exponent character, gene-7

  g-ave-C1-s0             ;; c1, strength character, gene-0
  g-ave-C1-s1             ;; c1, strength character, gene-1
  g-ave-C1-s2             ;; c1, strength character, gene-2
  g-ave-C1-s3             ;; c1, strength character, gene-3
  g-ave-C1-s4             ;; c1, strength character, gene-4
  g-ave-C1-s5             ;; c1, strength character, gene-5
  g-ave-C1-s6             ;; c1, strength character, gene-6
  g-ave-C1-s7             ;; c1, strength character, gene-7

  g-ave-C1-p0             ;; c1, phenotypic character, gene-0
  g-ave-C1-p1             ;; c1, phenotypic character, gene-1
  g-ave-C1-p2             ;; c1, phenotypic character, gene-2
  g-ave-C1-p3             ;; c1, phenotypic character, gene-3
  g-ave-C1-p4             ;; c1, phenotypic character, gene-4
  g-ave-C1-p5             ;; c1, phenotypic character, gene-5
  g-ave-C1-p6             ;; c1, phenotypic character, gene-6
  g-ave-C1-p7             ;; c1, phenotypic character, gene-7

  ;; Variables used to calculate and display entropy.
  g-energy-entropic-index  ;; Entropy associated with energy distribution.
  g-pheno-entropic-index   ;; Entropy associated with genetic distribution.
  gl-ave-pheno             ;; Average phenotype.
  
  ;; SWITCHES - These are declared in the switch itself, and so are 
  ;;   commented out here.  They are all native Booleans, having values of
  ;;   true or false.
  ;; gb-plot-data              ;; Enables plotting

  ;; Expanding the scope of evolutionary pressures.
  ;; gb-mutate-epm             ;; Enables mutation of EPM.
  ;; gb-mutate-epa             ;; Enables mutation of EPA.
  
  ;; gb-include-dnd            ;; Enables inclusion of D&D nrg uses.
  ;; D&D stands for Detrivores and Decomposers.  When agents die with
  ;;   still-useful-energy they release that energy to a sink.  This
  ;;   switch enables inclusion of that released energy in the calculation
  ;;   of EROI and ETA.

  ;; Other - built-in or declared implicitly in plot interface items
  ;; See each plot design dialogue.

  ;;---------------
  ;; DEBUG CONTROLS
  ;;---------------
  
  gb-debug-on                 ;; Numeric Boolean, opens debug log file, 0 or 1.
  gs-debug-status             ;; for monitor, '1 (On)' or '0 (Off)', 
  ;; gs-debug-step-chooser    ;; Chooser, used with gb-debug-flow-on
  gb-debug-flow-on            ;; Numeric Boolean, in association with chooser, 
  gs-log-file-name            ;; name of the debug log file
                              ;;   opens flow to log file
]

  ;;-------------------------------------
  ;; DEFINING PATCHES AND BREEDS
  ;;-------------------------------------
  
;;-----------------------------------------------------------------------------|
;; Attributes of patches
patches-own 
[
  ;; BUILT-IN ATTRIBUTES 
  ;; pxcor        ;; min-pxcor <= pxcor < max-pxcor
  ;; pycor        ;; min-pxcor <= pxcor < max-pxcor 
  ;; pcolor       ;; color of this patch ( 0 <= color < 140 ) 
  ;; plabel       ;; label of this patch
  ;; plabel-color ;; color of this patch's label ( 0 <= label-color < 140 ) 
   
  ;; EffLab-DETERMINED ATTRIBUTES
  fruit
]

;;-----------------------------------------------------------------------------|
;; Attributes of links
;; nil
;; I don't understand links and did not use any.

;;-----------------------------------------------------------------------------|
;; Turtles and breeds
breed [ seekers seeker ]

;;-----------------------------------------------------------------------------|
;; Attributes of seekers
seekers-own 
[
  ;; BUILT-IN ATTRIBUTES
  ;; who         ;; fixed id number
  ;; breed       ;; to which breed this turtle belongs [seeker]
  ;; heading     ;; 0 <= heading < 360, 0 = north
  ;; xcor        ;; min-pxcor <= xcor < max-pxcor
  ;; ycor        ;; min-pxcor <= xcor < max-pxcor
  ;; size        ;; size relative to a patch, default is 1
  ;; shape       ;; a shape chosen from the shape library
  ;; color       ;; color of this turtle ( 0 <= color < 140 )
  ;; pen-mode    ;; "up" or "down"
  ;; pen-size    ;; in pixels
  ;; hidden?     ;; true or false
  ;; label       ;; label of this turtle
  ;; label-color ;; color of this turtle's label ( 0 <= label-color < 140 )
  
  ;; USER-DETERMINED ATTRIBUTES
  ;; The chromosome 1 (c1) genes are used to distinguish behaviours.
  c1-bases    ;; c1 - list of 8 [B]ases for genes (S=B^E)
  c1-expos    ;; c1 - list of 8 heading delta [E]xponents
  c1-stren    ;; c1 - list of 8 [S]trengths
  c1-pheno    ;; c1 - list of 8 [P]henotypic characters (Pi=Si/sum(Sj))
  
  ;; The chromosome 2 (C2) genes are static in this model.
  DAT         ;; Death Age Threshold.
  DET         ;; Death Energy Threshold.
  RAT         ;; Reproductive Age Threshold.
  RET         ;; Reproductive Energy Threshold.
  EPM         ;; Energy Per Move.
  EPA         ;; Maximum Energy Per Agent.
  
  ;; Other variable characteristics.
  mas-who              ;; serial number of parent agent.
  age                  ;; age of the agent in ticks
  nrg                  ;; nrg in this agent
  cause-of-death       ;; for statistical purposes
  b-is-ready-to-move      ;; 0 = no; 1 = ready to move
  b-is-ready-to-reproduce ;; mature (in age) and healthy (in nrg)
  b-is-ready-to-die       ;; old (in age) or starved (in nrg)
  
  ;; Variables for calculating individual EROI and ETA.
  ind-nrg-returned      ;; Numerator of EROI - an aggregate = Income of (I/C)
  ind-nrg-invested      ;; Denominator of EROI - an aggregate = Costs of (I/C)
  ind-nrg-benefits      ;; Numerator of ETA - an aggregate = Benefits of (B/I)
  ind-eroi              ;; Gross nrg returned on nrg invested = (I/C)
  ind-eta               ;; Net nrg efficiency = (B/I)
  l-ind-er              ;; A list of delta ERs of length delta T
  l-ind-ei              ;; A list of delta EIs of length delta T
  ind-eroi-tick-counter ;; For tracking time up to delta T.
  
  ;; Life-time efficiency (lte) variables.
  lte-er               ;; Energy returned (harvested) per lifetime
  lte-ei               ;; Energy invested (spent) per lifetime
  lte-eta              ;; Life-time efficiency - eta
  lte-eroi             ;; Life-time efficiency - eroi
]

;;-----------------------------------------------------------------------------|
;; SECTION C – INITIALIZATION OR SETUP PROCEDURE( S )
;;-----------------------------------------------------------------------------|

;;-----------------------------------------------------------------------------|
;; The 'autostart' startup routine

to startup
  ;; This routine is to be executed by the observer.

  ;; The manual describes this routine as follows:
  ;; This procedure, if it exists, will be called when a model is first loaded
  ;;   in the NetLogo application.  Startup does not run when a model is run 
  ;;   headless from the command line, or by parallel BehaviorSpace.

  ;; On loading the model, the debug feature is always off.
  set gb-debug-on 0
  set gs-debug-status "0 (Off)"
  
  ;; On loading the model, the model, the choosers, switches and sliders are
  ;;   always reset to the values that are known to work by here invoking 
  ;;   the f-reset-default-parameters routine.  Only the chooser
  ;;   for the scenario is not reset.  The last saved 
  ;;   selection of scenario will therefore be persistant.  This allows the 
  ;;  'Reset Defaults' button to NOT reset the scenario number, but to reset 
  ;;  correct parameters for the scenario.
  f-reset-default-parameters

  ;; Run the setup routine to initialize other globals.
  setup
end 

;;-----------------------------------------------------------------------------|
;; Reset the default values for the interface-declared items.

to f-reset-default-parameters 
  ;; The observer executes this routine.

  ;; Switches, sliders and choosers implicitly declare global variables.  The
  ;;   values in these variables are parameters for the model, and many 
  ;;   combinations of those parameters are not sustainable.  However, the
  ;;   values in those user interface devices are stored with the model and
  ;;   are persistant across a save/load action.  The default values must
  ;;   be reset on load, or available to a user as a parameter set.  The
  ;;   purpose of this routine is to store at least one viable set of 
  ;;   parameter values.
  
  ;; DO NOT re-initialize the gs-scenario chooser.  The selected scenario
  ;;   is intended to be persistent, and not subject to a default setting.
  
  ;; Initialize the Pseudo Random Number Generator (PRNG).
  set g-use-this-seed 7          ;; [1,1,100,7]
  
  set gb-plot-data true          ;; Turn plotting on.
   
  ;;-----------------------------------------------
  ;; BIOPHYSICAL SUB-SYSTEM CONTROLS AND PARAMETERS
  ;;-----------------------------------------------

  ;; Slider range settings are shown as (Min,Inc,Max,Default)
  set g-seekers-at-start      10 ;; For Scenario 0, [1,1,100,10]
  set g-nrg-per-deposit       40 ;; [1,1,100,40]
  set g-prob-of-deposit     0.05 ;; [0,.001,1,.05]
  set g-prob-of-mutation    0.95 ;; [0,.001,1,0.95]
  set g-max-for-lte-stats   5000 ;; [40,40,5000,5000]
  set g-dt-for-ind-stats     200 ;; [40,40,400,200]
  set gb-include-dnd       false ;; Detrivores and Decomposers not included.

  ;; Static chromosome 2 (C2) biophysical controls - borrowed from PSoup model.
  set g-c2-dat-parm        1600  ;; [100,10,3200,1600]
  set g-c2-det-parm           4  ;; [4,4,40,4]
  set g-c2-rat-parm         800  ;; [50,10,3200,800]
  set g-c2-ret-parm        1000  ;; [200,1,1600,1000]
  set g-c2-epm-parm           4  ;; [1,1,40,4]
  set g-c2-epa-parm        1600  ;; [1600,100,3000,1600]
  
  ;; Expanding the scope of evolutionary pressures.
  set gb-mutate-epm         true ;; Enables mutation of EPM.
  set gb-mutate-epa         true ;; Enables mutation of EPA.
  
  set gb-include-dnd       false ;; Enables inclusion of D&D nrg uses.

  ;; End of f-reset-default-parameters
end 

;;-----------------------------------------------------------------------------|
;; The setup button(s)

to setup
  ;; This routine is to be executed by the observer.

  ;; NOTE: The contents of switches, sliders, and choosers seem to be 
  ;;   immune to these 'clear' commands.
  clear-ticks
  clear-turtles
  clear-patches
  clear-drawing
  clear-all-plots
  clear-output
  ;; clear-globals   ;; Suppressed to make gb-debug-on value persistent.
  ;; NOTE: Instead of 'clear-globals', you must ensure all globals are 
  ;;   initialized properly in 'setup'.
  
  ;; import-drawing "01-B OrrSW.jpg"
  
  ;; Set the nrg (encoded in the variable fruit) in all of the patches to zero.
  ask patches
  [
    set fruit 0
    set pcolor brown
  ]
  
  ;; The version should be coded in this global variable to be included in
  ;;   output files.
  set gs-Version "EffLab_I_V1.04" 

  ;; Debug features may be off or on depending on history.
  ;;   - Perhaps 'setup' was called by 'to startup'.
  ;;   - Perhaps 'setup' was called during a 'BehaviorSpace' run.
  ;;   - Perhaps 'setup' was called by a user-pushed 'setup' button.
  ;; Setup needs to handle some quasi-persistant values correctly regardless of
  ;;   the history.  For gb-debug-on, in particular, I want it to be 
  ;;   persistant so I can have debug output from the 'setup' routine routed
  ;;   to the debug log file, or to the command centre.
  
  ;; 'startup' automatically sets gb-debug-on to 0 when the application is first
  ;;   loaded.  I want to be able to (A) toggle debug on, then, (B) press 
  ;;   'setup' and watch the debug output of the 'setup' command.  The 
  ;;   gb-debug-on must be persistant through the above 'clear' commands.  The 
  ;;   debug log file name and status, however, should not be persistent and 
  ;;   must be reset when setup runs, if appropriate.
  ifelse ( gb-debug-on = 1 )
  [
    ;; Debug is on due to user setting, so file name and status should be 
    ;;   reset.  I do this by turning the feature off then on.
    ;; First toggle it off, closing any remnant log file, if needed.
    f-toggle-debug
    ;; Then toggle it back on, opening a new time-stamped log file.
    f-toggle-debug
  ]
  ;; else
  [
    ;; Debug is off, possibly due to startup execution, possibly due to user 
    ;;   choice.
    ;; Ensure associated variables have compatible settings.
    set gb-debug-on 0              ;; Redundant but ensures consistency.
    set gs-debug-status "0 (Off)"  ;; Redundant but ensures consistency.
    set gb-debug-flow-on 0         ;; Step-specific flow is off.
    file-close-all                 ;; Close the debug log file.
    set gs-log-file-name "dummyname"
  ]
  
  ;; Now, do the standard check that is done at the start of each debuggable 
  ;;   routine.  This must follow the clear commands, which reset everything 
  ;;   except globals, switches, sliders and choosers.
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "setup" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-setup: Debug on; tick = " 0 ]
    [ set gb-debug-flow-on 0 ]
  ]

  ;; g-use-this-seed comes from a slider, and is persistant during setup.
  ;; However it is NOT persistent in a 'reset-defaults' call.
  random-seed g-use-this-seed      ;; Tells the PRNG to use this seed.
  
  ;; Establish the list of allowed headings, each 45 degrees from the last.
  ;;   These are the possible deltas that will be added to the current heading
  ;;   based on which of the 8 genes is expressed during a move.
  set gl-heading-list [ 0 45 90 135 180 225 270 315 ] 
  set gl-index-list   [ 0 1 2 3 4 5 6 7 ] 

  ;; The factors used to mutate the base values of the genes need to be 
  ;;   calculated.
  let prime-list [ 7 11 13 17 ]
  let factor-list ( map [ 1 + ( 1 / ? ) ] prime-list )
  let inverse-list ( map [ 1 - ( 1 / ? ) ] prime-list )
  set gl-base-factors ( sentence factor-list inverse-list )

  ;; Glogal enumeration variables - There are 2 scenarios possible.
  set ge-scenario-zero 0  ;; Small beginnings
  set ge-scenario-one  1  ;; At Carrying Capacity
  ;; Use the input from the chooser gs-scenario to invoke the selected scenario.
  f-set-scenario-number
  
  ;; For debugging the setup procedure, log the values of the globals.
  LOG-TO-FILE ( word "  Do-set: Scenario number    - " g-scenario-number ) 
  LOG-TO-FILE ( word "  Do-set: Scenario name      - " gs-scenario )
  LOG-TO-FILE ( word "  Do-set: Random seed        - " g-use-this-seed )

  ;; Declare values of hidden declarations from sliders.
  LOG-TO-FILE ( word "  Do-set: g-nrg-per-deposit  - " g-nrg-per-deposit )
  LOG-TO-FILE ( word "  Do-set: g-prob-of-deposit  - " g-prob-of-deposit )
  LOG-TO-FILE ( word "  Do-set: g-prob-of-mutation - " g-prob-of-mutation )
  LOG-TO-FILE ( word "  Do-set: g-max-for-lte-stats - " g-max-for-lte-stats )
  LOG-TO-FILE ( word "  Do-set: g-dt-for-ind-stats - " g-dt-for-ind-stats )

  ;; Nrg accounting variables
  set g-nrg-in-agents       0 ;; Nrg held in the agents.
  set g-nrg-in-fruit        0 ;; Nrg held in the fruit.
  set g-nrg-in-system       0 ;; Nrg in the system.
  set g-sun-takeup-actual   0 ;; As measured

  ;; Global enumeration (ge-) codes for cause of death.
  set ge-cod-none     0
  set ge-cod-fission  1
  set ge-cod-hunger   2
  set ge-cod-oldage   3
  
  ;; List to hold counts of cause of death.
  set gl-causes-of-death-per-tick   ( n-values 4 [0] )
  set gl-causes-of-death-cumulative ( n-values 4 [0] )

  ;; Global enumeration (ge-) codes for sinktype.
  set ge-sinktype-discard     0 ;; Discarded sunlight
  set ge-sinktype-move-EPM    1 ;; Seeker EPM
  set ge-sinktype-die-DET     2 ;; Remaining nrg of seeker on death.
  set ge-sinktype-die-DAT     3 ;; Remaining nrg of seeker on death.
  set ge-sinktype-repro-RET   4 ;; Nrg passed mother to daughter, NOT A HEAT SINK.
  
  ;; System of nrg sinks.
  set gl-sinks-per-tick   ( n-values 5 [0] )
  set gl-sinks-cumulative ( n-values 5 [0] )

  ;; Global EROI system-wide calculations.
  set g-sys-nrg-returned      0 ;; Gross nrg returned within delta T (er).
  set g-sys-nrg-invested      0 ;; Gross nrg invested within delta T (ei).
  set g-sys-nrg-benefits      0 ;; Net nrg returned within delta T (er-ei).
  set gl-sys-nrg-returned    [] ;; List of changes.
  set gl-sys-nrg-invested    [] ;; List of changes.
  set g-sys-eroi              0 ;; System-wide EROI, per tick = (I/C).
  set g-sys-eta              -5 ;; System-wide ETA, per tick  = (B/I).

  ;; Global lists for EROI/ETA for death by xxx.
  set g-dbr-stat-count        0 ;; Count of ticks included in lists.
  set g-dbh-stat-count        0 ;; Count of ticks included in lists.
  set g-dbo-stat-count        0 ;; Count of ticks included in lists.
  ;; set g-max-for-lte-stats  0 ;; Maximum agents included [40,40,1000,1000]
  set gl-lte-eroi-dbr        [] ;; List of EROI for death by repro
  set gl-lte-eroi-dbh        [] ;; List of EROI for death by hunger
  set gl-lte-eroi-dbo        [] ;; List of EROI for death by old age
  set gl-lte-eroi-all        [] ;; List of EROI for death by all causes
  set gl-lte-eta-dbr         [] ;; List of ETA for death by repro
  set gl-lte-eta-dbh         [] ;; List of ETA for death by hunger
  set gl-lte-eta-dbo         [] ;; List of ETA for death by old age
  set gl-lte-eta-all         [] ;; List of ETA for death by all causes
  set g-lte-eta-min          -1 ;; Used to set min value for histograms
  set g-lte-eroi-max          1 ;; Used to set max value for histograms

  ;; Other histogram limits
  set g-hist-epm-max g-c2-epm-parm + 0.1 ;; Max value for EPM histogram
  set g-hist-epm-min g-c2-epm-parm - 0.1 ;; Min value for EPM histogram
  set g-hist-epa-max g-c2-epa-parm + 1   ;; Max value for EPA histogram
  set g-hist-epa-min g-c2-epa-parm - 1   ;; Min value for EPA histogram

  ;;---------------------------------------------------------------------------|
  ;; The following agent sets, counts and averages are for data collection 
  ;;   and display in monitors and plots.
  
  ;; Counts
  set g-no-of-patches          0 ;; count of all patches
  set g-no-of-dales            0 ;; count of all dales with fruit
  set g-no-of-empty-patches    0 ;; count of all empty patches
  set g-no-of-seekers          0 ;; counts of all seekers
  set g-carrying-capacity      0 ;; sustainable load of seekers

  ;; Averages for seekers
  set g-ave-age      0        ;; age of seekers
  set g-ave-nrg      0        ;; nrg of seekers
  set g-ind-min-eroi 0        ;; min individual eroi of seekers = (I/C)
  set g-ind-ave-eroi 0        ;; ave individual eroi of seekers = (I/C)
  set g-ind-max-eroi 0        ;; max individual eroi of seekers = (I/C)
  set g-ind-min-eta  -5       ;; min individual eta of seekers = (B/I)
  set g-ind-ave-eta  -5       ;; ave individual eta of seekers = (B/I)
  set g-ind-max-eta  -5       ;; max individual eta of seekers = (B/I)

  set g-ave-C1-b0   0         ;; c1, base character, gene-0
  set g-ave-C1-b1   0         ;; c1, base character, gene-1
  set g-ave-C1-b2   0         ;; c1, base character, gene-2
  set g-ave-C1-b3   0         ;; c1, base character, gene-3
  set g-ave-C1-b4   0         ;; c1, base character, gene-4
  set g-ave-C1-b5   0         ;; c1, base character, gene-5
  set g-ave-C1-b6   0         ;; c1, base character, gene-6
  set g-ave-C1-b7   0         ;; c1, base character, gene-7

  set g-ave-c1-e0   0         ;; c1, exponent character, gene-0
  set g-ave-c1-e1   0         ;; c1, exponent character, gene-1
  set g-ave-c1-e2   0         ;; c1, exponent character, gene-2
  set g-ave-c1-e3   0         ;; c1, exponent character, gene-3
  set g-ave-c1-e4   0         ;; c1, exponent character, gene-4
  set g-ave-c1-e5   0         ;; c1, exponent character, gene-5
  set g-ave-c1-e6   0         ;; c1, exponent character, gene-6
  set g-ave-c1-e7   0         ;; c1, exponent character, gene-7

  set g-ave-C1-s0   0         ;; c1, strength character, gene-0
  set g-ave-C1-s1   0         ;; c1, strength character, gene-1
  set g-ave-C1-s2   0         ;; c1, strength character, gene-2
  set g-ave-C1-s3   0         ;; c1, strength character, gene-3
  set g-ave-C1-s4   0         ;; c1, strength character, gene-4
  set g-ave-C1-s5   0         ;; c1, strength character, gene-5
  set g-ave-C1-s6   0         ;; c1, strength character, gene-6
  set g-ave-C1-s7   0         ;; c1, strength character, gene-7

  set g-ave-C1-p0   0         ;; c1, phenotypic character, gene-0
  set g-ave-C1-p1   0         ;; c1, phenotypic character, gene-1
  set g-ave-C1-p2   0         ;; c1, phenotypic character, gene-2
  set g-ave-C1-p3   0         ;; c1, phenotypic character, gene-3
  set g-ave-C1-p4   0         ;; c1, phenotypic character, gene-4
  set g-ave-C1-p5   0         ;; c1, phenotypic character, gene-5
  set g-ave-C1-p6   0         ;; c1, phenotypic character, gene-6
  set g-ave-C1-p7   0         ;; c1, phenotypic character, gene-7

  ;; For debugging the debug feature!!!  Suppressed now.
  ;; show ( word "SETUP: Debug Is " gb-debug-on )
  ;; show ( word "SETUP: Debug Status Is " gs-debug-status )
  ;; show ( word "SETUP: Step Chooser Is " gs-debug-step-chooser )
  ;; show ( word "SETUP: Flow Control Is " gb-debug-flow-on )

  set-default-shape seekers  "arrow" ;; pulled from shapes library

  ask patches 
  [ 
    set pcolor brown
  ]
   
  set g-energy-entropic-index 1 ;; Entropy associated with energy distribution.
  set g-pheno-entropic-index  1 ;; Entropy associated with genetic distribution.
  set gl-ave-pheno [ 10 10 10 10 10 10 10 10 ] ;; Average phenotype.

  ;; Initialize the seekers and the patches.
  f-initialize-seekers-and-patches
  
  reset-ticks ;; restarts tick counter, runs setup commands within plots
  set gb-plot-data true ;; Enables all plotting calls.
  
  ;; This call must follow 'reset-ticks' and initialization of seekers.
  f-update-aggregates  ;; Totals and averages.
 
  ;; Clears unwanted zeros in plots.
  ;; clear-all-plots
  ;; setup-plots xxx
  
  ;; Debug controls
  ;; Boolean, in association with chooser, turns debug LOG-TO-FILE on/off
  set gb-debug-flow-on 0 
  ;; Input variable to set a tick for stopping.
  set g-halt-at-tick -1  
  
  ;; Detrivores and Decomposers not normally included in calculations of 
  ;;   EROI and ETA.
  set gb-include-dnd false

  Set g-nrg-in-fruit ( sum [fruit] of patches )
  ;; ASSERT ( frb-nrg-accounts-are-all-valid ) 
  ;;   ( "Do-set: Nrg accounts invalid." ) -1
  LOG-TO-FILE "  Do-set: procedure completed" 

  ;; end of to setup
end 

;;-----------------------------------------------------------------------------|
;; Set the scenario number using the input from the chooser.

to f-set-scenario-number
  ;; This routine is to be executed by the observer.

  set g-scenario-number ge-scenario-zero  ;; default

  if( gs-scenario = "Small Beginnings" )
    [ set g-scenario-number ge-scenario-zero ]
  if( gs-scenario = "At Carrying Capacity" )
    [ set g-scenario-number ge-scenario-one ]

  ;; End f-set-scenario-number
end 

;;-----------------------------------------------------------------------------|
;; Initialize a population of seekers.

to f-initialize-seekers-and-patches
  ;; This routine is to be executed by the observer.

  set g-nrg-in-system ( 0 )
  set g-no-of-patches ( count patches )
  
  if( g-scenario-number = ge-scenario-zero )
    [ f-initialize-scenario-zero ]
  if( g-scenario-number = ge-scenario-one )
    [ f-initialize-scenario-one ]
  
  ;; Nrg accounting
  set g-nrg-in-agents ( sum [nrg] of seekers )
  set g-nrg-in-system ( g-nrg-in-system + g-nrg-in-agents )

  ;; Place more energy into patches.
  ask patches
  [
    let random-number ( random-float 1 )
    if( random-number < g-prob-of-deposit )
    [
      set fruit g-nrg-per-deposit
      set pcolor green
    ]
  ]

  set g-nrg-in-fruit ( sum [fruit] of patches )
  set g-sun-takeup-actual ( g-nrg-in-fruit )
  set g-carrying-capacity ( floor ( g-sun-takeup-actual / g-c2-epm-parm ) )
  set g-nrg-in-system ( g-nrg-in-system + g-nrg-in-fruit )
  
  ;; End of f-initialize-seekers-and-patches
end 

;;-----------------------------------------------------------------------------|
;; Calculate the strengths and phenotypic values.

to f-find-strens-n-phenos
  ;; This routine is to be executed by a seeker.

  ;; It uses the second example of the map feature.
  ;; Examples of the map feature.
  ;; show (map + [1 2 3] [2 4 6])
  ;; => [3 6 9]
  ;; show (map [?1 + ?2 = ?3] 
  ;;           [1 2 3] 
  ;;           [2 4 6] 
  ;;           [3 5 9])
  ;; => [true false true]
    
  ;; Compute the strength as S=B^(G+L).
  set c1-stren ( map [?1 ^ ?2] 
                     c1-bases 
                     c1-expos )
  ;; Compute the phenotypic character as Pi=100*(Si/sum(Sj)).
  set c1-pheno 
    ( map [?1 * ?2 / ?3] 
          ( n-values 8 [100] ) 
          c1-stren 
          ( n-values 8 [sum c1-stren] ) )
  ;; End of f-find-strens-n-phenos
end 

;;-----------------------------------------------------------------------------|
;; Initialize scenario-zero.

to f-initialize-scenario-zero
  ;; This routine is to be executed by the observer.

  ;; This scenario is called "Small Beginnings".  The slider 
  ;;   g-seekers-at-start is used to size the initial population.  By default
  ;;   it is rather small.
  
  ;; In this scenario, we create a population of seekers which are all
  ;;   identical except for (a) location and (b) heading.
  
  create-seekers g-seekers-at-start 
  [ 
    f-initialize-new-seeker 
     
    ;; Set the heading as one of the 8 allowed headings.
    set heading ( item ( random 8 ) gl-heading-list )

    set color RED
    set age ( random RAT ) ;; Age is random with uniform distribution.
    set nrg ( random RET ) ;; Nrg is random with uniform distribution.
    ;; All start with varied age and nrg level to reduce transient time.
      
    ;; Genetic characters.
    set c1-bases [ 2 2 2 2 2 2 2 2 ]  ;; 8 unbiased bases
    set c1-expos [ 0 0 0 0 0 0 0 0 ]  ;; 8 unbiased exponents

    ;; Calculate the strengths and phenotypic characters.
    f-find-strens-n-phenos
     
    LOG-TO-FILE ( word "  Do-set: C1-bases - " c1-bases )
    LOG-TO-FILE ( word "  Do-set: c1-expos - " c1-expos )
    LOG-TO-FILE ( word "  Do-set: c1-stren - " c1-stren )
    LOG-TO-FILE ( word "  Do-set: c1-pheno - " c1-pheno )

    ;; Move each agent to a random point.
    setxy random-xcor random-ycor

  ]  ;; End of create.
  
  ;; End of f-initialize-scenario-zero
end 

;;-----------------------------------------------------------------------------|
;; Initialize a single seeker.

to f-initialize-new-seeker
  ;; This routine is to be executed by a seeker.

  ;; BUILT-IN ATTRIBUTES
  ;; who         ;; set automatically
  ;; heading     ;; direction of motion
  ;; xcor        ;; min-pxcor <= xcor < max-pxcor
  ;; ycor        ;; min-pxcor <= xcor < max-pxcor
  ;; pen-mode    ;; "up" or "down"
  ;; pen-size    ;; in pixels
  ;; size        ;; size relative to a patch, default is 1

  ;; USER-DETERMINED ATTRIBUTES
  ;; These two are re-initialized specifically for some scenarios.
  set color RED
  
  ;; The biophysical body function genes are static in this model.
  ;; Load chromosome 2 with the parameters from sliders.
  set DAT g-c2-dat-parm
  set DET g-c2-det-parm
  set RAT g-c2-rat-parm
  set RET g-c2-ret-parm
  set EPM g-c2-epm-parm
  set EPA g-c2-epa-parm

  ;; Associated with seeker dynamics.
  set mas-who -1                 ;; serial number of parent seeker.
  ;; age and nrg are set in group initialization routine.
  set cause-of-death ge-cod-none ;; for statistical purposes.

  ;; Set the logic trigger flags.
  set b-is-ready-to-move      1 ;; i.e. true
  set b-is-ready-to-reproduce 0 ;; i.e. false
  set b-is-ready-to-die       0 ;; i.e. false
  
  ;; Variables for calculating individual EROI and ETA.
  set ind-nrg-returned g-dt-for-ind-stats ;; Numerator of EROI - an aggregate
  set ind-nrg-invested g-dt-for-ind-stats ;; Denominator of EROI - an aggregate
  set ind-nrg-benefits ( ind-nrg-returned - ind-nrg-invested )
  set ind-eroi                0 ;; Nrg returned on nrg invested = (I/C)
  set ind-eta                -5 ;; individual efficiency        = (B/I)
  set l-ind-er ( n-values g-dt-for-ind-stats [0] ) ;; Delta ERs = B of B/C
  set l-ind-ei ( n-values g-dt-for-ind-stats [0] ) ;; Delta EIs = C of B/C
  set ind-eroi-tick-counter g-dt-for-ind-stats ;; For tracking time up to delta T.
  
  ;; Life-time efficiency (lte) variables.
  set lte-er             0  ;; Energy returned (harvested) per lifetime
  set lte-ei             0  ;; Energy invested (spent) per lifetime
  set lte-eta           -5  ;; Life-time efficiency - eta
  set lte-eroi           0  ;; Life-time efficiency - eroi

  ;; end f-initialize-new-seeker
end 

;;-----------------------------------------------------------------------------|
;; Initialize scenario-one.

to f-initialize-scenario-one
  ;; This routine is to be executed by the observer.

  ;; This scenario is called "At Carrying Capacity".  The slider 
  ;;   g-seekers-at-start is ignored.  Instead, I calculate the maximum
  ;;   carrying capacity, and start with that many seekers.
  
  ;; In this scenario, we create a population of seekers which are all
  ;;   identical except for (a) location and (b) heading.
  
  let estimated-sunshine-takeup 
    ( g-no-of-patches * g-nrg-per-deposit * g-prob-of-deposit )
  set g-carrying-capacity 
    ( floor ( estimated-sunshine-takeup / g-c2-epm-parm ) )

  create-seekers g-carrying-capacity 
  [ 
    f-initialize-new-seeker 
     
    ;; Set the heading as one of the 8 allowed headings.
    set heading ( item ( random 8 ) gl-heading-list )

    set color RED
    set age ( random RAT ) ;; Age is random with uniform distribution.
    set nrg ( random RET ) ;; Nrg is random with uniform distribution.
    ;; All start with varied age and nrg level to reduce transient time.
      
    ;; Genetic characters.
    set c1-bases [ 2 2 2 2 2 2 2 2 ]  ;; 8 unbiased bases
    set c1-expos [ 0 0 0 0 0 0 0 0 ]  ;; 8 unbiased exponents

    ;; Calculate the strengths and phenotypic characters.
    f-find-strens-n-phenos
     
    LOG-TO-FILE ( word "  Do-set: C1-bases - " c1-bases )
    LOG-TO-FILE ( word "  Do-set: c1-expos - " c1-expos )
    LOG-TO-FILE ( word "  Do-set: c1-stren - " c1-stren )
    LOG-TO-FILE ( word "  Do-set: c1-pheno - " c1-pheno )

    ;; Move each agent to a random point.
    setxy random-xcor random-ycor

  ]  ;; End of create.
  
  ;; End of f-initialize-scenario-one
end 

;;-----------------------------------------------------------------------------|
;; SECTION D – GO OR MAIN-LOOP PROCEDURE( S )
;;-----------------------------------------------------------------------------|

;;-----------------------------------------------------------------------------|
;; The go button

to go
  ;; This routine is to be executed by the observer.

  ;; Stop codes:
  ;; All stop decisions must be here in the 'go' procedure, as it causes an
  ;;   exit from the current procdure only.

  ;; XXX Special stop code for lte statistics.
  ;; if( g-dbr-stat-count >= g-max-for-lte-stats )
  ;; [
  ;;   stop
  ;; ]
  
  if( g-halt-at-tick = ticks  ) 
  [
    set g-halt-at-tick -1
    stop
  ]
  
  let b-should-stop-now false
  if( count turtles <= 0 ) [ set b-should-stop-now true ]
  if( b-should-stop-now = true )
  [
    stop
  ]

  ;; MANUAL CHANGE FOR DEBUG
  ;; If needed, each check for validity can be enabled between steps.
  ;; They have been suppressed (turned into comments) for the sake 
  ;;   of speed of execution, but can be re-enabled if a bug has 
  ;;   somehow been re-introduced.
  ;; A single call to the validity check has been left active inside of the
  ;;   Do-Post-Tick step.  If it flags a problem, re-activate these to
  ;;   narrow down where the problem starts.
  
  ;; Major steps or functions, done once per tick, in order of execution.
  do-pre-tick
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-pre-tick." ) ]

  do-energize
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-energize." ) ]

  do-move
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-move." ) ]

  do-feed
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: do-feed." ) ]

  do-reproduce
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-reproduce." ) ]

  do-die
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-die." ) ]

  do-post-tick
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-post-tick." ) ]
end 

;;-----------------------------------------------------------------------------|
;; D1 - do-pre-tick procedure( s )
;;-----------------------------------------------------------------------------|

to do-pre-tick
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "pre-tick" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-pre-tick: Debug on.; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; Enter all commands that need to be done before a tick begins.
  ;; Supressed. f-update-aggregates
  
  ;; Advance the tick counter by 1 tick.
  ifelse( gb-plot-data = true )
  [
    ;; Advance the ticks by one and update the plots.
    tick
    ;; 'tick' is exactly the same as 'update-plots' except that the tick counter 
    ;;   is incremented before the plot commands are executed.
  ]
  ;; else
  [
    ;; Advance ticks by one but do not update the plots.
    tick-advance 1
  ]
  ;; End else

  ;; Once the data is plotted, the per-tick counts can be cleared.
  ;; List to hold counts of cause of death.
  set gl-causes-of-death-per-tick   ( n-values 6 [0] )

  ;; Global EROI system-wide calculations.
  ifelse( length gl-sys-nrg-returned <= g-dt-for-ind-stats )
  [
    ;; Append a zero for new data.
    set gl-sys-nrg-returned ( lput 0 gl-sys-nrg-returned ) ;; List of changes.
    set gl-sys-nrg-invested ( lput 0 gl-sys-nrg-invested ) ;; List of changes.
  ]
  ;; Else
  [
    ;; Remove old data
    set gl-sys-nrg-returned ( butfirst gl-sys-nrg-returned ) ;; List of changes.
    set gl-sys-nrg-invested ( butfirst gl-sys-nrg-invested ) ;; List of changes.
    ;; Append a zero for new data.
    set gl-sys-nrg-returned ( lput 0 gl-sys-nrg-returned ) ;; List of changes.
    set gl-sys-nrg-invested ( lput 0 gl-sys-nrg-invested ) ;; List of changes.
  ]

  ;; Reset the scenario number, in case the chooser has been changed.
  f-set-scenario-number
  
  ;; Clear the per-tick data for energy sinks.
  ;; This call must happen before the seeker population is stabilized.
  set gl-sinks-per-tick ( n-values 5 [0] )
  
  ask seekers [ set age ( age + 1 ) ]
  LOG-TO-FILE ( word "  Do-pre-tick: Seekers aged." )

  LOG-TO-FILE ( word "  Do-pre-tick: Halt at tick - " g-halt-at-tick  ) 
  LOG-TO-FILE ( word "  Do-pre-tick: Current tick - " ticks ) 

  LOG-TO-FILE "  Do-pre-tick: Routine completed."
  
  ;; End of do-pre-tick
end 

;;-----------------------------------------------------------------------------|
;; D2 – do-energize procedure(s)
;;-----------------------------------------------------------------------------|

to do-energize
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "energize" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-energize: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; Make a list of the patches that are without fruit (without nrg)
  let empty-patch-list ( patches with [fruit = 0] )

  ;; Record the status of the patches, prior to energizing.
  set g-no-of-empty-patches ( count empty-patch-list )
  set g-no-of-dales ( g-no-of-patches - g-no-of-empty-patches )
  set g-sun-takeup-actual 0

  ;; Use the probability of deposit to determine if fruit is added.
  ask empty-patch-list
  [
    let random-number ( random-float 1 )
    let threshold ( g-prob-of-deposit )
    if ( random-number <= threshold )
    [
      set fruit ( fruit + g-nrg-per-deposit )
      set pcolor green
      ;; Record in system nrg accounts
      set g-nrg-in-fruit  ( g-nrg-in-fruit + g-nrg-per-deposit )
      set g-sun-takeup-actual ( g-sun-takeup-actual + g-nrg-per-deposit )
    ]
  ]
  
  ;; Estimate the carrying capacity, based on the take-up rate this tick.
  let mean-epm ( mean [epm] of seekers )
  set g-carrying-capacity ( floor ( g-sun-takeup-actual / mean-epm ) )
  set g-nrg-in-system ( g-nrg-in-system + g-sun-takeup-actual )
  
  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-energize: procedure completed"
  
  ;; End of do-energize
end 

;;-----------------------------------------------------------------------------|
;; D3 – do-move procedure(s)
;;-----------------------------------------------------------------------------|

to do-move
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "move" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-move: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; The seekers move.
  ask seekers
  [
    if( b-is-ready-to-move = 1 )
    [
      f-seeker-moves
    ]  ;; End if( b-is-ready-to-move = 1 )
  ]  ;; End ask seekers

  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-move: procedure completed"
end 

;;-----------------------------------------------------------------------------|
;; A seeker moves according to genes and heuristics.

to f-seeker-moves
  ;; This routine is to be executed by a seeker.

  ;; When a seeker moves it expends energy out of its pool of nrg.
  ;; Determine if this seeker has sufficient nrg to move.
  ifelse ( nrg >= EPM )
  [
    ;; Establish a heading.
    f-seeker-sets-heading
    
    ;; Step forward
    forward 1
    
    ;; Expend the nrg to the sink.
    f-store-data-in-sink ge-sinktype-move-EPM EPM
    set nrg ( nrg - EPM )
    
    ;; Record the expenditure in the stats.
    set g-nrg-in-system ( g-nrg-in-system - EPM )
    set g-nrg-in-agents ( g-nrg-in-agents - EPM )

    ;; Record the expenditure in the EROI variables
    f-record-ei-for-eroi EPM
    
    set b-is-ready-to-move 1
    ;; set b-is-ready-to-die 0
  ] 
  ;; Else
  [
    ;; The seeker is marked for death, and nrg is removed.
    ;; It will die and be removed when do-die is executed.    
    f-store-data-in-sink ge-sinktype-move-EPM nrg
    set g-nrg-in-system ( g-nrg-in-system - nrg )
    set g-nrg-in-agents ( g-nrg-in-agents - nrg )

    ;; Record the expenditure in the EROI variables
    f-record-ei-for-eroi nrg
    
    set nrg 0 
    set cause-of-death ge-cod-hunger
    set b-is-ready-to-move 0
    set b-is-ready-to-die 1
  ]
  ;; End else

  LOG-TO-FILE ( word "  Do-move: S(heading,nrg,move-flag,die-flag) - (" 
    heading "," 
    floor nrg "," 
    b-is-ready-to-move"," 
    b-is-ready-to-die ")" )
  
  ;; End of f-seeker-moves  
end 

;;-----------------------------------------------------------------------------|
;; A seeker sets a heading using c1-pheno.

to f-seeker-sets-heading
  ;; This routine is to be executed by a seeker.

    ;; The agent will consult its phenotypic characters, to determine the
    ;;   best direction for the next heading.  It is blind, and cannot sense
    ;;   other agents, or patches of fruit.  So the only guidance it has is
    ;;   the genetic information received from its mother.
    
    ;; Take note of the current heading.
    let old-heading heading
    
    ;; DECIDE HOW MUCH TO TURN AS DELTA-HEADING.
    ;; Add up the indicators.
    let sum-of-phenos ( round ( sum c1-pheno ) )
    LOG-TO-FILE ( word "  Do-move: Phenos          - " c1-pheno )
    LOG-TO-FILE ( word "  Do-move: Summed Phenos   - " sum-of-phenos )
    ;; Each pheno is derived from genes plus learnings.  The size of
    ;;   the pheno creates a proportional target interval in the sum.  
    ;;   Choose an interval (i.e. choose a pheno) by getting a random number.
    let random-number ( random-float sum-of-phenos )
    LOG-TO-FILE ( word "  Do-move: Random Number   - " random-number )
    ;; The random-number must fall between two sequential pheno aggregates.
    ;; E.g if the random-number is 50%, and the first two pheno numbers 
    ;;   are 13% and 25% (+=38%) then that sum is less than 50%.  If the 
    ;;   next pheno is 20%, then the aggregate is 58%, which is bigger 
    ;;   than 50%.  So it falls between the 2nd and 3rd aggregate of the 
    ;;   phenos.  The third interval then is selected "randomly" with 
    ;;   probability determined by its relative size, among all phenos.
    ;;   Due to zero-based indexing, the correct index is 3-1 = 2.

    let counter 0
    let good-index -1
    let this-pheno 0
    let this-sum 0
    let next-sum 0
    while [ counter < 8 ]  ;; Do not overshoot
    [
      LOG-TO-FILE ( word "  Do-move: Counter         - " counter )
      set this-pheno ( item counter c1-pheno )
      LOG-TO-FILE ( word "  Do-move: This sum        - " this-sum )
      LOG-TO-FILE ( word "  Do-move: Pheno           - " this-pheno )
      set next-sum ( this-pheno + this-sum )
      LOG-TO-FILE ( word "  Do-move: Next sum        - " next-sum )
      if ( ( random-number >= this-sum ) and 
           ( random-number < next-sum  ) )
      [
        set good-index counter
        LOG-TO-FILE ( word "  Do-move: Selected gene   - " good-index )
      ]
      set this-sum next-sum
      set counter ( counter + 1 )
    ]
    let heading-delta ( item good-index gl-heading-list )
    LOG-TO-FILE ( word "  Do-move: Old heading     - " heading )

    ;; Set the new heading
    set heading ( heading + heading-delta )
    LOG-TO-FILE ( word "  Do-move: New heading     - " heading )
  
  ;; End of f-seeker-sets-heading  
end 

;;-----------------------------------------------------------------------------|
;; Store data in the lists of sinks.

to f-store-data-in-sink [ sinktype value ]
  ;; This routine is to be executed by anyone.
  
  ;; Record it in the per-tick list.
  let old-value ( item sinktype gl-sinks-per-tick )
  let new-value ( old-value + value )
  set gl-sinks-per-tick ( replace-item sinktype gl-sinks-per-tick new-value )

  ;; Record it in the cumulative list.
  set old-value ( item sinktype gl-sinks-cumulative )
  set new-value ( old-value + value )
  set gl-sinks-cumulative 
    ( replace-item sinktype gl-sinks-cumulative new-value )

  ;; end of f-store-data-in-sink
end 

;;-----------------------------------------------------------------------------|
;; Increment the count in the lists of causes of death.

to f-increment-cod-list [ breedtype codtype ]
  ;; This routine is to be executed by anyone.
  
  ;; Record it in the per-tick list.
  let old-count ( item codtype gl-causes-of-death-per-tick )
  let new-count ( old-count + 1 )
  set gl-causes-of-death-per-tick 
    ( replace-item codtype gl-causes-of-death-per-tick new-count )
    
  ;; Record it in the cumulative list.
  set old-count ( item codtype gl-causes-of-death-cumulative )
  set new-count ( old-count + 1 )
  set gl-causes-of-death-cumulative 
    ( replace-item codtype gl-causes-of-death-cumulative new-count )

  ;; End of f-increment-cod-list
end 

;;-----------------------------------------------------------------------------|
;; Record the 'energy invested' component of EROI calculation.

to f-record-ei-for-eroi [eroi-ei]
  ;; This routine is to be executed by a seeker.
  ;;   It updates both individual values, and sys-wide values.
  
  ;; There are three associated routines:
  ;;   f-record-er-for-eroi is called by Do-feed.
  ;;   f-record-ei-for-eroi is called by Do-Move.
  ;;   f-record-ei-for-dnd-eroi is called by Do-Death.
  ;; The three routines work together to calculate individual and 
  ;;   system-wide EROI and ETA.  

  ;; NOTE: EROI is ER/EI, that is Benefits over Costs, or (B/C).
  ;;       ETA is (ER-EI)/ER, that is Benefits over Income, or (B/I).
  
  ;; LOG-TO-FILE ( word "  Do-move: Eroi-counter - " ind-eroi-tick-counter )
  ;; LOG-TO-FILE ( word "  Do-move: Nrg-returned - " ind-nrg-returned )
  ;; LOG-TO-FILE ( word "  Do-move: Nrg-invested - " ind-nrg-invested )
  ;; LOG-TO-FILE ( word "  Do-move: Nrg-benefits - " ind-nrg-benefits )
  ;; LOG-TO-FILE ( word "  Do-move: L-ind-er     - " l-ind-er )
  ;; LOG-TO-FILE ( word "  Do-move: L-ind-ei     - " l-ind-ei )

  ;; LOG-TO-FILE ( word "  Do-move: Lte-er       - " lte-er )
  ;; LOG-TO-FILE ( word "  Do-move: Lte-ei       - " lte-ei )
  ;; LOG-TO-FILE ( word "  Do-move: Lte-eta      - " lte-eta )
  ;; LOG-TO-FILE ( word "  Do-move: Lte-eroi     - " lte-eroi )
  
  ;; First, record it in the system-wide data.
  LOG-TO-FILE ( word "  Do-move: g-sys-ei was    - " gl-sys-nrg-invested )
  let last-index ( ( length gl-sys-nrg-invested ) - 1 )
  let old-value ( last gl-sys-nrg-invested )
  let new-value ( old-value + eroi-ei )
  set gl-sys-nrg-invested 
    ( replace-item last-index gl-sys-nrg-invested new-value )
  LOG-TO-FILE ( word "  Do-move: g-sys-ei is now - " gl-sys-nrg-invested )
  
  ;; Now record it in the individual data for this seeker.
  ;; Check to determine whether we are only appending data to the list,
  ;;   or we are dropping old data and appending new data.
  ifelse ( ind-eroi-tick-counter < g-dt-for-ind-stats )
  [
    ;; Case of appending new data only.
    ;; Increment the counter - done only in move-related function.
    set ind-eroi-tick-counter ( ind-eroi-tick-counter + 1 )
    ;; Append new entry to last of l-ind-ei.
    set l-ind-ei ( lput eroi-ei l-ind-ei )
    ;; Append a place-holder zero to l-ind-er.
    set l-ind-er ( lput 0 l-ind-er )
  ]
  ;; Else
  [
    ;; Case of dropping/appending data
    ;; Remove oldest entry.
    set l-ind-ei ( butfirst l-ind-ei )
    ;; Append new entry to last of l-ind-ei
    set l-ind-ei ( lput eroi-ei l-ind-ei )
    
    ;; Adjust l-ind-er, removing oldest and appending a place-holder zero.
    ;; Remove oldest entry.
    set l-ind-er ( butfirst l-ind-er )
    ;; Append zero to last of l-ind-er
    set l-ind-er ( lput 0 l-ind-er )
  ]  ;; End else dropping/appending

  ;; Life-time efficiency (lte) stats were added later.
  ;;   Lte data is aggregated over the entire life of the seeker.
  set lte-ei ( lte-ei + eroi-ei )  ;; Note the added investment.

  ;; Re-calculate the seekers stats.
  set ind-nrg-invested ( sum l-ind-ei )
  set ind-nrg-benefits ( ind-nrg-returned - ind-nrg-invested )

  ifelse (ind-nrg-invested > 0) 
    [ set ind-eroi ( ind-nrg-returned / ind-nrg-invested ) ] ;; (I/C)
    [ set ind-eroi 0 ] ;; (I/C)

  ifelse (ind-nrg-returned > 0) 
    [ set ind-eta ( ind-nrg-benefits / ind-nrg-returned ) ]  ;; (B/I)
    [ set ind-eta -5 ]  ;; (B/I)
  
  ;; Re-calculate the life-time-efficiency stats
  ifelse (lte-ei > 0) 
    [ set lte-eroi ( lte-er / lte-ei ) ]              ;; (I/C)
    [ set lte-eroi 0 ]              ;; (I/C)

  ifelse (lte-er > 0) 
    [ set lte-eta ( ( lte-er - lte-ei ) / lte-er ) ]  ;; (B/I)
    [ set lte-eta -5 ]  ;; (B/I)

  ;; LOG-TO-FILE ( word "  Do-move: Eroi-counter - " ind-eroi-tick-counter )
  ;; LOG-TO-FILE ( word "  Do-move: Nrg-returned - " ind-nrg-returned )
  ;; LOG-TO-FILE ( word "  Do-move: Nrg-invested - " ind-nrg-invested )
  ;; LOG-TO-FILE ( word "  Do-move: Nrg-benefits - " ind-nrg-benefits )
  ;; LOG-TO-FILE ( word "  Do-move: L-ind-er     - " l-ind-er )
  ;; LOG-TO-FILE ( word "  Do-move: L-ind-ei     - " l-ind-ei )

  ;; LOG-TO-FILE ( word "  Do-move: Lte-er       - " lte-er )
  ;; LOG-TO-FILE ( word "  Do-move: Lte-ei       - " lte-ei )
  ;; LOG-TO-FILE ( word "  Do-move: Lte-eta      - " lte-eta )
  ;; LOG-TO-FILE ( word "  Do-move: Lte-eroi     - " lte-eroi )  
  
  ;; End of f-record-ei-for-eroi
end 

;;-----------------------------------------------------------------------------|
;; Record the 'energy invested' component of EROI calculation.

to f-record-ei-for-dnd-eroi [eroi-ei]
  ;; This routine is to be executed by a seeker.
  ;;   It updates sys-wide values only, since the activity of decomposers
  ;;   and detrivores should not affect individual statistics.
  
  ;; There are three associated routines:
  ;;   f-record-er-for-eroi is called by Do-feed.
  ;;   f-record-ei-for-eroi is called by Do-Move.
  ;;   f-record-ei-for-dnd-eroi is called by Do-Death.
  ;; The three routines work together to calculate individual and 
  ;;   system-wide EROI and ETA.  

  ;; NOTE: EROI is ER/EI, that is Benefits over Costs, or (B/C).
  ;;       ETA is (ER-EI)/ER, that is Benefits over Income, or (B/I).
  
  LOG-TO-FILE ( word "  Do-death: g-sys-ei was   - " gl-sys-nrg-invested )
  ;; First, record it in the system-wide data.
  let last-index ( ( length gl-sys-nrg-invested ) - 1 )
  let old-value ( last gl-sys-nrg-invested )
  let new-value ( old-value + eroi-ei )
  set gl-sys-nrg-invested 
    ( replace-item last-index gl-sys-nrg-invested new-value )
  LOG-TO-FILE ( word " Do-death: g-sys-ei is now - " gl-sys-nrg-invested )
  
  ;; End of f-record-ei-for-dnd-eroi
end 

;;-----------------------------------------------------------------------------|
;; D4 – do-feed procedure(s)
;;-----------------------------------------------------------------------------|

to do-feed
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "feed" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-feed: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; Agents feed on fruit found in patches.
  ask seekers
  [
    let this-patch patch-here  ;; handle to the patch under the seeker.
    let nrg-available ( [fruit] of this-patch )
    if ( ( nrg < ( EPA - g-nrg-per-deposit ) ) and 
         ( nrg-available > 0 ) )
    [
      ;; Case of there is food to eat.
      ;; Seeker eats.
      set nrg ( nrg + nrg-available )
      set g-nrg-in-agents ( g-nrg-in-agents + nrg-available )
      f-record-er-for-eroi nrg-available
      ask this-patch
      [
        set fruit 0
        set g-nrg-in-fruit ( g-nrg-in-fruit - nrg-available )
        set pcolor brown
      ]
    ]
  ]  ;; End of ask seekers.
  
  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-feed: procedure completed"
  
  ;; End Do-feed procedure.
end 

;;-----------------------------------------------------------------------------|
;; Record the 'energy returned' component of EROI calculation.

to f-record-er-for-eroi [eroi-er]
  ;; This routine is to be executed by a seeker.
  ;;   It updates both individual values, and sys-wide values.
  
  ;; There are three associated routines:
  ;;   f-record-er-for-eroi is called by Do-feed.
  ;;   f-record-ei-for-eroi is called by Do-Move.
  ;;   f-record-ei-for-dnd-eroi is called by Do-Death.
  ;; The three routines work together to calculate individual and 
  ;;   system-wide EROI and ETA.  

  ;; NOTE: EROI is ER/EI, that is Benefits over Costs, or (B/C).
  ;;       ETA is (ER-EI)/ER, that is Benefits over Income, or (B/I).
  
  ;; LOG-TO-FILE ( word "  Do-feed: Eroi-counter - " ind-eroi-tick-counter )
  ;; LOG-TO-FILE ( word "  Do-feed: Nrg-returned - " ind-nrg-returned )
  ;; LOG-TO-FILE ( word "  Do-feed: Nrg-invested - " ind-nrg-invested )
  ;; LOG-TO-FILE ( word "  Do-feed: Nrg-benefits - " ind-nrg-benefits )
  ;; LOG-TO-FILE ( word "  Do-feed: L-ind-er     - " l-ind-er )
  ;; LOG-TO-FILE ( word "  Do-feed: L-ind-ei     - " l-ind-ei )

  ;; LOG-TO-FILE ( word "  Do-feed: Lte-er       - " lte-er )
  ;; LOG-TO-FILE ( word "  Do-feed: Lte-ei       - " lte-ei )
  ;; LOG-TO-FILE ( word "  Do-feed: Lte-eta      - " lte-eta )
  ;; LOG-TO-FILE ( word "  Do-feed: Lte-eroi     - " lte-eroi )  
  
  ;; First, record it in the system-wide data.
  ;; LOG-TO-FILE ( word "  Do-feed: g-sys-er was    - " gl-sys-nrg-returned )
  let last-index ( ( length gl-sys-nrg-returned ) - 1 )
  let old-value ( last gl-sys-nrg-returned )
  let new-value ( old-value + eroi-er )
  set gl-sys-nrg-returned 
    ( replace-item last-index gl-sys-nrg-returned new-value )
  ;; LOG-TO-FILE ( word "  Do-feed: g-sys-er is now - " gl-sys-nrg-returned )
  
  ;; Now, record it in the individual data.
  ;; DO NOT increment the counter here - done only in move-related function.
  ;; set ind-eroi-tick-counter ( ind-eroi-tick-counter + 1 )
  ;; Remove the place-holder zero, put there in the move-related routine.
  set l-ind-er ( butlast l-ind-er )
  ;; Append new entry to last of l-ind-er.
  set l-ind-er ( lput eroi-er l-ind-er )
  
  ;; Update the life-time-efficiency (lte) stats.
  set lte-er ( lte-er + eroi-er )

  ;; Re-calculate the seeker's stats.
  set ind-nrg-returned ( sum l-ind-er )
  set ind-nrg-benefits ( ind-nrg-returned - ind-nrg-invested )

  ifelse (ind-nrg-invested > 0) 
    [ set ind-eroi ( ind-nrg-returned / ind-nrg-invested ) ]  ;; (I/C)
    [ set ind-eroi 0 ]  ;; (I/C)

  ifelse (ind-nrg-returned > 0) 
    [ set ind-eta ( ind-nrg-benefits / ind-nrg-returned ) ]   ;; (B/I)
    [ set ind-eta -5 ]   ;; (B/I)
  
  ;; Recalculate the life-time stats.
  ifelse (lte-ei > 0) 
    [ set lte-eroi ( lte-er / lte-ei ) ]
    [ set lte-eroi 0 ]

  ifelse (lte-er > 0) 
    [ set lte-eta ( ( lte-er - lte-ei ) / lte-er ) ]
    [ set lte-eta -5 ]
  
  ;; LOG-TO-FILE ( word "  Do-feed: Eroi-counter - " ind-eroi-tick-counter )
  ;; LOG-TO-FILE ( word "  Do-feed: Nrg-returned - " ind-nrg-returned )
  ;; LOG-TO-FILE ( word "  Do-feed: Nrg-invested - " ind-nrg-invested )
  ;; LOG-TO-FILE ( word "  Do-feed: Nrg-benefits - " ind-nrg-benefits )
  ;; LOG-TO-FILE ( word "  Do-feed: L-ind-er     - " l-ind-er )
  ;; LOG-TO-FILE ( word "  Do-feed: L-ind-ei     - " l-ind-ei )

  ;; LOG-TO-FILE ( word "  Do-feed: Lte-er       - " lte-er )
  ;; LOG-TO-FILE ( word "  Do-feed: Lte-ei       - " lte-ei )
  ;; LOG-TO-FILE ( word "  Do-feed: Lte-eta      - " lte-eta )
  ;; LOG-TO-FILE ( word "  Do-feed: Lte-eroi     - " lte-eroi )  
  
  ;; End of f-record-er-for-eroi
end 

;;-----------------------------------------------------------------------------|
;; D5 – do-reproduce procedure(s)
;;-----------------------------------------------------------------------------|

to do-reproduce
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "reproduce" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-rep: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ask seekers
  [
    f-set-seeker-repro-flag
    f-reproduce-seeker-by-fission
  ]
  
  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-rep: procedure completed"
end 

;;-----------------------------------------------------------------------------|
;; f-set-seeker-repro-flag

to f-set-seeker-repro-flag
  ;; This routine is to be executed by a seeker.
  
  set b-is-ready-to-reproduce 1        ;; i.e. true is the default.
  if( nrg < RET )
    [ set b-is-ready-to-reproduce 0 ]  ;; i.e. false due to lack of health.
  
  if( age < RAT )
    [ set b-is-ready-to-reproduce 0 ]  ;; i.e. false due to lack of maturity.
  
  if( b-is-ready-to-reproduce = 1 )
  [
    LOG-TO-FILE 
      ( word "  Do-rep: S(age,nrg,rep-flag) - (" 
        age "," floor nrg  "," b-is-ready-to-reproduce ")" )
  ]
    
  ;; End f-set-seeker-repro-flag
end 

;;-----------------------------------------------------------------------------|
;; A seeker reproduces via fission, one mother having two daughters.

to f-reproduce-seeker-by-fission
  ;; This routine is to be executed by a seeker.
  
  if( b-is-ready-to-reproduce = 1 )   ;; 1 = true
  [
    LOG-TO-FILE ( word "  Do-rep: seeker Ma - " who )

    ;; This mother is dying due to reproduction.  Her lte-eroi and lte-eta
    ;;   values need to be recorded in the death statistics.
    ;; Record the eroi and eta data of mother before reproduction by fission.
    if( g-dbr-stat-count >= g-max-for-lte-stats )
    [
      ;; Remove old data for "death by repro" (dbr).
      set gl-lte-eroi-dbr ( butfirst gl-lte-eroi-dbr )
      set gl-lte-eta-dbr ( butfirst gl-lte-eta-dbr )
      set g-dbr-stat-count ( g-dbr-stat-count - 1 )
    ]
    set gl-lte-eroi-dbr ( lput lte-eroi gl-lte-eroi-dbr )
    set gl-lte-eta-dbr ( lput lte-eta gl-lte-eta-dbr )
    set g-dbr-stat-count ( g-dbr-stat-count + 1 )
    set gl-lte-eroi-all
      ( sentence gl-lte-eroi-dbh gl-lte-eroi-dbo gl-lte-eroi-dbr )
    set gl-lte-eta-all
      ( sentence gl-lte-eta-dbh gl-lte-eta-dbo gl-lte-eta-dbr )

    ;; Let statements for fission.
    let mother self
    let mothers-who who
    let mothers-patch patch-here

    let first-share-of-nrg floor( nrg / 2 )
    let second-share-of-nrg ( nrg - first-share-of-nrg )
  
    ;; Record the nrg as passed on to daughters.
    f-store-data-in-sink ge-sinktype-repro-RET nrg

    let daughter-count 0
    ask mothers-patch
    [
      sprout-seekers 2
      [
        set daughter-count ( daughter-count + 1 )
        LOG-TO-FILE ( word "  Do-rep: seeker D" daughter-count " - " who )
        f-initialize-new-seeker
        set color ( [color] of mother )
        
        ;; Copy the C1 genetic/learned material.
        set c1-bases ( [c1-bases] of mother )
        set c1-expos ( [c1-expos] of mother )
        set c1-stren ( [c1-stren] of mother )
        set c1-pheno ( [c1-pheno] of mother )

        ;; C2 genes are static.
        set DAT ( [DAT] of mother )
        set DET ( [DET] of mother )
        set RAT ( [RAT] of mother )
        set RET ( [RET] of mother )
        set EPM ( [EPM] of mother )
        set EPA ( [EPA] of mother )
        
        ;; Note the mother of this daughter.
        set mas-who ( [who] of mother )
        set age 0

        ifelse ( daughter-count = 1 )
        [ set nrg first-share-of-nrg ]
        [ set nrg second-share-of-nrg ]
        
        set cause-of-death          0
        set b-is-ready-to-move      1
        set b-is-ready-to-reproduce 0
        set b-is-ready-to-die       0
        
        ;; Variables for calculating individual EROI and ETA.
        ;; All inherited from mother.
        set ind-nrg-returned ( [ind-nrg-returned] of mother )
        set ind-nrg-invested ( [ind-nrg-invested] of mother )
        set ind-nrg-benefits ( [ind-nrg-benefits] of mother )
        set ind-eroi         ( [ind-eroi] of mother )
        set ind-eta          ( [ind-eta]  of mother )
        set l-ind-er         ( [l-ind-er] of mother )
        set l-ind-ei         ( [l-ind-ei] of mother )
        set ind-eroi-tick-counter ( [ind-eroi-tick-counter] of mother )
        
        ;; Variables for calculating life-time-efficiencies EROI and ETA.
        set lte-ei 0
        set lte-er 0
        set lte-eta 0
        set lte-eroi 0

        f-mutate-new-seeker
      ]
    ]
    
    ;; Set the cause of death for the mother.
    set cause-of-death ge-cod-fission
    ;; The mother disappears after fission, leaving two daughters.
    ;; Death actually occurs in the Do-die step.
    
  ]

  ;; End f-reproduce-seeker-by-fission
end 

;;-----------------------------------------------------------------------------|
;; A new seeker mutates, changing the genetic basis of strategies.

to f-mutate-new-seeker
  ;; This routine is to be executed by a seeker.
  
  ;; When a mutation is called for, one gene is mutated.  So when one or both 
  ;;   switches are on, the probability that a C1 gene will mutate must 
  ;;   decrease.  I could give each of C1, EPM and EPA equal probability of 
  ;;   occurrence.  Since there are, in fact 8 C1 genes, (as opposed to 2 
  ;;   possible C2 genes) they should get to mutate 8/10 = 80% of the time 
  ;;   or more when a mutation is called for.  However, since my interest 
  ;;   is NOT on the C1 genes, a dynamic that I understand well, I want the 
  ;;   EPM and EPA to evolve more rapidly when called for.   For that reason, 
  ;;   I have written the code to recognize the C1 chromosome, as a whole, 
  ;;   as having equal status as the EPM and EPA when activated.  
  ;; Given that a mutation of some sort must hapen, the probability of 
  ;;   mutation of the various genes must be spread around appropriately.  
  ;; The various scenarios are then:
  ;; -EPM=OFF; EPA=OFF; C1 gets 100%; EPM gets 0%;  EPA gets 0%
  ;; -EPM=OFF; EPA=ON;  C1 gets 50%;  EPM gets 0%;  EPA gets 50%
  ;; -EPM=ON;  EPA=OFF; C1 gets 50%;  EPM gets 50%; EPA gets 0%
  ;; -EPM=ON;  EPA=ON;  C1 gets 33 1/3%; EPM gets 33 1/3%; EPA gets 33 1/3%
  ;; This logic is rolled out over several calls to sub-routines.  Note that
  ;;   these percentages are conditional on determination that a mutation
  ;;   must happen for this seeker daughter in this reproductive event.
  
  ;; Decide if a genetic mutation is to happen.
  let random-number ( random-float 1 )
  let threshold ( g-prob-of-mutation )
  LOG-TO-FILE 
    ( word "  Do-rep: PreMut (RN, TH)    - (" random-number ", " threshold ")" )
  if ( random-number <= threshold )
  [
    ;; I want only one gene to mutate when mutation is called for.  So
    ;;   I need some logic that responds to the toggles that control which
    ;;   kinds of gene mutate - i.e. gb-mutate-epm and gb-mutate-epa.
    ifelse( ( gb-mutate-epm = false ) and ( gb-mutate-epa = false ) )
    [ 
      ;; Case of both EPM and EPA mutation is turned off.  C1 gets 100%.
      f-mutate-c1-gene 
    ]
    ;; Else
    [ 
      ;; Some other case.  C1 gets less than 100% probability of mutation.
      ;; Either a c1 gene mutates, or one of EPM or EPA (C2 genes) mutate.
      ;; At this point I know that at least one of EPM and EPA is to be included.
      ;; So, the competition is between two or three, with thresholds of 0.5
      ;; or 0.33333.
      set threshold ( 0.3333333333333 ) ;; Default
      if( ( gb-mutate-epm = false ) or ( gb-mutate-epm = false ) )
      [
        set threshold ( 0.5 )
      ]
      ;; Decide which type of genetic mutation is to happen.
      set random-number ( random-float 1 )
      LOG-TO-FILE 
        ( word "  Do-rep: PreCxMut (RN, TH)  - (" random-number ", " threshold ")" )
      ifelse ( random-number <= threshold )
      [ f-mutate-c1-gene ]
      [ f-mutate-c2-gene ]
    ]
  ]
  
  ;; End of f-mutate-new-seeker
end 
  
;;-----------------------------------------------------------------------------|
;; A seeker mutates a chromosome #1 (c1) gene.

to f-mutate-c1-gene
  ;; This routine is to be executed by a seeker.
  
  ;; Case of C1 mutation to be done.
  LOG-TO-FILE ( word "  Do-rep: PreC1Mut c1-bases  - " c1-bases )
  LOG-TO-FILE ( word "  Do-rep: PreC1Mut c1-expos  - " c1-expos )
  LOG-TO-FILE ( word "  Do-rep: PreC1Mut c1-stren  - " c1-stren )
  LOG-TO-FILE ( word "  Do-rep: PreC1Mut c1-pheno  - " c1-pheno )

  ;; There are 8 C1 genes.  Select the gene to be mutated.  These genes 
  ;;   control the heuristic search strategy.
  let gene-to-be-mutated ( random 8 )
  LOG-TO-FILE ( word "  Do-rep: Target gene #      - " gene-to-be-mutated )
    
  ;; Mutate the gene base.
  let oldbase ( item gene-to-be-mutated c1-bases )
  LOG-TO-FILE ( word "  Do-rep: Old base value     - " oldbase )
  ;; Choose a factor for the base.
  let base-factor ( item (random 8) gl-base-factors )
  ;; Mutate it
  let newbase ( oldbase * base-factor )
  LOG-TO-FILE ( word "  Do-rep: Factor             - " base-factor )
  set c1-bases ( replace-item gene-to-be-mutated c1-bases newbase )
  LOG-TO-FILE ( word "  Do-rep: New base value     - " newbase )
    
  ;; Mutate the gene.  The gene value is an integer of either sign.
  let oldgene ( item gene-to-be-mutated c1-expos )
  LOG-TO-FILE ( word "  Do-rep: Old gene value     - " oldgene )
  ;; Decide whether it will increase or decrease in value.
  let delta ( -1 + ( 2 * ( random 2 ) ) )  ;; Either a -1 or a 1.
  LOG-TO-FILE ( word "  Do-rep: Delta              - " delta )
  let newgene ( oldgene + delta )
  set c1-expos ( replace-item gene-to-be-mutated c1-expos newgene )
  LOG-TO-FILE ( word "  Do-rep: New gene value     - " newgene )

  ;; Calculate the strengths and phenotypic characters.
  f-find-strens-n-phenos
      
  LOG-TO-FILE ( word "  Do-rep: AftC1Mut c1-bases  - " c1-bases )
  LOG-TO-FILE ( word "  Do-rep: AftC1Mut c1-expos  - " c1-expos )
  LOG-TO-FILE ( word "  Do-rep: AftC1Mut c1-stren  - " c1-stren )
  LOG-TO-FILE ( word "  Do-rep: AftC1Mut c1-pheno  - " c1-pheno )
  
  ;; End of f-mutate-c1-gene
end 
  
;;-----------------------------------------------------------------------------|
;; A seeker mutates a Chromosome #2 (C2) gene.

to f-mutate-c2-gene
  ;; This routine is to be executed by a seeker.
  ;; To be called, at least one switch must be on.
  
  ;; One of two genes is to be mutated.  Either EPM or EPA.
  ;;   EPM is energy per move, and controls the rate of metabolic expenditure.
  ;;   EPA is energy per agent, and controls the maximal nrg content per agent.
  ;; Both of these genes play a role in the throughput of energy.  EPM
  ;;   has an obvious direct role, and should have great pressure put on it.
  ;;   EPA has an indirect role, and should have mild pressure put on it. 
  ;;   I.e. I think EPM has a strong effect on survivability, while EPA has
  ;;   a much lesser effect.
  
  ;; Decide which genetic mutation is to happen.  
  ;; Mutation of these genes is toggled on or off by Boolean switches.  To
  ;;   have this program called, at least one of those is on, but possibly
  ;;   both are on.
  if( gb-mutate-epa = false )
  [
    ;; Case of EPM to be mutated.
    f-mutate-epm
  ]
  
  if( gb-mutate-epm = false )
  [
    ;; Case of EPA to be mutated.
    f-mutate-epa
  ]
  
  if( ( gb-mutate-epm = true ) and ( gb-mutate-epa = true ) )
  [
    ;; Each has a 50/50 chance.
    let random-number ( random-float 1 )
    let threshold ( 0.50 )
    LOG-TO-FILE 
      ( word "  Do-rep: PreC2Mut (RN, TH)  - (" random-number ", " threshold ")" )
    ifelse ( random-number <= threshold )
    [ f-mutate-epm ]
    ;; Else
    [ f-mutate-epa ]
  ]
  
  ;; End of f-mutate-c2-gene
end 
  
;;-----------------------------------------------------------------------------|
;; The EPM C2 gene is to be mutated.

to f-mutate-EPM
  ;; This routine is to be executed by a seeker.
  
  ;; Case of mutation of EPM.
  LOG-TO-FILE ( word "  Do-rep: PreC2Mut EPM       - " EPM )

  ;; I want a variety of factors to avoid discreteness in values.
  ;; I want an unbiased chance of a rise or fall in value.
  let l-factor-list 
    [ 1.01 1.01 1.01 1.01 1.02 1.02 1.04 
      0.99 0.99 0.99 0.99 0.98 0.98 0.96 ]
  ;; Choose a factor.
  let factor ( item (random 14) l-factor-list )
  LOG-TO-FILE ( word "  Do-rep: Factor             - " factor )
  ;; Mutate it
  set EPM ( EPM * factor )
  LOG-TO-FILE ( word "  Do-rep: AftC2Mut EPM       - " EPM )
  
  ;; End of f-mutate-EPM
end 
  
;;-----------------------------------------------------------------------------|
;; The EPA C2 gene is to be mutated.

to f-mutate-EPA
  ;; This routine is to be executed by a seeker.
  
  ;; Case of mutation of EPA.
  LOG-TO-FILE ( word "  Do-rep: PreC2Mut EPA       - " EPA )

  ;; I want a variety of factors to avoid discreteness in values.
  ;; I want an unbiased chance of a rise or fall in value.
  let l-factor-list 
    [ 1.001 1.001 1.001 1.001 1.002 1.002 1.004 
      0.999 0.999 0.999 0.999 0.998 0.998 0.996 ]
  ;; Choose a factor.
  let factor ( item (random 14) l-factor-list )
  LOG-TO-FILE ( word "  Do-rep: Factor             - " factor )
  ;; Mutate it
  set EPA ( EPA * factor )
  LOG-TO-FILE ( word "  Do-rep: AftC2Mut EPA       - " EPA )
  
  ;; End of f-mutate-EPA
end 
  
;;-----------------------------------------------------------------------------|
;; D6 – do-die procedure(s)
;;-----------------------------------------------------------------------------|

to do-die
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "die" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-die: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  if( ( count seekers ) > 0 )
  [
    ask seekers
    [
      f-set-seeker-death-flag
      f-seeker-dies
    ]
  ]
  
  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-die: procedure completed"
end 

;;-----------------------------------------------------------------------------|
;; f-set-seeker-death-flag

to f-set-seeker-death-flag
  ;; This routine is to be executed by a seeker.
  
  set b-is-ready-to-die 0        ;; i.e. false, default.

  ;; If a cause of death has already been noted, it dies.
  ifelse( cause-of-death > ge-cod-none )
  [
    ;; A cause of death has been previously flagged.
    ;; This is either due to hunger (in do-move) or fission (in do-repro).
    ;; In both cases nrg has been stripped out already.
    ;; In the cases of DET and DAT, the flag is not yet set, 
    ;;   and the nrg remains.
    set b-is-ready-to-die 1 
  ]
  ;; Else
  [
    ;; No cause of death has been set yet.  Check basic vital signs.
    if( nrg <= DET )  ;; Death Energy Threshold.
    [ 
      set b-is-ready-to-die 1 
      set cause-of-death ge-cod-hunger 
      f-store-data-in-sink ge-sinktype-die-det nrg
      set g-nrg-in-system ( g-nrg-in-system - nrg )
      set g-nrg-in-agents ( g-nrg-in-agents - nrg )

      if( gb-include-dnd = true ) 
      [
        ;; Record the expenditure in the EROI variables
        f-record-ei-for-dnd-eroi nrg
      ]
    
      set nrg 0
    ]
    
    if( age > DAT )   ;; Death Age Threshold.
    [ 
      set b-is-ready-to-die 1 
      set cause-of-death ge-cod-oldage 
      f-store-data-in-sink ge-sinktype-die-dat nrg
      set g-nrg-in-agents ( g-nrg-in-agents - nrg )
      set g-nrg-in-system ( g-nrg-in-system - nrg )

      if( gb-include-dnd = true ) 
      [
        ;; Record the expenditure in the EROI variables
        f-record-ei-for-dnd-eroi nrg
      ]
    
      set nrg 0
    ]
  ]

  if( b-is-ready-to-die = 1 )
  [
    LOG-TO-FILE ( WORD "  Do-die: S(age,nrg,cod) - ("
      age "," 
      nrg "," 
      cause-of-death ")" )
  ]
  
  ;; End f-set-seeker-death-flag
end 

;;-----------------------------------------------------------------------------|
;; f-seeker-dies

to f-seeker-dies
  ;; This routine is to be executed by a seeker.
  
  if( b-is-ready-to-die = 1 )
  [
    ;; Record the eroi and eta data before death by hunger.
    if( cause-of-death = ge-cod-hunger )
    [
      if( g-dbh-stat-count >= g-max-for-lte-stats )
      [
        ;; Remove old data for "death by hunger" (dbh).
        set gl-lte-eroi-dbh ( butfirst gl-lte-eroi-dbh )
        set gl-lte-eta-dbh  ( butfirst gl-lte-eta-dbh )
        set g-dbh-stat-count ( g-dbh-stat-count - 1 )
      ]
      set gl-lte-eroi-dbh ( lput lte-eroi gl-lte-eroi-dbh )
      set gl-lte-eta-dbh  ( lput lte-eta gl-lte-eta-dbh )
      set g-dbh-stat-count ( g-dbh-stat-count + 1 )
      set gl-lte-eroi-all
        ( sentence gl-lte-eroi-dbh gl-lte-eroi-dbo gl-lte-eroi-dbr )
      set gl-lte-eta-all
        ( sentence gl-lte-eta-dbh gl-lte-eta-dbo gl-lte-eta-dbr )
    ]

    ;; Record the lte-eroi and lte-eta data before death by old age.
    if( cause-of-death = ge-cod-oldage ) 
    [
      if( g-dbo-stat-count >= g-max-for-lte-stats )
      [
        ;; Remove old data for "death by old age" (dbo).
        set gl-lte-eroi-dbo ( butfirst gl-lte-eroi-dbo )
        set gl-lte-eta-dbo  ( butfirst gl-lte-eta-dbo )
        set g-dbo-stat-count ( g-dbo-stat-count - 1 )
      ]
      set gl-lte-eroi-dbo ( lput lte-eroi gl-lte-eroi-dbo )
      set gl-lte-eta-dbo  ( lput lte-eta gl-lte-eta-dbo )
      set g-dbo-stat-count ( g-dbo-stat-count + 1 )
      set gl-lte-eroi-all
        ( sentence gl-lte-eroi-dbh gl-lte-eroi-dbo gl-lte-eroi-dbr )
      set gl-lte-eta-all
        ( sentence gl-lte-eta-dbh gl-lte-eta-dbo gl-lte-eta-dbr )
    ]

    ;; Nrg was stripped out in do-move step.
    ;; However, nrg may exist for those who die of old age.
    f-increment-cod-list breed cause-of-death
    die  ;; The seeker disappears from the system.    
  ]

  ;; End f-seeker-dies
end 

;;-----------------------------------------------------------------------------|
;; D7 - do-post-tick procedure(s)
;;-----------------------------------------------------------------------------|

to do-post-tick
  ;; This routine is to be executed by the observer.
   
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "post-tick" ) )
    [ set gb-debug-flow-on 1  LOG-TO-FILE "" LOG-TO-FILE word "Do-Post-tick: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; MANUAL CHANGE FOR DEBUG.
  ;; This is a call to a debug routine which could be suppressed if all is okay.
  ;; This is one of a group of such calls, most of which are between steps in 
  ;;   the 'Go' routine.  They are suppressed there, but can be enabled again.
  ;; I have decided to leave this one active, for now.
  ;; It checks all agents, every tick, to ensure that all values are greater than
  ;;   or equal to zero.  
  if( frb-agents-are-all-valid = false ) 
    [ LOG-TO-FILE ( word "  Do-post-tick: Agents failed validity test." ) ]
  
  ;; Global EROI system-wide calculations.
  set g-sys-nrg-returned 
    ( sum gl-sys-nrg-returned ) ;; Total nrg returned within delta T (er).
  set g-sys-nrg-invested 
    ( sum gl-sys-nrg-invested ) ;; Total nrg invested within delta T (ei).
  set g-sys-nrg-benefits 
    ( g-sys-nrg-returned - g-sys-nrg-invested ) ;; (er-ei)

  ifelse( g-sys-nrg-invested > 0 ) 
    [ set g-sys-eroi ( g-sys-nrg-returned / g-sys-nrg-invested ) ] ;; (I/C)
    [ set g-sys-eroi 0 ] ;; (I/C)

  ifelse( g-sys-nrg-returned > 0 ) 
    [ set g-sys-eta ( g-sys-nrg-benefits / g-sys-nrg-returned ) ]  ;; (B/I)
    [ set g-sys-eta -5 ]  ;; (B/I)

  ;; Update the aggregates for display in the monitors.
  f-update-aggregates

  display

  LOG-TO-FILE "  Do-post-tick: procedure completed."
end 

;;-----------------------------------------------------------------------------|
;; SECTION E – DRAWING AND MAINTENANCE PROCEDURE(S)
;;-----------------------------------------------------------------------------|

;;-----------------------------------------------------------------------------|
;; Update the values of global aggregate numbers.

to f-update-aggregates
  ;; This routine is to be executed by the observer.

  ;; Although this is a display-only routine, it may implicitly call the 
  ;;   PRNG and so may have an effect on the trajectory of the model.  In a 
  ;;   standard 'go' run it is called only once per tick, before graphs are 
  ;;   updated.  If you use the one-step debug buttons, it is called once 
  ;;   after each step, so debug runs that use those buttons will not 
  ;;   replicate a real run.
  
  ;;---------------------------------------------------------------------------|
  ;; The following agent sets, counts and averages are for data collection 
  ;;   and display in monitors and plots.
  
  ;; Counts
  ;; set g-no-of-patches ( count patches )
  set g-no-of-seekers ( count seekers )
  
  ;; Max value for eroi domain.
  let temp-list ( sentence gl-lte-eroi-dbh gl-lte-eta-dbr gl-lte-eroi-dbo)
  ifelse( ( length temp-list ) > 0 )
  [ set g-lte-eroi-max ( max temp-list) ]
  ;; else
  [ set g-lte-eroi-max ( 0 ) ]
  
  ;; Min value for eta domain.
  set temp-list ( sentence gl-lte-eta-dbh gl-lte-eta-dbr gl-lte-eta-dbo)
  ifelse( ( length temp-list ) > 0 )
  [ set g-lte-eta-min ( min temp-list ) ]
  ;; else
  [ set g-lte-eta-min ( 0 ) ]
  
  ;; Other histogram limits
  set g-hist-epm-max ( ( ceiling ( (  .1 + max [epm] of seekers ) * 10 ) ) / 10 ) 
  set g-hist-epm-min ( ( floor   ( ( -.1 + min [epm] of seekers ) * 10 ) ) / 10 )
  set g-hist-epa-max ( ceiling ( 1 + max [epa] of seekers ) )
  set g-hist-epa-min ( floor  ( -1 + min [epa] of seekers ) )

  ;; Averages - seekers
  ifelse( 0 = ( count seekers ) )
  [
    set g-ave-age      0        ;; age of seekers
    set g-ave-nrg      0        ;; nrg of seekers
    set g-ind-min-eroi 0        ;; eroi of seekers
    set g-ind-ave-eroi 0        ;; eroi of seekers
    set g-ind-max-eroi 0        ;; eroi of seekers
    set g-ind-min-eta  0        ;; eta of seekers
    set g-ind-ave-eta  0        ;; eta of seekers
    set g-ind-max-eta  0        ;; eta of seekers

    set g-ave-C1-b0   0         ;; c1, base character, gene-0
    set g-ave-C1-b1   0         ;; c1, base character, gene-1
    set g-ave-C1-b2   0         ;; c1, base character, gene-2
    set g-ave-C1-b3   0         ;; c1, base character, gene-3
    set g-ave-C1-b4   0         ;; c1, base character, gene-4
    set g-ave-C1-b5   0         ;; c1, base character, gene-5
    set g-ave-C1-b6   0         ;; c1, base character, gene-6
    set g-ave-C1-b7   0         ;; c1, base character, gene-7
 
    set g-ave-c1-e0   0         ;; c1, exponent character, gene-0
    set g-ave-c1-e1   0         ;; c1, exponent character, gene-1
    set g-ave-c1-e2   0         ;; c1, exponent character, gene-2
    set g-ave-c1-e3   0         ;; c1, exponent character, gene-3
    set g-ave-c1-e4   0         ;; c1, exponent character, gene-4
    set g-ave-c1-e5   0         ;; c1, exponent character, gene-5
    set g-ave-c1-e6   0         ;; c1, exponent character, gene-6
    set g-ave-c1-e7   0         ;; c1, exponent character, gene-7
 
    set g-ave-C1-s0   0         ;; c1, strength character, gene-0
    set g-ave-C1-s1   0         ;; c1, strength character, gene-1
    set g-ave-C1-s2   0         ;; c1, strength character, gene-2
    set g-ave-C1-s3   0         ;; c1, strength character, gene-3
    set g-ave-C1-s4   0         ;; c1, strength character, gene-4
    set g-ave-C1-s5   0         ;; c1, strength character, gene-5
    set g-ave-C1-s6   0         ;; c1, strength character, gene-6
    set g-ave-C1-s7   0         ;; c1, strength character, gene-7

    set g-ave-C1-p0   0         ;; c1, phenotypic character, gene-0
    set g-ave-C1-p1   0         ;; c1, phenotypic character, gene-1
    set g-ave-C1-p2   0         ;; c1, phenotypic character, gene-2
    set g-ave-C1-p3   0         ;; c1, phenotypic character, gene-3
    set g-ave-C1-p4   0         ;; c1, phenotypic character, gene-4
    set g-ave-C1-p5   0         ;; c1, phenotypic character, gene-5
    set g-ave-C1-p6   0         ;; c1, phenotypic character, gene-6
    set g-ave-C1-p7   0         ;; c1, phenotypic character, gene-7
  ]
  ;; Else
  [
    set g-ave-age       ( mean [age] of seekers ) 
    set g-ave-nrg       ( mean [nrg] of seekers ) 
    set g-ind-min-eroi  ( min  [ind-eroi] of seekers )
    set g-ind-ave-eroi  ( mean [ind-eroi] of seekers ) 
    set g-ind-max-eroi  ( max  [ind-eroi] of seekers )
    set g-ind-min-eta   ( min  [ind-eta] of seekers )
    set g-ind-ave-eta   ( mean [ind-eta] of seekers ) 
    set g-ind-max-eta   ( max  [ind-eta] of seekers )

    set g-ave-C1-b0 ( f-compute-C1-bases-average 0 )
    set g-ave-C1-b1 ( f-compute-C1-bases-average 1 )
    set g-ave-C1-b2 ( f-compute-C1-bases-average 2 )
    set g-ave-C1-b3 ( f-compute-C1-bases-average 3 )
    set g-ave-C1-b4 ( f-compute-C1-bases-average 4 )
    set g-ave-C1-b5 ( f-compute-C1-bases-average 5 )
    set g-ave-C1-b6 ( f-compute-C1-bases-average 6 )
    set g-ave-C1-b7 ( f-compute-C1-bases-average 7 )

    set g-ave-c1-e0 ( f-compute-c1-expos-average 0 )
    set g-ave-c1-e1 ( f-compute-c1-expos-average 1 )
    set g-ave-c1-e2 ( f-compute-c1-expos-average 2 )
    set g-ave-c1-e3 ( f-compute-c1-expos-average 3 )
    set g-ave-c1-e4 ( f-compute-c1-expos-average 4 )
    set g-ave-c1-e5 ( f-compute-c1-expos-average 5 )
    set g-ave-c1-e6 ( f-compute-c1-expos-average 6 )
    set g-ave-c1-e7 ( f-compute-c1-expos-average 7 )

    set g-ave-C1-s0 ( f-compute-c1-stren-average 0 )
    set g-ave-C1-s1 ( f-compute-c1-stren-average 1 )
    set g-ave-C1-s2 ( f-compute-c1-stren-average 2 )
    set g-ave-C1-s3 ( f-compute-c1-stren-average 3 )
    set g-ave-C1-s4 ( f-compute-c1-stren-average 4 )
    set g-ave-C1-s5 ( f-compute-c1-stren-average 5 )
    set g-ave-C1-s6 ( f-compute-c1-stren-average 6 )
    set g-ave-C1-s7 ( f-compute-c1-stren-average 7 )

    set g-ave-C1-p0 ( f-compute-c1-pheno-average 0 )
    set g-ave-C1-p1 ( f-compute-c1-pheno-average 1 )
    set g-ave-C1-p2 ( f-compute-c1-pheno-average 2 )
    set g-ave-C1-p3 ( f-compute-c1-pheno-average 3 )
    set g-ave-C1-p4 ( f-compute-c1-pheno-average 4 )
    set g-ave-C1-p5 ( f-compute-c1-pheno-average 5 )
    set g-ave-C1-p6 ( f-compute-c1-pheno-average 6 )
    set g-ave-C1-p7 ( f-compute-c1-pheno-average 7 )
    
  ]
  ;; End else
  
  ;; Calculate the entropic index of the energy distribution.
  set g-energy-entropic-index 
    ( fr-get-energy-entropic-index ( [nrg] of seekers ) )
  print ""
  
  ;; Calculate the entropic index of the phenotype probability distribution.
  let l-pheno-partition ( fr-make-pheno-partition )
  set g-pheno-entropic-index ( fr-calc-pheno-entropic-index l-pheno-partition )

  ;; This log entry may come from any step during debug operations.  
  LOG-TO-FILE "  Do-update: All aggregates updated."  

  ;; End of f-update-aggregates
end 

;;-----------------------------------------------------------------------------|
;; Clear the Life-Time Efficiency (LTE) data.

to f-clear-lte-data
  ;; This routine is to be executed by the observer.

  ;; Global lists for EROI/ETA for death by repro/hunger.
  set g-dbr-stat-count        0 ;; Count of ticks included in lists.
  set g-dbh-stat-count        0 ;; Count of ticks included in lists.
  set g-dbo-stat-count        0 ;; Count of ticks included in lists.
  ;; set g-max-for-lte-stats  0 ;; Maximum agents included [40,40,1000,1000]
  set gl-lte-eroi-dbr        [] ;; List of EROI for death by repro
  set gl-lte-eroi-dbh        [] ;; List of EROI for death by hunger
  set gl-lte-eroi-dbo        [] ;; List of EROI for death by old age
  set gl-lte-eroi-all        [] ;; List of EROI for death by all causes
  set gl-lte-eta-dbr         [] ;; List of ETA for death by repro
  set gl-lte-eta-dbh         [] ;; List of ETA for death by hunger
  set gl-lte-eta-dbo         [] ;; List of ETA for death by old age
  set gl-lte-eta-all         [] ;; List of ETA for death by all causes
  set g-lte-eroi-max          1 ;; Used to set max value for histograms

  ;; End of f-clear-lte-data
end 

;;-----------------------------------------------------------------------------|
;; Compute an average for C1-bases, by preferred gene type.

to-report f-compute-C1-bases-average [ gene-to-check ]
  ;; This routine is to be executed by the observer.
  let count-of-seekers ( count seekers )
  let appropriate-sum ( sum ( [item gene-to-check c1-bases] of seekers ) )
  let answer 0
  if ( count-of-seekers > 0 ) 
    [ set answer ( appropriate-sum / count-of-seekers ) ]
  ;; LOG-TO-FILE ( word "  Do-update: g# - " gene-to-check ", ave [B] - " answer ) 
  
  report answer
  
  ;; End of f-compute-C1-bases-average
end 

;;-----------------------------------------------------------------------------|
;; Compute an average for c1-expos, by preferred gene type.

to-report f-compute-c1-expos-average [ gene-to-check ]
  ;; This routine is to be executed by the observer.
  let count-of-seekers ( count seekers )
  let appropriate-sum ( sum ( [item gene-to-check c1-expos] of seekers ) )
  let answer 0
  if ( count-of-seekers > 0 ) 
    [ set answer ( appropriate-sum / count-of-seekers ) ]
  ;; LOG-TO-FILE ( word "  Do-update: g# - " gene-to-check ", ave [E] - " answer ) 
  
  report answer
  
  ;; End of f-compute-c1-expos-average
end 

;;-----------------------------------------------------------------------------|
;; Compute an average for c1-stren, by preferred gene type.

to-report f-compute-c1-stren-average [ gene-to-check ]
  ;; This routine is to be executed by the observer.
  let count-of-seekers ( count seekers )
  let appropriate-sum ( sum ( [item gene-to-check c1-stren] of seekers ) )
  let answer 0
  if ( count-of-seekers > 0 ) 
    [ set answer ( appropriate-sum / count-of-seekers ) ]
  ;; LOG-TO-FILE ( word "  Do-update: g# - " gene-to-check ", ave [S] - " answer ) 
  
  report answer
  
  ;; End of f-compute-c1-stren-average
end 

;;-----------------------------------------------------------------------------|
;; Compute an average for c1-pheno, by preferred gene type.

to-report f-compute-c1-pheno-average [ gene-to-check ]
  ;; This routine is to be executed by the observer.
  let count-of-seekers ( count seekers )
  let appropriate-sum ( sum ( [item gene-to-check c1-pheno] of seekers ) )
  let answer 0
  if ( count-of-seekers > 0 ) 
    [ set answer ( appropriate-sum / count-of-seekers ) ]
  ;; LOG-TO-FILE ( word "  Do-update: g# - " gene-to-check ", ave [P] - " answer ) 
  
  report answer
  
  ;; End of f-compute-c1-pheno-average
end 

;;--------------------------
;; DATA CAPTURE TO CSV FILES
;;--------------------------

;;-----------------------------------------------------------------------------|
;; Record the data is several selected plots to CSV files

to f-record-selected-plots
  ;; This routine is to be executed by the observer.
  
  ;; The template for the export command is:
  ;; export-plot plotname filename

  ;; Get a common timestamp for all plots.
  let timestamp fr-get-time-stamp
  
  ;; Plot 01
  let plotname "[B]ase Values By Gene #"
  let plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl01_BVBG.CSV" )
  export-plot plotname plot-filename
  
  ;; Plot 02
  set plotname "[E]xponent Values By Gene #"
  set plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl02_EVBG.CSV" )
  export-plot plotname plot-filename
  
  ;; Plot 03
  set plotname "[S]trengths By Gene #"
  set plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl03_SVBG.CSV" )
  export-plot plotname plot-filename
  
  ;; Plot 04
  set plotname "[P]henotype Values By Gene #"
  set plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl04_PVBG.CSV" )
  export-plot plotname plot-filename
  
  ;; End f-record-selected-plots
end 

;;-----------------------------------------------------------------------------|
;; Construct a time stamp for a file name for data in CSV format.

to-report fr-get-time-stamp
  ;; This routine is to be executed by the observer.
  ;;
  ;; Date-string format "01:19:36.685 PM 19-Sep-2002"
  let date-string date-and-time
  let time-stamp ""
  ;; Append the year as yy.
  set time-stamp word time-stamp ( substring date-string 25 27 )
  ;; Append the month as Mmm.
  set time-stamp word time-stamp fr-convert-mmm-mm ( substring date-string 19 22 )
  ;; Append the day as dd.
  set time-stamp word time-stamp ( substring date-string 16 18 )
  ;; Append a dash.
  set time-stamp word time-stamp "_"

  ;; Append the hour as hh.
  set time-stamp word time-stamp fr-convert1224 ( substring date-string 0 2 ) ( substring date-string 13 15 )
  ;; Append the minute as mm.
  set time-stamp word time-stamp ( substring date-string 3 5 )
  ;; Append the second as ss.
  set time-stamp word time-stamp ( substring date-string 6 8 )

  report time-stamp
  ;; End fr-get-time-stamp
end 

;;-----------------------------------------------------------------------------|
;; DEBUG AND DEBUG LOG FILE MANAGEMENT FUNCTIONS
;;-----------------------------------------------------------------------------|

;;-----------------------------------------------------------------------------|
;; Open a log file for debug output.

to f-open-log-file
  ;; This routine is to be executed by the observer.
  
  ;; Ensure previous log file is closed.
  if ( is-string? gs-log-file-name )
  [
    if ( file-exists? gs-log-file-name )
    [
      file-close-all
    ]
  ]
  
  ;; Date-string format "01:19:36.685 PM 19-Sep-2002"
  let date-string date-and-time
  set gs-log-file-name "EffLab_I_Log_"
  ;; Append the year as yy.
  set gs-log-file-name word gs-log-file-name ( substring date-string 25 27 )
  ;; Append the month as Mmm.
  set gs-log-file-name word gs-log-file-name fr-convert-mmm-mm ( substring date-string 19 22 )
  ;; Append the day as dd.
  set gs-log-file-name word gs-log-file-name ( substring date-string 16 18 )
  ;; Append a dash.
  set gs-log-file-name word gs-log-file-name "_"

  ;; Append the hour as hh.
  set gs-log-file-name word gs-log-file-name fr-convert1224 ( substring date-string 0 2 ) ( substring date-string 13 15 )
  ;; Append the minute as mm.
  set gs-log-file-name word gs-log-file-name ( substring date-string 3 5 )
  ;; Append the second as ss.
  set gs-log-file-name word gs-log-file-name ( substring date-string 6 8 )
  ;; Append the .txt extension.
  set gs-log-file-name word gs-log-file-name ".txt"

  file-open gs-log-file-name
  file-show "Log File for a EffLab (NetLogo) Model."
  file-show word "File Name: " gs-log-file-name
  file-show word "File opened at:" date-and-time
  file-show ""
  
  ;; Send a message directly to the command centre.
  ifelse ( file-exists? gs-log-file-name )
  [
    show word gs-log-file-name " opened."
  ]
  [
    show word gs-log-file-name " not opened."
  ]
end 

;;-----------------------------------------------------------------------------|
;; Convert month in text form to digital form.

to-report fr-convert-mmm-mm [ mmm ]
  ;; This routine is to be executed by the observer.
  ;; It converts a string in the form mmm ( alpha text ) to the form mm ( digit-text ).
  
  let mm "00"
  if( mmm = "Jan" ) [ set mm "01" ]
  if( mmm = "Feb" ) [ set mm "02" ]
  if( mmm = "Mar" ) [ set mm "03" ]
  if( mmm = "Apr" ) [ set mm "04" ]
  if( mmm = "May" ) [ set mm "05" ]
  if( mmm = "Jun" ) [ set mm "06" ]
  if( mmm = "Jul" ) [ set mm "07" ]
  if( mmm = "Aug" ) [ set mm "08" ]
  if( mmm = "SeP" ) [ set mm "09" ]
  if( mmm = "Oct" ) [ set mm "10" ]
  if( mmm = "Nov" ) [ set mm "11" ]
  if( mmm = "Dec" ) [ set mm "12" ]
  report mm
end 

;;-----------------------------------------------------------------------------|
;; Convert hour in 12 format to 24 hour format.

to-report fr-convert1224 [ hh ampm ]
  ;; This routine is to be executed by the observer.
  ;; It converts a string in 12 hour format to 24 hour format.
  
  let hour read-from-string hh
  if( ampm = "PM" ) [ set hour ( hour + 12 ) ]
  
  let dd ( word "00" hour )
  let d2 last dd
  set dd but-last dd
  let d1 last dd
  set dd ( word d1 d2 )
  report dd
end 

;;-----------------------------------------------------------------------------|
;; Close a log file for debug output.

to f-close-log-file
  ;; This routine is to be executed by the observer.
  
  let b-filename-exists 0
  if ( is-string? gs-log-file-name ) 
  [
    if ( file-exists? gs-log-file-name )
    [
      set b-filename-exists 1
    ]
  ] 

  ifelse( b-filename-exists = 1 )
  [
    ;; Ensure the file is selected.
    file-open gs-log-file-name
      
    ;; Stanp it.
    LOG-TO-FILE word "File closed at: " date-and-time
      
    ;; Flush the buffers.
    file-flush 
      
    ;; Close it.
    file-close-all
      
    ;; Note sent to command centre.
    show word gs-log-file-name " closed."
    
    ;; Revert to dummy name.
    set gs-log-file-name "dummyname"
  ]
  [
    if( gs-log-file-name = "dummyname" )
      [ show "No log file is open.  Cannot close it." ]
  ]
end 

;;-----------------------------------------------------------------------------|
;; Select an already opened log file.

to f-select-log-file
  ;; This routine is to be executed by the observer.
  
  ifelse ( file-exists? gs-log-file-name )
  [
    ;; Ensure the file is selected.
    file-open gs-log-file-name
    
    ;; Ensure it is open for writing.
    LOG-TO-FILE ""
    LOG-TO-FILE "SELECTED"    
  ]
  [
    show word gs-log-file-name " is not open.  Cannot select it."
  ]
end 

;;-----------------------------------------------------------------------------|
;; Change the debug mode from on to off, or vice versa.

to f-toggle-debug
  ;; This routine is to be executed by the observer, and is activated by a 
  ;;   button.
  
  ifelse( gb-debug-on = 1 )
  [
    ;; Debug is On, turn it Off.
    ;; Close the file before turning debug logging off.
    f-close-log-file
    set gs-debug-status "0 (Off)"  ;; This appears in the monitor.
    set gb-debug-on 0              ;; But this controls the debug feature.
  ]
  [
    ;; Debug is Off, turn it On.
    set gs-debug-status "1 (On)"   ;; This appears in the monitor.
    set gb-debug-on 1              ;; But this controls the debug feature.
    ;; The switches, if needed, are reset manually by the user.
    ;; Open the log file after turning debug logging on.
    f-open-log-file
  ]
end 

;;-----------------------------------------------------------------------------|
;; 'Show' a string in a debug log.

to LOG-TO-FILE [ log-this-string ]
  ;; This routine may be executed by observer or seeker.
  ;; It should be invoked as a debug routine only, and would not be used for 
  ;;    normal output.  It sends output to the debug log file, or, optionally,
  ;;    also to the command centre.
  
  ;; gb-debug-on is a global Boolean and has value 1 (true) or 0 (false).
  if( gb-debug-on = 1 )
  [
    ;; gb-debug-flow-on is declared as a global Boolean variable, and its value 
    ;;   is 0 ( false ) or 1 ( true ) and is set on or off at the beginning of each 
    ;;   function ( each do-step ).  It is controlled by the chooser that selects 'all' 
    ;;   or a specific do-function.
    ;; 
    ;; When it is 'on' you can assume the debug log file exists and is open for
    ;;   write.
    
    if( gb-debug-flow-on = 1 )
    [
      file-show log-this-string
      show log-this-string
    ] 
  ]
end 

;;-----------------------------------------------------------------------------|
;; This replicates the effect of an 'ASSERTION' in C++

to ASSERT [ error-test error-string error-who ]
;; This routine can be run by observer or seeker.

if( error-test = false )
[
  show ( word error-test " " error-string " " error-who )
  ;; Cause a run-time error and display a message.
  error ( word "Agent: " error-who " - " error-string )
]
end 

;;-----------------------------------------------------------------------------|
;; Check whether the nrg accounts are all valid.

to-report frb-nrg-accounts-are-all-valid 
;; This routine can be run by the observer.

  let b-accounts-are-all-valid 1
  
  if( gb-debug-on = 1 )
  [
    ;; Do the check only if debug is on.
    let temp-nrg-in-seekers  ( sum [nrg] of seekers )
    let temp-nrg-in-fruit    ( sum [fruit] of patches )
    
    let temp-total-nrg ( temp-nrg-in-seekers +
      temp-nrg-in-fruit )
    
    if (temp-nrg-in-fruit != g-nrg-in-fruit )
    [ 
      set b-accounts-are-all-valid 0 
      LOG-TO-FILE ( word 
        "F-nrg-check: SB:" temp-nrg-in-fruit 
        ", IS:" g-nrg-in-fruit )    
    ]
    
    if (temp-nrg-in-seekers != g-nrg-in-agents )
    [ 
      set b-accounts-are-all-valid 0 
      LOG-TO-FILE ( word 
        "S-nrg-check: SB:" temp-nrg-in-seekers 
        ", IS:" g-nrg-in-agents )    
    ]
    
    if (temp-total-nrg != g-nrg-in-system )
    [ 
      set b-accounts-are-all-valid 0 
      LOG-TO-FILE ( word 
        "T-nrg-check: SB:" temp-total-nrg 
        ", IS:" g-nrg-in-system )    
    ]
  ]
  
  report b-accounts-are-all-valid
  
  ;; End of frb-nrg-accounts-are-all-valid
end 

;;-----------------------------------------------------------------------------|
;; Check whether the agents are all valid.

to-report frb-agents-are-all-valid 
;; This routine can be run by the observer.

  let b-agents-are-all-valid true
  
  if( gb-debug-on = 1 )
  [
    ;; Do the check only if debug is on.
    
    ;; Check the seekers.
    ask seekers
    [
      if( frb-seeker-is-valid = false ) [ set b-agents-are-all-valid false ]
    ]
  ]
  
  report b-agents-are-all-valid
  
  ;; End of frb-agents-are-all-valid
end 

;;-----------------------------------------------------------------------------|
;; Check whether a seeker is valid.

to-report frb-seeker-is-valid 
;; This routine can be run by a seeker.

  let b-seeker-is-valid true
  
  report b-seeker-is-valid
  
  ;; End of frb-seeker-is-valid
end 

;;---------------------------------------------------------------------|-------|
;;  Partitions in ABMs.  Entropic index in ABMs.  GammaLn() function in ABMs.
;;---------------------------------------------------------------------|-------|
;;
;; REFERENCES: The diary notes including (or more recent versions):
;; A.  150527 PPR - Definition of Ei R17.PDF
;; B.  190927 NTF Shannon Vs Boltzmann R4.PDF
;; C.  180214 NTF Entropy and Units of Measure R5.PDF
;; D.  180822 NTF FactLn() and GammaLn() R3.PDF
;; E.  190927 NTF Entropy in a Histogram R4.PDF
;;

;; NOTE:  These routines create a partition (i.e. a histogram) independent of 
;;   the capabilities of the plot controls in the interface tab.

;;---------------------------------------------------------------------|-------|

to-report fr-get-energy-entropic-index [ l-data-input ]
  ;; This routine is to be executed by the observer.
  
  ;; show "----------"
  ;; show "fr-get-energy-entropic-index"
  
  let l-energy-partition ( fr-make-energy-partition l-data-input )
  ;; show ( word "fr-nrg-ei: l-energy-partition - " l-energy-partition )

  let nrg-ei ( fr-calc-energy-entropic-index l-energy-partition )
  ;; show ( word "nrg-ei: " nrg-ei )

  report nrg-ei
  
  ;; End of fr-get-energy-entropic-index
end 

;;---------------------------------------------------------------------|-------|

to-report fr-make-energy-partition [ l-data-input ]
  ;; This routine is to be executed by the observer.
  
  ;; show "----------"
  ;; show "fr-make-energy-partition"
  ;; show ( word "l-data-input:" l-data-input )
  
  ;; It creates binned data (a partition) that can be used to plot a histogram.
  ;; A typical call might look like this:
  ;;  set l-energy-partition 
  ;;              ( fr-make-energy-partition ( [energy] in seekers ) )
  ;;  reports [ l-partition ]
  
  ;; Allocate memory.
  let a-no-of-agents length l-data-input
  let k-no-of-bins ( floor ( sqrt a-no-of-agents ) )
  let ave-data ( mean l-data-input )
  let min-data ( ( min l-data-input ) - 0.001 )
  let max-data ( ( max l-data-input ) + 0.001 )
  let bin-delta 0
    ;; show ( word "fmep: ave-data(1): " ave-data )
    ;; show ( word "fmep: min-data(1): " min-data )
    ;; show ( word "fmep: max-data(1): " max-data )
    ;; show ( word "fmep: bin-delta(1): " bin-delta )
    ;; show ""
  
  ifelse ( ( max-data - min-data ) < k-no-of-bins )
  [
    ;; Case of all data-points being the same.
    set min-data ( ave-data - ( k-no-of-bins / 2 ) )
    set max-data ( ave-data + ( k-no-of-bins / 2 ) )
    set bin-delta ( ( max-data - min-data ) / k-no-of-bins )
    ;; show ( word "fmep: min-data(2): " min-data )
    ;; show ( word "fmep: max-data(2): " max-data )
    ;; show ( word "fmep: bin-delta(2): " bin-delta )
  ]
  ;; Else
  [
    set bin-delta ( ( max-data - min-data ) / k-no-of-bins )
  ]
    
  ;; Initialize the output histogram with zeros.
  let l-partition ( n-values k-no-of-bins [0] )
  ;; show ( word "fmep: l-partition: " l-partition )
  
  let counter 0
  let data-point 0
  let bin-no 0
  let agents-in-bin 0
  let limit ( ( length l-data-input ) - 1 )
  ;; show ( word "fmep: limit: " limit )

  while [counter <= limit ] 
  [
    ;; show ( word "fmep: counter(3): " counter )
    set data-point ( item counter l-data-input )
    ;; We need to convert this data point into a bin-number for the partition.
    set bin-no ( ( ( data-point - min-data ) / bin-delta ) )
    ;; show ( word "fmep: bin-no(3): " bin-no )
    set bin-no ( floor ( ( data-point - min-data ) / bin-delta ) )
    ;; show ( word "fmep: bin-no(3): " bin-no )
    ;; bin-no is a whole number which determines which bin the agent is counted in.
    ;; show ( word "fmep: data-point(3): " data-point )
    ;; show ( word "fmep: min-data(3): " min-data )
    ;; show ( word "fmep: bin-delta(3): " bin-delta )
    
    set agents-in-bin ( item bin-no l-partition )
    set agents-in-bin ( agents-in-bin + 1 )
    set l-partition ( replace-item bin-no l-partition agents-in-bin )
    
    set counter ( counter + 1 )
  ]
  
  report l-partition
  
  ;; End fr-make-energy-partition.
end 

;;---------------------------------------------------------------------|-------|

to-report fr-calc-energy-entropic-index [ l-partition ]
  ;; This routine can be called by any agent.
  
  ;; show "----------"
  ;; show "fr-calc-energy-entropic-index"
  
  ;; It uses the formula that was developed in a series of diary notes
  ;;   that investigated the most effective formula for calculating
  ;;   entropy in an agent-based model such as "Model I" of EiLab.

  ;; I hypothesize that it is equally valid in most agent-based models, but 
  ;;   that hypothesis needs to be expored and examined and tested.

  ;; THIS IS AN EXAMPLE OF AN AS-YET UNEXAMINED USAGE.

  ;;
  ;; REFERENCES: The diary notes including (or more recent versions):
  ;; A.  150527 PPR - Definition of Ei R17.PDF
  ;; B.  190927 NTF Shannon Vs Boltzmann R4.PDF
  ;; C.  180214 NTF Entropy and Units of Measure R5.PDF
  ;; D.  180822 NTF FactLn() and GammaLn() R3.PDF
  ;; E.  190927 NTF Entropy in a Histogram R4.PDF
  ;;

  ;; The formula used is equation 30 in the Ref E document.

  ;; It can be written like this:
  ;;   I = (GammaLn(A+1) - Sum(GammaLn(ai+1))) / (A*Ln(K))
  ;;   where:
  ;;          K is the number of bins in a histogram of some conserved quantity.   
  ;;          A is the number of agents in the model.
  ;;          ai is the count of agents in bin i of the histogram.
  
  ;; The expected input is a partition constructed from a list of energy values.
  ;; The sum of all elements of all bins equals the number of agents.
  let a-no-of-agents ( sum l-partition )
  let k-no-of-bins ( length l-partition )
  
  ;; Note that GammaLn( ) is not native to NetLogo.  A version is implemented
  ;;   below.

  ;; show ( word "l-partition: " l-partition )
  
  let entropic-index fr-gammaln ( 1 + a-no-of-agents )
  foreach l-partition
     [ set entropic-index ( entropic-index - fr-gammaln ( 1 + ? ) ) ]

  let alpha ( a-no-of-agents / k-no-of-bins )
  let boltzmann-max ( fr-gammaln ( 1 + a-no-of-agents ) )
  set boltzmann-max 
    ( boltzmann-max - ( k-no-of-bins * fr-gammaln ( alpha + 1 ) ) )

  set entropic-index ( entropic-index / boltzmann-max )
  
  report entropic-index 
  
  ;; End of fr-calc-entropic-index.
end 

;;---------------------------------------------------------------------|-------|

to-report fr-make-pheno-partition 
  ;; This routine is to be executed by the observer.
  
  ;; show "----------"
  ;; show "fr-make-pheno-partition"
  
  ;; It creates binned data (a partition) that can be used to plot a histogram.
  ;; A typical call might look like this:
  ;;  set l-pheno-partition ( fr-make-pheno-partition )
  ;;  reports [ l-partition ]
  
  ;; Allocate memory.
  let a-no-of-agents count turtles
  let k-no-of-bins 8
  let new-value 0
  let l-pheno-list 0
    
  ;; Initialize the output histogram with zeros.
  let l-partition ( n-values k-no-of-bins [0] )
  ;; show ( word "fmpp: l-partition: " l-partition )
  
  ;; One-by-one, calculate the average phenotype value, and insert.
  let counter 0
  let limit ( length l-partition )
  while [ counter < limit ]
  [
    set l-pheno-list ( [ item counter c1-pheno ] of seekers )
    ;; show ( word "fmpp: l-pheno-list: " l-pheno-list )
    set new-value ( mean l-pheno-list )
    ;; show ( word "fmpp: new-value: " new-value )
    set l-partition ( replace-item counter l-partition new-value )
    ;; show ( word "fmpp: l-partition:" l-partition )
    set counter ( counter + 1 )
  ]

  ;; show ( word "fmpp: l-partition: " l-partition )
  set gl-ave-pheno l-partition

  report l-partition
  
  ;; End fr-make-pheno-partition.
end 

;;---------------------------------------------------------------------|-------|

to-report fr-calc-pheno-entropic-index [ l-partition ]
  ;; This routine can be called by any agent.
  
  ;; show "----------"
  ;; show "fr-calc-pheno-entropic-index"
  
  ;; It uses the formula that was developed in a series of diary notes
  ;;   that investigated the most effective formula for calculating
  ;;   entropy in an agent-based model such as "Model I" of EiLab.

  ;; I hypothesize that it is equally valid in most agent-based models, but 
  ;;   that hypothesis needs to be expored and examined and tested.

  ;; THIS IS AN EXAMPLE OF AN AS-YET UNEXAMINED USAGE.

  ;;
  ;; REFERENCES: The diary notes including (or more recent versions):
  ;; A.  150527 PPR - Definition of Ei R17.PDF
  ;; B.  190927 NTF Shannon Vs Boltzmann R4.PDF
  ;; C.  180214 NTF Entropy and Units of Measure R5.PDF
  ;; D.  180822 NTF FactLn() and GammaLn() R3.PDF
  ;; E.  190927 NTF Entropy in a Histogram R4.PDF
  ;;

  ;; The formula used is equation 30 in the Ref E document.

  ;; It can be written like this:
  ;;   I = (GammaLn(A+1) - Sum(GammaLn(ai+1))) / (A*Ln(K))
  ;;   where:
  ;;          K is the number of bins in a histogram of some conserved quantity.   
  ;;          A is the number of agents in the model.
  ;;          ai is the count of agents in bin i of the histogram.
  
  ;; The expected input is a partition constructed from a list of energy values.
  ;; The sum of all elements of all bins equals the number of agents.
  let a-total ( sum l-partition )
  let k-no-of-bins ( length l-partition )
  
  ;; Note that GammaLn( ) is not native to NetLogo.  A version is implemented
  ;;   below.

  ;; show ( word "frcpei: l-partition: " l-partition )
  
  let entropic-index fr-gammaln ( 1 + a-total )
  foreach l-partition
     [ set entropic-index ( entropic-index - fr-gammaln ( 1 + ? ) ) ]

  let alpha ( a-total / k-no-of-bins )
  let boltzmann-max ( fr-gammaln ( 1 + a-total ) )
  set boltzmann-max 
    ( boltzmann-max - ( k-no-of-bins * fr-gammaln ( alpha + 1 ) ) )

  set entropic-index ( entropic-index / boltzmann-max )
  
  report entropic-index 
  
  ;; End of fr-calc-pheno-entropic-index.
end 

;;---------------------------------------------------------------------|-------|

to-report fr-gammaln [ input-value ]
  ;; This routine can be called by any agent.
  
  ;; It reproduces a routine found on page 207 of this book:
  ;; Press, Teukolsky, Vetterling and Flanery (1986) "Numerical Recipes in 
  ;;   Fortran", Cambridge, pp 206-209.
  ;; It uses Lanczos' approximation of the Ln(Gamma(x)) function.
  ;; Note that, when input-value is an integer, GammaLn(x+1) approximates Ln(x!).
  ;; When x = 160, the error seems to be about 1 in a billion.  That's pretty good.

  ;; This follows the Fortran code rather closely here.
  let x input-value
  let y x
  let tmp ( x + 5.5 )
  ;; Note that here I use ln( ) instead of log( ) as shown in the text.
  ;; The same problem comes up down below also.  With ln() it seems
  ;;   to work correctly.
  set tmp ( ( ( x + 0.5 ) * ( ln tmp ) ) - tmp )
  let ser 1.000000000190015

  ;; Next, I have unscrolled the six iterations of the loop.
  ;; cof(6) is now six different parameters.

  ;; Iteration 1
  set y ( y + 1 )
  set ser ( ser + ( 76.18009172947146 / y ) )

  ;; Iteration 2
  set y ( y + 1 )
  set ser ( ser + ( -86.50532032941677 / y ) )

  ;; Iteration 3
  set y ( y + 1 )
  set ser ( ser + ( 24.01409824083091 / y ) )

  ;; Iteration 4
  set y ( y + 1 )
  set ser ( ser + ( -1.231739572450155 / y ) )

  ;; Iteration 5
  set y ( y + 1 )
  set ser ( ser + ( 0.001208650973866179 / y ) )

  ;; Iteration 6
  set y ( y + 1 )
  set ser ( ser + ( -0.000005395239384953 / y ) )

  ;; Now, I follow the Fortran code closely again.
  let stp 2.5066282746310005

  ;; Note that here I use ln( ) instead of log( ) as shown in the text.
  let gammaln ( tmp + ( ln ( stp * ser / x ) ) )

  report precision gammaln 15

  ;; End of fr-gammaln.
end 

;;---------------------------------------------------------------------|-------|

to-report fr-factorial [ input-value ]
  ;; This routine can be called by any agent.
  
  ;; It uses recursion to calculate n!.
  let n input-value
  ifelse ( n > 0 ) [ report n * fr-factorial ( n - 1 ) ]
                   [ report 1 ]

  ;; End of fr-factorial.
end 

;;---------------------------------------------------------------------|-------|

to-report fr-factorialln [ input-value ]
  ;; This routine can be called by any agent.
  
  ;; It uses the recursive function to calculate n!, then takes the logarithm.
  let n input-value
  let factorialln fr-factorial n
  
  report precision ( ln factorialln ) 15
  
  ;; End of fr-factorialln.
end 

There is only one version of this model, created about 5 years ago by Garvin Boyle.

Attached files

File Type Description Last updated
07 EffLab_V5.07 NL.png preview Preview for '07 EffLab_V5.07 NL' about 5 years ago, by Garvin Boyle Download
151224 NTF ICBT and PowEff R8.pdf pdf Brute-force Examination of All Possible Ways to Combine Income, Costs and Benefits about 5 years ago, by Garvin Boyle Download
170430 NTF On Efficiency and Energy Grade R6.pdf pdf Background File. about 5 years ago, by Garvin Boyle Download
170514 NTF On Efficiencies R3.pdf pdf Background File. about 5 years ago, by Garvin Boyle Download
170518 NTF On Efficiency and Growth R3.pdf pdf Background File. about 5 years ago, by Garvin Boyle Download
190207 NTF Goldilocks Hypothesis R1.pdf pdf Background File. about 5 years ago, by Garvin Boyle Download
190506 NTF Telecon - On Conservation in EffLab R1.pdf pdf Record of a telephone conversation about EffLab. about 5 years ago, by Garvin Boyle Download
190927 NTF Entropy in a Histogram R4.pdf pdf Background information about entropy in ABMs. about 5 years ago, by Garvin Boyle Download
191007 NTF EffLab V5.07 User Doc R2.pdf pdf High Level Design Document / User Document. about 5 years ago, by Garvin Boyle Download
Boyle_ISBPE_2017 Modeling EROI R9.pptx powerpoint Presentation made at ISBPE conference in 2017. about 5 years ago, by Garvin Boyle Download

This model does not have any ancestors.

This model does not have any descendants.