[Avida-SVN] r2020 - in branches/collect: Avida.xcodeproj documentation source/actions source/analyze source/cpu source/main source/tools

blwalker at myxo.css.msu.edu blwalker at myxo.css.msu.edu
Tue Aug 28 09:09:12 PDT 2007


Author: blwalker
Date: 2007-08-28 12:09:11 -0400 (Tue, 28 Aug 2007)
New Revision: 2020

Added:
   branches/collect/source/main/cPlasticCPUTestInfo.cc
   branches/collect/source/main/cPlasticCPUTestInfo.h
Modified:
   branches/collect/Avida.xcodeproj/project.pbxproj
   branches/collect/documentation/actions.html
   branches/collect/documentation/analyze.html
   branches/collect/documentation/environment.html
   branches/collect/source/actions/PopulationActions.cc
   branches/collect/source/actions/PrintActions.cc
   branches/collect/source/analyze/cAnalyze.cc
   branches/collect/source/analyze/cAnalyze.h
   branches/collect/source/analyze/cAnalyzeGenotype.cc
   branches/collect/source/analyze/cAnalyzeGenotype.h
   branches/collect/source/cpu/cHardwareBase.cc
   branches/collect/source/cpu/cHardwareBase.h
   branches/collect/source/cpu/cHardwareCPU.cc
   branches/collect/source/cpu/cHardwareCPU.h
   branches/collect/source/cpu/cHardwareExperimental.cc
   branches/collect/source/cpu/cHardwareGX.cc
   branches/collect/source/cpu/cHardwareGX.h
   branches/collect/source/main/cAvidaConfig.h
   branches/collect/source/main/cEnvironment.cc
   branches/collect/source/main/cOrganism.cc
   branches/collect/source/main/cOrganism.h
   branches/collect/source/main/cPhenPlastGenotype.cc
   branches/collect/source/main/cPhenPlastGenotype.h
   branches/collect/source/main/cPhenotype.cc
   branches/collect/source/main/cPhenotype.h
   branches/collect/source/main/cPlasticPhenotype.cc
   branches/collect/source/main/cPlasticPhenotype.h
   branches/collect/source/main/cPopulation.cc
   branches/collect/source/main/cPopulation.h
   branches/collect/source/main/cReactionProcess.h
   branches/collect/source/main/cTaskLib.cc
   branches/collect/source/main/nReaction.h
   branches/collect/source/tools/cStringList.cc
   branches/collect/source/tools/cStringList.h
Log:

Porting development r1888:1910 into collect branch. 

Conflict resolution
- changed internal_task and rbins stats in cAnalyzeGenotype to pull from likely_phenotype
- kept Depletable()? guard around result.Consume() in cEnvironment::DoProcesses, but with internal resources taken into account 


Modified: branches/collect/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/collect/Avida.xcodeproj/project.pbxproj	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/Avida.xcodeproj/project.pbxproj	2007-08-28 16:09:11 UTC (rev 2020)
@@ -211,23 +211,6 @@
 		};
 /* End PBXBuildRule section */
 
-/* Begin PBXBuildStyle section */
-		B512934E0C4FCA11004B0E41 /* Development */ = {
-			isa = PBXBuildStyle;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-			};
-			name = Development;
-		};
-		B512934F0C4FCA11004B0E41 /* Deployment */ = {
-			isa = PBXBuildStyle;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-			};
-			name = Deployment;
-		};
-/* End PBXBuildStyle section */
-
 /* Begin PBXContainerItemProxy section */
 		56F555DA0C3B36FC00E2E929 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
@@ -1788,12 +1771,6 @@
 		DCC30C4D0762532C008F7A48 /* Project object */ = {
 			isa = PBXProject;
 			buildConfigurationList = 702442D70859E0B00059BD9B /* Build configuration list for PBXProject "Avida" */;
-			buildSettings = {
-			};
-			buildStyles = (
-				B512934E0C4FCA11004B0E41 /* Development */,
-				B512934F0C4FCA11004B0E41 /* Deployment */,
-			);
 			hasScannedForEncodings = 0;
 			mainGroup = DCC30C490762532C008F7A48;
 			productRefGroup = DCC3164E07626CF3008F7A48 /* Products */;

Modified: branches/collect/documentation/actions.html
===================================================================
--- branches/collect/documentation/actions.html	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/documentation/actions.html	2007-08-28 16:09:11 UTC (rev 2020)
@@ -88,11 +88,11 @@
       <br /><a href="#JoinGridRow">JoinGridRow</a>
       <br /><a href="#KillProb">KillProb</a>
       <br /><a href="#KillRate">KillRate</a>
+      <br /><a href="#KillRectangle">KillRectangle</a>
+      <br /><a href="#LoadClone">LoadClone</a>
     </td>
     <td>
-      <a href="#KillRectangle">KillRectangle</a>
-      <br /><a href="#LoadClone">LoadClone</a>
-      <br /><a href="#LoadPopulation">LoadPopulation</a>
+      <a href="#LoadPopulation">LoadPopulation</a>
       <br /><a href="#ModMutProb">ModMutProb</a>
       <br /><a href="#OutflowScaledResource">OutflowScaledResource</a>
       <br /><a href="#PairTestLandscape">PairTestLandscape</a>
@@ -100,6 +100,9 @@
       <br /><a href="#PredictNuLandscape">PredictNuLandscape</a>
       <br /><a href="#PredictWLandscape">PredictWLandscape</a>
       <br /><a href="#PrintAverageData">PrintAverageData</a>
+      <br /><a href="#PrintCCladeCounts">PrintCCladeCounts</a>
+      <br /><a href="#PrintCCladeFitnessHistogram">PrintCCladeFitnessHistogram</a>
+      <br /><a href="#PrintCCladeRelativeFitnessHistogram">PrintCCladeRelativeFitnessHistogram</a>
       <br /><a href="#PrintCountData">PrintCountData</a>
       <br /><a href="#PrintData">PrintData</a>
       <br /><a href="#PrintDebug">PrintDebug</a>
@@ -113,6 +116,7 @@
       <br /><a href="#PrintDominantParasiteGenotype">PrintDominantParasiteGenotype</a>
       <br /><a href="#PrintErrorData">PrintErrorData</a>
       <br /><a href="#PrintGeneticDistanceData">PrintGeneticDistanceData</a>
+      <br /><a href="#PrintGenomicSiteEntropy">PrintGenomicSiteEntropy</a>
       <br /><a href="#PrintGenotypeAbundanceHistogram">PrintGenotypeAbundanceHistogram</a>
       <br /><a href="#PrintGenotypeMap">PrintGenotypeMap</a>
       <br /><a href="#PrintGenotypes">PrintGenotypes</a>
@@ -120,12 +124,15 @@
       <br /><a href="#PrintInstructionData">PrintInstructionData</a>
       <br /><a href="#PrintLineageCounts">PrintLineageCounts</a>
       <br /><a href="#PrintLineageTotals">PrintLineageTotals</a>
+      <br /><a href="#PrintLogFitnessHistogram">PrintLogFitnessHistogram</a>
       <br /><a href="#PrintMutationRateData">PrintMutationRateData</a>
       <br /><a href="#PrintPhenotypeData">PrintPhenotypeData</a>
-      <br /><a href="#PrintPhenotypeStatus">PrintPhenotypeStatus</a>
     </td>
     <td>
-      <a href="#PrintPopulationDistanceData">PrintPopulationDistanceData</a>
+      <a href="#PrintPhenotypeStatus">PrintPhenotypeStatus</a>
+      <br /><a href="#PrintPhenotypicPlasticity">PrintPhenotypicPlasticity</a>
+      <br /><a href="#PrintPopulationDistanceData">PrintPopulationDistanceData</a>
+      <br /><a href="#PrintRelativeFitnessHistogram">PrintRelativeFitnessHistogram</a>
       <br /><a href="#PrintResourceData">PrintResourceData</a>
       <br /><a href="#PrintSpeciesAbundanceData">PrintSpeciesAbundanceData</a>
       <br /><a href="#PrintStatsData">PrintStatsData</a>
@@ -183,6 +190,59 @@
   </p>
 </li>
 <li>
+  <strong><a name="PrintCCladeCounts">PrintCCladeCounts</a></strong>
+  [<span class="cmdarg">string filename="cclade_count.dat"</span>]
+  <p>
+    Print a count of the number of oraganisms belonging to a each coalescence clade currently in the population.
+    <br />This action will only work in run mode.
+    <br />This action will require TRACK_CCLADE to be enabled.
+  </p>
+</li>
+
+<li>
+  <strong><a name="PrintCCladeFitnessHistogram">PrintCCladeFitnessHistogram</a></strong>
+  [<span class="cmdarg">string filename="cclade_fitness_hist.dat"</span>]
+  [<span class="cmdarg">string mode="CURRENT"</span>] 
+  [<span class="cmdarg">double lower_bound=-3.0</span>] 
+  [<span class="cmdarg">double step=0.5</span>] 
+  [<span class="cmdarg">double upper_bound=12.0</span>]
+  <p>
+    Print a histogram of fitnesses for each coalescence clade in the population.
+    <br />This action will only work in run mode.
+    <br />This action will rerequire TRACK_CCLADE to be enabled.
+    <br/>
+    <kbd>mode</kbd> may be {<kbd>CURRENT, ACTUAL, TESTCPU</kbd>}, where
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>CURRENT</kbd> uses the current phenotype value of fitness</li>
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>ACTUAL</kbd> uses the current merit and the true gestation time (via test cpu calculation)</li>
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>TESTCPU</kbd> uses the test cpu measurement.</li>
+      <br />
+    <kbd>lower_bound, step, upper_bound</kbd> are log10 values for the individual histogram bins.</kbd>
+  </p>
+</li>
+
+<li>
+  <strong><a name="PrintCCladeRelativeFitnessHistogram">PrintCCladeRelativeFitnessHistogram</a></strong>
+  [<span class="cmdarg">string filename="cclade_rel_fitness_histogram.dat"</span>]
+  [<span class="cmdarg">string mode="CURRENT"</span>] 
+  [<span class="cmdarg">double lower_bound=0.0</span>] 
+  [<span class="cmdarg">double step=0.1</span>] 
+  [<span class="cmdarg">double upper_bound=2.0</span>]
+  <p>
+    Print a histogram of parent-relative fitness ratios for each coalescence clade in the population.
+    <br />This action will only work in run mode.
+    <br />This action will rerequire TRACK_CCLADE to be enabled.
+    <br/>
+    <kbd>mode</kbd> may be {<kbd>CURRENT, ACTUAL, TESTCPU</kbd>}, where
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>CURRENT</kbd> uses the current phenotype value of fitness</li>
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>ACTUAL</kbd> uses the current merit and the true gestation time (via test cpu calculation)</li>
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>TESTCPU</kbd> uses the test cpu measurement.</li>
+      <br />
+    <kbd>lower_bound, step, upper_bound</kbd> are values for the individual histogram bins.</kbd>
+  </p>
+</li>
+
+
+<li>
   <strong><a name="PrintErrorData">PrintErrorData</a></strong>
   [<span class="cmdarg">string filename='error.dat'</span>]
   
@@ -447,7 +507,76 @@
   <p>
   </p>
 </li>
+
+
 <li>
+  <strong><a name="PrintLogFitnessHistogram">PrintLogFitnessHistogram</a></strong>
+  [<span class="cmdarg">string filename="fitness_log_hist.dat"</span>]
+  [<span class="cmdarg">string mode="CURRENT"</span>] 
+  [<span class="cmdarg">double lower_bound=-3.0</span>] 
+  [<span class="cmdarg">double step=0.5</span>] 
+  [<span class="cmdarg">double upper_bound=12.0</span>]
+  <p>
+    Print a histogram of organism fitnesses in the current population.
+    <br />This action will only work in run mode.
+    <br/>
+    <kbd>mode</kbd> may be {<kbd>CURRENT, ACTUAL, TESTCPU</kbd>}, where
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>CURRENT</kbd> uses the current phenotype value of fitness</li>
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>ACTUAL</kbd> uses the current merit and the true gestation time (via test cpu calculation)</li>
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>TESTCPU</kbd> uses the test cpu measurement.</li>
+      <br />
+    <kbd>lower_bound, step, upper_bound</kbd> are log10 values for the individual histogram bins.</kbd>
+  </p>
+</li>
+
+<li>
+  <strong><a name="PrintRelativeFitnessHistogram">PrintRelativeFitnessHistogram</a></strong>
+  [<span class="cmdarg">string filename="rel_fitness_histogram.dat"</span>]
+  [<span class="cmdarg">string mode="CURRENT"</span>] 
+  [<span class="cmdarg">double lower_bound=0.0</span>] 
+  [<span class="cmdarg">double step=0.1</span>] 
+  [<span class="cmdarg">double upper_bound=2.0</span>]
+  <p>
+    Print a histogram of parent-relative fitness ratios for each coalescence clade in the population.
+    <br />This action will only work in run mode.
+    <br/>
+    <kbd>mode</kbd> may be {<kbd>CURRENT, ACTUAL, TESTCPU</kbd>}, where
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>CURRENT</kbd> uses the current phenotype value of fitness</li>
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>ACTUAL</kbd> uses the current merit and the true gestation time (via test cpu calculation)</li>
+      <br/>&nbsp; &nbsp; &nbsp;<kbd>TESTCPU</kbd> uses the test cpu measurement.</li>
+      <br />
+    <kbd>lower_bound, step, upper_bound</kbd> are values for the individual histogram bins.</kbd>
+  </p>
+</li>
+
+<li>
+  <strong><a name="PrintGenomicSiteEntropy">PrintGenomicSiteEntropy</a></strong>
+  [<span class="cmdarg">string filename="GenomicSiteEntropy.dat"</span>]
+  <p>
+   This function will take the initial genotype for each organism in the
+   population/batch, align them, and calculate the per-site entropy of the
+   aligned sequences.  Please note that there may be a variable number
+   of columns in each line if the runs are not fixed length.  The site
+   entropy will be measured in mers, normalized by the instruction set size.
+   This is a population/batch measure of entropy, not a mutation-selection balance
+   measure.  
+  </p>
+</li>
+
+<li>
+  <strong><a name="PrintPhenotypicPlasticity">PrintPhenotypicPlasticity</a></strong>
+  [<span class="cmdarg">string filename="phenplast.dat | phenplast-Update.dat"</span>] [<span class="cmdarg">int num_trials=1000</span>]
+  <p>
+  This function will provided detailed information about the phenotypic varients
+  of the current population/batch by running each genome through a test cpu <kbd>num_trials</kbd> times.
+  If this command is executed in run mode, the
+  <kbd>filename</kbd> will be appeneded with <kbd>-Update.dat</kbd> where <kbd>Update</kbd>
+  is the current update.  In analyze mode, the default file is merely </kbd>phenplast.dat</kbd>.
+  The output file contains the following: id, parent_id, phenotypic_varient_number, frequency, fitness, merit, 
+  gestation_time, and task counts for each phenotypic variant of each genotype.  
+  </p>
+</li>
+<li>
   <strong><a name="PrintGeneticDistanceData">PrintGeneticDistanceData</a></strong>
   [<span class="cmdarg">string ref_creature_file='START_CREATURE'</span>]
   [<span class="cmdarg">string filename='genetic_distance.dat'</span>]

Modified: branches/collect/documentation/analyze.html
===================================================================
--- branches/collect/documentation/analyze.html	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/documentation/analyze.html	2007-08-28 16:09:11 UTC (rev 2020)
@@ -195,7 +195,7 @@
 </p>
 
 <dl>
-<dt><strong>RECALCULATE [<span class="cmdargopt">use_resources=0</span>] [<span class="cmdargopt">update=-1</span>] [<span class="cmdargopt">use_random_inputs=0</span>]</strong></dt>
+<dt><strong>RECALCULATE [<span class="cmdargopt">use_resources=0</span>] [<span class="cmdargopt">update=-1</span>] [<span class="cmdargopt">use_random_inputs=0</span>]  [<span class="cmdargopt">env_input.1 env_input.2 env_input.3</span>]</strong></dt>
 <dd>
   Run all of the genotypes in the current batch through a test CPU
   and record the measurements taken (fitness, gestation time, etc.).
@@ -208,7 +208,40 @@
   is set, then organisms will be provided with new, random input strings for 
   each trace as they would experience during an actual Avida run. By default, 
   the same inputs are provided every time to organisms in analysis mode.
+  If additional arguments are specified after use_random_input's value, these
+  integers will be used as environmental inputs for the genotype's test cpu
+  recalculation. Manually specified test cpu inputs must conform to the pseudo-random
+  formatting described in cEnvironment::SetupInputs. Phenotypic plasticity information is not available from the
+  RECALCULATE command; use RECALC with <kbd>num_trials X</kbd>, where X is greater than 1,
+  for phenotypic plasticity statistics.
 </dd>
+<dt><strong>RECALC [<span class="cmdargopt">use_resources</span>] [<span class="cmdargopt">use_random_inputs</span>] [<span class="cmdargopt">update N (N=-1)</span>] [<span class="cmdargopt">use_manual_inputs input.1 input.2 input.3</span>] [<span class="cmdargopt">num_trials T (T=1)</span>]</strong></dt>
+<dd>
+  This command will perform the same operations as RECALCULATE but has a few additional features.
+  Instead of having a specified ordering for inputs to this command, argument order does not matter.
+  To use resources, for instance, use the flag <kbd>use_resources</kbd> following RECALC.  
+  Arguments with parameters must have the values specified immediately after them.  For instance
+  <br>
+  <kbd>&nbsp;&nbsp;&nbsp;RECALC update 10 use_resources use_manual_inputs 256948023 870730840 1441302276</kbd>
+  <br>
+  will set the update to 10, request the use of resources, and test the genotypes using the inputs 256948023, 870730840, and 1441302276. Manually specified environment inputs must conform to the pseudo-random numbers as
+  described in cEnvironment::SetupInputs.
+  Typically, <kbd>use_manual_inputs</kbd> will override <kbd>use_random_inputs</kbd>, however if <kbd>num_trials</kbd> is set to greater than one, manual input specficiation will be overriden
+  and random inputs will be used to gather phenotypic plasticity information that will be available
+  for <a href="#GENOTYPE_STATS">genotype statistics</a> at the bottom of this document.  <i>Please note that phenotypic plasticity
+  analysis perfoemd by using RECALC will reset genotype statistics to the values for the most <b>likely</b> 
+  phenotype.</i>  Implicit phenotypic plasticity analysis (e.g. by not calling RECALC or calling RECALC with <kbd>num_trials 1</kbd>)
+  will not re-evaluate the genotype statistics in this manner and instead rely on the initial values or
+  those values from a single recalculation.
+<dt><strong>FILTER [<span class="cmdarg">stat</span>] [<span class="cmdarg">relation</span>] [<span class="cmdarg">test_value</span>] [<span class="cmdargopt">batch=current</span>]</strong></dt>
+<dd>
+    Perform the given test on all genotypes and Remove all those that do not pass.  Stat indicates which
+    metric you want to compare, relation is the test to perform (==, !=, &lt;, &gt;, &lt;=, or &gt;=), and
+    test_value is the value to compare it to.  For example <br>
+    &nbsp;&nbsp;<kbd>FILTER fitness >= 1.5</kbd><br>
+    will save only those genotypes with a fitness greater than or equal to 1.5.  Set the section on
+    <a href="#GENOTYPE_STATS">Genotype Statistics</a> for more information on what keywords can be used here.
+</dd>
 <dt><strong>FIND_GENOTYPE [<span class="cmdargopt">type='num_cpus' ...</span>]</strong></dt>
 <dd>
   Remove all genotypes but the one selected.  Type indicates which
@@ -299,7 +332,7 @@
   the files will be named by the genotype name, with a <kbd>.gen</kbd> appended to 
   them. Specifying the filename is useful when printing a single genotype. 
 </dd>
-<dt><strong>TRACE [<span class="cmdargopt">dir='archive/'</span>] [ <span class="cmdargopt">use_resources=0</span>] [<span class="cmdargopt">update=-1</span>] [ <span class="cmdargopt">use_random_inputs=0</span>]</strong></dt>
+<dt><strong>TRACE [<span class="cmdargopt">dir='archive/'</span>] [ <span class="cmdargopt">use_resources=0</span>] [<span class="cmdargopt">update=-1</span>] [ <span class="cmdargopt">use_random_inputs=0</span>]  [<span class="cmdargopt">env_input.1 env_input.2 env_input.3</span>]</strong></dt>
 <dd>
   Trace all of the genotypes and print a listing of their execution.
   This will show step-by-step the status of all of the CPU components
@@ -311,13 +344,16 @@
   For more information on resources, see the <a href="#USING_RESOURCES">summary</a> below.
   If the use_random_inputs flag is set, then organisms will be provided with new, 
   random input strings for each trace as they would experience during an actual Avida run.  
-  By default, the same inputs are provided every time to organisms in analysis mode.
+  By default, the same inputs are provided every time to organisms in analysis mode.  You can
+  manually specify environmental inputs by setting use_random_inputs to 0 setting env_input.X
+  values.  Manually specified environment inputs must conform to the pseudo-random numbers as
+  described in cEnvironment::SetupInputs.
 </dd>
 <dt><strong>PRINT_TASKS [<span class="cmdargopt">file='tasks.dat'</span>]</strong></dt>
 <dd>
   This will print out the tasks doable by each genotype, one per line
   in the output file specified.  Note that this information must either
-  have been loaded in, or a RECALCULATE must have been run to collect
+  have been loaded in, or a RECALCULATE (or RECALC) must have been run to collect
   it.
 </dd>
 <dt><strong>DETAIL [<span class="cmdargopt">file='detail.dat'</span>] [<span class="cmdargopt">format ...</span>]</strong></dt>
@@ -389,12 +425,15 @@
 	[<span class="cmdargopt">flags ...</span>] [<span class="cmdargopt">format ...</span>]
 </strong></dt>
 <dd>
-  Construct a genotype-phenotype array for each genotype in the
-  current batch.  The format is the list of stats that you want
-  to include as columns in the array.  Additionally you can have
-  special format flags; the possible flags are 'html' to print output
-  in HTML format, and 'link_maps' to create html links between
-  consecutive genotypes in a lineage.
+    Construct a genotype-phenotype array for each genotype in the current batch.  The format is
+    the list of stats that you want to include as columns in the array
+    (see <a href="#GENOTYPE_STATS">Genotype Statistics</a> for more info).  Additionally you can have
+    special format flags; the possible flags are 'html' to print output in HTML format, and
+    'link_maps' to create html links between consecutive genotypes in a lineage. The flag
+    'use_manual_inputs input.1 input.2 input.3' where input.X are integers
+    allow for designated environmental inputs to be used when evaluating the genotype-phenotype mapping.
+    Manually specified environment inputs must conform to the pseudo-random numbers as
+    described in cEnvironment::SetupInputs.
 </dd>
 <dt><strong>
   MAP_MUTATIONS [<span class="cmdargopt">dir="mutations/"</span>]
@@ -500,7 +539,7 @@
 <p>
 In analyze, a new data structure was included which contains a time ordered 
 list of resource concentrations.  This list can be used to set up resources 
-from different time points.  By using the update parameter in the RECALCULATE function, 
+from different time points.  By using the update parameter in the RECALCULATE (or RECALC) function, 
 you can use the resource concentrations from a specified time 
 point.  If the LOAD_RESOURCES command is not called, the list defaults to 
 a single entry which is the the initial concentrations of the resources 
@@ -559,7 +598,7 @@
 </div>
 
 <p>
-After a RECALCULATE, the additional formats become available:
+After a RECALCULATE (or RECALC), these additional formats become available:
 </p>
 
 <div align="center">
@@ -589,9 +628,10 @@
 
 <p>
 Please note that inst.n is only valid if INSTRUCTION_COUNT is on in defs.h
+</p>
 
 <p>
-If a FIND_LINEAGE was done before the RECALCULATE, the parent
+If a FIND_LINEAGE was done before the RECALCULATE (or RECALC), the parent
 genotype for each regular genotype will be available, enabling the
 additional formats:
 </p>
@@ -624,9 +664,34 @@
 </tr>
 </table>
 </div>
+
+<p>
+If a RECALCULATE (or RECALC) was done before the ALIGN, the following format is available:
+</p>
+
+<div align="center">
+<table width="95%">
+<tr>
+  <td><strong>alignment_executed_flags</strong> (Alignment Executed Flags)</td>
+</tr>
+</table>
+</div>
+
+<p>
+If tags have been applied to genotypes in analyze mode, an additional format 
+is available:
+</p>
+
+<div align="center">
+<table width="95%">
+<tr>
+  <td><strong>tag</strong> (Genotype Tag)</td>
+</tr>
+</table>
+</div>
     
 <p>
-Finally, there are a handful of commands that will automatically perform
+There are a handful of commands that will automatically perform
 landscapping.  The landscape will only be run once per organism even when
 multiple output variables are used.  For enhanced performance on
 multi-processor/multi-core systems, see the
@@ -650,6 +715,40 @@
 </table>
 </div>
 
+<p>
+Phenotypic plasticity information is available through a number
+of different commands.  This information will be gathered in one
+of two manners.  If <kbd>RECALC num_trials X</kbd> is called, where X is greater
+than 1, phenotypic plasticity information for each genotype in the
+batch will be collected.  If RECALC is not called or is called with
+with just one trial (the default for RECALC), then using these commands will request 1000
+trials for each genotype to gather plasticity information.  Requesting an analysis
+of phenotypic plasticity in this manner will not re-evaluate other genotype statistics.
+<p>
+<div align="center">
+<table width="95%">
+<tr>
+  <td width="50%"><strong>num_phen</strong> (Number of Phenotypes Identified)</td>
+  <td width="50%"><strong>phen_avg_fitness</strong> (Weighted Average Fitness)</td>
+</tr>
+<tr>
+  <td><strong>num_trials</strong> (Number of Phenotype Tests)</td>
+  <td><strong>phen_entropy</strong> (Phenotypic Entropy [bits])</td>
+</tr>
+<tr>
+  <td><strong>phen_max_fit_freq</strong> (Maximum Fitness Phenotype Frequency)</td>
+  <td><strong>phen_max_fitness</strong> (Maximum Phenotype Fitness)</td>
+</tr>
+<tr>
+  <td><strong>phen_min_fit_freq</strong> (Minimum Fitness Phenotype Frequency)</td>
+  <td><strong>phen_min_fitness</strong> (Minimum Phenotype Fitness)</td>
+</tr>
+<tr>
+  <td><strong>phen_likely_freq</strong> (Most Likely Phenotype Frequency)</td>
+  <td><strong>phen_likely_fitness</strong> (Fitness of the Most Likely Phenotype)</td>
+</tr>
+</table>
+</div>
 
 <h3>Variables</h3>
 

Modified: branches/collect/documentation/environment.html
===================================================================
--- branches/collect/documentation/environment.html	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/documentation/environment.html	2007-08-28 16:09:11 UTC (rev 2020)
@@ -552,6 +552,9 @@
     <br /><em>pow</em>: Multiply the current merit by 2<sup>bonus</sup>.
        this is effectively multiplicative, but positive bonuses are
        always beneficial, and negative bonuses are harmful.
+    <br /><em>enzyme</em>: Add bonus * resource / (resource + frac) to the current merit.
+    	This is gives a Michaelis-Menten enzyme type reward where bonus is the K<sub>cat</sub>
+    	and frac is the K<sub>m</sub>. Does not work with unlimited resources.
   </td>
   <td>add</td>
 </tr>
@@ -601,6 +604,13 @@
   <td>Whether the cell dies after performing the process</td>
   <td>0</td>
 </tr>
+<tr>
+  <td class="resall">depletable</td>
+  <td>
+    Whether this resource is consumed by reactions.
+  </td>
+  <td>true</td>
+</tr>
 </table>
 <p>&nbsp;</p>
 </div>

Modified: branches/collect/source/actions/PopulationActions.cc
===================================================================
--- branches/collect/source/actions/PopulationActions.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/actions/PopulationActions.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -1091,6 +1091,49 @@
 };
 
 
+class cActionNewTrial : public cAction
+{
+private:
+public:
+  cActionNewTrial(cWorld* world, const cString& args) : cAction(world, args)
+  {
+    cString largs(args);
+  }
+  
+  static const cString GetDescription() { return "No Arguments"; }
+  
+  void Process(cAvidaContext& ctx)
+  {
+    m_world->GetPopulation().NewTrial();
+  }
+};
+
+class cActionCompeteOrganisms : public cAction
+{
+private:
+  int m_type;
+  int m_parents_survive;
+  double m_scaled_time;
+  int m_dynamic_scaling;
+public:
+  cActionCompeteOrganisms(cWorld* world, const cString& args) : cAction(world, args), m_type(0), m_parents_survive(0), m_scaled_time(1.0), m_dynamic_scaling(0)
+  {
+    cString largs(args);
+    if (largs.GetSize()) m_type = largs.PopWord().AsInt();
+    if (largs.GetSize()) m_parents_survive = largs.PopWord().AsInt();
+    if (largs.GetSize()) m_scaled_time = largs.PopWord().AsDouble();
+    if (largs.GetSize()) m_dynamic_scaling = largs.PopWord().AsInt();
+  }
+  
+  static const cString GetDescription() { return "Arguments: [int type=0] [int parents_survive=0] [double scaled_time=1.0] [int dynamic_scaling=0]"; }
+  
+  void Process(cAvidaContext& ctx)
+  {
+    m_world->GetPopulation().CompeteOrganisms(m_type, m_parents_survive, m_scaled_time, m_dynamic_scaling);
+  }
+};
+
+
 /*
  Remove the connections between cells along a column in an avida grid.
  
@@ -1501,6 +1544,9 @@
   action_lib->Register<cActionResetDemes>("ResetDemes");
   action_lib->Register<cActionCopyDeme>("CopyDeme");
   
+  action_lib->Register<cActionNewTrial>("NewTrial");
+  action_lib->Register<cActionCompeteOrganisms>("CompeteOrganisms");
+  
   action_lib->Register<cActionSeverGridCol>("SeverGridCol");
   action_lib->Register<cActionSeverGridRow>("SeverGridRow");
   action_lib->Register<cActionJoinGridCol>("JoinGridCol");
@@ -1531,6 +1577,9 @@
   action_lib->Register<cActionResetDemes>("reset_demes");
   action_lib->Register<cActionCopyDeme>("copy_deme");
   
+  action_lib->Register<cActionCompeteDemes>("new_trial");
+  action_lib->Register<cActionCompeteDemes>("compete_organisms");
+  
   action_lib->Register<cActionSeverGridCol>("sever_grid_col");
   action_lib->Register<cActionSeverGridRow>("sever_grid_row");
   action_lib->Register<cActionJoinGridCol>("join_grid_col");

Modified: branches/collect/source/actions/PrintActions.cc
===================================================================
--- branches/collect/source/actions/PrintActions.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/actions/PrintActions.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -40,6 +40,8 @@
 #include "cInjectGenotype.h"
 #include "cInstSet.h"
 #include "cOrganism.h"
+#include "cPhenPlastGenotype.h"
+#include "cPlasticPhenotype.h"
 #include "cPopulation.h"
 #include "cPopulationCell.h"
 #include "cSpecies.h"
@@ -1137,11 +1139,9 @@
  
  Parameters:
  filename	(cString)				Name of the output file
- fit_mode (cString)				Either {Current, Actual, ActualRepro, TestCPU}, where
+ fit_mode (cString)				Either {Current, Actual, TestCPU}, where
 																Current is the current value in the grid. [Default]
 																Actual uses the current merit, but the true gestation time.
-																CurrentRepro is the same as current, but counts only those orgs
-                                              that have reproduced.
 																TestCPU determined.
  hist_fmin  (double)      The minimum fitness value for the fitness histogram.  [Default: -3]
  hist_fmax  (double)      The maximum fitness value for the fitness histogram.  [Default: 12]
@@ -1386,7 +1386,7 @@
 			m_filename = (largs.GetSize()) ? largs.PopWord() : "GenomicSiteEntropy.dat";
 		}
 
-		static const cString GetDescription() { return "Arguments: [filename = \"GenomicSiteEntropyData.datcd \"] [use_gap = false]";}
+		static const cString GetDescription() { return "Arguments: [filename = \"GenomicSiteEntropyData.datcd \"]";}
 		
 		void Process(cAvidaContext& ctx){
 			const int        num_insts  = m_world->GetNumInstructions();
@@ -1487,7 +1487,100 @@
 };
 
 
+
 /*
+ This function will go through all genotypes in the population/batch and
+ allow you to retrieve information about the different plastic phenotypes.
+ Arguments:
+    filename    name of output file in analyze mode; root of filename in
+                run mode (-update.dat appeneded in run mode).
+                [default: phenpalst-update.dat in run-mode, phenplast.dat in analyze]
+    trials      number of test_cpu recalculations for each genotype [default: 1000]
+*/
+class cActionPrintPhenotypicPlasticity : public cAction
+{
+  private:
+    cString m_filename;
+    int     m_num_trials;
+  
+  private:
+    void PrintHeader(ofstream& fot)
+    {
+      fot << "# Phenotypic Plasticity" << endl
+          << "# Format: " << endl
+          << "# genotype id" << endl
+          << "# parent genotype id" << endl
+          << "# phenotypic varient number" << endl
+          << "# varient frequency" << endl
+          << "# fitness" << endl
+          << "# merit" << endl
+          << "# gestation time" << endl;
+      for (int k = 0; k < m_world->GetEnvironment().GetNumTasks(); k++)
+        fot << "# task." << k << endl;
+      fot << endl;
+    }
+    
+    void PrintPPG(ofstream& fot, const cPhenPlastGenotype* ppgen, int id, int pid)
+    {
+      
+      for (int k = 0; k < ppgen->GetNumPhenotypes(); k++){
+        const cPlasticPhenotype* pp = ppgen->GetPlasticPhenotype(k);
+        fot << id << " "
+            << pid << " "
+            << k << " "
+            << pp->GetFrequency() << " "
+            << pp->GetFitness() << " "
+            << pp->GetMerit() << " "
+            << pp->GetGestationTime() << " ";
+        tArray<int> tasks = pp->GetLastTaskCount();
+        for (int t = 0; t < tasks.GetSize(); t++)
+          fot << tasks[t] << " ";
+        fot << endl;
+      }
+    }
+    
+  public:
+  cActionPrintPhenotypicPlasticity(cWorld* world, const cString& args)
+      : cAction(world,  args)
+    {
+        cString largs(args);
+        m_filename = (largs.GetSize()) ? largs.PopWord() : "phenplast";
+        m_num_trials = (largs.GetSize()) ? largs.PopWord().AsInt() : 1000;
+    }
+    
+    static const cString GetDescription() { return "Arguments: [string filename='phenplast'] [int num_trials=1000]"; };
+    
+    void Process(cAvidaContext& ctx)
+    {
+      if (ctx.GetAnalyzeMode()){ // Analyze mode
+        cString this_path = m_filename;
+        ofstream& fot = m_world->GetDataFileOFStream(this_path);
+        PrintHeader(fot);
+        tListIterator<cAnalyzeGenotype> batch_it(m_world->GetAnalyze().GetCurrentBatch().List());
+				cAnalyzeGenotype* genotype = NULL;
+				while((genotype = batch_it.Next())){
+					const cPhenPlastGenotype* ppgen = new cPhenPlastGenotype(genotype->GetGenome(), m_num_trials, m_world, ctx);
+          PrintPPG(fot, ppgen, genotype->GetID(), genotype->GetParentID());
+          delete ppgen;
+				}
+        m_world->GetDataFileManager().Remove(this_path);
+      } else{  // Run mode
+        cString this_path = m_filename + "-" + cStringUtil::Convert(m_world->GetStats().GetUpdate()) + ".dat";
+        ofstream& fot = m_world->GetDataFileOFStream(this_path);
+        PrintHeader(fot);
+        cGenotype* genotype = m_world->GetClassificationManager().GetBestGenotype();
+        for (int k = 0; k < m_world->GetClassificationManager().GetGenotypeCount(); k++){
+          const cPhenPlastGenotype* ppgen = new cPhenPlastGenotype(genotype->GetGenome(), m_num_trials, m_world, ctx);
+          PrintPPG(fot, ppgen, genotype->GetID(), genotype->GetParentID());
+          delete ppgen;
+          genotype = genotype->GetNext();
+        }
+        m_world->GetDataFileManager().Remove(this_path);
+      }
+    }
+};
+
+/*
  This function goes through all genotypes currently present in the soup,
  and writes into an output file the average Hamming distance between the
  creatures in the population and a given reference genome.
@@ -2391,7 +2484,8 @@
   action_lib->Register<cActionPrintDebug>("PrintDebug");
 
   action_lib->Register<cActionPrintGenotypes>("PrintGenotypes");
-
+  action_lib->Register<cActionPrintPhenotypicPlasticity>("PrintPhenotypicPlasticity");
+  
   action_lib->Register<cActionTestDominant>("TestDominant");
   action_lib->Register<cActionPrintTaskSnapshot>("PrintTaskSnapshot");
   action_lib->Register<cActionPrintViableTasksData>("PrintViableTasksData");

Modified: branches/collect/source/analyze/cAnalyze.cc
===================================================================
--- branches/collect/source/analyze/cAnalyze.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/analyze/cAnalyze.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -1747,6 +1747,7 @@
     }
   }
   
+  
   if (m_world->GetVerbosity() >= VERBOSE_ON) 
     msg.Set("Tracing batch %d", cur_batch);
   else 
@@ -4425,9 +4426,9 @@
     int pos = arg_list.LocateString("use_manual_inputs");
     arg_list.PopString("use_manual_inputs");
     manual_inputs.Resize(m_world->GetEnvironment().GetInputSize());
-    if (arg_list.GetSize() >= pos + m_world->GetEnvironment().GetInputSize())
+    if (arg_list.GetSize() >= pos + m_world->GetEnvironment().GetInputSize() - 1)
       for (int k = 0; k < m_world->GetEnvironment().GetInputSize(); k++)
-        manual_inputs[k] = arg_list.PopString(arg_list.GetLine(pos)).AsInt();  
+        manual_inputs[k] = arg_list.PopLine(pos).AsInt();  
     else
       m_world->GetDriver().RaiseFatalException(1, "CommandMapTask: Invalid use of use_manual_inputs");
   }
@@ -7033,22 +7034,6 @@
 }
 
 
-void cAnalyze::CommandAnalyzePlasticity(cString cur_string)
-{
-  tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
-  cAnalyzeGenotype* genotype;
-  while ( (genotype = batch_it.Next()) != NULL ){
-    cerr << "Using Genome: " << genotype->GetGenome().AsString() << endl;
-    cPhenPlastGenotype PPG(genotype->GetGenome(), 1000, m_world, m_ctx);
-    cerr << "There are " << PPG.GetNumPhenotypes() << " phenotype(s) for this genome.\n";
-    for (int k = 0; k < PPG.GetNumPhenotypes(); k++)
-      cerr << "\t Phenotype " << k << " has fitness " << PPG.GetPlasticPhenotype(k).GetFitness() 
-           << " with frequency " << PPG.GetPlasticPhenotype(k).GetFrequency() <<  endl;
-    cerr << endl;
-  }
-  cerr << "here" << endl;
-  
-}
 
 
 //////////////// Control...
@@ -7269,6 +7254,100 @@
   return;
 }
 
+
+void cAnalyze::BatchRecalculateWithArgs(cString cur_string)
+{
+  // RECALC <use_resources> <random_inputs> <manual_inputs in.1 in.2 in.3> <update N> <num_trials X>
+
+  tArray<int> manual_inputs;  // Used only if manual inputs are specified
+  cString msg;                // Holds any information we may want to send the driver to display
+  
+  // Defaults
+  bool use_resources     = false;
+  int  update            = -1;
+  bool use_random_inputs = false;
+  bool use_manual_inputs = false;
+  int  num_trials        = 1;
+  
+  // Handle our recalculate arguments
+  // Really, we should have a generalized tokenizer handle this
+  cStringList args(cur_string);
+  int pos = -1;
+  if (args.PopString("use_resources") != "")      use_resources     = true;
+  if (args.PopString("use_random_inputs") != "")  use_random_inputs = true;
+  if ( (pos = args.LocateString("use_manual_inputs") ) != -1){
+    use_manual_inputs = true;
+    args.PopString("use_manual_inputs");
+    int num = m_world->GetEnvironment().GetInputSize();
+    manual_inputs.Resize(num);
+    if (args.GetSize() >= pos + num - 2) 
+      for (int k = 0; k < num; k++)
+        manual_inputs[k] = args.PopLine(pos).AsInt();  
+    else
+      m_world->GetDriver().RaiseFatalException(1, "RecalculateWithArgs: Invalid use of use_manual_inputs");
+  }
+  if ( (pos = args.LocateString("update")) != -1 ){
+    args.PopString("update");
+    if (args.GetSize() >= pos - 1){
+      update = args.PopLine(pos).AsInt();
+    } else
+       m_world->GetDriver().RaiseFatalException(1, "RecalculateWithArgs: Invalid use of update (did you specify a value?)");
+  }
+  if ( (pos = args.LocateString("num_trials")) != -1){
+    args.PopString("num_trials");
+    if (args.GetSize() >= pos - 1)
+      num_trials = args.PopLine(pos).AsInt();
+    else
+      m_world->GetDriver().RaiseFatalException(1, "RecalculateWithArgs: Invalid use of num_trials (did you specify a value?)");
+  }
+  
+  if (use_manual_inputs)
+    use_random_inputs = false;
+  
+  cTestCPU*     test_cpu = m_world->GetHardwareManager().CreateTestCPU();
+  cCPUTestInfo *test_info = new cCPUTestInfo();
+  if (use_manual_inputs)
+    test_info->UseManualInputs(manual_inputs);
+  else
+    test_info->UseRandomInputs(use_random_inputs); 
+  
+  // Notifications
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    msg.Set("Running batch %d through test CPUs...", cur_batch);
+    m_world->GetDriver().NotifyComment(msg);
+  } else{ 
+    msg.Set("Running through test CPUs...");
+    m_world->GetDriver().NotifyComment(msg);
+  }
+  if (m_world->GetVerbosity() >= VERBOSE_ON && batch[cur_batch].IsLineage() == false) {
+    msg.Set("Batch may not be a lineage; parent and ancestor distances may not be correct"); 
+    m_world->GetDriver().NotifyWarning(msg);
+  }
+  
+  tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
+  cAnalyzeGenotype * genotype = NULL;
+  cAnalyzeGenotype * last_genotype = NULL;
+  while ((genotype = batch_it.Next()) != NULL) {
+    // Load proper resources according to update_born
+    test_cpu->InitResources(use_resources, &resources, update, m_resource_time_spent_offset);
+    
+    // If the previous genotype was the parent of this one, pass in a pointer
+    // to it for improved recalculate (such as distance to parent, etc.)
+    if (last_genotype != NULL && genotype->GetParentID() == last_genotype->GetID()) {
+      genotype->Recalculate(m_ctx, test_cpu, last_genotype, test_info, num_trials);
+    } else {
+      genotype->Recalculate(m_ctx, test_cpu, NULL, test_info, num_trials);
+    }
+    last_genotype = genotype;
+  }
+  
+  delete test_info;
+  delete test_cpu;
+  
+  return;
+}
+
+
 void cAnalyze::BatchRename(cString cur_string)
 {
   if (m_world->GetVerbosity() <= VERBOSE_NORMAL) cout << "Renaming organisms..." << endl;
@@ -8063,6 +8142,17 @@
   ADD_GDATA(double, "complexity",   "Basic Complexity (beneficial muts are neutral)", GetComplexity, SetNULL, 0, 0, 0);
   ADD_GDATA(double, "land_fitness", "Average Lanscape Fitness",      GetLandscapeFitness, SetNULL,     0, 0, 0);
   
+  ADD_GDATA(int,    "num_phen",           "Number of Plastic Phenotypes",          GetNumPhenotypes,          SetNULL, 0, 0, 0);
+  ADD_GDATA(int,    "num_trials",         "Number of Recalculation Trials",        GetNumTrials,              SetNULL, 0, 0, 0);
+  ADD_GDATA(double, "phen_entropy",       "Phenotpyic Entropy",                    GetPhenotypicEntropy,      SetNULL, 0, 0, 0);
+  ADD_GDATA(double, "phen_max_fitness",   "Phen Plast Maximum Fitness",            GetMaximumFitness,         SetNULL, 0, 0, 0);
+  ADD_GDATA(double, "phen_max_fit_freq",  "Phen Plast Maximum Fitness Frequency",  GetMaximumFitnessFrequency,SetNULL, 0, 0, 0);
+  ADD_GDATA(double, "phen_min_fitness",   "Phen Plast Minimum Fitness",            GetMinimumFitness,         SetNULL, 0, 0, 0);
+  ADD_GDATA(double, "phen_min_freq",      "Phen Plast Minimum Fitness Frequency",  GetMinimumFitnessFrequency,SetNULL, 0, 0, 0);
+  ADD_GDATA(double, "phen_avg_fitness",   "Phen Plast Wtd Avg Fitness",            GetAverageFitness,         SetNULL, 0, 0, 0);
+  ADD_GDATA(double, "phen_likely_freq",   "Freq of Most Likely Phenotype",         GetLikelyFrequency,        SetNULL, 0, 0, 0);
+  ADD_GDATA(double, "phen_likely_fitness","Fitness of Most Likely Phenotype",      GetLikelyFitness,          SetNULL, 0, 0, 0);
+  
   ADD_GDATA(const cString &, "parent_muts", "Mutations from Parent", GetParentMuts,   SetParentMuts, 0, "(none)", "");
   ADD_GDATA(const cString &, "task_order", "Task Performance Order", GetTaskOrder,    SetTaskOrder,  0, "(none)", "");
   ADD_GDATA(cString, "sequence",    "Genome Sequence",               GetSequence,     SetSequence,   0, "(N/A)", "");
@@ -8273,7 +8363,6 @@
   AddLibraryDef("ANALYZE_POP_COMPLEXITY", &cAnalyze::AnalyzePopComplexity);
   AddLibraryDef("MAP_DEPTH", &cAnalyze::CommandMapDepth);
   // (Untested) AddLibraryDef("PAIRWISE_ENTROPY", &cAnalyze::CommandPairwiseEntropy); 
-  AddLibraryDef("ANALYZE_PLASTICITY", &cAnalyze::CommandAnalyzePlasticity); 
   
   // Population comparison commands...
   AddLibraryDef("HAMMING", &cAnalyze::CommandHamming);
@@ -8316,6 +8405,7 @@
   AddLibraryDef("PURGE_BATCH", &cAnalyze::BatchPurge);
   AddLibraryDef("DUPLICATE", &cAnalyze::BatchDuplicate);
   AddLibraryDef("RECALCULATE", &cAnalyze::BatchRecalculate);
+  AddLibraryDef("RECALC", &cAnalyze::BatchRecalculateWithArgs);
   AddLibraryDef("RENAME", &cAnalyze::BatchRename);
   AddLibraryDef("STATUS", &cAnalyze::PrintStatus);
   AddLibraryDef("ECHO", &cAnalyze::PrintDebug);

Modified: branches/collect/source/analyze/cAnalyze.h
===================================================================
--- branches/collect/source/analyze/cAnalyze.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/analyze/cAnalyze.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -221,6 +221,7 @@
   void SampleGenotypes(cString cur_string);
   void KeepTopGenotypes(cString cur_string);
   void TruncateLineage(cString cur_string);
+  
 
   // Direct Output Commands...
   void CommandPrint(cString cur_string);
@@ -250,8 +251,7 @@
   void CommandMapMutations(cString cur_string);
   void CommandMapDepth(cString cur_string);
   void CommandPairwiseEntropy(cString cur_string);
-  void CommandAnalyzePlasticity(cString cur_string);
-
+ 
   // Population Comparison Commands...
   void CommandHamming(cString cur_string);
   void CommandLevenstein(cString cur_string);
@@ -295,6 +295,7 @@
   void BatchPurge(cString cur_string);
   void BatchDuplicate(cString cur_string);
   void BatchRecalculate(cString cur_string);
+  void BatchRecalculateWithArgs(cString cur_string);
   void BatchRename(cString cur_string);
   void PrintStatus(cString cur_string);
   void PrintDebug(cString cur_string);

Modified: branches/collect/source/analyze/cAnalyzeGenotype.cc
===================================================================
--- branches/collect/source/analyze/cAnalyzeGenotype.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/analyze/cAnalyzeGenotype.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -32,12 +32,15 @@
 #include "cInstSet.h"
 #include "cOrganism.h"
 #include "cPhenotype.h"
+#include "cPhenPlastGenotype.h"
+#include "cPlasticPhenotype.h"
 #include "cTestCPU.h"
 #include "cEnvironment.h"
 #include "cHardwareManager.h"
 #include "cWorld.h"
 #include "cWorldDriver.h"
 
+#include <cmath>
 using namespace std;
 
 cAnalyzeGenotype::cAnalyzeGenotype(cWorld* world, cString symbol_string, cInstSet& in_inst_set)
@@ -78,7 +81,9 @@
   , parent_muts("")
   , knockout_stats(NULL)
   , m_land(NULL)
+  , m_phenplast_stats(NULL)
 {
+    
   // Make sure that the sequences jive with the inst_set
   for (int i = 0; i < genome.GetSize(); i++) {
     if (genome[i].GetOp() >= inst_set.GetSize()) {
@@ -129,7 +134,8 @@
   , parent_muts("")
   , knockout_stats(NULL)
   , m_land(NULL)
-{
+  , m_phenplast_stats(NULL){
+  
 }
 
 cAnalyzeGenotype::cAnalyzeGenotype(const cAnalyzeGenotype& _gen)
@@ -170,16 +176,22 @@
   , parent_muts(_gen.parent_muts)
   , knockout_stats(NULL)
   , m_land(NULL)
+  , m_phenplast_stats(NULL)
 {
   if (_gen.knockout_stats != NULL) {
     knockout_stats = new cAnalyzeKnockouts;
     *knockout_stats = *(_gen.knockout_stats);
   }
+  if (_gen.m_phenplast_stats != NULL){
+    m_phenplast_stats = new cAnalyzePhenPlast;
+    *m_phenplast_stats = *(_gen.m_phenplast_stats);
+  }
 }
 
 cAnalyzeGenotype::~cAnalyzeGenotype()
 {
   if (knockout_stats != NULL) delete knockout_stats;
+  if (m_phenplast_stats != NULL) delete m_phenplast_stats;
   Unlink();
 }
 
@@ -365,7 +377,32 @@
   }
 }
 
+void cAnalyzeGenotype::CheckPhenPlast() const
+{
+  // Implicit genotype recalculation if required
+  if (m_phenplast_stats == NULL){
+    cPhenPlastGenotype pp(genome, 1000, m_world, m_world->GetDefaultContext());
+    SummarizePhenotypicPlasticity(pp);
+  }
+}
 
+void cAnalyzeGenotype::SummarizePhenotypicPlasticity(const cPhenPlastGenotype& pp) const
+{
+
+  if (m_phenplast_stats == NULL)
+    m_phenplast_stats = new cAnalyzePhenPlast;
+  m_phenplast_stats->m_recalculate_trials = pp.GetNumTrials();
+  m_phenplast_stats->m_max_fitness = pp.GetMaximumFitness();
+  m_phenplast_stats->m_avg_fitness = pp.GetAverageFitness();
+  m_phenplast_stats->m_min_fitness = pp.GetMinimumFitness();
+  m_phenplast_stats->m_phenotypic_entropy = pp.GetPhenotypicEntropy();
+  m_phenplast_stats->m_likely_frequency  = pp.GetMaximumFrequency();
+  m_phenplast_stats->m_max_fit_frequency = pp.GetMaximumFitnessFrequency();
+  m_phenplast_stats->m_min_fit_frequency = pp.GetMinimumFitnessFrequency();
+  m_phenplast_stats->m_likely_fitness = pp.GetLikelyFitness();
+  m_phenplast_stats->m_num_phenotypes = pp.GetNumPhenotypes();
+}
+
 void cAnalyzeGenotype::CalcLandscape(cAvidaContext& ctx)
 {
   if (m_land == NULL) m_land = new cLandscape(m_world, genome, inst_set);
@@ -373,9 +410,8 @@
   m_land->Process(ctx);
 }
 
-void cAnalyzeGenotype::Recalculate(cAvidaContext& ctx, cTestCPU* testcpu, cAnalyzeGenotype* parent_genotype, cCPUTestInfo* test_info)
+void cAnalyzeGenotype::Recalculate(cAvidaContext& ctx, cTestCPU* testcpu, cAnalyzeGenotype* parent_genotype, cCPUTestInfo* test_info, int num_trials)
 {
-    // Build the test info for printing.
   
   //Allocate our own test info if it wasn't provided
   cCPUTestInfo* temp_test_info = NULL;
@@ -384,57 +420,55 @@
       temp_test_info = new cCPUTestInfo();
       test_info = temp_test_info;
   }
-  
-  //cCPUTestInfo test_info;
-  // test_info.TraceTaskOrder();
 
   // @DMB - This does some 'interesting' things with the instruction set
-  
   // Use the inst lib for this genotype... and syncrhonize environment
   
   // Backup old instruction set, update with new
   cInstSet env_inst_set_backup = m_world->GetHardwareManager().GetInstSet();
   m_world->GetHardwareManager().GetInstSet() = inst_set;
 
-  testcpu->TestGenome(ctx, *test_info, genome);
-  
+  // Handling recalculation here
+  cPhenPlastGenotype recalc_data(genome, num_trials, *test_info, m_world, ctx);
+ 
   // Restore the instruction set
   m_world->GetHardwareManager().GetInstSet() = env_inst_set_backup;
+  
+  // The most likely phenotype will be assigned to the phenotype stats
+  const cPlasticPhenotype* likely_phenotype = recalc_data.GetMostLikelyPhenotype();
+  
+  viable         = likely_phenotype->IsViable();
+  m_env_inputs   = likely_phenotype->GetEnvInputs()[0];
+  executed_flags = likely_phenotype->GetExecutedFlags();
+  length         = likely_phenotype->GetGenomeLength();
+  copy_length    = likely_phenotype->GetCopiedSize();
+  exe_length     = likely_phenotype->GetExecutedSize();
+  merit          = likely_phenotype->GetMerit().GetDouble();
+  gest_time      = likely_phenotype->GetGestationTime();
+  fitness        = likely_phenotype->GetFitness();
+  errors         = likely_phenotype->GetLastNumErrors();
+  div_type       = likely_phenotype->GetDivType();
+  mate_id        = likely_phenotype->MateSelectID();
+  task_counts    = likely_phenotype->GetLastTaskCount();
+  task_qualities = likely_phenotype->GetLastTaskQuality();
+  internal_task_counts = likely_phenotype->GetLastInternalTaskCount();
+  internal_task_qualities = likely_phenotype->GetLastInternalTaskQuality();
+  rbins_total    = likely_phenotype->GetLastRBinsTotal();
+  rbins_avail    = likely_phenotype->GetLastRBinsAvail();
 
-  viable = test_info->IsViable();
-
-  cOrganism* test_organism = test_info->GetTestOrganism();
-  cPhenotype& test_phenotype = test_organism->GetPhenotype();
-
-  m_env_inputs = test_info->GetTestCPUInputs();
-  SetExecutedFlags(test_organism->GetHardware().GetMemory());
-
-  length = test_organism->GetGenome().GetSize();
-  copy_length = test_phenotype.GetCopiedSize();
-  exe_length = test_phenotype.GetExecutedSize();
-  merit = test_phenotype.GetMerit().GetDouble();
-  gest_time = test_phenotype.GetGestationTime();
-  fitness = test_phenotype.GetFitness();
-  errors = test_phenotype.GetLastNumErrors();
-  div_type = test_phenotype.GetDivType();
-  mate_id = test_phenotype.MateSelectID();
-  inst_executed_counts = test_phenotype.GetLastInstCount();
-  task_counts = test_phenotype.GetLastTaskCount();
-  task_qualities = test_phenotype.GetLastTaskQuality();
-  internal_task_counts = test_phenotype.GetLastInternalTaskCount();
-  internal_task_qualities = test_phenotype.GetLastInternalTaskQuality();
-  rbins_total = test_phenotype.GetLastRBinsTotal();
-  rbins_avail = test_phenotype.GetLastRBinsAvail();
-
   // Setup a new parent stats if we have a parent to work with.
   if (parent_genotype != NULL) {
     fitness_ratio = GetFitness() / parent_genotype->GetFitness();
     efficiency_ratio = GetEfficiency() / parent_genotype->GetEfficiency();
     comp_merit_ratio = GetCompMerit() / parent_genotype->GetCompMerit();
     parent_dist = cStringUtil::EditDistance(genome.AsString(),
-		    parent_genotype->GetGenome().AsString(), parent_muts);
+        parent_genotype->GetGenome().AsString(), parent_muts);
     ancestor_dist = parent_genotype->GetAncestorDist() + parent_dist;
   }
+
+  // Summarize plasticity information if multiple recalculations performed
+  if (num_trials > 1)
+    SummarizePhenotypicPlasticity(recalc_data);
   
   //Deallocate if we created
   if (temp_test_info) delete temp_test_info;
@@ -483,17 +517,7 @@
   genome = new_genome;
 }
 
-void cAnalyzeGenotype::SetExecutedFlags(cCPUMemory & cpu_memory)
-{
-  cString new_executed_flags;
-  for (int i=0; i<cpu_memory.GetSize(); i++)
-  {
-    new_executed_flags += (cpu_memory.FlagExecuted(i)) ? "+" : "-";
-  }
-  executed_flags = new_executed_flags;
-}
 
-
 cString cAnalyzeGenotype::GetAlignmentExecutedFlags() const
 {
   // Make this on the fly from executed flags

Modified: branches/collect/source/analyze/cAnalyzeGenotype.h
===================================================================
--- branches/collect/source/analyze/cAnalyzeGenotype.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/analyze/cAnalyzeGenotype.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -40,6 +40,9 @@
 #ifndef cLandscape_h
 #include "cLandscape.h"
 #endif
+#ifndef cPhenPlastGenotype_h
+#include "cPhenPlastGenotype.h"
+#endif
 #ifndef cString_h
 #include "cString.h"
 #endif
@@ -190,6 +193,23 @@
   // Group 5 : More complex stats (obtained indvidually, through tests)
   cString task_order;
 
+  
+  // Group 6: Phenotypic Plasticity
+  class cAnalyzePhenPlast{
+  public:
+      int     m_recalculate_trials;  
+      int     m_num_phenotypes;
+      double  m_min_fitness;
+      double  m_max_fitness;
+      double  m_avg_fitness;
+      double  m_likely_fitness;
+      double  m_phenotypic_entropy;
+      double  m_likely_frequency;
+      double  m_min_fit_frequency;
+      double  m_max_fit_frequency;
+  };
+  mutable cAnalyzePhenPlast* m_phenplast_stats;
+  
   cStringList special_args; // These are args placed after a ':' in details...
 
   int NumCompare(double new_val, double old_val) const {
@@ -204,8 +224,11 @@
   int CalcMaxGestation() const;
   void CalcKnockouts(bool check_pairs = false, bool check_chart = false) const;
   void CheckLand() const;
+  void CheckPhenPlast() const;
+  void SummarizePhenotypicPlasticity(const cPhenPlastGenotype& pp) const;
 
 
+
 public:
   cAnalyzeGenotype(cWorld* world, cString symbol_string, cInstSet & in_inst_set);
   cAnalyzeGenotype(cWorld* world, const cGenome & _genome, cInstSet & in_inst_set);
@@ -215,7 +238,7 @@
   const cStringList & GetSpecialArgs() { return special_args; }
   void SetSpecialArgs(const cStringList & _args) { special_args = _args; }
 
-  void Recalculate(cAvidaContext& ctx, cTestCPU* testcpu, cAnalyzeGenotype* parent_genotype = NULL, cCPUTestInfo* test_info = NULL);
+  void Recalculate(cAvidaContext& ctx, cTestCPU* testcpu, cAnalyzeGenotype* parent_genotype = NULL, cCPUTestInfo* test_info = NULL, int num_trials = 1);
   void PrintTasks(std::ofstream& fp, int min_task = 0, int max_task = -1);
   void PrintTasksQuality(std::ofstream& fp, int min_task = 0, int max_task = -1);
   void PrintInternalTasks(std::ofstream& fp, int min_task = 0, int max_task = -1);
@@ -224,7 +247,6 @@
 
   // Set...
   void SetSequence(cString _sequence);
-  void SetExecutedFlags(cCPUMemory & cpu_memory);
   void SetName(const cString & _name) { name = _name; }
   void SetAlignedSequence(const cString & _seq) { aligned_sequence = _seq; }
   void SetTag(const cString & _tag) { tag = _tag; }
@@ -326,6 +348,20 @@
   double GetComplexity() const { CheckLand(); return m_land->GetComplexity(); }
   double GetLandscapeFitness() const { CheckLand(); return m_land->GetAveFitness(); }
 
+  
+  // Phenotypic Plasticity accessors
+  int    GetNumPhenotypes()     const { CheckPhenPlast(); return m_phenplast_stats->m_num_phenotypes; }
+  double GetPhenotypicEntropy() const { CheckPhenPlast(); return m_phenplast_stats->m_phenotypic_entropy; }
+  double GetMaximumFitness()    const { CheckPhenPlast(); return m_phenplast_stats->m_max_fitness; }
+  double GetMaximumFitnessFrequency() const {CheckPhenPlast(); return m_phenplast_stats->m_min_fit_frequency;}
+  double GetMinimumFitness()    const { CheckPhenPlast(); return m_phenplast_stats->m_min_fitness; }
+  double GetMinimumFitnessFrequency() const {CheckPhenPlast(); return m_phenplast_stats->m_min_fit_frequency;}
+  double GetAverageFitness()    const { CheckPhenPlast(); return m_phenplast_stats->m_avg_fitness; }
+  double GetLikelyFrequency()  const { CheckPhenPlast(); return m_phenplast_stats->m_likely_frequency; }
+  double GetLikelyFitness()     const { CheckPhenPlast(); return m_phenplast_stats->m_likely_fitness; }
+  int    GetNumTrials()         const { CheckPhenPlast(); return m_phenplast_stats->m_recalculate_trials; }
+  
+  
   double GetFitnessRatio() const { return fitness_ratio; }
   double GetEfficiencyRatio() const { return efficiency_ratio; }
   double GetCompMeritRatio() const { return comp_merit_ratio; }

Modified: branches/collect/source/cpu/cHardwareBase.cc
===================================================================
--- branches/collect/source/cpu/cHardwareBase.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/cpu/cHardwareBase.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -740,8 +740,9 @@
 // @JEB Check implicit repro conditions -- meant to be called at the end of SingleProcess
 void cHardwareBase::CheckImplicitRepro(cAvidaContext& ctx)         
 {  
-  if( (m_world->GetConfig().IMPLICIT_REPRO_TIME.Get() && (organism->GetPhenotype().GetCPUCyclesUsed() >= m_world->GetConfig().IMPLICIT_REPRO_TIME.Get()))
-      || (m_world->GetConfig().IMPLICIT_REPRO_BONUS.Get() && (organism->GetPhenotype().GetCurBonus() >= m_world->GetConfig().IMPLICIT_REPRO_BONUS.Get())) )
+  if( (m_world->GetConfig().IMPLICIT_REPRO_TIME.Get() && (organism->GetPhenotype().GetTimeUsed() >= m_world->GetConfig().IMPLICIT_REPRO_TIME.Get()))
+   || (m_world->GetConfig().IMPLICIT_REPRO_CPU_CYCLES.Get() && (organism->GetPhenotype().GetCurBonus() >= m_world->GetConfig().IMPLICIT_REPRO_CPU_CYCLES.Get()))
+   || (m_world->GetConfig().IMPLICIT_REPRO_BONUS.Get() && (organism->GetPhenotype().GetCPUCyclesUsed() >= m_world->GetConfig().IMPLICIT_REPRO_BONUS.Get())) )
   {
     Inst_Repro(ctx);
   }
@@ -751,7 +752,7 @@
 bool cHardwareBase::Inst_Repro(cAvidaContext& ctx) 
 {
   cout << "This hardware type does not have a =repro= instruction. IMPLICIT_REPRO conditions cannot be used!" << endl;
-  assert(1);
+  exit(1);
   return false;
 }
 
@@ -762,30 +763,32 @@
 {
 #if INSTRUCTION_COSTS
   assert(cur_inst.GetOp() < inst_cost.GetSize());
-  
-  // TODO:  Get rid of magic number. check avaliable energy first
-  double energy_req = inst_energy_cost[cur_inst.GetOp()] * (organism->GetPhenotype().GetMerit().GetDouble() / 100.0); //compensate by factor of 100
 
-  if(m_world->GetConfig().ENERGY_ENABLED.Get() > 0 && energy_req > 0.0) {
-    if(organism->GetPhenotype().GetStoredEnergy() >= energy_req) {
-      inst_energy_cost[cur_inst.GetOp()] = 0;
-      //subtract energy used from current org energy.
-      organism->GetPhenotype().ReduceEnergy(energy_req);  
-      
-      // tracking sleeping organisms
-      cString instName = m_world->GetHardwareManager().GetInstSet().GetName(cur_inst);
-      int cellID = organism->GetCellID();
-      if( instName == cString("sleep") || instName == cString("sleep1") || instName == cString("sleep2") ||
-          instName == cString("sleep3") || instName == cString("sleep4")) {
-        cPopulation& pop = m_world->GetPopulation();
-        if(m_world->GetConfig().LOG_SLEEP_TIMES.Get() == 1) {
-          pop.AddBeginSleep(cellID,m_world->GetStats().GetUpdate());
+  if(m_world->GetConfig().ENERGY_ENABLED.Get() > 0) {
+    // TODO:  Get rid of magic number. check avaliable energy first
+    double energy_req = inst_energy_cost[cur_inst.GetOp()] * (organism->GetPhenotype().GetMerit().GetDouble() / 100.0); //compensate by factor of 100
+    
+    if (energy_req > 0.0) { 
+      if (organism->GetPhenotype().GetStoredEnergy() >= energy_req) {
+        inst_energy_cost[cur_inst.GetOp()] = 0;
+        // subtract energy used from current org energy.
+        organism->GetPhenotype().ReduceEnergy(energy_req);  
+        
+        // tracking sleeping organisms
+        cString instName = m_world->GetHardwareManager().GetInstSet().GetName(cur_inst);
+        int cellID = organism->GetCellID();
+        if( instName == cString("sleep") || instName == cString("sleep1") || instName == cString("sleep2") ||
+            instName == cString("sleep3") || instName == cString("sleep4")) {
+          cPopulation& pop = m_world->GetPopulation();
+          if(m_world->GetConfig().LOG_SLEEP_TIMES.Get() == 1) {
+            pop.AddBeginSleep(cellID,m_world->GetStats().GetUpdate());
+          }
+          pop.GetCell(cellID).GetOrganism()->SetSleeping(true);
+          m_world->GetStats().incNumAsleep(pop.GetCell(cellID).GetDemeID());
         }
-        pop.GetCell(cellID).GetOrganism()->SetSleeping(true);
-        m_world->GetStats().incNumAsleep(pop.GetCell(cellID).GetDemeID());
+      } else { // not enough energy
+        return false;
       }
-    } else { // not enough energy
-      return false;
     }
   }
 
@@ -805,7 +808,9 @@
     }
   }
   
-  inst_energy_cost[cur_inst.GetOp()] = m_inst_set->GetEnergyCost(cur_inst); //reset instruction energy cost
+  if (m_world->GetConfig().ENERGY_ENABLED.Get() > 0) {
+    inst_energy_cost[cur_inst.GetOp()] = m_inst_set->GetEnergyCost(cur_inst); // reset instruction energy cost
+  }
 #endif
   return true;
 }

Modified: branches/collect/source/cpu/cHardwareBase.h
===================================================================
--- branches/collect/source/cpu/cHardwareBase.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/cpu/cHardwareBase.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -72,7 +72,9 @@
   virtual int GetCopiedSize(const int parent_size, const int child_size) = 0;  
   
   bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size);
+public:  //@JEB
   unsigned Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1.0, const int maxmut = INT_MAX);
+protected:
   unsigned Divide_DoExactMutations(cAvidaContext& ctx, double mut_multiplier = 1.0, const int pointmut = INT_MAX);
   bool Divide_TestFitnessMeasures(cAvidaContext& ctx);
   

Modified: branches/collect/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/collect/source/cpu/cHardwareCPU.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/cpu/cHardwareCPU.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -194,6 +194,7 @@
     tInstLibEntry<tMethod>("put-reset", &cHardwareCPU::Inst_TaskPutResetInputs),
     tInstLibEntry<tMethod>("IO", &cHardwareCPU::Inst_TaskIO, nInstFlag::DEFAULT, "Output ?BX?, and input new number back into ?BX?"),
     tInstLibEntry<tMethod>("IO-Feedback", &cHardwareCPU::Inst_TaskIO_Feedback, 0, "Output ?BX?, and input new number back into ?BX?,  and push 1,0,  or -1 onto stack1 if merit increased, stayed the same, or decreased"),
+    tInstLibEntry<tMethod>("IO-bc-0.001", &cHardwareCPU::Inst_TaskIO_BonusCost_0_001),
     tInstLibEntry<tMethod>("match-strings", &cHardwareCPU::Inst_MatchStrings),
     tInstLibEntry<tMethod>("sell", &cHardwareCPU::Inst_Sell),
     tInstLibEntry<tMethod>("buy", &cHardwareCPU::Inst_Buy),
@@ -214,25 +215,24 @@
     tInstLibEntry<tMethod>("donate-quantagb",  &cHardwareCPU::Inst_DonateQuantaThreshGreenBeard),
     tInstLibEntry<tMethod>("donate-NUL", &cHardwareCPU::Inst_DonateNULL),
 
-	tInstLibEntry<tMethod>("IObuf-add1", &cHardwareCPU::Inst_IOBufAdd1),
+    tInstLibEntry<tMethod>("IObuf-add1", &cHardwareCPU::Inst_IOBufAdd1),
     tInstLibEntry<tMethod>("IObuf-add0", &cHardwareCPU::Inst_IOBufAdd0),
 
     tInstLibEntry<tMethod>("rotate-l", &cHardwareCPU::Inst_RotateL),
     tInstLibEntry<tMethod>("rotate-r", &cHardwareCPU::Inst_RotateR),
     tInstLibEntry<tMethod>("rotate-label", &cHardwareCPU::Inst_RotateLabel),
-
     
     tInstLibEntry<tMethod>("set-cmut", &cHardwareCPU::Inst_SetCopyMut),
     tInstLibEntry<tMethod>("mod-cmut", &cHardwareCPU::Inst_ModCopyMut),
     // @WRE additions for movement
     tInstLibEntry<tMethod>("tumble", &cHardwareCPU::Inst_Tumble),
     tInstLibEntry<tMethod>("move", &cHardwareCPU::Inst_Move),
-
-    // Energy instruction
-    tInstLibEntry<tMethod>("recover", &cHardwareCPU::Inst_ZeroEnergyUsed),
     
     // Threading instructions
     tInstLibEntry<tMethod>("fork-th", &cHardwareCPU::Inst_ForkThread),
+    tInstLibEntry<tMethod>("forkl", &cHardwareCPU::Inst_ForkThreadLabel),
+    tInstLibEntry<tMethod>("forkl!=0", &cHardwareCPU::Inst_ForkThreadLabelIfNot0),
+    tInstLibEntry<tMethod>("forkl=0", &cHardwareCPU::Inst_ForkThreadLabelIf0),
     tInstLibEntry<tMethod>("kill-th", &cHardwareCPU::Inst_KillThread),
     tInstLibEntry<tMethod>("id-th", &cHardwareCPU::Inst_ThreadID),
     
@@ -495,11 +495,11 @@
   
   if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) {
     //First instruction - check whether we should be starting at a promoter.
-    if (phenotype.GetTimeUsed() == 0) Inst_Terminate(m_world->GetDefaultContext());
+    if (phenotype.GetCPUCyclesUsed() == 0) Inst_Terminate(m_world->GetDefaultContext());
   }
   
-  phenotype.IncTimeUsed();
   phenotype.IncCPUCyclesUsed();
+  if (!m_world->GetConfig().NO_CPU_CYCLE_TIME.Get()) phenotype.IncTimeUsed();
 
   const int num_threads = GetNumThreads();
   
@@ -537,7 +537,7 @@
       // NOTE: This call based on the cur_inst must occur prior to instruction
       //       execution, because this instruction reference may be invalid after
       //       certain classes of instructions (namely divide instructions) @DMB
-      const int addl_time_cost = m_inst_set->GetAddlTimeCost(cur_inst);
+      const int time_cost = m_inst_set->GetAddlTimeCost(cur_inst);
 
       // Prob of exec (moved from SingleProcess_PayCosts so that we advance IP after a fail)
       if ( m_inst_set->GetProbFail(cur_inst) > 0.0 ) {
@@ -550,8 +550,8 @@
       // we now want to move to the next instruction in the memory.
       if (m_advance_ip == true) IP().Advance();
       
-      // Pay the additional death_cost of the instruction now
-      phenotype.IncTimeUsed(addl_time_cost);
+      // Pay the time cost of the instruction now
+      phenotype.IncTimeUsed(time_cost);
       
       // In the promoter model, there may be a chance of termination
       // that causes execution to start at a new instruction (per instruction executed)
@@ -2819,6 +2819,17 @@
   return true;
 }
 
+bool cHardwareCPU::Inst_TaskIO_BonusCost(cAvidaContext& ctx, double bonus_cost)
+{
+  // Levy the cost
+  double new_bonus = organism->GetPhenotype().GetCurBonus() * (1 - bonus_cost);
+  if (new_bonus < 0) new_bonus = 0;
+  //keep the bonus positive or zero
+  organism->GetPhenotype().SetCurBonus(new_bonus);
+  
+  return Inst_TaskIO(ctx);
+}
+
 bool cHardwareCPU::Inst_TaskIO_Feedback(cAvidaContext& ctx)
 {
   const int reg_used = FindModifiedRegister(REG_BX);
@@ -2920,11 +2931,11 @@
 
 bool cHardwareCPU::DoSense(cAvidaContext& ctx, int conversion_method, double base)
 {
-  // Returns the log2 amount of a resource or resources 
+  // Returns the amount of a resource or resources 
   // specified by modifying NOPs into register BX
   const tArray<double> & res_count = organism->GetOrgInterface().GetResources();
 
-  // Arbitrarily set to BX since the conditionals use this directly.
+  // Arbitrarily set to BX since the conditional instructions use this directly.
   int reg_to_set = REG_BX;
 
   // There are no resources, return
@@ -2953,7 +2964,7 @@
   // because their mapping to resources will be disrupted
   
   // Attempt to read a label with this maximum length
-  cHardwareCPU::ReadLabel(max_label_length);
+  ReadLabel(max_label_length);
   
   // Find the length of the label that we actually obtained (max is max_reg_needed)
   int real_label_length = GetLabel().GetSize();
@@ -3830,15 +3841,6 @@
   }
 }
 
-// Energy use
-
-bool cHardwareCPU::Inst_ZeroEnergyUsed(cAvidaContext& ctx)
-{
-  // Typically, this instruction should be triggered by a REACTION
-  organism->GetPhenotype().SetTimeUsed(0); 
-  return true;  
-}
-
 // Multi-threading.
 
 bool cHardwareCPU::Inst_ForkThread(cAvidaContext& ctx)
@@ -3848,6 +3850,49 @@
   return true;
 }
 
+bool cHardwareCPU::Inst_ForkThreadLabel(cAvidaContext& ctx)
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+  
+  // If there is no label, then do normal fork behavior
+  if (GetLabel().GetSize() == 0)
+  {
+    return Inst_ForkThread(ctx);
+  }
+  
+  cHeadCPU searchHead = FindLabel(+1);
+  if ( searchHead.GetPosition() != IP().GetPosition() )
+  {
+    int save_pos = IP().GetPosition();
+    IP().Set(searchHead.GetPosition() + 1);
+    if (!ForkThread()) organism->Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+    IP().Set( save_pos );
+  }
+  
+  return true;
+}
+
+bool cHardwareCPU::Inst_ForkThreadLabelIfNot0(cAvidaContext& ctx)
+{
+  if (GetRegister(REG_BX) == 0) 
+  {
+    ReadLabel();
+    return false;
+  }
+  return Inst_ForkThreadLabel(ctx);
+}
+
+bool cHardwareCPU::Inst_ForkThreadLabelIf0(cAvidaContext& ctx)
+{
+  if (GetRegister(REG_BX) != 0)
+  {
+    ReadLabel();
+    return false;
+  }
+  return Inst_ForkThreadLabel(ctx);
+}
+
 bool cHardwareCPU::Inst_KillThread(cAvidaContext& ctx)
 {
   if (!KillThread()) organism->Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);

Modified: branches/collect/source/cpu/cHardwareCPU.h
===================================================================
--- branches/collect/source/cpu/cHardwareCPU.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/cpu/cHardwareCPU.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -408,6 +408,8 @@
   bool Inst_TaskPutResetInputs(cAvidaContext& ctx);
   bool Inst_TaskIO(cAvidaContext& ctx);
   bool Inst_TaskIO_Feedback(cAvidaContext& ctx);
+  bool Inst_TaskIO_BonusCost(cAvidaContext& ctx, double bonus_cost);
+  bool Inst_TaskIO_BonusCost_0_001(cAvidaContext& ctx) { return Inst_TaskIO_BonusCost(ctx, 0.001); };
   bool Inst_MatchStrings(cAvidaContext& ctx);
   bool Inst_Sell(cAvidaContext& ctx);
   bool Inst_Buy(cAvidaContext& ctx);
@@ -449,13 +451,12 @@
   bool Inst_Tumble(cAvidaContext& ctx);
   bool Inst_Move(cAvidaContext& ctx);
 
-  // Energy use
-  
-  bool Inst_ZeroEnergyUsed(cAvidaContext& ctx); 
-
   // Multi-threading...
 
   bool Inst_ForkThread(cAvidaContext& ctx);
+  bool Inst_ForkThreadLabel(cAvidaContext& ctx);
+  bool Inst_ForkThreadLabelIf0(cAvidaContext& ctx);
+  bool Inst_ForkThreadLabelIfNot0(cAvidaContext& ctx);
   bool Inst_KillThread(cAvidaContext& ctx);
   bool Inst_ThreadID(cAvidaContext& ctx);
 

Modified: branches/collect/source/cpu/cHardwareExperimental.cc
===================================================================
--- branches/collect/source/cpu/cHardwareExperimental.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/cpu/cHardwareExperimental.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -249,8 +249,8 @@
   organism->SetRunning(true);
   
   cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.IncTimeUsed();
   phenotype.IncCPUCyclesUsed();
+  if (!m_world->GetConfig().NO_CPU_CYCLE_TIME.Get()) phenotype.IncTimeUsed();
 
   const int num_threads = GetNumThreads();
   

Modified: branches/collect/source/cpu/cHardwareGX.cc
===================================================================
--- branches/collect/source/cpu/cHardwareGX.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/cpu/cHardwareGX.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -187,6 +187,7 @@
     tInstLibEntry<tMethod>("put", &cHardwareGX::Inst_TaskPut),
     tInstLibEntry<tMethod>("put-reset", &cHardwareGX::Inst_TaskPutResetInputs),
     tInstLibEntry<tMethod>("IO", &cHardwareGX::Inst_TaskIO, nInstFlag::DEFAULT, "Output ?BX?, and input new number back into ?BX?"),
+    tInstLibEntry<tMethod>("IO-decay", &cHardwareGX::Inst_TaskIO_DecayBonus),
     tInstLibEntry<tMethod>("IO-Feedback", &cHardwareGX::Inst_TaskIO_Feedback, 0, "Output ?BX?, and input new number back into ?BX?,  and push 1,0,  or -1 onto stack1 if merit increased, stayed the same, or decreased"),
     tInstLibEntry<tMethod>("match-strings", &cHardwareGX::Inst_MatchStrings),
     tInstLibEntry<tMethod>("sell", &cHardwareGX::Inst_Sell),
@@ -395,7 +396,8 @@
     AdjustPromoterRates();
     
     // \todo implement different initial conditions for created executable programids
-    ProcessImplicitGeneExpression(); 
+    m_promoter_update_head.Set(organism->GetGenome().GetSize() - 1); //So that ++ moves it to position zero
+    ProcessImplicitGeneExpression(1); 
   }
   
   m_current = m_programids.back();
@@ -436,12 +438,20 @@
   if ( m_world->GetConfig().IMPLICIT_GENE_EXPRESSION.Get() )
   {
     m_recycle_state += (double)m_world->GetConfig().IMPLICIT_TURNOVER_RATE.Get();
+    int num_programids = m_programids.size();
     while (m_recycle_state >= 1.0)
     {
-      if (m_programids.size() > 1) RemoveProgramid(1);
+      if (m_programids.size() > (unsigned int)m_world->GetConfig().MAX_PROGRAMIDS.Get()) 
+      {
+        RemoveProgramid(1);
+      }
+      else
+      {
+        num_programids++;
+      }
       m_recycle_state -= 1.0;
     }
-    ProcessImplicitGeneExpression();
+    ProcessImplicitGeneExpression(num_programids);
   }
     
   organism->SetRunning(true);
@@ -2317,6 +2327,13 @@
   return true;
 }
 
+bool cHardwareGX::Inst_TaskIO_DecayBonus(cAvidaContext& ctx)
+{
+  (void) Inst_TaskIO(ctx);  
+  organism->GetPhenotype().SetCurBonus(organism->GetPhenotype().GetCurBonus() * 0.99);
+  return true;
+}
+
 bool cHardwareGX::Inst_TaskIO_Feedback(cAvidaContext& ctx)
 {
   const int reg_used = FindModifiedRegister(REG_BX);
@@ -3981,6 +3998,7 @@
 
   // Find next best match.
   ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
 
   int match_pos = FindRegulatoryMatch( GetLabel() );
   if (match_pos == -1) return false;
@@ -4029,6 +4047,7 @@
 
   // Find next best match.
   ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
 
   int match_pos = FindRegulatoryMatch( GetLabel() );
   if (match_pos == -1) return false;
@@ -4145,7 +4164,8 @@
   static cInstruction terminator_inst = GetInstSet().GetInst(cStringUtil::Stringf("terminator"));
 
   if (in_limit == -1 ) in_limit = m_world->GetConfig().MAX_PROGRAMIDS.Get();
-  
+  if (in_limit > m_world->GetConfig().MAX_PROGRAMIDS.Get()) in_limit = m_world->GetConfig().MAX_PROGRAMIDS.Get();
+
   // Create executable programids up to the limit
   const int genome_size = m_programids[m_promoter_update_head.GetMemSpace()]->GetMemory().GetSize();
   const int inc = Min(genome_size, m_world->GetConfig().IMPLICIT_MAX_PROGRAMID_LENGTH.Get());
@@ -4154,10 +4174,12 @@
   {
     // Update promoter states according to rates until one fires
     
-    while ( m_promoter_states[m_promoter_update_head.GetPosition()] < 1.0)
-    {
-      m_promoter_states[m_promoter_update_head.GetPosition()] += m_promoter_rates[m_promoter_update_head.GetPosition()];
-
+    do  {
+      // This way goes straight through the genome
+      m_promoter_update_head++;
+      
+      // This way goes interspersed through the genome -- Add as a config option @JEB
+      /*
       int new_pos = m_promoter_update_head.GetPosition();
       new_pos += inc;
       if ( new_pos >= genome_size )
@@ -4165,10 +4187,15 @@
         new_pos++;
         new_pos %= inc;
       }
+      */
       
-      assert((new_pos >= 0) && (new_pos < genome_size));
-      m_promoter_update_head.Set(new_pos);
-    }
+      m_promoter_states[m_promoter_update_head.GetPosition()] += m_promoter_rates[m_promoter_update_head.GetPosition()];
+      if ( (m_world->GetVerbosity() >= VERBOSE_DETAILS) && (m_promoter_states[m_promoter_update_head.GetPosition()] > 0) )
+      {
+        cout << "Promoter position " <<  m_promoter_update_head.GetPosition() << " value " << m_promoter_states[m_promoter_update_head.GetPosition()] << endl;
+      }
+    } while (m_promoter_states[m_promoter_update_head.GetPosition()] < 1.0);
+    
     m_promoter_states[m_promoter_update_head.GetPosition()] -= 1.0;
     
     // Create new programid
@@ -4205,10 +4232,9 @@
       cout << "New programid created. Start position = " << new_programid->GetHead(nHardware::HEAD_READ).GetPosition();
       cout << " length = " <<  new_programid->m_memory.GetSize() << endl;
     }
+    
+    m_promoter_update_head++; //move on to the next position
   }
-
-  m_promoter_update_head++;
-  
 }
 
 
@@ -4257,7 +4283,7 @@
     for (int i=0; i<label.GetSize(); i++)
     {
       // Don't allow a site that overlaps current regulation
-      if (m_promoter_occupied_sites[i] != 0)
+      if (m_promoter_occupied_sites[m.GetPosition()] != 0)
       {
         matched_positions = 0;
         break;
@@ -4524,8 +4550,8 @@
   for (int i=0; i < 2*regulatory_footprint + _label_size; i++)
   {
     m_gx_hardware->m_promoter_occupied_sites[h.GetPosition()] = 0; //Zero regulation
-  }
-  h++;    
+    h++;   
+  } 
   
   m_gx_hardware->AdjustPromoterRates();
 }

Modified: branches/collect/source/cpu/cHardwareGX.h
===================================================================
--- branches/collect/source/cpu/cHardwareGX.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/cpu/cHardwareGX.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -501,6 +501,7 @@
   bool Inst_TaskPut(cAvidaContext& ctx);
   bool Inst_TaskPutResetInputs(cAvidaContext& ctx);
   bool Inst_TaskIO(cAvidaContext& ctx);
+  bool Inst_TaskIO_DecayBonus(cAvidaContext& ctx);
   bool Inst_TaskIO_Feedback(cAvidaContext& ctx);
   bool Inst_MatchStrings(cAvidaContext& ctx);
   bool Inst_Sell(cAvidaContext& ctx);

Modified: branches/collect/source/main/cAvidaConfig.h
===================================================================
--- branches/collect/source/main/cAvidaConfig.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cAvidaConfig.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -246,8 +246,9 @@
   CONFIG_ADD_VAR(REQUIRED_TASK, int, -1, "Task ID required for successful divide.");
   CONFIG_ADD_VAR(IMMUNITY_TASK, int, -1, "Task providing immunity from the required task.");
   CONFIG_ADD_VAR(REQUIRED_REACTION, int, -1, "Reaction ID required for successful divide.");
-  CONFIG_ADD_VAR(IMPLICIT_REPRO_BONUS, int, 0, "Immediately call Inst_Repro to divide when upon achieving this bonus. 0 = OFF");  
-  CONFIG_ADD_VAR(IMPLICIT_REPRO_TIME, int, 0, "Immediately call Inst_Repro after this many cpu cycles. 0 = OFF");  
+  CONFIG_ADD_VAR(IMPLICIT_REPRO_BONUS, int, 0, "Call Inst_Repro to divide upon achieving this bonus. 0 = OFF");  
+  CONFIG_ADD_VAR(IMPLICIT_REPRO_CPU_CYCLES, int, 0, "Call Inst_Repro after this many cpu cycles. 0 = OFF");  
+  CONFIG_ADD_VAR(IMPLICIT_REPRO_TIME, int, 0, "Call Inst_Repro after this time used. 0 = OFF");  
 
   CONFIG_ADD_GROUP(MUTATION_GROUP, "Mutations");
   CONFIG_ADD_VAR(POINT_MUT_PROB, double, 0.0, "Mutation rate (per-location per update)");
@@ -291,11 +292,14 @@
   CONFIG_ADD_VAR(MERIT_DEFAULT_BONUS, int, 0, "Scale the merit of an offspring by the default bonus\nrather than the accumulated bonus of the parent?"); 
   CONFIG_ADD_VAR(MERIT_BONUS_INST, int, 0, "in BASE_MERIT_METHOD 6, this sets which instruction counts\n(-1 = none, 0 = First in INST_SET.)"); 
   CONFIG_ADD_VAR(MERIT_BONUS_EFFECT, int, 0, "in BASE_MERIT_METHOD 6, this sets how much merit is earned\nper instruction (-1 = penalty, 0 = no effect.)"); 
+  CONFIG_ADD_VAR(FITNESS_METHOD, int, 0, "0 = default, >1 = experimental"); 
+  CONFIG_ADD_VAR(FITNESS_COEFF, double, 1.0, "A FITNESS_METHOD parameter");  
   CONFIG_ADD_VAR(FITNESS_VALLEY, int, 0, "in BASE_MERIT_METHOD 6, this creates valleys from\nFITNESS_VALLEY_START to FITNESS_VALLEY_STOP\n(0 = off, 1 = on)"); 
   CONFIG_ADD_VAR(FITNESS_VALLEY_START, int, 0, "if FITNESS_VALLEY = 1, orgs with num_key_instructions\nfrom FITNESS_VALLEY_START to FITNESS_VALLEY_STOP\nget fitness 1 (lowest)"); 
   CONFIG_ADD_VAR(FITNESS_VALLEY_STOP, int, 0, "if FITNESS_VALLEY = 1, orgs with num_key_instructions\nfrom FITNESS_VALLEY_START to FITNESS_VALLEY_STOP\nget fitness 1 (lowest)"); 
   CONFIG_ADD_VAR(MAX_CPU_THREADS, int, 1, "Number of Threads a CPU can spawn");
   CONFIG_ADD_VAR(THREAD_SLICING_METHOD, int, 0, "Formula for and organism's thread slicing\n  (num_threads-1) * THREAD_SLICING_METHOD + 1\n0 = One thread executed per time slice.\n1 = All threads executed each time slice.\n");
+  CONFIG_ADD_VAR(NO_CPU_CYCLE_TIME, int, 0, "Don't count each CPU cycle as part of gestation time\n");
   CONFIG_ADD_VAR(MAX_LABEL_EXE_SIZE, int, 1, "Max nops marked as executed when labels are used");
   CONFIG_ADD_VAR(MERIT_GIVEN, double, 0.0, "Fraction of merit donated with 'donate' command");
   CONFIG_ADD_VAR(MERIT_RECEIVED, double, 0.0, "Multiplier of merit given with 'donate' command"); 

Modified: branches/collect/source/main/cEnvironment.cc
===================================================================
--- branches/collect/source/main/cEnvironment.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cEnvironment.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -160,6 +160,7 @@
       else if (var_value=="pow") new_process->SetType(nReaction::PROCTYPE_POW);
       else if (var_value=="lin") new_process->SetType(nReaction::PROCTYPE_LIN);
       else if (var_value=="energy") new_process->SetType(nReaction::PROCTYPE_ENERGY);
+      else if (var_value=="enzyme") new_process->SetType(nReaction::PROCTYPE_ENZYME);
       else {
         cerr << "Unknown reaction process type '" << var_value
         << "' found in '" << reaction->GetName() << "'." << endl;
@@ -218,7 +219,13 @@
     }
     else if (var_name == "string") {
       new_process->SetMatchString(var_value);
-	}
+    }
+    else if (var_name == "depletable") {
+    if (!AssertInputBool(var_value, "depletable", var_type))
+        return false;
+    new_process->SetDepletable(var_value.AsInt());  
+    }
+
     else {
       cerr << "Error: Unknown process variable '" << var_name
       << "' in reaction '" << reaction->GetName() << "'" << endl;
@@ -958,7 +965,7 @@
       // Test if infinite resource
       consumed = max_consumed * task_quality;
     } else {
-      // Otherwise we're using a finite resource
+      // Otherwise we're using a finite resource      
       const int res_id = in_resource->GetID();
       
       assert(resource_count[res_id] >= 0);
@@ -989,11 +996,13 @@
       if (consumed == 0.0) continue;
       
       // Mark in the results the resource consumed.
-      result.Consume(res_id, consumed, !using_rbins);
+			if (cur_process->GetDepletable()) {
+      	result.Consume(res_id, consumed, !using_rbins);
       
-      //if we consumed resource from an internal resource bin, remove it
-      if (may_use_rbins && using_rbins)
-      {rbins_count[res_id] -= consumed;}
+      	//if we consumed resource from an internal resource bin, remove it
+      	if (may_use_rbins && using_rbins)
+      	{rbins_count[res_id] -= consumed;}
+      }
     }
     
     // Calculate the bonus
@@ -1015,7 +1024,14 @@
       case nReaction::PROCTYPE_ENERGY:
         result.AddEnergy(bonus);
         break;
-        
+      case nReaction::PROCTYPE_ENZYME: //@JEB
+        const int res_id = in_resource->GetID();
+        assert(cur_process->GetMaxFraction() != 0);
+        assert(resource_count[res_id] != 0);
+        double reward = cur_process->GetValue() * resource_count[res_id] / (resource_count[res_id] + cur_process->GetMaxFraction());
+        result.AddBonus( reward , reaction_id);
+        break;
+          
       default:
         assert(false);  // Should not get here!
         break;

Modified: branches/collect/source/main/cOrganism.cc
===================================================================
--- branches/collect/source/main/cOrganism.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cOrganism.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -633,3 +633,12 @@
 
   m_phenotype.IncErrors();
 }
+
+void cOrganism::NewTrial()
+{
+  //More should be reset here... @JEB
+  GetPhenotype().NewTrial();
+  m_input_pointer = 0;
+  m_input_buf.Clear();
+  m_output_buf.Clear();
+}

Modified: branches/collect/source/main/cOrganism.h
===================================================================
--- branches/collect/source/main/cOrganism.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cOrganism.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -257,6 +257,7 @@
   void PrintFinalStatus(std::ostream& fp, int time_used, int time_allocated) const;
   void Fault(int fault_loc, int fault_type, cString fault_desc="");
 
+  void NewTrial();
 
   // --------  Mutation Rate Convenience Methods  --------
   bool TestCopyMut(cAvidaContext& ctx) const { return m_mut_rates.TestCopyMut(ctx); }

Modified: branches/collect/source/main/cPhenPlastGenotype.cc
===================================================================
--- branches/collect/source/main/cPhenPlastGenotype.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cPhenPlastGenotype.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -24,14 +24,40 @@
 
 #include "cPhenPlastGenotype.h"
 #include <iostream>
+#include <cmath>
 
 cPhenPlastGenotype::cPhenPlastGenotype(const cGenome& in_genome, int num_trials, cWorld* world, cAvidaContext& ctx)
 : m_genome(in_genome), m_num_trials(num_trials), m_world(world)
 {
+  cCPUTestInfo test_info;
+  test_info.UseRandomInputs(true);
+  Process(test_info, world, ctx);
+}
+
+cPhenPlastGenotype::cPhenPlastGenotype(const cGenome& in_genome, int num_trials, cCPUTestInfo& test_info, cWorld* world, cAvidaContext& ctx)
+: m_genome(in_genome), m_num_trials(num_trials), m_world(world)
+{
+  // Override input mode if more than one recalculation requested
+  if (num_trials > 1)  
+    test_info.UseRandomInputs(true);
+  Process(test_info, world, ctx);
+}
+
+cPhenPlastGenotype::~cPhenPlastGenotype()
+{
+  UniquePhenotypes::iterator it = m_unique.begin();
+  while (it != m_unique.end()){
+    delete *it;
+    ++it;
+  }
+}
+
+void cPhenPlastGenotype::Process(cCPUTestInfo& test_info, cWorld* world, cAvidaContext& ctx)
+{
+  if (m_num_trials > 1)
+    test_info.UseRandomInputs(true);
   cTestCPU* test_cpu = m_world->GetHardwareManager().CreateTestCPU();
   for (int k = 0; k < m_num_trials; k++){
-    cCPUTestInfo test_info;
-    test_info.UseRandomInputs(true);
     test_cpu->TestGenome(ctx, test_info, m_genome);
     
     //Is this a new phenotype?
@@ -43,24 +69,68 @@
       assert( static_cast<cPlasticPhenotype*>((*uit))->AddObservation(test_info) );
     }
   }
+  // Update statistics
+  UniquePhenotypes::iterator uit = m_unique.begin();
+  m_max_fitness     =  -1.0;
+  m_avg_fitness     =   0.0;
+  m_likely_fitness  =  -1.0;
+  m_max_freq        =   0.0;
+  m_max_fit_freq    =   0.0;
+  m_min_fit_freq    =   0.0;
+  m_phenotypic_entropy = 0.0;
+  m_min_fitness     = (*uit)->GetFitness();
+  while(uit != m_unique.end()){
+    cPlasticPhenotype* this_phen = static_cast<cPlasticPhenotype*>(*uit);
+    double fit = this_phen->GetFitness();
+    double freq = this_phen->GetFrequency();
+    if (fit > m_max_fitness){
+      m_max_fitness = fit;
+      m_max_fit_freq = freq;
+    }
+    if (fit < m_min_fitness){
+      m_min_fitness = fit;
+      m_min_fit_freq = freq;
+    }
+    if (freq > m_max_freq){
+      m_max_freq = freq;
+      m_likely_fitness = fit;
+    }
+    m_avg_fitness += freq * fit;
+    m_phenotypic_entropy -= freq * log(freq) / log(2);
+    ++uit;
+  }
   delete test_cpu;
 }
 
-cPhenPlastGenotype::~cPhenPlastGenotype()
+
+const cPlasticPhenotype* cPhenPlastGenotype::GetPlasticPhenotype(int num) const
 {
-  UniquePhenotypes::iterator it = m_unique.begin();
-  while (it != m_unique.end()){
-    delete *it;
-    ++it;
-  }
+  assert(num >= 0 && num < (int) m_unique.size() && m_unique.size() > 0);
+  UniquePhenotypes::const_iterator it = m_unique.begin();
+  for (int k = 0; k < num; k++, it++);
+  return static_cast<cPlasticPhenotype*>(*it);
 }
 
+const cPlasticPhenotype* cPhenPlastGenotype::GetMostLikelyPhenotype() const
+{
+  assert(m_unique.size() > 0);
+  UniquePhenotypes::const_iterator it = m_unique.begin();
+  UniquePhenotypes::const_iterator ret_it = it;
+  for (int k = 0; k < (int) m_unique.size(); k++, it++)
+    if ( static_cast<cPlasticPhenotype*>(*it)->GetFrequency() > 
+         static_cast<cPlasticPhenotype*>(*ret_it)->GetFrequency() )
+      ret_it = it;
+  return static_cast<cPlasticPhenotype*>(*ret_it);
+}
 
-cPlasticPhenotype cPhenPlastGenotype::GetPlasticPhenotype(int num) const
+const cPlasticPhenotype* cPhenPlastGenotype::GetHighestFitnessPhenotype() const
 {
-  assert(num >= 0 && num < (int) m_unique.size());
-  UniquePhenotypes::iterator it = m_unique.begin();
-  for (int k = 0; k < num; k++, it++);
-  return *static_cast<cPlasticPhenotype*>(*it);
+  assert(m_unique.size() > 0);
+  UniquePhenotypes::const_iterator it = m_unique.begin();
+  UniquePhenotypes::const_iterator ret_it = it;
+  for (int k = 0; k < (int) m_unique.size(); k++, it++)
+    if ( static_cast<cPlasticPhenotype*>(*it)->GetFitness() > 
+         static_cast<cPlasticPhenotype*>(*ret_it)->GetFitness() )
+      ret_it = it;
+  return static_cast<cPlasticPhenotype*>(*ret_it);
 }
-

Modified: branches/collect/source/main/cPhenPlastGenotype.h
===================================================================
--- branches/collect/source/main/cPhenPlastGenotype.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cPhenPlastGenotype.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -56,19 +56,44 @@
 {
   private:
 
-  typedef set<cPhenotype*, cPhenotype::lt_phenotype  > UniquePhenotypes;  //Actually, these are cPlasticPhenotype*
+  typedef set<cPhenotype*, cPhenotype::lt_phenotype  > UniquePhenotypes;  //Actually, these are cPlatsicPhenotypes*
     cGenome m_genome;
     int m_num_trials;  
     UniquePhenotypes m_unique;
     cWorld* m_world;
+    
+    double m_max_fitness;
+    double m_avg_fitness;
+    double m_likely_fitness;
+    double m_phenotypic_entropy;
+    double m_max_freq;
+    double m_max_fit_freq;
+    double m_min_fit_freq;
+    double m_min_fitness;
+    
+    void Process(cCPUTestInfo& test_info, cWorld* world, cAvidaContext& ctx);
 
   public:
       cPhenPlastGenotype(const cGenome& in_genome, int num_trials, cWorld* world, cAvidaContext& ctx);
+    cPhenPlastGenotype(const cGenome& in_genome, int num_trails, cCPUTestInfo& test_info, cWorld* world, cAvidaContext& ctx);
     ~cPhenPlastGenotype();
     
-    int GetNumPhenotypes() const { return m_unique.size(); }
-    cPlasticPhenotype GetPlasticPhenotype(int num) const;
+    // Accessors
+    int    GetNumPhenotypes() const     { return m_unique.size();  }
+    int    GetNumTrials() const         { return m_num_trials;     }
+    double GetMaximumFitness() const    { return m_max_fitness;    }
+    double GetMinimumFitness() const    { return m_min_fitness;    }
+    double GetAverageFitness() const    { return m_avg_fitness;    }
+    double GetLikelyFitness()  const    { return m_likely_fitness; }
+    double GetPhenotypicEntropy() const { return m_phenotypic_entropy; }
+    double GetMaximumFrequency() const  { return m_max_freq; }
+    double GetMaximumFitnessFrequency() const {return m_max_fit_freq;}
+    double GetMinimumFitnessFrequency() const {return m_min_fit_freq;}
+    const cPlasticPhenotype* GetPlasticPhenotype(int num) const;
+    const cPlasticPhenotype* GetMostLikelyPhenotype() const;
+    const cPlasticPhenotype* GetHighestFitnessPhenotype() const;
     
+    
 };
 
 #endif

Modified: branches/collect/source/main/cPhenotype.cc
===================================================================
--- branches/collect/source/main/cPhenotype.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cPhenotype.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -279,13 +279,14 @@
   
   gestation_time  = parent_phenotype.gestation_time;
   gestation_start = 0;
+  cpu_cycles_used = 0;
   fitness         = parent_phenotype.fitness;
   div_type        = parent_phenotype.div_type;
 
   assert(genome_length > 0);
   assert(copied_size > 0);
   assert(executed_size > 0);
-  assert(gestation_time > 0);
+  assert(gestation_time >= 0); //@JEB 0 valid for some fitness methods
   assert(div_type > 0);
 
   // Initialize current values, as neeeded.
@@ -309,10 +310,16 @@
   for (int j = 0; j < sensed_resources.GetSize(); j++)
 	      sensed_resources[j] =  parent_phenotype.sensed_resources[j];
   SetupPromoterWeights(_genome, true);
+  cur_trial_fitnesses.Resize(0); 
+  cur_trial_bonuses.Resize(0); 
+  cur_trial_times_used.Resize(0); 
+  trial_time_used = 0;
+  trial_cpu_cycles_used = 0;
   
   // Copy last values from parent
   last_merit_base           = parent_phenotype.last_merit_base;
   last_bonus                = parent_phenotype.last_bonus;
+  last_cpu_cycles_used      = parent_phenotype.last_cpu_cycles_used;
   last_num_errors           = parent_phenotype.last_num_errors;
   last_num_donates          = parent_phenotype.last_num_donates;
   last_task_count           = parent_phenotype.last_task_count;
@@ -326,7 +333,7 @@
   last_reaction_add_reward  = parent_phenotype.last_reaction_add_reward;
   last_inst_count           = parent_phenotype.last_inst_count;
   last_sense_count          = parent_phenotype.last_sense_count;
-  last_fitness              = last_merit_base * last_bonus / gestation_time;
+  last_fitness              = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
 
   // Setup other miscellaneous values...
   num_divides     = 0;
@@ -445,10 +452,16 @@
   cur_sense_count.SetAll(0);
   cur_task_time.SetAll(0.0);
   SetupPromoterWeights(_genome, true);
+  cur_trial_fitnesses.Resize(0);
+  cur_trial_bonuses.Resize(0); 
+  cur_trial_times_used.Resize(0); 
+  trial_time_used = 0;
+  trial_cpu_cycles_used = 0;
   
   // Copy last values from parent
   last_merit_base = genome_length;
   last_bonus      = 1;
+  last_cpu_cycles_used = 0;
   last_num_errors = 0;
   last_num_donates = 0;
   last_task_count.SetAll(0);
@@ -539,10 +552,10 @@
 /**
  * This function is run whenever an organism executes a successful divide.
  **/
-
-void cPhenotype::DivideReset(const cGenome & _genome)
+ 
+ void cPhenotype::DivideReset(const cGenome & _genome)
 {
-  assert(time_used > 0);
+  assert(time_used >= 0);
   assert(initialized == true);
 
   // Update these values as needed...
@@ -566,11 +579,12 @@
   (void) executed_size;        // Unchanged
   gestation_time  = time_used - gestation_start;
   gestation_start = time_used;
-  fitness         = merit.GetDouble() / gestation_time;
+  fitness = CalcFitness( cur_merit_base, cur_bonus, gestation_time, cpu_cycles_used); 
 
   // Lock in cur values as last values.
   last_merit_base           = cur_merit_base;
   last_bonus                = cur_bonus;
+  last_cpu_cycles_used      = cpu_cycles_used;
 //TODO?  last_energy         = cur_energy_bonus;
   last_num_errors           = cur_num_errors;
   last_num_donates          = cur_num_donates;
@@ -588,6 +602,7 @@
 
   // Reset cur values.
   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
+  cpu_cycles_used = 0;
   cur_energy_bonus = 0.0;
   cur_num_errors  = 0;
   cur_num_donates  = 0;
@@ -690,7 +705,6 @@
   m_task_states.ClearAll();
 }
 
-
 /**
  * This function runs whenever a *test* CPU divides. It processes much of
  * the information for that CPU in order to actively reflect its executed
@@ -711,12 +725,13 @@
   (void) executed_size;                          // Unchanged
   gestation_time  = time_used - gestation_start;
   gestation_start = time_used;
-  fitness         = merit.GetDouble() / gestation_time;
+  fitness         = CalcFitness(cur_merit_base, cur_bonus, gestation_time, cpu_cycles_used);
   (void) div_type; 				// Unchanged
 
   // Lock in cur values as last values.
   last_merit_base           = cur_merit_base;
   last_bonus                = cur_bonus;
+  last_cpu_cycles_used      = cpu_cycles_used;
   last_num_errors           = cur_num_errors;
   last_num_donates          = cur_num_donates;
   last_task_count           = cur_task_count;
@@ -733,6 +748,7 @@
 
   // Reset cur values.
   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
+  cpu_cycles_used = 0;
   cur_num_errors  = 0;
   cur_num_donates  = 0;
   cur_task_count.SetAll(0);
@@ -750,7 +766,12 @@
   cur_task_time.SetAll(0.0);
   sensed_resources.SetAll(-1.0);
   SetupPromoterWeights(_genome, true);
-  
+  cur_trial_fitnesses.Resize(0); 
+  cur_trial_bonuses.Resize(0); 
+  cur_trial_times_used.Resize(0); 
+  trial_time_used = 0;
+  trial_cpu_cycles_used = 0;
+
   // Setup other miscellaneous values...
   num_divides++;
   generation++;
@@ -848,11 +869,12 @@
   assert(genome_length > 0);
   assert(copied_size > 0);
   assert(executed_size > 0);
-  assert(gestation_time > 0);
+  assert(gestation_time >= 0); //@JEB 0 valid for some fitness methods
   assert(div_type > 0);
 
   // Initialize current values, as neeeded.
   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
+  cpu_cycles_used = 0;
   cur_num_errors  = 0;
   cur_num_donates  = 0;
   cur_task_count.SetAll(0);
@@ -865,11 +887,17 @@
   cur_task_time.SetAll(0.0);
   for (int j = 0; j < sensed_resources.GetSize(); j++)
 	      sensed_resources[j] =  clone_phenotype.sensed_resources[j];
-  //SetupPromoterWeights(_genome); Do we reset here?
+  //SetupPromoterWeights(_genome); Do we reset here? @JEB
+  cur_trial_fitnesses.Resize(0); 
+  cur_trial_bonuses.Resize(0); 
+  cur_trial_times_used.Resize(0); 
+  trial_time_used = 0;
+  trial_cpu_cycles_used = 0;
 
   // Copy last values from parent
   last_merit_base          = clone_phenotype.last_merit_base;
   last_bonus               = clone_phenotype.last_bonus;
+  last_cpu_cycles_used     = clone_phenotype.last_cpu_cycles_used;
   last_num_errors          = clone_phenotype.last_num_errors;
   last_num_donates         = clone_phenotype.last_num_donates;
   last_task_count          = clone_phenotype.last_task_count;
@@ -878,7 +906,7 @@
   last_reaction_add_reward = clone_phenotype.last_reaction_add_reward;
   last_inst_count          = clone_phenotype.last_inst_count;
   last_sense_count         = clone_phenotype.last_sense_count;  
-  last_fitness             = last_merit_base * last_bonus / gestation_time;
+  last_fitness             = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
 
   // Setup other miscellaneous values...
   num_divides     = 0;
@@ -1417,33 +1445,31 @@
   return out_size;
 } 
 
-void cPhenotype::SetupPromoterWeights(const cGenome & _genome, const bool clear)
+
+double cPhenotype::CalcFitness(double _merit_base, double _bonus, int _gestation_time, int _cpu_cycles) const
 {
-  if (!m_world->GetConfig().PROMOTERS_ENABLED.Get()) return;
-
-  // Ideally, this wouldn't be hard-coded
-  static cInstruction promoter_inst = m_world->GetHardwareManager().GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
-
-  int old_size = base_promoter_weights.GetSize();
-  cur_promoter_weights.Resize(_genome.GetSize());
-  base_promoter_weights.Resize(_genome.GetSize());
-  promoter_repression.Resize(_genome.GetSize());
-  promoter_activation.Resize(_genome.GetSize());
-
-  // Only change new regions of the genome (that might have been allocated since this was last called)
-  for ( int i = (clear ? 0 : old_size); i<_genome.GetSize(); i++)
+  double out_fitness = 0;
+  switch (m_world->GetConfig().FITNESS_METHOD.Get())
   {
-    base_promoter_weights[i] = 1;
-    promoter_repression[i] = 0;
-    promoter_activation[i] = 0;
+    case 0: // Normal
+    assert(_gestation_time > 0);
+    out_fitness = _merit_base * _bonus / _gestation_time;
+    break;
 
-    // Now change the weights at instructions that are not promoters if called for
-    if ( _genome[i] != promoter_inst)
+    case 1: //Activity of one enzyme in pathway altered (with diminishing returns and a cost for each executed instruction)
     {
-      base_promoter_weights[i] *= m_world->GetConfig().PROMOTER_BG_STRENGTH.Get(); 
+      out_fitness = 0;
+      double net_bonus = _bonus +  - m_world->GetConfig().DEFAULT_BONUS.Get();
+      out_fitness = net_bonus / (net_bonus + 1)* exp (_gestation_time * log(1 - m_world->GetConfig().FITNESS_COEFF.Get())); 
     }
-    cur_promoter_weights[i] = base_promoter_weights[i];
+    break;
+     
+    default:
+    cout << "Unknown FITNESS_METHOD!" << endl;
+    exit(1);
   }
+  
+  return out_fitness;
 }
 
 void cPhenotype::ReduceEnergy(const double cost) {
@@ -1476,17 +1502,6 @@
   energy_tobe_applied = 0.0;
 }
 
-void cPhenotype::DecayAllPromoterRegulation()
-{
-  for ( int i=0; i<cur_promoter_weights.GetSize(); i++)
-  {
-    promoter_activation[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
-    promoter_repression[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
-    cur_promoter_weights[i] = base_promoter_weights[i] * exp((1+promoter_activation[i])*log(2.0)) / exp((1+promoter_repression[i])*log(2.0));
-
-  }
-}
-
 double cPhenotype::ExtractParentEnergy() {
   assert(m_world->GetConfig().ENERGY_ENABLED.Get() > 0);
   // energy model config variables
@@ -1521,6 +1536,47 @@
   return child_energy;
 }
 
+void cPhenotype::SetupPromoterWeights(const cGenome & _genome, const bool clear)
+{
+  if (!m_world->GetConfig().PROMOTERS_ENABLED.Get()) return;
+
+  // Ideally, this wouldn't be hard-coded
+  static cInstruction promoter_inst = m_world->GetHardwareManager().GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
+
+  int old_size = base_promoter_weights.GetSize();
+  cur_promoter_weights.Resize(_genome.GetSize());
+  base_promoter_weights.Resize(_genome.GetSize());
+  promoter_repression.Resize(_genome.GetSize());
+  promoter_activation.Resize(_genome.GetSize());
+
+  // Only change new regions of the genome (that might have been allocated since this was last called)
+  for ( int i = (clear ? 0 : old_size); i<_genome.GetSize(); i++)
+  {
+    base_promoter_weights[i] = 1;
+    promoter_repression[i] = 0;
+    promoter_activation[i] = 0;
+
+    // Now change the weights at instructions that are not promoters if called for
+    if ( _genome[i] != promoter_inst)
+    {
+      base_promoter_weights[i] *= m_world->GetConfig().PROMOTER_BG_STRENGTH.Get(); 
+    }
+    cur_promoter_weights[i] = base_promoter_weights[i];
+  }
+}
+
+
+void cPhenotype::DecayAllPromoterRegulation()
+{
+  for ( int i=0; i<cur_promoter_weights.GetSize(); i++)
+  {
+    promoter_activation[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
+    promoter_repression[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
+    cur_promoter_weights[i] = base_promoter_weights[i] * exp((1+promoter_activation[i])*log(2.0)) / exp((1+promoter_repression[i])*log(2.0));
+
+  }
+}
+
 void cPhenotype::RegulatePromoter(const int i, const bool up )
 {
   // Make sure we were initialized
@@ -1538,7 +1594,196 @@
   cur_promoter_weights[i] = base_promoter_weights[i] * exp((1+promoter_activation[i])*log(2.0)) / exp((1+promoter_repression[i])*log(2.0));
 }
 
+// Save the current fitness and reset relevant parts of the phenotype
+void cPhenotype::NewTrial()
+{ 
+  //Return if a complete trial has not occurred.
+  //(This will happen if CompeteOrganisms was called before in the same update
+  if (trial_cpu_cycles_used == 0) return;
+  
+  //Record the merit of this trial
+  fitness = CalcFitness( GetCurMeritBase(), GetCurBonus() , trial_time_used, trial_cpu_cycles_used); // This is a per-trial fitness @JEB
+  cur_trial_fitnesses.Push(fitness);
+  cur_trial_bonuses.Push(GetCurBonus());
+  cur_trial_times_used.Push(trial_time_used);
 
+  //The rest of the function, resets the phenotype like DivideReset(), but without
+  //incrementing the generation or child statistics.
+  
+  //Most importantly, this does (below):
+  // trial_time_used = 0;
+  // trial_cpu_cycles_used = 0;
+  // SetCurBonus(m_world->GetConfig().DEFAULT_BONUS.Get());
+  
+  // Update these values as needed...
+  int cur_merit_base = CalcSizeMerit();
+  
+  // If we are resetting the current merit, do it here
+  // and it will also be propagated to the child
+  int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
+  if (merit_default_bonus) {
+    merit = cur_merit_base * m_world->GetConfig().DEFAULT_BONUS.Get();
+  }
+  else { // Default
+    merit = cur_merit_base * cur_bonus;
+  }
+  
+  // update energy store
+  energy_store += cur_energy_bonus;
+  energy_store = m_world->GetConfig().ENERGY_GIVEN_AT_BIRTH.Get(); // We reset to what they had at birth
+  cur_energy_bonus = 0;
+      // to be perfectly accurate, this should be from a last_energy value??
+
+  
+ // genome_length   = _genome.GetSize();  //No child! @JEB
+  (void) copied_size;          // Unchanged
+  (void) executed_size;        // Unchanged
+  gestation_time  = time_used - gestation_start;  //Keep gestation referring to actual replication time! @JEB
+  gestation_start = time_used;                    //Keep gestation referring to actual replication time! @JEB
+ // fitness         = merit.GetDouble() / gestation_time; //Use fitness measure that is per-trial @JEB
+
+  // Lock in cur values as last values.
+  last_merit_base           = cur_merit_base;
+  last_bonus                = cur_bonus;
+  last_cpu_cycles_used      = cpu_cycles_used;
+//TODO?  last_energy         = cur_energy_bonus;
+  last_num_errors           = cur_num_errors;
+  last_num_donates          = cur_num_donates;
+  last_task_count           = cur_task_count;
+  last_task_quality         = cur_task_quality;
+  last_task_value			= cur_task_value;
+  last_reaction_count       = cur_reaction_count;
+  last_reaction_add_reward  = cur_reaction_add_reward;
+  last_inst_count           = cur_inst_count;
+  last_sense_count          = cur_sense_count;
+
+  // Reset cur values.
+  cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
+  cpu_cycles_used = 0;
+  cur_energy_bonus = 0.0;
+  cur_num_errors  = 0;
+  cur_num_donates  = 0;
+  cur_task_count.SetAll(0);
+  eff_task_count.SetAll(0);
+  cur_task_quality.SetAll(0);
+  cur_task_value.SetAll(0);
+  cur_reaction_count.SetAll(0);
+  cur_reaction_add_reward.SetAll(0);
+  cur_inst_count.SetAll(0);
+  cur_sense_count.SetAll(0);
+  //cur_trial_fitnesses.Resize(0); Don't throw out the tiral fitnesses! @JEB
+  trial_time_used = 0;
+  trial_cpu_cycles_used = 0;
+
+  // Setup other miscellaneous values...
+  num_divides++;
+  (void) generation;
+  (void) time_used;
+  age             = 0;
+  fault_desc      = "";
+  (void) neutral_metric;
+  life_fitness = fitness; 
+
+  num_thresh_gb_donations_last = num_thresh_gb_donations;
+  num_thresh_gb_donations = 0;
+  num_quanta_thresh_gb_donations_last = num_quanta_thresh_gb_donations;
+  num_quanta_thresh_gb_donations = 0;
+
+  // Leave flags alone...
+  (void) is_injected;
+  is_donor_last = is_donor_cur;
+  is_donor_cur = false;
+  is_donor_rand_last = is_donor_rand;
+  is_donor_rand = false;
+  is_donor_null_last = is_donor_null;
+  is_donor_null = false;
+  is_donor_kin_last = is_donor_kin;
+  is_donor_kin = false;
+  is_donor_edit_last = is_donor_edit;
+  is_donor_edit = false;
+  is_donor_gbg_last = is_donor_gbg;
+  is_donor_gbg = false;
+  is_donor_truegb_last = is_donor_truegb;
+  is_donor_truegb = false;
+  is_donor_threshgb_last = is_donor_threshgb;
+  is_donor_threshgb = false;
+  is_donor_quanta_threshgb_last = is_donor_quanta_threshgb;
+  is_donor_quanta_threshgb = false;
+  is_receiver_last = is_receiver;
+  is_receiver = false;
+  is_receiver_rand = false;
+  is_receiver_kin_last = is_receiver_kin;
+  is_receiver_kin = false;
+  is_receiver_edit_last = is_receiver_edit;
+  is_receiver_edit = false;
+  is_receiver_gbg = false;
+  is_receiver_truegb_last = is_receiver_truegb;
+  is_receiver_truegb = false;
+  is_receiver_threshgb_last = is_receiver_threshgb;
+  is_receiver_threshgb = false;
+  is_receiver_quanta_threshgb_last = is_receiver_quanta_threshgb;
+  is_receiver_quanta_threshgb = false;
+  (void) is_modifier;
+  (void) is_modified;
+  (void) is_fertile;
+  (void) is_mutated;
+  (void) is_multi_thread;
+  (void) parent_true;
+  (void) parent_sex;
+  (void) parent_cross_num;
+
+}
+
+/**
+ * This function is run to reset an organism whose task counts (etc) have already been moved from cur to last
+ * by another call (like NewTrial). It is a subset of DivideReset @JEB
+ **/
+ 
+void cPhenotype::TrialDivideReset(const cGenome & _genome)
+{
+  int cur_merit_base = CalcSizeMerit();
+
+  // If we are resetting the current merit, do it here
+  // and it will also be propagated to the child
+  const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
+  if (merit_default_bonus) {
+    merit = cur_merit_base * m_world->GetConfig().DEFAULT_BONUS.Get();
+  }
+  else { // Defaul
+    merit = cur_merit_base * cur_bonus;
+  }
+
+  //BB:TODO update energy store
+  SetEnergy(energy_store + cur_energy_bonus);
+    
+  genome_length   = _genome.GetSize();
+  gestation_start = time_used;
+  cur_trial_fitnesses.Resize(0); 
+  cur_trial_bonuses.Resize(0); 
+  cur_trial_times_used.Resize(0); 
+
+  // Reset child info...
+  (void) copy_true;
+  (void) divide_sex;
+  (void) mate_select_id;
+  (void) cross_num;
+  last_child_fertile = child_fertile;
+  child_fertile     = true;
+  (void) child_copied_size;
+
+  // A few final changes if the parent was supposed to be be considered
+  // a second child on the divide.
+  if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
+    gestation_start = 0;
+    cpu_cycles_used = 0;
+    time_used = 0;
+    neutral_metric += m_world->GetRandom().GetRandNormal();
+    SetupPromoterWeights(_genome, true);
+  }
+
+  if (m_world->GetConfig().GENERATION_INC_METHOD.Get() == GENERATION_INC_BOTH) generation++;
+}
+
 // C O M P A R I S O N    O P E R A T O R S
 
 bool cPhenotype::operator<(const cPhenotype&  rhs) const
@@ -1549,8 +1794,8 @@
   if ( this->GetGestationTime() < rhs.GetGestationTime() )
     return true;
   
-  tArray<int> lhsTasks = this->GetCurTaskCount();
-  tArray<int> rhsTasks = rhs.GetCurTaskCount();
+  tArray<int> lhsTasks = this->GetLastTaskCount();
+  tArray<int> rhsTasks = rhs.GetLastTaskCount();
   for (int k = 0; k < lhsTasks.GetSize(); k++)
     if (lhsTasks[k] < rhsTasks[k])
       return true;
@@ -1566,8 +1811,8 @@
   if ( this->GetGestationTime() != rhs.GetGestationTime() )
     return false;
   
-  tArray<int> lhsTasks = this->GetCurTaskCount();
-  tArray<int> rhsTasks = rhs.GetCurTaskCount();
+  tArray<int> lhsTasks = this->GetLastTaskCount();
+  tArray<int> rhsTasks = rhs.GetLastTaskCount();
   for (int k = 0; k < lhsTasks.GetSize(); k++)
     if (lhsTasks[k] != rhsTasks[k])
       return false;
@@ -1588,8 +1833,8 @@
   if ( this->GetGestationTime() > rhs.GetGestationTime() )
     return true;
   
-  tArray<int> lhsTasks = this->GetCurTaskCount();
-  tArray<int> rhsTasks = rhs.GetCurTaskCount();
+  tArray<int> lhsTasks = this->GetLastTaskCount();
+  tArray<int> rhsTasks = rhs.GetLastTaskCount();
   for (int k = 0; k < lhsTasks.GetSize(); k++)
     if (lhsTasks[k] > rhsTasks[k])
       return true;

Modified: branches/collect/source/main/cPhenotype.h
===================================================================
--- branches/collect/source/main/cPhenotype.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cPhenotype.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -114,7 +114,7 @@
   tArray<int> cur_internal_task_count;        // Total times each task was performed using internal resources
   tArray<int> eff_task_count;                 // Total times each task was performed (resetable during the life of the organism)
   tArray<double> cur_task_quality;            // Average (total?) quality with which each task was performed
-  tArray<double> cur_task_value;			  // Value with which this phenotype performs task
+  tArray<double> cur_task_value;              // Value with which this phenotype performs task
   tArray<double> cur_internal_task_quality;   // Average (total?) quaility with which each task using internal resources was performed
   tArray<double> cur_rbins_total;              // Total amount of resources collected
   tArray<double> cur_rbins_avail;              // Total amount of internal resources available
@@ -129,11 +129,13 @@
   tArray<double> cur_promoter_weights;        // Current of starting execution from each position, adjusted for regulation; @JEB 
   tArray<double> promoter_activation;         // Amount of positive regulation in play at each site; @JEB 
   tArray<double> promoter_repression;         // Amount of negative regulation in play at each site; @JEB 
-  bool promoter_last_inst_terminated;         // Did terminatin occur when executing the last instruction
-  
-
+  bool promoter_last_inst_terminated;         // Did termination occur when executing the last instruction; @JEB
   tHashTable<void*, cTaskState*> m_task_states;
-
+  tArray<double> cur_trial_fitnesses;         // Fitnesses of various trials.; @JEB
+  tArray<double> cur_trial_bonuses;           // Bonuses of various trials.; @JEB
+  tArray<int> cur_trial_times_used;        // Time used in of various trials.; @JEB
+  int trial_time_used;                        // like time_used, but reset every trial; @JEB
+  int trial_cpu_cycles_used;                  // like cpu_cycles_used, but reset every trial; @JEB
   
   // 3. These mark the status of "in progess" variables at the last divide.
   double last_merit_base;         // Either constant or based on genome length.
@@ -153,6 +155,7 @@
   tArray<int> last_inst_count;	  // Instruction exection counter
   tArray<int> last_sense_count;   // Total times resource combinations have been sensed; @JEB 
   double last_fitness;            // Used to determine sterilization.
+  int last_cpu_cycles_used;
 
   // 4. Records from this organism's life...
   int num_divides;       // Total successful divides organism has produced.
@@ -265,6 +268,8 @@
 
   // Some useful methods...
   int CalcSizeMerit() const;
+  double CalcFitness(double _merit_base, double _bonus, int _gestation_time, int _cpu_cycles) const;
+
   double CalcFitnessRatio() {
     const int merit_base = CalcSizeMerit();
     const double cur_fitness = merit_base * cur_bonus / time_used;
@@ -313,6 +318,12 @@
   double GetSensedResource(int _in) { assert(initialized == true); return sensed_resources[_in]; }
   const tArray<cCodeLabel>& GetActiveTransposons() { assert(initialized == true); return active_transposons; }
   const tArray<double>& GetCurPromoterWeights() { assert(initialized == true); return cur_promoter_weights; }
+  
+  void  NewTrial(); //Save the current fitness, and reset the bonus. @JEB
+  void  TrialDivideReset(const cGenome & _genome); //Subset of resets specific to division not done by NewTrial. @JEB
+  const tArray<double>& GetTrialFitnesses() { return cur_trial_fitnesses; }; //Return list of trial fitnesses. @JEB
+  const tArray<double>& GetTrialBonuses() { return cur_trial_bonuses; }; //Return list of trial bonuses. @JEB
+  const tArray<int>& GetTrialTimesUsed() { return cur_trial_times_used; }; //Return list of trial times used. @JEB
 
   double GetLastMeritBase() const { assert(initialized == true); return last_merit_base; }
   double GetLastBonus() const { assert(initialized == true); return last_bonus; }
@@ -455,8 +466,8 @@
   void IncNumQuantaThreshGbDonations() { assert(initialized == true); num_quanta_thresh_gb_donations++; }
 
   void IncAge()      { assert(initialized == true); age++; }
-  void IncCPUCyclesUsed() { assert(initialized == true); cpu_cycles_used++; }
-  void IncTimeUsed(int i=1) { assert(initialized == true); time_used+=i; }
+  void IncCPUCyclesUsed() { assert(initialized == true); cpu_cycles_used++; trial_cpu_cycles_used++; }
+  void IncTimeUsed(int i=1) { assert(initialized == true); time_used+=i; trial_time_used+=i; }
   void IncErrors()   { assert(initialized == true); cur_num_errors++; }
   void IncDonates()   { assert(initialized == true); cur_num_donates++; }
   void IncSenseCount(const int i) { assert(initialized == true); cur_sense_count[i]++; }  

Copied: branches/collect/source/main/cPlasticCPUTestInfo.cc (from rev 1903, development/source/main/cPlasticCPUTestInfo.cc)
===================================================================
--- branches/collect/source/main/cPlasticCPUTestInfo.cc	                        (rev 0)
+++ branches/collect/source/main/cPlasticCPUTestInfo.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -0,0 +1,56 @@
+/*
+ *  cPlasticCPUTestInfo.cpp
+ *  Avida
+ *
+ *  Created by Matthew Rupp on 7/27/07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; version 2
+ *  of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include "cPlasticPhenotype.h"
+
+
+bool cPlasticPhenotype::AddObservation( const cPhenotype& in_phen, const tArray<int>& env_inputs )
+{
+  if (in_phen == *this){
+    if (m_num_observations == 0)
+      m_env_inputs.Resize(1, env_inputs.GetSize());
+    else
+      m_env_inputs.Resize(m_env_inputs.GetNumRows()+1, env_inputs.GetSize());
+    m_env_inputs[m_env_inputs.GetNumRows()-1] = env_inputs;
+    m_num_observations++;
+    return true;
+  }
+  return false;  //Wrong phenotype
+}
+
+bool cPlasticPhenotype::AddObservation( cCPUTestInfo& test_info )
+{
+  tArray<int> env_inputs = test_info.GetTestCPUInputs();
+  cPhenotype& test_phenotype = test_info.GetTestPhenotype();
+  if (test_phenotype == *this ){
+    if (m_num_observations == 0)
+      m_env_inputs.Resize(1, env_inputs.GetSize());
+    else
+      m_env_inputs.Resize(m_env_inputs.GetNumRows()+1, env_inputs.GetSize());
+    m_env_inputs[m_env_inputs.GetNumRows()-1] = env_inputs;
+    m_num_observations++;
+    return true;
+  }
+  return false; //Wrong phenotype
+}

Copied: branches/collect/source/main/cPlasticCPUTestInfo.h (from rev 1903, development/source/main/cPlasticCPUTestInfo.h)
===================================================================
--- branches/collect/source/main/cPlasticCPUTestInfo.h	                        (rev 0)
+++ branches/collect/source/main/cPlasticCPUTestInfo.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -0,0 +1,74 @@
+/*
+ *  cPlasticCPUTestInfo.h
+ *  Avida
+ *
+ *  Created by Matthew Rupp on 7/27/07.
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; version 2
+ *  of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef cPlasticCPUTestInfo
+#define cPlasticCPUTestInfo
+
+
+#include <cassert>
+
+#ifndef cCPUTestInfo_h
+#include "cCPUTestInfo.h"
+#endif
+
+#ifndef cPhenotype_h
+#include "cPhenotype.h"
+#endif
+
+#ifndef tMatrix_h
+#include "tMatrix.h"
+#endif
+
+
+#include <iostream>
+
+class cPlasticPhenotype : public cPhenotype{
+
+  private:
+    int m_num_observations;
+    int m_num_trials;
+    tMatrix<int> m_env_inputs;
+    
+  public:
+      cPlasticPhenotype(cCPUTestInfo& test_info, int num_trials) : 
+      cPhenotype(test_info.GetTestPhenotype()), m_num_observations(1), m_num_trials(num_trials) { assert(m_num_trials > 0); }
+    
+    ~cPlasticPhenotype() { ; }
+    
+    //Modifiers
+    bool AddObservation( const cPhenotype& in_phen, const tArray<int>& env_inputs );
+    bool AddObservation(  cCPUTestInfo& test_info );
+    
+    //Accessors
+    int GetNumObservations() const { return m_num_observations; }
+    int GetNumTrials()       const { return m_num_trials; }
+    double GetFrequency()    const { return static_cast<double>(m_num_observations) / m_num_trials; }
+    tMatrix<int> GetEnvInputs()   const { return m_env_inputs; }
+    
+  
+
+};
+
+#endif
+

Modified: branches/collect/source/main/cPlasticPhenotype.cc
===================================================================
--- branches/collect/source/main/cPlasticPhenotype.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cPlasticPhenotype.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -23,30 +23,20 @@
  */
 
 #include "cPlasticPhenotype.h"
+#include "cCPUMemory.h"
+#include "cOrganism.h"
+#include "cHardwareBase.h"
 
-
-bool cPlasticPhenotype::AddObservation( const cPhenotype& in_phen, const tArray<int>& env_inputs )
-{
-  if (in_phen == *this){
-    if (m_num_observations == 0)
-      m_env_inputs.Resize(1, env_inputs.GetSize());
-    else
-      m_env_inputs.Resize(m_env_inputs.GetNumRows()+1, env_inputs.GetSize());
-    m_env_inputs[m_env_inputs.GetNumRows()-1] = env_inputs;
-    m_num_observations++;
-    return true;
-  }
-  return false;  //Wrong phenotype
-}
-
 bool cPlasticPhenotype::AddObservation( cCPUTestInfo& test_info )
 {
   tArray<int> env_inputs = test_info.GetTestCPUInputs();
   cPhenotype& test_phenotype = test_info.GetTestPhenotype();
   if (test_phenotype == *this ){
-    if (m_num_observations == 0)
+    if (m_num_observations == 0){
       m_env_inputs.Resize(1, env_inputs.GetSize());
-    else
+      SetExecutedFlags(test_info);
+      m_viable = test_info.IsViable();
+    } else
       m_env_inputs.Resize(m_env_inputs.GetNumRows()+1, env_inputs.GetSize());
     m_env_inputs[m_env_inputs.GetNumRows()-1] = env_inputs;
     m_num_observations++;
@@ -54,3 +44,15 @@
   }
   return false; //Wrong phenotype
 }
+
+
+void cPlasticPhenotype::SetExecutedFlags(cCPUTestInfo& test_info)
+{
+  cCPUMemory& cpu_memory = test_info.GetTestOrganism()->GetHardware().GetMemory();
+  cString new_executed_flags;
+  for (int i=0; i<cpu_memory.GetSize(); i++)
+  {
+    new_executed_flags += (cpu_memory.FlagExecuted(i)) ? "+" : "-";
+  }
+  m_executed_flags = new_executed_flags;
+}

Modified: branches/collect/source/main/cPlasticPhenotype.h
===================================================================
--- branches/collect/source/main/cPlasticPhenotype.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cPlasticPhenotype.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -50,9 +50,16 @@
     int m_num_trials;
     tMatrix<int> m_env_inputs;
     
+    //Information retrieved from test_info not available in phenotype
+    cString m_executed_flags;
+    int m_viable;
+    
+    void SetExecutedFlags(cCPUTestInfo& test_info);
+    
   public:
       cPlasticPhenotype(cCPUTestInfo& test_info, int num_trials) : 
-      cPhenotype(test_info.GetTestPhenotype()), m_num_observations(1), m_num_trials(num_trials) { assert(m_num_trials > 0); }
+        cPhenotype(test_info.GetTestPhenotype()), m_num_observations(0), m_num_trials(num_trials) 
+        { assert(m_num_trials > 0); AddObservation(test_info);}
     
     ~cPlasticPhenotype() { ; }
     
@@ -61,11 +68,12 @@
     bool AddObservation(  cCPUTestInfo& test_info );
     
     //Accessors
-    int GetNumObservations() const { return m_num_observations; }
-    int GetNumTrials()       const { return m_num_trials; }
-    double GetFrequency()    const { return static_cast<double>(m_num_observations) / m_num_trials; }
+    int GetNumObservations()      const { return m_num_observations; }
+    int GetNumTrials()            const { return m_num_trials; }
+    double GetFrequency()         const { return static_cast<double>(m_num_observations) / m_num_trials; }
     tMatrix<int> GetEnvInputs()   const { return m_env_inputs; }
-    
+    int IsViable()               const { return m_viable; }
+    cString GetExecutedFlags()    const { return m_executed_flags; }
   
 
 };

Modified: branches/collect/source/main/cPopulation.cc
===================================================================
--- branches/collect/source/main/cPopulation.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cPopulation.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -2747,7 +2747,66 @@
   ActivateOrganism(ctx, new_organism, cell_array[cell_id]);
 }
 
+// This function injects the child genome of an organism into the population at cell_id.
+// Takes care of divide mutations.
+void cPopulation::InjectChild(int cell_id, cOrganism& orig_org)
+{
+  assert(cell_id >= 0 && cell_id < cell_array.GetSize());
+  
+  cAvidaContext& ctx = m_world->GetDefaultContext();
+  
+  // Do mutations on the child genome, but restore it to its current state afterward.
+  cGenome save_child = orig_org.ChildGenome();
+  orig_org.GetHardware().Divide_DoMutations(ctx);
+  
+  tArray<cOrganism*> child_array;
+  tArray<cMerit> merit_array;
+  birth_chamber.SubmitOffspring(ctx, orig_org.ChildGenome(), orig_org, child_array, merit_array);
+    //@JEB may want to force asex for an injected child, sex will mess up CompeteOrganisms
+  assert(child_array.GetSize() == 1);
+  cOrganism * new_organism = child_array[0];
+  orig_org.ChildGenome() = save_child;
+  
+  // Set the genotype...
+  //new_organism->SetGenotype(orig_org.GetGenotype());
 
+  // Setup the phenotype...
+  orig_org.GetPhenotype().SetLinesCopied(new_organism->ChildGenome().GetSize());
+  new_organism->GetPhenotype().SetMerit(merit_array[0]);
+  new_organism->GetPhenotype().SetupOffspring(orig_org.GetPhenotype(), new_organism->GetGenome());
+  
+  // Do lineage tracking for the new organisms.
+  LineageSetupOrganism(new_organism, orig_org.GetLineage(),
+                       orig_org.GetLineageLabel(), orig_org.GetGenotype());
+		
+  //By default, store the parent cclade, this may get modified in ActivateOrgansim (@MRR)
+  new_organism->SetCCladeLabel(orig_org.GetCCladeLabel());
+  
+  // Prep the cell..
+  if (m_world->GetConfig().BIRTH_METHOD.Get() == POSITION_CHILD_FULL_SOUP_ELDEST &&
+      cell_array[cell_id].IsOccupied() == true) {
+    // Have to manually take this cell out of the reaper Queue.
+    reaper_queue.Remove( &(cell_array[cell_id]) );
+  }
+  
+  // Setup the mutation rate based on the population cell...
+  const int mut_source = m_world->GetConfig().MUT_RATE_SOURCE.Get();
+  if (mut_source == 1) {
+    // Update the mutation rates of each child from the environment....
+    new_organism->MutationRates().Copy(cell_array[cell_id].MutationRates());
+  } else {
+    // Update the mutation rates of each child from its parent.
+    new_organism->MutationRates().Copy(orig_org.MutationRates());
+  }
+  
+  // Activate the organism in the population...
+//  cGenotype* child_genotype = new_organism->GetGenotype();
+//  child_genotype->DecDeferAdjust();
+//  m_world->GetClassificationManager().AdjustGenotype(*child_genotype);
+  ActivateOrganism(ctx, new_organism, cell_array[cell_id]);
+}
+
+
 void cPopulation::InjectGenome(int cell_id, const cGenome& genome, int lineage_label)
 {
   // Setup the genotype...
@@ -2898,3 +2957,274 @@
   sleep_log[cellID].RemoveAt(sleep_log[cellID].Size()-1);
   sleep_log[cellID].Add(make_pair(p.first, end_time));
 }
+
+// Starts a new trial for each organism in the population
+void cPopulation::NewTrial()
+{
+  for (int i=0; i< GetSize(); i++)
+  {
+    if (GetCell(i).IsOccupied())
+    {
+      GetCell(i).GetOrganism()->NewTrial();
+      GetCell(i).GetOrganism()->GetHardware().Reset();
+    }
+  }
+  
+  //Recalculate the stats immediately, so that if they are printed before a new update 
+  //is processed, they accurately reflect this trial only...
+  cStats& stats = m_world->GetStats();
+  stats.ProcessUpdate();
+  CalcUpdateStats();
+}
+
+/*
+  CompeteOrganisms
+  
+   parents_survive => for any organism represented by >=1 child, the first created is the parent (has no mutations)
+   dynamic_scaling => rescale the time interval such that the geometric mean of the highest fitness versus lower fitnesses
+                      equals a time of 1 unit
+*/
+
+void cPopulation::CompeteOrganisms(int competition_type, int parents_survive, double scaled_time, int dynamic_scaling)
+{
+  cout << "==Compete Organisms==" << endl;
+  double total_fitness = 0;
+  int num_cells = GetSize();
+  tArray<double> org_fitness(num_cells); 
+
+  double lowest_fitness = -1.0;
+  double highest_fitness = -1.0;
+  double lowest_fitness_copied = -1.0;
+  double highest_fitness_copied = -1.0;
+  int different_orgs_copied = 0;
+  int num_competed_orgs = 0;
+
+  int num_trials = 0;
+  
+  // How many trials were there?
+  for (int i = 0; i < num_cells; i++) 
+  {
+    if (GetCell(i).IsOccupied())
+    { 
+      cPhenotype& p = GetCell(i).GetOrganism()->GetPhenotype();
+      num_trials = p.GetTrialFitnesses().GetSize();
+      break;
+    }
+  }
+  tArray<double> min_trial_fitnesses(num_trials);
+  tArray<double> max_trial_fitnesses(num_trials);
+  tArray<double> bonus_sums(num_trials);
+  bonus_sums.SetAll(0);
+  double max_bonus_sum = -1;
+
+  bool init = false;
+  // What is the min and max fitness in each trial
+  for (int i = 0; i < num_cells; i++) 
+  {
+    if (GetCell(i).IsOccupied())
+    {
+      cPhenotype& p = GetCell(i).GetOrganism()->GetPhenotype();
+      tArray<double> trial_fitnesses = p.GetTrialFitnesses();
+      for (int t=0; t < trial_fitnesses.GetSize(); t++) 
+      { 
+        if ((!init) || (min_trial_fitnesses[t] > trial_fitnesses[t])) min_trial_fitnesses[t] = trial_fitnesses[t];
+        if ((!init) || (max_trial_fitnesses[t] < trial_fitnesses[t])) max_trial_fitnesses[t] = trial_fitnesses[t];
+      }
+      init = true;
+    }
+  }  
+  
+  
+  for (int t=0; t < min_trial_fitnesses.GetSize(); t++) 
+  {
+    cout << "Trial #" << t << " Min Fitness = " << min_trial_fitnesses[t] << " Max Fitness = " << max_trial_fitnesses[t] << endl;
+    //cout << "Bonus sum = " << bonus_sums[t] << endl;
+  }
+  
+  bool using_trials = true;
+  for (int i = 0; i < num_cells; i++) 
+  {
+    if (GetCell(i).IsOccupied())
+    {
+      num_competed_orgs++;
+      double fitness = 0.0;
+      cPhenotype& p = GetCell(i).GetOrganism()->GetPhenotype();
+      //Don't need to reset trial_fitnesses because we will call cPhenotype::OffspringReset on the entire pop
+      tArray<double> trial_fitnesses = p.GetTrialFitnesses();
+      tArray<int> trial_times_used = p.GetTrialTimesUsed();
+
+      //If there are no trial fitnesses...use the actual fitness.
+      if (trial_fitnesses.GetSize() == 0)
+      {
+        using_trials = false;
+        trial_fitnesses.Push(p.GetFitness());
+      }
+      switch (competition_type)
+      {
+        //Arithmetic Mean
+        case 0:
+        fitness = 0;
+        for (int t=0; t < trial_fitnesses.GetSize(); t++) 
+        { 
+          fitness+=trial_fitnesses[t]; 
+        }
+        fitness /= trial_fitnesses.GetSize();
+        break;
+      
+        //Product        
+        case 1:
+        fitness = 1.0;
+        for (int t=0; t < trial_fitnesses.GetSize(); t++) 
+        { 
+          fitness*=trial_fitnesses[t]; 
+        }
+        break;
+      
+        //Geometric Mean        
+        case 2:
+        fitness = 1;
+        for (int t=0; t < trial_fitnesses.GetSize(); t++) 
+        { 
+          fitness*=trial_fitnesses[t]; 
+        }
+        fitness = exp( (1/trial_fitnesses.GetSize()) * log(fitness) );
+        break;
+                         
+        default:
+        cout << "Unknown CompeteOrganisms method!" << endl;
+        exit(1);
+      }
+      if (m_world->GetVerbosity() >= VERBOSE_DETAILS) cout << "Trial fitness in cell " << i << " = " << fitness << endl;
+      //-->Note: Setting fitness here will not print out the value of the last trial's fitness because the makeup of the population is going to change anyway.
+      //It will be printed out correctly only if NewTrial and PrintAverages are called on the same update, before CompeteDemes.
+      //p.SetCurBonus( fitness *  (p.GetTimeUsed() - p.GetGestationStart()) / p.GetCurMeritBase() ); //Indirectly set fitness over all trials...??
+     // p.SetCurBonus( trial_fitnesses[trial_fitnesses.GetSize()-1] *  (p.GetTimeUsed() - p.GetGestationStart()) / p.CalcSizeMerit() ); //Or to last trial
+
+      org_fitness[i] = fitness;
+      total_fitness += fitness;
+      
+      if ((highest_fitness == -1.0) || (fitness > highest_fitness)) highest_fitness = fitness;
+      if ((lowest_fitness == -1.0) || (fitness < lowest_fitness)) lowest_fitness = fitness;
+    } // end if occupied
+  }
+  
+  //Rescale by the geometric mean of the difference from the top score and the median
+  if ( dynamic_scaling )
+  {
+    int num_org_not_max = 0;
+    double dynamic_factor = 0;
+    for (int i = 0; i < num_cells; i++) 
+    {
+      if (GetCell(i).IsOccupied())
+      {
+          if (org_fitness[i] != highest_fitness)
+          {
+            num_org_not_max++;
+            dynamic_factor += log(highest_fitness - org_fitness[i]);
+            //cout << "Time scaling factor " << time_scaling_factor << endl;
+          }
+      }
+    }
+    if (num_org_not_max > 0) scaled_time *= exp ( -(1.0/num_org_not_max) * dynamic_factor );
+  }
+  
+  cout << "Competition time " << scaled_time << " units" << endl;
+  total_fitness = 0;
+  for (int i = 0; i < num_cells; i++) 
+  {
+    if (GetCell(i).IsOccupied())
+    {
+        double fitness = exp(log(2) * scaled_time *  (org_fitness[i] - highest_fitness));
+        org_fitness[i] = fitness;
+        total_fitness += fitness;
+    }
+  }
+  
+   // Pick which orgs should be in the next generation. (Filling all cells)
+  tArray<int> new_orgs(num_cells);
+  for (int i = 0; i < num_cells; i++) {
+    double birth_choice = (double) m_world->GetRandom().GetDouble(total_fitness);
+    double test_total = 0;
+    for (int test_org = 0; test_org < num_cells; test_org++) {
+      test_total += org_fitness[test_org];
+      if (birth_choice < test_total) {
+        new_orgs[i] = test_org;
+        if (m_world->GetVerbosity() >= VERBOSE_DETAILS) cout << "Propagating from cell " << test_org << " to " << i << endl;
+        if ((highest_fitness_copied == -1.0) || (org_fitness[test_org] > highest_fitness_copied)) highest_fitness_copied = org_fitness[test_org];
+        if ((lowest_fitness_copied == -1.0) || (org_fitness[test_org] < lowest_fitness_copied)) lowest_fitness_copied = org_fitness[test_org];
+        break;
+      }
+    }
+  }
+  
+  // Track how many of each org we should have.
+  tArray<int> org_count(num_cells);
+  org_count.SetAll(0);
+  for (int i = 0; i < num_cells; i++) {
+    org_count[new_orgs[i]]++;
+  }
+  
+  // Reset organism phenotypes that have successfully divided! Must do before injecting children.
+  // -- but not the full reset if we are using trials, the trial reset should already cover things like task counts, etc.
+  // calling that twice would erase this information before it could potentially be output between NewTrial and CompeteOrganisms events.
+  for (int i = 0; i < num_cells; i++) {
+    if (org_count[i] > 0) {
+      different_orgs_copied++;
+      cPhenotype& p = GetCell(i).GetOrganism()->GetPhenotype();
+      if (using_trials)
+      {
+        p.TrialDivideReset( GetCell(i).GetOrganism()->GetGenome() );
+      }
+      else //trials not used
+      {
+        //TrialReset has never been called so we need the entire routine to make "last" of "cur" stats.
+        p.DivideReset( GetCell(i).GetOrganism()->GetGenome() );
+      }
+    }
+  }
+  
+  tArray<bool> is_init(num_cells); 
+  is_init.SetAll(false);
+  
+  // Copy orgs until all org counts are 1.
+  while (true) {
+    // Find the next org to copy...
+    int from_cell_id, to_cell_id;
+    for (from_cell_id = 0; from_cell_id < num_cells; from_cell_id++) {
+      if (org_count[from_cell_id] > 1) break;
+    }
+    
+    // Stop If we didn't find another org to copy
+    if (from_cell_id == num_cells) break;
+    
+    for (to_cell_id = 0; to_cell_id < num_cells; to_cell_id++) {
+      if (org_count[to_cell_id] == 0) break;
+    }
+    
+    // We now have both a from and a to org....
+    org_count[from_cell_id]--;
+    org_count[to_cell_id]++;
+    
+    cOrganism * organism = GetCell(from_cell_id).GetOrganism();
+    organism->ChildGenome() = organism->GetGenome();
+    InjectChild( to_cell_id, *organism );    
+    
+    is_init[to_cell_id] = true;
+  }
+
+  if (!parents_survive)
+  {
+    // Now create children from remaining cells into themselves
+    for (int cell_id = 0; cell_id < num_cells; cell_id++) {
+      if (is_init[cell_id] == true) continue;
+      cOrganism * organism = GetCell(cell_id).GetOrganism();
+      organism->ChildGenome() = organism->GetGenome();
+      InjectChild( cell_id, *organism ); 
+    }
+  }
+  
+  cout << "Competed: Min fitness = " << lowest_fitness << ", Max fitness = " << highest_fitness << endl;
+  cout << "Copied  : Min fitness = " << lowest_fitness_copied << ", Max fitness = " << highest_fitness_copied << " (scaled to Max = 1.0)" << endl;
+  cout << "Copied  : Different organisms = " << different_orgs_copied << endl;
+
+}

Modified: branches/collect/source/main/cPopulation.h
===================================================================
--- branches/collect/source/main/cPopulation.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cPopulation.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -135,6 +135,7 @@
   void InjectGenotype(int cell_id, cGenotype* genotype);
   void InjectGenome(int cell_id, const cGenome& genome, int lineage_label);
   void InjectClone(int cell_id, cOrganism& orig_org);
+  void InjectChild(int cell_id, cOrganism& orig_org);
 
   void LineageSetupOrganism(cOrganism* organism, cLineage* lineage, int lin_label, cGenotype* parent_genotype = NULL);
   void CCladeSetupOrganism(cOrganism* organism); 
@@ -243,6 +244,10 @@
   void AddEndSleep(int cellID, int end_time);
  
   tVector<pair<int,int> > getCellSleepLog(int i) { return sleep_log[i]; }
+
+  // Trials and genetic algorithm @JEB
+  void NewTrial();
+  void CompeteOrganisms(int competition_type, int parents_survive, double scaled_time, int dynamic_scaling);
 };
 
 

Modified: branches/collect/source/main/cReactionProcess.h
===================================================================
--- branches/collect/source/main/cReactionProcess.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cReactionProcess.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -55,6 +55,9 @@
   bool lethal;		 // Lethality of reaction
   cString match_string;	 // Bit string to match if this is a match string reaction
   int inst_id;           // Instruction to be triggered if reaction successful.
+  bool depletable;       // Does completing consume resource?
+                         // (This is not quite redundant with an infinite resource
+                         // because it allows the resource level to be sensed @JEB)
 
   // Resource detection
   cResource * detect;    // Resource Measured
@@ -77,6 +80,7 @@
     , conversion(1.0)
     , lethal(0)
     , inst_id(-1)
+    , depletable(true)
     , detect(NULL)
     , detection_threshold(0.0)
     , detection_error(0.0)
@@ -93,6 +97,7 @@
   cResource* GetProduct() const { return product; }
   double GetConversion() const { return conversion; }
   int GetInstID() const { return inst_id; }
+  bool GetDepletable() const { return depletable; }
   bool GetLethal() const { return lethal; }
   cResource* GetDetect() const { return detect; }
   double GetDetectionThreshold() const { return detection_threshold; }
@@ -108,6 +113,7 @@
   void SetProduct(cResource* _in) { product = _in; }
   void SetConversion(double _in) { conversion = _in; }
   void SetInstID(int _in) { inst_id = _in; }
+  void SetDepletable(bool _in) { depletable = _in; }
   void SetLethal(int _in) { lethal = _in; }
   void SetDetect(cResource* _in) { detect = _in; }
   void SetDetectionThreshold(double _in) { detection_threshold = _in; }

Modified: branches/collect/source/main/cTaskLib.cc
===================================================================
--- branches/collect/source/main/cTaskLib.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/cTaskLib.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -2260,8 +2260,8 @@
     {
       double sum = 0;
       //      cout << "9x: " << vars[0] << " ";
-      for (int i=1; i<5; i++)
-	sum += vars[i]/4.0;
+      for (int i=1; i<args.GetInt(3); i++)
+		  sum += vars[i]/double(args.GetInt(3)-1);
       double Gx = 1+9*sum;
       Fx = Gx * (1.0 - sqrt(vars[0]/Gx));
       break;
@@ -2270,8 +2270,8 @@
     case 10:
     {
       double sum = 0;
-      for (int i=1; i<5; i++)
-	sum += vars[i]/4.0;
+      for (int i=1; i<args.GetInt(3); i++)
+		  sum += vars[i]/double(args.GetInt(3)-1);
       double Gx = 1+9*sum;
       Fx = Gx * (1.0 - pow(vars[0]/Gx, 2.0));
       break;
@@ -2280,8 +2280,8 @@
     case 11:
     {
       double sum = 0;
-      for (int i=1; i<5; i++)
-	sum += vars[i]/4.0;
+      for (int i=1; i<args.GetInt(3); i++)
+		  sum += vars[i]/double(args.GetInt(3)-1);
       double Gx = 1+9*sum;
       Fx = Gx * (1 - sqrt(vars[0]/Gx) - (vars[0]/Gx)*(sin(3.14159*vars[0]*10)));
       break;

Modified: branches/collect/source/main/nReaction.h
===================================================================
--- branches/collect/source/main/nReaction.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/main/nReaction.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -31,7 +31,8 @@
     PROCTYPE_MULT,
     PROCTYPE_POW,
     PROCTYPE_LIN,
-    PROCTYPE_ENERGY
+    PROCTYPE_ENERGY,
+    PROCTYPE_ENZYME
   };
 }
 

Modified: branches/collect/source/tools/cStringList.cc
===================================================================
--- branches/collect/source/tools/cStringList.cc	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/tools/cStringList.cc	2007-08-28 16:09:11 UTC (rev 2020)
@@ -87,6 +87,14 @@
   return "";
 }
 
+cString cStringList::PopLine(int line_num)
+{
+  tListIterator<cString> string_it(string_list);
+  string_it.Next();
+  for (int k = 0; k < line_num && string_it.Next(); k++);
+  return ReturnString(string_list.Remove(string_it));
+}
+
 int cStringList::LocateString(const cString & test_string) const
 {
   tConstListIterator<cString> string_it(string_list);

Modified: branches/collect/source/tools/cStringList.h
===================================================================
--- branches/collect/source/tools/cStringList.h	2007-08-28 02:52:55 UTC (rev 2019)
+++ branches/collect/source/tools/cStringList.h	2007-08-28 16:09:11 UTC (rev 2020)
@@ -69,6 +69,7 @@
 
   bool HasString(const cString & test_string) const;
   cString PopString(const cString & test_string);
+  cString PopLine(int);
   int LocateString(const cString& test_string) const;
   
   void Push(const cString & _in) { string_list.Push(new cString(_in));}




More information about the Avida-cvs mailing list