[Avida-SVN] r1973 - in development: Avida.xcodeproj documentation source/actions source/classification source/cpu source/main

beckma24 at myxo.css.msu.edu beckma24 at myxo.css.msu.edu
Tue Aug 21 10:01:36 PDT 2007


Author: beckma24
Date: 2007-08-21 13:01:36 -0400 (Tue, 21 Aug 2007)
New Revision: 1973

Modified:
   development/Avida.xcodeproj/project.pbxproj
   development/documentation/environment.html
   development/source/actions/PopulationActions.cc
   development/source/actions/PrintActions.cc
   development/source/classification/cClassificationManager.cc
   development/source/cpu/cHardwareBase.cc
   development/source/cpu/cHardwareBase.h
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/main/cAvidaConfig.h
   development/source/main/cDeme.cc
   development/source/main/cDeme.h
   development/source/main/cEnvironment.cc
   development/source/main/cOrganism.cc
   development/source/main/cPhenotype.cc
   development/source/main/cPhenotype.h
   development/source/main/cPopulation.cc
   development/source/main/cPopulation.h
   development/source/main/cPopulationCell.cc
   development/source/main/cPopulationCell.h
   development/source/main/cResource.cc
   development/source/main/cResource.h
   development/source/main/cWorld.cc
Log:
Merging current version of energy branch into development

Added:
- Instructions that allow organsism to half/double their execution speed
- FRAC_ENERGY_TRANSFER - allows new organism to consume energy in organism being replaced
- Instruction to donate energy to neighbor
- Divided PrintDemeStats in to multiple subfunctions and added print actions to for sum of those functions
- Incorporated energy model into ReplicateDemes

Removed:
- Out-of-date energy_deme_level_res test


Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/Avida.xcodeproj/project.pbxproj	2007-08-21 17:01:36 UTC (rev 1973)
@@ -210,6 +210,23 @@
 		};
 /* End PBXBuildRule section */
 
+/* Begin PBXBuildStyle section */
+		B5029AA90C6B83D600D10480 /* Development */ = {
+			isa = PBXBuildStyle;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			name = Development;
+		};
+		B5029AAA0C6B83D600D10480 /* Deployment */ = {
+			isa = PBXBuildStyle;
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			name = Deployment;
+		};
+/* End PBXBuildStyle section */
+
 /* Begin PBXContainerItemProxy section */
 		56F555DA0C3B36FC00E2E929 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
@@ -1765,6 +1782,12 @@
 		DCC30C4D0762532C008F7A48 /* Project object */ = {
 			isa = PBXProject;
 			buildConfigurationList = 702442D70859E0B00059BD9B /* Build configuration list for PBXProject "Avida" */;
+			buildSettings = {
+			};
+			buildStyles = (
+				B5029AA90C6B83D600D10480 /* Development */,
+				B5029AAA0C6B83D600D10480 /* Deployment */,
+			);
 			hasScannedForEncodings = 0;
 			mainGroup = DCC30C490762532C008F7A48;
 			productRefGroup = DCC3164E07626CF3008F7A48 /* Products */;

Modified: development/documentation/environment.html
===================================================================
--- development/documentation/environment.html	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/documentation/environment.html	2007-08-21 17:01:36 UTC (rev 1973)
@@ -133,6 +133,17 @@
   </td>
 </tr>
 <tr>
+  <td class="resall">energy</td>
+  <td>
+    Is this an energy resource. Currently, only implemented for
+    spacial resources, and the energy model must be used.
+    (<em>True</em> or <em>False</em>)
+  </td>
+  <td>
+    false
+  </td>
+</tr>
+<tr>
   <td class="resspatial">inflowx1</td>
   <td>
     Leftmost coordinate of the rectangle where resource will flow

Modified: development/source/actions/PopulationActions.cc
===================================================================
--- development/source/actions/PopulationActions.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/actions/PopulationActions.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -473,32 +473,42 @@
 class cActionInjectDemes : public cAction
 {
 private:
-	cString m_filename;
-	double m_merit;
-	int m_lineage_label;
-	double m_neutral_metric;
+  cString m_filename;
+  double m_merit;
+  int m_lineage_label;
+  double m_neutral_metric;
 public:
-		cActionInjectDemes(cWorld* world, const cString& args) : cAction(world, args), m_merit(-1), m_lineage_label(0), m_neutral_metric(0)
-	{
-			cString largs(args);
-			if (!largs.GetSize()) m_filename = "START_CREATURE"; else m_filename = largs.PopWord();
-			if (largs.GetSize()) m_merit = largs.PopWord().AsDouble();
-			if (largs.GetSize()) m_lineage_label = largs.PopWord().AsInt();
-			if (largs.GetSize()) m_neutral_metric = largs.PopWord().AsDouble();
-			if (m_filename == "START_CREATURE") m_filename = m_world->GetConfig().START_CREATURE.Get();
-	}
-	
-	static const cString GetDescription() { return "Arguments: [string fname=\"START_CREATURE\"] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]"; }
-	
-	void Process(cAvidaContext& ctx)
-	{
-		cGenome genome = cGenomeUtil::LoadGenome(m_filename, m_world->GetHardwareManager().GetInstSet());
-		for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
-			m_world->GetPopulation().Inject(genome,
-                                      m_world->GetPopulation().GetDeme(i).GetCellID(0),
-                                      m_merit, m_lineage_label, m_neutral_metric);
-		}
-	}
+    cActionInjectDemes(cWorld* world, const cString& args) : cAction(world, args), m_merit(-1), m_lineage_label(0), m_neutral_metric(0)
+  {
+      cString largs(args);
+      if (!largs.GetSize()) m_filename = "START_CREATURE"; else m_filename = largs.PopWord();
+      if (largs.GetSize()) m_merit = largs.PopWord().AsDouble();
+      if (largs.GetSize()) m_lineage_label = largs.PopWord().AsInt();
+      if (largs.GetSize()) m_neutral_metric = largs.PopWord().AsDouble();
+      if (m_filename == "START_CREATURE") m_filename = m_world->GetConfig().START_CREATURE.Get();
+  }
+  
+  static const cString GetDescription() { return "Arguments: [string fname=\"START_CREATURE\"] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]"; }
+  
+  void Process(cAvidaContext& ctx)
+  {
+    cGenome genome = cGenomeUtil::LoadGenome(m_filename, m_world->GetHardwareManager().GetInstSet());
+    if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
+      for(int i=1; i<m_world->GetPopulation().GetNumDemes(); ++i) {  // first org has already been injected
+        m_world->GetPopulation().Inject(genome,
+                                        m_world->GetPopulation().GetDeme(i).GetCellID(0),
+                                        m_merit, m_lineage_label, m_neutral_metric);
+      }
+    } else {
+      for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+        // WARNING: initial ancestor has already be injected into the population
+        //           calling this will overwrite it.
+        m_world->GetPopulation().Inject(genome,
+                                        m_world->GetPopulation().GetDeme(i).GetCellID(0),
+                                        m_merit, m_lineage_label, m_neutral_metric);
+      }
+    }
+  }
 };
 
 

Modified: development/source/actions/PrintActions.cc
===================================================================
--- development/source/actions/PrintActions.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/actions/PrintActions.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -2365,20 +2365,72 @@
   }
 };
 
-class cActionPrintDemeStats : public cAction
+class cActionPrintDemeAllStats : public cAction
 {
 public:
-  cActionPrintDemeStats(cWorld* world, const cString& args) : cAction(world, args) { ; }
+  cActionPrintDemeAllStats(cWorld* world, const cString& args) : cAction(world, args) { ; }
   
   static const cString GetDescription() { return "No Arguments"; }
   
   void Process(cAvidaContext& ctx)
   {
-    m_world->GetPopulation().PrintDemeStats();
+    m_world->GetPopulation().PrintDemeAllStats();
   }
 };
 
+class cActionPrintDemeDonorStats : public cAction
+{
+public:
+  cActionPrintDemeDonorStats(cWorld* world, const cString& args) : cAction(world, args) { ; }
+  
+  static const cString GetDescription() { return "No Arguments"; }
+  
+  void Process(cAvidaContext& ctx)
+  {
+    m_world->GetPopulation().PrintDemeDonor();
+  }
+};
 
+
+class cActionPrintDemeSpacialEnergy : public cAction
+{
+public:
+  cActionPrintDemeSpacialEnergy(cWorld* world, const cString& args) : cAction(world, args) { ; }
+  
+  static const cString GetDescription() { return "No Arguments"; }
+  
+  void Process(cAvidaContext& ctx)
+  {
+    m_world->GetPopulation().PrintDemeSpatialEnergyData();
+  }
+};
+
+class cActionPrintDemeSpacialSleep : public cAction
+{
+public:
+  cActionPrintDemeSpacialSleep(cWorld* world, const cString& args) : cAction(world, args) { ; }
+  
+  static const cString GetDescription() { return "No Arguments"; }
+  
+  void Process(cAvidaContext& ctx)
+  {
+    m_world->GetPopulation().PrintDemeSpatialSleepData();
+  }
+};
+
+class cActionPrintDemeResources : public cAction
+{
+public:
+  cActionPrintDemeResources(cWorld* world, const cString& args) : cAction(world, args) { ; }
+  
+  static const cString GetDescription() { return "No Arguments"; }
+  
+  void Process(cAvidaContext& ctx)
+  {
+    m_world->GetPopulation().PrintDemeResource();
+  }
+};
+
 class cActionSetVerbose : public cAction
 {
 private:
@@ -2453,8 +2505,15 @@
   // Population Out Files
   action_lib->Register<cActionPrintPhenotypeData>("PrintPhenotypeData");
   action_lib->Register<cActionPrintPhenotypeStatus>("PrintPhenotypeStatus");
-  action_lib->Register<cActionPrintDemeStats>("PrintDemeStats");
-	
+  
+  // deme output files
+  action_lib->Register<cActionPrintDemeAllStats>("PrintDemeAllStats");
+  action_lib->Register<cActionPrintDemeAllStats>("PrintDemeStats"); //duplicate of previous
+  action_lib->Register<cActionPrintDemeDonorStats>("PrintDemeDonorStats");
+  action_lib->Register<cActionPrintDemeSpacialEnergy>("PrintDemeSpacialEnergyStats");
+  action_lib->Register<cActionPrintDemeSpacialSleep>("PrintDemeSpacialSleepStats");
+  action_lib->Register<cActionPrintDemeResources>("PrintDemeResourceStats");
+
   //Coalescence Clade Actions
   action_lib->Register<cActionPrintCCladeCounts>("PrintCCladeCounts");
   action_lib->Register<cActionPrintCCladeFitnessHistogram>("PrintCCladeFitnessHistogram");
@@ -2526,7 +2585,7 @@
   action_lib->Register<cActionPrintPhenotypeData>("print_number_phenotypes");
   action_lib->Register<cActionPrintPhenotypeStatus>("print_phenotype_status");
   action_lib->Register<cActionPrintDonationStats>("print_donation_stats");
-  action_lib->Register<cActionPrintDemeStats>("print_deme_stats");
+  action_lib->Register<cActionPrintDemeAllStats>("print_deme_stats");
   
   action_lib->Register<cActionPrintData>("print_data");
   action_lib->Register<cActionPrintInstructionAbundanceHistogram>("print_instruction_abundance_histogram");

Modified: development/source/classification/cClassificationManager.cc
===================================================================
--- development/source/classification/cClassificationManager.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/classification/cClassificationManager.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -938,7 +938,7 @@
   // when a creature is added to this lineage
   m_lineage_list.push_back(new_lineage);  
   m_world->GetStats().AddLineage();
-  
+
   return new_lineage;
 }
 

Modified: development/source/cpu/cHardwareBase.cc
===================================================================
--- development/source/cpu/cHardwareBase.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/cpu/cHardwareBase.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -816,6 +816,17 @@
   return false;
 }
 
+bool cHardwareBase::Inst_DoubleEnergyUsage(cAvidaContext& ctx) {
+  organism->GetPhenotype().DoubleEnergyUsage();
+  return true;
+}
+
+bool cHardwareBase::Inst_HalfEnergyUsage(cAvidaContext& ctx) {
+  organism->GetPhenotype().HalfEnergyUsage();
+  return true;
+}
+
+
 // This method will test to see if all costs have been paid associated
 // with executing an instruction and only return true when that instruction
 // should proceed.
@@ -827,7 +838,7 @@
   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;

Modified: development/source/cpu/cHardwareBase.h
===================================================================
--- development/source/cpu/cHardwareBase.h	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/cpu/cHardwareBase.h	2007-08-21 17:01:36 UTC (rev 1973)
@@ -184,6 +184,10 @@
   // -------- Implicit Repro Check/Instruction -------- @JEB
   void CheckImplicitRepro(cAvidaContext& ctx, bool exec_last_inst = false);
   virtual bool Inst_Repro(cAvidaContext& ctx);
+
+  // --------  Execution Speed Instruction --------
+  bool Inst_DoubleEnergyUsage(cAvidaContext& ctx);
+  bool Inst_HalfEnergyUsage(cAvidaContext& ctx);
 };
 
 

Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/cpu/cHardwareCPU.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -210,12 +210,16 @@
     tInstLibEntry<tMethod>("donate-threshgb",  &cHardwareCPU::Inst_DonateThreshGreenBeard),
     tInstLibEntry<tMethod>("donate-quantagb",  &cHardwareCPU::Inst_DonateQuantaThreshGreenBeard),
     tInstLibEntry<tMethod>("donate-NUL", &cHardwareCPU::Inst_DonateNULL),
-
+    tInstLibEntry<tMethod>("donate-facing", &cHardwareCPU::Inst_DonateFacing),
+    
     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-left-one", &cHardwareCPU::Inst_RotateLeftOne),
+    tInstLibEntry<tMethod>("rotate-right-one", &cHardwareCPU::Inst_RotateRightOne),
+
     tInstLibEntry<tMethod>("rotate-label", &cHardwareCPU::Inst_RotateLabel),
     
     tInstLibEntry<tMethod>("set-cmut", &cHardwareCPU::Inst_SetCopyMut),
@@ -358,6 +362,10 @@
     tInstLibEntry<tMethod>("promoter", &cHardwareCPU::Inst_Promoter),
     tInstLibEntry<tMethod>("decay-reg", &cHardwareCPU::Inst_DecayRegulation),
     
+    // Energy usage
+    tInstLibEntry<tMethod>("double-energy-usage", &cHardwareCPU::Inst_DoubleEnergyUsage),
+    tInstLibEntry<tMethod>("half-energy-usage", &cHardwareCPU::Inst_HalfEnergyUsage),
+    
     // Placebo instructions
     tInstLibEntry<tMethod>("skip", &cHardwareCPU::Inst_Skip),
 
@@ -3093,6 +3101,45 @@
   to_org->UpdateMerit(other_merit);
 }
 
+void cHardwareCPU::DoEnergyDonate(cOrganism* to_org)
+{
+  assert(to_org != NULL);
+
+  const double frac_energy_given = m_world->GetConfig().MERIT_GIVEN.Get();
+
+  double cur_energy = organism->GetPhenotype().GetStoredEnergy();
+  double energy_given = cur_energy * frac_energy_given;
+  
+  //update energy store and merit of donor
+  organism->GetPhenotype().ReduceEnergy(energy_given);
+  double senderMerit = cMerit::EnergyToMerit(organism->GetPhenotype().GetStoredEnergy(), m_world) * organism->GetPhenotype().GetExecutionRatio();
+  organism->UpdateMerit(senderMerit);
+  
+  // update energy store and merit of donee
+  to_org->GetPhenotype().ReduceEnergy(-1.0*energy_given);
+  double receiverMerit = cMerit::EnergyToMerit(to_org->GetPhenotype().GetStoredEnergy(), m_world) * to_org->GetPhenotype().GetExecutionRatio();
+  to_org->UpdateMerit(receiverMerit);
+}
+
+bool cHardwareCPU::Inst_DonateFacing(cAvidaContext& ctx) {
+  if (organism->GetPhenotype().GetCurNumDonates() > m_world->GetConfig().MAX_DONATES.Get()) {
+    return false;
+  }
+  organism->GetPhenotype().IncDonates();
+  organism->GetPhenotype().SetIsDonorRand();
+
+  // Get faced neighbor
+  cOrganism * neighbor = organism->GetNeighbor();
+  
+  // Donate only if we have found a neighbor.
+  if (neighbor != NULL) {
+    DoEnergyDonate(neighbor);
+    
+    neighbor->GetPhenotype().SetIsReceiver();
+  }
+  return true;
+}
+
 bool cHardwareCPU::Inst_DonateRandom(cAvidaContext& ctx)
 {
   
@@ -3667,6 +3714,18 @@
   return true;
 }
 
+bool cHardwareCPU::Inst_RotateLeftOne(cAvidaContext& ctx)
+{
+  organism->Rotate(-1);
+  return true;
+}
+
+bool cHardwareCPU::Inst_RotateRightOne(cAvidaContext& ctx)
+{
+  organism->Rotate(1);
+  return true;
+}
+
 /**
   Rotate to facing specified by following label
 */
@@ -4167,7 +4226,8 @@
   if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 2) {
     organism->GetPhenotype().RefreshEnergy();
     organism->GetPhenotype().ApplyToEnergyStore();
-    pop.UpdateMerit(organism->GetCellID(), cMerit::EnergyToMerit(organism->GetPhenotype().GetStoredEnergy(), m_world));
+    double newMerit = cMerit::EnergyToMerit(organism->GetPhenotype().GetStoredEnergy(), m_world) * organism->GetPhenotype().GetExecutionRatio();
+    pop.UpdateMerit(organism->GetCellID(), newMerit);
   }
   return true;
 }

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/cpu/cHardwareCPU.h	2007-08-21 17:01:36 UTC (rev 1973)
@@ -427,6 +427,7 @@
   bool DoSense(cAvidaContext& ctx, int conversion_method, double base);
 
   void DoDonate(cOrganism * to_org);
+  void DoEnergyDonate(cOrganism* to_org);
   bool Inst_DonateRandom(cAvidaContext& ctx);
   bool Inst_DonateKin(cAvidaContext& ctx);
   bool Inst_DonateEditDist(cAvidaContext& ctx);
@@ -435,6 +436,7 @@
   bool Inst_DonateThreshGreenBeard(cAvidaContext& ctx);
   bool Inst_DonateQuantaThreshGreenBeard(cAvidaContext& ctx);
   bool Inst_DonateNULL(cAvidaContext& ctx);
+  bool Inst_DonateFacing(cAvidaContext& ctx);
 
   bool Inst_SearchF(cAvidaContext& ctx);
   bool Inst_SearchB(cAvidaContext& ctx);
@@ -447,6 +449,8 @@
 
   bool Inst_RotateL(cAvidaContext& ctx);
   bool Inst_RotateR(cAvidaContext& ctx);
+  bool Inst_RotateLeftOne(cAvidaContext& ctx);
+  bool Inst_RotateRightOne(cAvidaContext& ctx);
   bool Inst_RotateLabel(cAvidaContext& ctx);
   bool Inst_SetCopyMut(cAvidaContext& ctx);
   bool Inst_ModCopyMut(cAvidaContext& ctx);

Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cAvidaConfig.h	2007-08-21 17:01:36 UTC (rev 1973)
@@ -445,6 +445,7 @@
   CONFIG_ADD_VAR(NUM_INST_EXC_BEFORE_0_ENERGY, int, 0, "Number of instructions executed before energy is exhausted.");
   CONFIG_ADD_VAR(ENERGY_CAP, int, -1, "Maximum amount of energy that can be stored in an organism.  -1 means the cap is set to Max Int");  // TODO - is this done?
   CONFIG_ADD_VAR(APPLY_ENERGY_METHOD, int, 0, "When should rewarded energy be applied to current energy?\n0 = on divide\n1 = on completion of task\n2 = on sleep");  
+  CONFIG_ADD_VAR(FRAC_ENERGY_TRANSFER, double, 0.0, "Fraction of replaced organism's energy take by new resident");
 //  CONFIG_ADD_VAR(ENERGY_VERBOSE, bool, 0, "Print energy and merit values. 0/1 (off/on)");
   CONFIG_ADD_VAR(LOG_SLEEP_TIMES, bool, 0, "Log sleep start and end times. 0/1 (off/on)\nWARNING: may use lots of memory.");
   //  CONFIG_ADD_VAR(FIX_METABOLIC_RATE, bool, 0, "When activated the metabolic rate of all orgiansims are equal. 0/1 (off/on)"); // TODO - check for correctness

Modified: development/source/main/cDeme.cc
===================================================================
--- development/source/main/cDeme.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cDeme.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -22,6 +22,7 @@
  */
 
 #include "cDeme.h"
+#include "cPopulationCell.h"
 #include "cResource.h"
 
 
@@ -34,6 +35,8 @@
   // If width is negative, set it to the full number of cells.
   width = in_width;
   if (width < 1) width = cell_ids.GetSize();
+  
+  // drain spacial energy resources and place energy in cells
 }
 
 
@@ -51,10 +54,10 @@
 monotonically increasing order!! */
 std::pair<int, int> cDeme::GetCellPosition(int cellid) const 
 {
-	assert(cell_ids.GetSize()>0);
+  assert(cell_ids.GetSize()>0);
   assert(GetWidth() > 0);
-	cellid -= cell_ids[0];
-	return std::make_pair(cellid % GetWidth(), cellid / GetWidth());
+  cellid -= cell_ids[0];
+  return std::make_pair(cellid % GetWidth(), cellid / GetWidth());
 }
 
 
@@ -62,6 +65,8 @@
 {
   birth_count = 0; 
   _age = 0;
+  //clear cell energy
+  
   deme_resource_count.ReinitializeResources();
 }
 
@@ -77,7 +82,7 @@
 
 void cDeme::ModifyDemeResCount(const tArray<double> & res_change, const int absolute_cell_id) {
   // find relative cell_id in deme resource count
-  const int relative_cell_id = absolute_cell_id % GetSize();  //assumes all demes are the same size
+  const int relative_cell_id = GetRelativeCellID(absolute_cell_id);
   deme_resource_count.ModifyCell(res_change, relative_cell_id);
 }
 
@@ -95,4 +100,44 @@
                            res->GetOutflowX2(), res->GetOutflowY1(), 
                            res->GetOutflowY2(), res->GetCellListPtr(),
                            verbosity);
+                           
+  if(res->GetEnergyResource()) {
+    energy_res_ids.Push(id);
+  }
 }
+
+double cDeme::GetAndClearCellEnergy(int absolute_cell_id) {
+  assert(cell_ids[0] <= absolute_cell_id);
+  assert(absolute_cell_id <= cell_ids[cell_ids.GetSize()-1]);
+
+  double total_energy = 0.0;
+  int relative_cell_id = GetRelativeCellID(absolute_cell_id);
+  tArray<double> cell_resources = deme_resource_count.GetCellResources(relative_cell_id);
+
+  // sum all energy resources
+  for(int i = 0; i < energy_res_ids.GetSize(); i++) {
+    if(cell_resources[energy_res_ids[i]] > 0.0) {
+      total_energy += cell_resources[energy_res_ids[i]];
+      cell_resources[energy_res_ids[i]] *= -1.0;
+    }
+  }
+  // set energy resources to zero
+  deme_resource_count.ModifyCell(cell_resources, relative_cell_id);
+  return total_energy;
+}
+
+void cDeme::GiveBackCellEnergy(int absolute_cell_id, double value) {
+  assert(cell_ids[0] <= absolute_cell_id);
+  assert(absolute_cell_id <= cell_ids[cell_ids.GetSize()-1]);
+
+  int relative_cell_id = GetRelativeCellID(absolute_cell_id);
+  tArray<double> cell_resources = deme_resource_count.GetCellResources(relative_cell_id);
+
+  double amount_per_resource = value / energy_res_ids.GetSize();
+  
+  // put back energy resources evenly
+  for(int i = 0; i < energy_res_ids.GetSize(); i++) {
+    cell_resources[energy_res_ids[i]] += amount_per_resource;
+  }
+  deme_resource_count.ModifyCell(cell_resources, relative_cell_id);
+}

Modified: development/source/main/cDeme.h
===================================================================
--- development/source/main/cDeme.h	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cDeme.h	2007-08-21 17:01:36 UTC (rev 1973)
@@ -49,6 +49,7 @@
   cDeme(const cDeme&); // @not_implemented
   
   cResourceCount deme_resource_count; //!< Resources available to the deme
+  tArray<int> energy_res_ids; //!< IDs of energy resources
   
 public:
   cDeme() : width(0), birth_count(0), org_count(0), _age(0), deme_resource_count(0) { ; }
@@ -93,9 +94,12 @@
   void SetDemeResourceCount(const cResourceCount in_res) { deme_resource_count = in_res; }
   void ResizeSpatialGrids(const int in_x, const int in_y) { deme_resource_count.ResizeSpatialGrids(in_x, in_y); }
   void ModifyDemeResCount(const tArray<double> & res_change, const int absolute_cell_id);
+  double GetAndClearCellEnergy(int absolute_cell_id);
+  void GiveBackCellEnergy(int absolute_cell_id, double value);
   void SetupDemeRes(int id, cResource * res, int verbosity);
   void UpdateDemeRes() { deme_resource_count.GetResources(); }
   void Update(double time_step) { deme_resource_count.Update(time_step); }
+  int GetRelativeCellID(int absolute_cell_id) { return absolute_cell_id % GetSize(); } //!< assumes all demes are the same size
 };
 
 #endif

Modified: development/source/main/cEnvironment.cc
===================================================================
--- development/source/main/cEnvironment.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cEnvironment.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -396,6 +396,15 @@
           return false;
         }
       }
+      else if (var_name == "energy") {
+        if (!new_resource->SetEnergyResource( var_value )) {
+          cerr << "Error: In " << var_type << "," << var_value <<
+          " must be true or false" << endl;
+          return false;
+        } else if(m_world->GetConfig().ENERGY_ENABLED.Get() == 0) {
+          cerr <<"Error: Energy resources can not be used without the energy model.\n";
+        }
+      }
       else {
         cerr << "Error: Unknown variable '" << var_name
         << "' in resource '" << name << "'" << endl;

Modified: development/source/main/cOrganism.cc
===================================================================
--- development/source/main/cOrganism.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cOrganism.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -243,7 +243,7 @@
   if(m_world->GetConfig().ENERGY_ENABLED.Get() && m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 1 && task_completed) {
     m_phenotype.RefreshEnergy();
     m_phenotype.ApplyToEnergyStore();
-    double newMerit = cMerit::EnergyToMerit(GetPhenotype().GetStoredEnergy(), m_world);
+    double newMerit = cMerit::EnergyToMerit(GetPhenotype().GetStoredEnergy(), m_world) * GetPhenotype().GetExecutionRatio();
     if(newMerit != -1) {
       m_interface->UpdateMerit(newMerit);
     }

Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cPhenotype.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -86,9 +86,10 @@
   
   
   // 1. These are values calculated at the last divide (of self or offspring)
-  merit                    = in_phen.merit;             
+  merit                    = in_phen.merit;
+  executionRatio          = in_phen.executionRatio;
   energy_store             = in_phen.energy_store;    
-  energy_tobe_applied      = in_phen.energy_tobe_applied; 
+  energy_tobe_applied      = in_phen.energy_tobe_applied;
   genome_length            = in_phen.genome_length;        
   bonus_instruction_count  = in_phen.bonus_instruction_count; 
   copied_size              = in_phen.copied_size;          
@@ -262,6 +263,7 @@
 {
   // Copy divide values from parent, which should already be setup.
   merit           = parent_phenotype.merit;
+  executionRatio = 1.0;
   energy_store    = min(energy_store, (double) m_world->GetConfig().ENERGY_CAP.Get());
   energy_tobe_applied = 0.0;
   genome_length   = _genome.GetSize();
@@ -411,6 +413,7 @@
   executed_size   = genome_length;
   energy_store    = min(m_world->GetConfig().ENERGY_GIVEN_ON_INJECT.Get(), m_world->GetConfig().ENERGY_CAP.Get());
   energy_tobe_applied = 0.0;
+  executionRatio = 1.0;
   gestation_time  = 0;
   gestation_start = 0;
   fitness         = 0;
@@ -813,6 +816,12 @@
 {
   // Copy divide values from parent, which should already be setup.
   merit           = clone_phenotype.merit;
+  
+  energy_store    = clone_phenotype.energy_store;
+  energy_tobe_applied = 0.0;
+  executionRatio = 1.0;
+  
+  executionRatio  = clone_phenotype.executionRatio;
   genome_length   = clone_phenotype.genome_length;
   copied_size     = clone_phenotype.copied_size;
   // copied_size     = clone_phenotype.child_copied_size;
@@ -1373,10 +1382,11 @@
  */
 void cPhenotype::RefreshEnergy() {
   if(cur_energy_bonus > 0) {
-    if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 0 || m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 2) {
+    if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 0 || // on divide
+       m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 2) {  // on sleep
       energy_tobe_applied += cur_energy_bonus;
     } else if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 1) {
-      SetEnergy(energy_store + cur_energy_bonus);  //TODO: use SetEnergy
+      SetEnergy(energy_store + cur_energy_bonus);
     } else {
       cerr<< "Unknown APPLY_ENERGY_METHOD value " << m_world->GetConfig().APPLY_ENERGY_METHOD.Get();
       exit(-1);
@@ -1414,7 +1424,7 @@
   ReduceEnergy(child_energy - 2*energy_given_at_birth); // 2*energy_given_at_birth: 1 in child_energy & 1 for parent
     
   //TODO: add energy_given_at_birth to Stored_energy
-  cMerit parentMerit = cMerit(min(cMerit::EnergyToMerit(GetStoredEnergy(), m_world), energy_cap));
+  cMerit parentMerit = cMerit(cMerit::EnergyToMerit(GetStoredEnergy(), m_world) * GetExecutionRatio());
   SetMerit(parentMerit);
   
 /*  if(m_world->GetConfig().ENERGY_VERBOSE.Get()) {

Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cPhenotype.h	2007-08-21 17:01:36 UTC (rev 1973)
@@ -93,6 +93,7 @@
 
   // 1. These are values calculated at the last divide (of self or offspring)
   cMerit merit;             // Relative speed of CPU
+  double executionRatio;    //  ratio of current execution merit over base execution merit
   double energy_store;      // Amount of energy.  Determines relative speed of CPU when turned on.
   double energy_tobe_applied; //Energy that has not yet been added to energy store.
   int genome_length;        // Number of instructions in genome.
@@ -277,6 +278,7 @@
 
   /////////////////////  Accessors -- Retrieving  ////////////////////
   const cMerit & GetMerit() const { assert(initialized == true); return merit; }
+  double GetExecutionRatio() const { assert(initialized == true); return executionRatio; }
   int GetGenomeLength() const { assert(initialized == true); return genome_length; }
   int GetCopiedSize() const { assert(initialized == true); return copied_size; }
   int GetExecutedSize() const { assert(initialized == true); return executed_size; }
@@ -463,6 +465,8 @@
   bool& ChildFertile() { assert(initialized == true); return child_fertile; }
   bool& IsMultiThread() { assert(initialized == true); return is_multi_thread; }
   
+  void DoubleEnergyUsage() { executionRatio *= 2.0; }
+  void HalfEnergyUsage() { executionRatio *= 0.5; }
   void RefreshEnergy();
   void ApplyToEnergyStore();
   double ExtractParentEnergy();

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cPopulation.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -230,13 +230,17 @@
     }
   }
 
+}
+
+void cPopulation::InitiatePop() {
+
   // Load a clone if one is provided, otherwise setup start organism.
   if (m_world->GetConfig().CLONE_FILE.Get() == "-" || m_world->GetConfig().CLONE_FILE.Get() == "") {
     cGenome start_org(0);
     const cString& filename = m_world->GetConfig().START_CREATURE.Get();
 
     if (filename != "-" && filename != "") {
-      if (!cGenomeUtil::LoadGenome(filename, world->GetHardwareManager().GetInstSet(), start_org)) {
+      if (!cGenomeUtil::LoadGenome(filename, m_world->GetHardwareManager().GetInstSet(), start_org)) {
         cerr << "Error: Unable to load start creature" << endl;
         exit(-1);
       }
@@ -270,7 +274,7 @@
   
   tArray<cOrganism*> child_array;
   tArray<cMerit> merit_array;
-    
+  
   // Update the parent's phenotype.
   // This needs to be done before the parent goes into the birth chamber
   // or the merit doesn't get passed onto the child correctly
@@ -316,32 +320,32 @@
     // Do lineage tracking for the new organisms.
     LineageSetupOrganism(child_array[i], parent_organism.GetLineage(),
                          parent_organism.GetLineageLabel(), parent_genotype);
-		
-		//By default, store the parent cclade, this may get modified in ActivateOrgansim (@MRR)
-		child_array[i]->SetCCladeLabel(parent_organism.GetCCladeLabel());
+    
+    //By default, store the parent cclade, this may get modified in ActivateOrgansim (@MRR)
+    child_array[i]->SetCCladeLabel(parent_organism.GetCCladeLabel());
   }
-    
+  
   // If we're not about to kill the parent, do some extra work on it.
   if (parent_alive == true) {
-		
-		// Reset inputs and re-calculate merit if required
+    
+    // Reset inputs and re-calculate merit if required
     if (m_world->GetConfig().RESET_INPUTS_ON_DIVIDE.Get() > 0){
-			environment.SetupInputs(ctx, parent_cell.m_inputs);
+      environment.SetupInputs(ctx, parent_cell.m_inputs);
       int pc_phenotype = m_world->GetConfig().PRECALC_PHENOTYPE.Get();
-			if (pc_phenotype){
-				cCPUTestInfo test_info;
-				cTestCPU* test_cpu = m_world->GetHardwareManager().CreateTestCPU();
-				test_info.UseManualInputs(parent_cell.GetInputs()); // Test using what the environment will be
-				test_cpu->TestGenome(ctx, test_info, parent_organism.GetHardware().GetMemory()); // Use the true genome
-				if (pc_phenotype & 1)  // If we must update the merit
+      if (pc_phenotype){
+        cCPUTestInfo test_info;
+        cTestCPU* test_cpu = m_world->GetHardwareManager().CreateTestCPU();
+        test_info.UseManualInputs(parent_cell.GetInputs()); // Test using what the environment will be
+        test_cpu->TestGenome(ctx, test_info, parent_organism.GetHardware().GetMemory()); // Use the true genome
+        if (pc_phenotype & 1)  // If we must update the merit
           parent_phenotype.SetMerit(test_info.GetTestPhenotype().GetMerit());
         if (pc_phenotype & 2)  // If we must update the gestation time
           parent_phenotype.SetGestationTime(test_info.GetTestPhenotype().GetGestationTime());
         parent_phenotype.SetFitness(parent_phenotype.GetMerit().CalcFitness(parent_phenotype.GetGestationTime())); //Update fitness
-				delete test_cpu;
-			}
-		}
-		schedule->Adjust(parent_cell.GetID(), parent_phenotype.GetMerit());
+        delete test_cpu;
+      }
+    }
+    schedule->Adjust(parent_cell.GetID(), parent_phenotype.GetMerit());
     
     // In a local run, face the child toward the parent. 
     const int birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
@@ -514,7 +518,6 @@
     } 
     in_organism->GetPhenotype().SetCurBonusInstCount(num_rewarded_instructions);
   }
-  
 }
 
 // @WRE 2007/07/05 Helper function to take care of side effects of Avidian 
@@ -1065,12 +1068,12 @@
   const int num_demes = GetNumDemes();
   
   // Loop through all candidate demes...
-	for (int deme_id = 0; deme_id < num_demes; deme_id++) {
-		cDeme & source_deme = deme_array[deme_id];
-
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cDeme & source_deme = deme_array[deme_id];
+    
     // Doesn't make sense to try and replicate a deme that *has no organisms*.
     if(source_deme.IsEmpty()) continue;
-
+    
     // Test this deme to determine if it should be replicated.  If not,
     // continue on to the next deme.
     switch (rep_trigger) {
@@ -1087,46 +1090,46 @@
       case 2: {
         // Replicate all demes with the corners filled in.
         // The first and last IDs represent the two corners.
-				const int id1 = source_deme.GetCellID(0);
-				const int id2 = source_deme.GetCellID(source_deme.GetSize() - 1);
-				if(cell_array[id1].IsOccupied() == false ||
+        const int id1 = source_deme.GetCellID(0);
+        const int id2 = source_deme.GetCellID(source_deme.GetSize() - 1);
+        if(cell_array[id1].IsOccupied() == false ||
            cell_array[id2].IsOccupied() == false) continue;
-				break;
+        break;
       }
-			case 3: {
+      case 3: {
         // Replicate old demes.
         if(source_deme.GetAge() < m_world->GetConfig().MAX_DEME_AGE.Get()) continue;
         break;
       }
-			default: {
-				cerr << "ERROR: Invalid replication trigger " << rep_trigger
-				<< " in cPopulation::ReplicateDemes()" << endl;
+      default: {
+        cerr << "ERROR: Invalid replication trigger " << rep_trigger
+        << " in cPopulation::ReplicateDemes()" << endl;
         assert(false);
       }
     }
     
-		// -- If we made it this far, we should replicate this deme --
-		cRandom& random = m_world->GetRandom();
-		
-		// Choose a random target deme to replicate to, and kill all the organisms
-		// in that deme.
-		int target_id = deme_id;
-		while(target_id == deme_id) {
-			target_id = random.GetUInt(num_demes);
-		}
-		cDeme& target_deme = deme_array[target_id];
-		for (int i=0; i<target_deme.GetSize(); i++) {
-			KillOrganism(cell_array[target_deme.GetCellID(i)]);
-		}
-		
-		// Ok, there are two potential places where the seed for the target deme can
-		// come from.  First, it could be a random organism in the source deme.
-		// Second, it could be an offspring of the source deme's germline, if the config
-		// option DEMES_USE_GERMLINE is set.
-		if(m_world->GetConfig().DEMES_USE_GERMLINE.Get()) {
-			// Get the latest germ from the source deme.
-			cGermline& source_germline = source_deme.GetGermline();
-			cGenome& source_germ = source_germline.GetLatest();
+    // -- If we made it this far, we should replicate this deme --
+    cRandom& random = m_world->GetRandom();
+    
+    // Choose a random target deme to replicate to, and kill all the organisms
+    // in that deme.
+    int target_id = deme_id;
+    while(target_id == deme_id) {
+      target_id = random.GetUInt(num_demes);
+    }
+    cDeme& target_deme = deme_array[target_id];
+    for (int i=0; i<target_deme.GetSize(); i++) {
+      KillOrganism(cell_array[target_deme.GetCellID(i)]);
+    }
+        
+    // Ok, there are two potential places where the seed for the target deme can
+    // come from.  First, it could be a random organism in the source deme.
+    // Second, it could be an offspring of the source deme's germline, if the config
+    // option DEMES_USE_GERMLINE is set.
+    if(m_world->GetConfig().DEMES_USE_GERMLINE.Get()) {
+      // Get the latest germ from the source deme.
+      cGermline& source_germline = source_deme.GetGermline();
+      cGenome& source_germ = source_germline.GetLatest();
       
       // Now create the next germ by manually mutating the source.
       // @refactor (strategy pattern)
@@ -1141,10 +1144,10 @@
         }
       }
       
-			// Here we're adding the next_germ to the germline(s).  Note the
+      // Here we're adding the next_germ to the germline(s).  Note the
       // config option to determine if we should update the source_germline
       // as well.
-			target_deme.ReplaceGermline(source_germline);
+      target_deme.ReplaceGermline(source_germline);
       cGermline& target_germline = target_deme.GetGermline();
       target_germline.Add(next_germ);
       if(m_world->GetConfig().GERMLINE_REPLACES_SOURCE.Get()) {
@@ -1152,11 +1155,15 @@
       }
       
       // Kill all the organisms in the source deme.
-			for (int i=0; i<source_deme.GetSize(); i++) {
-				KillOrganism(cell_array[source_deme.GetCellID(i)]);
-			}
-      
-			// Lineage label is wrong here; fix.
+      for (int i=0; i<source_deme.GetSize(); i++) {
+        KillOrganism(cell_array[source_deme.GetCellID(i)]);
+      }
+    
+      // And reset both demes, in case they have any cleanup work to do.
+      source_deme.Reset();
+      target_deme.Reset();
+  
+      // Lineage label is wrong here; fix.
       if(m_world->GetConfig().GERMLINE_RANDOM_PLACEMENT.Get()) {
         InjectGenome(source_deme.GetCellID(m_world->GetRandom().GetInt(0, source_deme.GetSize()-1)),
                      source_germline.GetLatest(), 0);
@@ -1166,46 +1173,65 @@
         InjectGenome(source_deme.GetCellID(source_deme.GetSize()/2), source_germline.GetLatest(), 0);
         InjectGenome(target_deme.GetCellID(target_deme.GetSize()/2), target_germline.GetLatest(), 0);
       }
-			
-			// Note: not rotating the clones.
-		} else {
-			// Not using germline; choose a random organism from this deme.
-			int cell1_id = -1;
-			while (cell1_id == -1 || cell_array[cell1_id].IsOccupied() == false) {
-				cell1_id = source_deme.GetCellID(random.GetUInt(source_deme.GetSize()));
-			}
-			
-			cOrganism* seed = cell_array[cell1_id].GetOrganism();
-			
-			// And do the replication into the central cell of the target deme...
-			const int cell2_id = target_deme.GetCellID(target_deme.GetWidth()/2, target_deme.GetHeight()/2);
-			InjectClone(cell2_id, *seed);
       
-			// Kill all the organisms in the source deme.
-			seed = 0; // Note that we're killing the organism that seed points to.
-			for (int i=0; i<source_deme.GetSize(); i++) {
-				KillOrganism(cell_array[source_deme.GetCellID(i)]);
-			}
-			
-			// Inject the target offspring back into the source ID.
-			const int cell3_id = source_deme.GetCellID(source_deme.GetWidth()/2, source_deme.GetHeight()/2);
-			InjectClone(cell3_id, *cell_array[cell2_id].GetOrganism());
+      // Note: not rotating the clones.
+    } else {
+      // Not using germline; choose a random organism from this deme.
+      int cell1_id = -1;
+      while (cell1_id == -1 || cell_array[cell1_id].IsOccupied() == false) {
+        cell1_id = source_deme.GetCellID(random.GetUInt(source_deme.GetSize()));
+      }
       
-			// Rotate both injected cells to face northwest.
-      int offset=target_deme.GetCellID(0);
-			cell_array[cell2_id].Rotate(cell_array[GridNeighbor(cell2_id-offset,
-                                                          target_deme.GetWidth(), 
-                                                          target_deme.GetHeight(), -1, -1)+offset]);
-      offset = source_deme.GetCellID(0);
-			cell_array[cell3_id].Rotate(cell_array[GridNeighbor(cell3_id-offset,
-                                                          source_deme.GetWidth(),
-                                                          source_deme.GetHeight(), -1, -1)+offset]);
-		}
-		
-		// And reset both demes, in case they have any cleanup work to do.
-		source_deme.Reset();
-		target_deme.Reset();
-	}
+      if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
+        cOrganism* seed_org = cell_array[cell1_id].GetOrganism();
+        cGenome seed_genome = seed_org->GetGenome();
+        int seed_lineage = seed_org->GetLineageLabel();
+
+        // Kill all the organisms in the source deme.  Orgs. in dest. deme are already killed
+        for (int i=0; i<source_deme.GetSize(); i++) {
+          KillOrganism(cell_array[source_deme.GetCellID(i)]);
+        }
+
+        source_deme.Reset();
+        target_deme.Reset();
+
+        InjectGenome(source_deme.GetCellID(source_deme.GetSize()/2), seed_genome, seed_lineage); // source deme
+        InjectGenome(target_deme.GetCellID(target_deme.GetSize()/2), seed_genome, seed_lineage); // destination deme
+        
+      } else {
+        cOrganism* seed = cell_array[cell1_id].GetOrganism();
+        
+        // And do the replication into the central cell of the target deme...
+        const int cell2_id = target_deme.GetCellID(target_deme.GetWidth()/2, target_deme.GetHeight()/2);
+        InjectClone(cell2_id, *seed);
+        
+        // Kill all the organisms in the source deme.
+        seed = 0; // Note that we're killing the organism that seed points to.
+        for (int i=0; i<source_deme.GetSize(); i++) {
+          KillOrganism(cell_array[source_deme.GetCellID(i)]);
+        }
+        
+        // Inject the target offspring back into the source ID.
+        const int cell3_id = source_deme.GetCellID(source_deme.GetWidth()/2, source_deme.GetHeight()/2);
+        InjectClone(cell3_id, *cell_array[cell2_id].GetOrganism());
+        
+        // Rotate both injected cells to face northwest.
+        int offset=target_deme.GetCellID(0);
+        cell_array[cell2_id].Rotate(cell_array[GridNeighbor(cell2_id-offset,
+                                                            target_deme.GetWidth(), 
+                                                            target_deme.GetHeight(), -1, -1)+offset]);
+        offset = source_deme.GetCellID(0);
+        cell_array[cell3_id].Rotate(cell_array[GridNeighbor(cell3_id-offset,
+                                                            source_deme.GetWidth(),
+                                                            source_deme.GetHeight(), -1, -1)+offset]);
+                                                            
+                                          
+        // This is in the wrong place.  Reset should be done after the demes are cleared and before the org. is injected.
+        source_deme.Reset();
+        target_deme.Reset();
+      }
+    }
+  }
 }
 
 // Loop through all demes to determine if any are ready to be divided.  All
@@ -1457,59 +1483,105 @@
   InjectClone( cell2_id, *(cell_array[cell1_id].GetOrganism()) );    
 }
 
+// Print out all statistics about individual demes
+void cPopulation::PrintDemeAllStats() {
+  PrintDemeFitness();
+  PrintDemeLifeFitness();
+  PrintDemeMerit();
+  PrintDemeGestationTime();
+  PrintDemeTasks();
+  PrintDemeDonor();
+  PrintDemeReceiver();
+  PrintDemeMutationRate();
+  PrintDemeResource();
+  PrintDemeInstructions();
+    
+  if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
+    PrintDemeSpatialEnergyData();
+    PrintDemeSpatialSleepData();
+  }
+}
 
-// Print out statistics about individual demes
+void cPopulation::PrintDemeDonor() {
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
+  cDataFile & df_donor = m_world->GetDataFile("deme_donor.dat");
+  df_donor.WriteComment("Num orgs doing doing a donate for each deme in population");
+  df_donor.WriteTimeStamp();
+  df_donor.Write(stats.GetUpdate(), "update");
 
-void cPopulation::PrintDemeStats()
-{
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cString comment;
+    const cDeme & cur_deme = deme_array[deme_id];
+    cDoubleSum single_deme_donor;
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell].IsOccupied() == false) continue;
+      cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+      single_deme_donor.Add(phenotype.IsDonorLast()); 	
+    }
+    comment.Set("Deme %d", deme_id);
+    df_donor.Write(single_deme_donor.Sum(), comment);
+  }
+  df_donor.Endl();
+}
+
+void cPopulation::PrintDemeFitness() {
   cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
+  cDataFile & df_fit = m_world->GetDataFile("deme_fitness.dat");
+  df_fit.WriteComment("Average fitnesses for each deme in the population");
+  df_fit.WriteTimeStamp();
+  df_fit.Write(stats.GetUpdate(), "update");
   
-  cDataFile & df_fit = m_world->GetDataFile("deme_fitness.dat");
-  cDataFile & df_life_fit = m_world->GetDataFile("deme_lifetime_fitness.dat");
-  cDataFile & df_merit = m_world->GetDataFile("deme_merit.dat");
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cString comment;
+    const cDeme & cur_deme = deme_array[deme_id];
+    cDoubleSum single_deme_fitness;
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell].IsOccupied() == false) continue;
+      cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+      single_deme_fitness.Add(phenotype.GetFitness()); 	
+    }
+    comment.Set("Deme %d", deme_id);
+    df_fit.Write(single_deme_fitness.Ave(), comment);
+  }
+  df_fit.Endl();
+}
+
+void cPopulation::PrintDemeGestationTime() {
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
   cDataFile & df_gest = m_world->GetDataFile("deme_gest_time.dat");
-  cDataFile & df_task = m_world->GetDataFile("deme_task.dat");
-  cDataFile & df_donor = m_world->GetDataFile("deme_donor.dat");
-  cDataFile & df_receiver = m_world->GetDataFile("deme_receiver.dat");
-  cDataFile & df_mut_rates = m_world->GetDataFile("deme_mut_rates.dat");
-  cDataFile & df_resources = m_world->GetDataFile("deme_resources.dat");
-  
-  df_fit.WriteComment("Average fitnesses for each deme in the population");
-  df_life_fit.WriteComment("Average life fitnesses for each deme in the population");
-  df_merit.WriteComment("Average merits for each deme in population");
   df_gest.WriteComment("Average gestation time for each deme in population");
-  df_task.WriteComment("Num orgs doing each task for each deme in population");
-  df_donor.WriteComment("Num orgs doing doing a donate for each deme in population");
-  df_receiver.WriteComment("Num orgs doing receiving a donate for each deme in population");
-  df_mut_rates.WriteComment("Average mutation rates for organisms in each deme");
-  df_resources.WriteComment("Avida deme resource data");
-  
-  df_fit.WriteTimeStamp();
-  df_life_fit.WriteTimeStamp();
-  df_merit.WriteTimeStamp();
   df_gest.WriteTimeStamp();
-  df_task.WriteTimeStamp();
-  df_donor.WriteTimeStamp();
-  df_receiver.WriteTimeStamp();
-  df_mut_rates.WriteTimeStamp();
-  df_resources.WriteTimeStamp();
-  
-  df_fit.Write(stats.GetUpdate(), "update");
-  df_life_fit.Write(stats.GetUpdate(), "update");
-  df_merit.Write(stats.GetUpdate(), "update");
   df_gest.Write(stats.GetUpdate(), "update");
-  df_task.Write(stats.GetUpdate(), "update");
-  df_donor.Write(stats.GetUpdate(), "update");
-  df_receiver.Write(stats.GetUpdate(), "update");
-  df_mut_rates.Write(stats.GetUpdate(), "update");
-  df_resources.Write(stats.GetUpdate(), "update");
-  
+
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cString comment;
+    const cDeme & cur_deme = deme_array[deme_id];
+    cDoubleSum single_deme_gest_time;
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell].IsOccupied() == false) continue;
+      cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+      single_deme_gest_time.Add(phenotype.GetGestationTime()); 	
+    }
+    comment.Set("Deme %d", deme_id);
+    df_gest.Write(single_deme_gest_time.Ave(), comment);
+  }
+  df_gest.Endl();
+}
+
+void cPopulation::PrintDemeInstructions() {  
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
   const int num_inst = m_world->GetNumInstructions();
-  const int num_task = environment.GetNumTasks();
   
-  cDoubleSum total_mut_rate;
-  
-  const int num_demes = deme_array.GetSize();
   for (int deme_id = 0; deme_id < num_demes; deme_id++) {
     cString filename;
     filename.Set("deme_instruction-%d.dat", deme_id);
@@ -1520,16 +1592,7 @@
     df_inst.WriteComment(comment);
     df_inst.WriteTimeStamp();
     df_inst.Write(stats.GetUpdate(), "update");
-    
-    cDoubleSum single_deme_fitness;
-    cDoubleSum single_deme_life_fitness;
-    cDoubleSum single_deme_merit;
-    cDoubleSum single_deme_gest_time;
-    cDoubleSum single_deme_donor;
-    cDoubleSum single_deme_receiver;
-    cDoubleSum single_deme_mut_rate;
-    
-    tArray<cIntSum> single_deme_task(num_task);
+        
     tArray<cIntSum> single_deme_inst(num_inst);
     
     const cDeme & cur_deme = deme_array[deme_id];
@@ -1537,81 +1600,181 @@
       int cur_cell = cur_deme.GetCellID(i);
       if (cell_array[cur_cell].IsOccupied() == false) continue;
       cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
-      single_deme_fitness.Add(phenotype.GetFitness()); 	
-      single_deme_life_fitness.Add(phenotype.GetLifeFitness()); 	
-      single_deme_merit.Add(phenotype.GetMerit().GetDouble()); 	
-      single_deme_gest_time.Add(phenotype.GetGestationTime()); 	
-      single_deme_donor.Add(phenotype.IsDonorLast()); 	
-      single_deme_receiver.Add(phenotype.IsReceiver()); 	
-      single_deme_mut_rate.Add(GetCell(cur_cell).GetOrganism()->MutationRates().GetCopyMutProb());
       
       for (int j = 0; j < num_inst; j++) {
         single_deme_inst[j].Add(phenotype.GetLastInstCount()[j]);
       } 
-      
-      for (int j = 0; j < num_task; j++) {
-        // only interested in tasks is done once! 
-        if (phenotype.GetLastTaskCount()[j] > 0) {
-          single_deme_task[j].Add(1);
-        }
-      }
     }
     
+    for (int j = 0; j < num_inst; j++) {
+      comment.Set("Inst %d", j);
+      df_inst.Write((int) single_deme_inst[j].Sum(), comment);
+    }
+    df_inst.Endl();    
+  }
+}
+
+void cPopulation::PrintDemeLifeFitness() {
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
+  cDataFile & df_life_fit = m_world->GetDataFile("deme_lifetime_fitness.dat");
+  df_life_fit.WriteComment("Average life fitnesses for each deme in the population");
+  df_life_fit.WriteTimeStamp();
+  df_life_fit.Write(stats.GetUpdate(), "update");
+
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cString comment;
+    const cDeme & cur_deme = deme_array[deme_id];
+    cDoubleSum single_deme_life_fitness;
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell].IsOccupied() == false) continue;
+      cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+      single_deme_life_fitness.Add(phenotype.GetLifeFitness()); 	
+    }
     comment.Set("Deme %d", deme_id);
-    df_fit.Write(single_deme_fitness.Ave(), comment);
     df_life_fit.Write(single_deme_life_fitness.Ave(), comment);
+  }
+  df_life_fit.Endl();
+}
+
+void cPopulation::PrintDemeMerit() {
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
+  cDataFile & df_merit = m_world->GetDataFile("deme_merit.dat");
+  df_merit.WriteComment("Average merits for each deme in population");
+  df_merit.WriteTimeStamp();
+  df_merit.Write(stats.GetUpdate(), "update");
+
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cString comment;
+    const cDeme & cur_deme = deme_array[deme_id];
+    cDoubleSum single_deme_merit;
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell].IsOccupied() == false) continue;
+      cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+      single_deme_merit.Add(phenotype.GetMerit().GetDouble()); 	
+    }
+    comment.Set("Deme %d", deme_id);
     df_merit.Write(single_deme_merit.Ave(), comment);
-    df_gest.Write(single_deme_gest_time.Ave(), comment);
-    df_donor.Write(single_deme_donor.Sum(), comment);
-    df_receiver.Write(single_deme_receiver.Sum(), comment);
+  }
+  df_merit.Endl();
+}
+
+void cPopulation::PrintDemeMutationRate() {
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
+  cDataFile & df_mut_rates = m_world->GetDataFile("deme_mut_rates.dat");
+  df_mut_rates.WriteComment("Average mutation rates for organisms in each deme");
+  df_mut_rates.WriteTimeStamp();
+  df_mut_rates.Write(stats.GetUpdate(), "update");
+  cDoubleSum total_mut_rate;
+
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cString comment;
+    const cDeme & cur_deme = deme_array[deme_id];
+    cDoubleSum single_deme_mut_rate;
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell].IsOccupied() == false) continue;
+      single_deme_mut_rate.Add(GetCell(cur_cell).GetOrganism()->MutationRates().GetCopyMutProb());
+    }
+    comment.Set("Deme %d", deme_id);
     df_mut_rates.Write(single_deme_mut_rate.Ave(), comment);
-    
     total_mut_rate.Add(single_deme_mut_rate.Ave());
-    
-    for (int j = 0; j < num_task; j++) {
-      comment.Set("Deme %d, Task %d", deme_id, j);
-      df_task.Write((int) single_deme_task[j].Sum(), comment);
+  }
+  df_mut_rates.Write(total_mut_rate.Ave(), "Average deme mutation rate averaged across Demes.");
+  df_mut_rates.Endl();
+}
+
+void cPopulation::PrintDemeReceiver() {
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
+  cDataFile & df_receiver = m_world->GetDataFile("deme_receiver.dat");
+  df_receiver.WriteComment("Num orgs doing receiving a donate for each deme in population");
+  df_receiver.WriteTimeStamp();
+  df_receiver.Write(stats.GetUpdate(), "update");
+
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cString comment;
+    const cDeme & cur_deme = deme_array[deme_id];
+    cDoubleSum single_deme_receiver;
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell].IsOccupied() == false) continue;
+      cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+      single_deme_receiver.Add(phenotype.IsReceiver()); 	
     }
-    
-    for (int j = 0; j < num_inst; j++) {
-      comment.Set("Inst %d", j);
-      df_inst.Write((int) single_deme_inst[j].Sum(), comment);
-    }
-    df_inst.Endl();
-    
-    GetDeme(deme_id).UpdateDemeRes();
+    comment.Set("Deme %d", deme_id);
+    df_receiver.Write(single_deme_receiver.Sum(), comment);
+  }
+    df_receiver.Endl();
+}
+
+void cPopulation::PrintDemeResource() {
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
+  cDataFile & df_resources = m_world->GetDataFile("deme_resources.dat");
+  df_resources.WriteComment("Avida deme resource data");
+  df_resources.WriteTimeStamp();
+  df_resources.Write(stats.GetUpdate(), "update");
+
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cDeme & cur_deme = deme_array[deme_id];
+
+    cur_deme.UpdateDemeRes();
     cResourceCount res = GetDeme(deme_id).GetDemeResourceCount();
     for(int j = 0; j < res.GetSize(); j++) {
       const char * tmp = res.GetResName(j);
       df_resources.Write(res.Get(j), cStringUtil::Stringf("Deme %d Resource %s", deme_id, tmp)); //comment);
-      
-      if ((res.GetResourcesGeometry())[j] != nGeometry::GLOBAL) {
+      if((res.GetResourcesGeometry())[j] != nGeometry::GLOBAL) {
         PrintDemeSpatialResData(res, j, deme_id);
       }
     }
-  } 
-  
-  df_mut_rates.Write(total_mut_rate.Ave(), "Average deme mutation rate averaged across Demes.");
-  
-  df_fit.Endl();
-  df_life_fit.Endl();
-  df_merit.Endl();
-  df_gest.Endl();
-  df_task.Endl();
-  df_donor.Endl();
-  df_receiver.Endl();
-  df_mut_rates.Endl();
+  }
   df_resources.Endl();
 }
 
+// Write spatial energy data to a file that can easily be read into Matlab
+void cPopulation::PrintDemeSpatialEnergyData() const {
+  int cellID = 0;
+  int update = m_world->GetStats().GetUpdate();
+  
+  for(int i = 0; i < m_world->GetPopulation().GetNumDemes(); i++) {
+    cString tmpfilename = cStringUtil::Stringf( "deme_%07i_spacial_energy.m", i);  // moved here for easy movie making
+    cDataFile& df = m_world->GetDataFile(tmpfilename);
+    cString UpdateStr = cStringUtil::Stringf( "deme_%07i_energy_%07i = [ ...", i, update );
+    df.WriteRaw(UpdateStr);
+
+    int gridsize = m_world->GetPopulation().GetDeme(i).GetSize();
+    int xsize = m_world->GetConfig().WORLD_X.Get();
+
+    // write grid to file
+    for (int j = 0; j < gridsize; j++) {
+      cPopulationCell& cell = m_world->GetPopulation().GetCell(cellID);
+      if(cell.IsOccupied()) {
+        df.WriteBlockElement(cell.GetOrganism()->GetPhenotype().GetStoredEnergy(), j, xsize);
+      } else {
+        df.WriteBlockElement(0.0, j, xsize);
+      }
+      cellID++;
+    }
+    df.WriteRaw("];");
+    df.Endl();
+  }
+}
+
 // Write spatial data to a file that can easily be read into Matlab
-void cPopulation::PrintDemeSpatialResData( cResourceCount res, const int i, const int deme_id){
+void cPopulation::PrintDemeSpatialResData( cResourceCount res, const int i, const int deme_id) const {
   const char* tmpResName = res.GetResName(i);
-  cString tmpfilename = cStringUtil::Stringf( "deme_spacial_resource_%s_%i.m", tmpResName, deme_id );
-//  tmpfilename +=  res.GetResName(i) + ".m";
+  cString tmpfilename = cStringUtil::Stringf( "deme_spacial_resource_%s.m", tmpResName );
   cDataFile& df = m_world->GetDataFile(tmpfilename);
-  cString UpdateStr = cStringUtil::Stringf( "deme_%07i_", deme_id ) + res.GetResName(i) + 
-                      cStringUtil::Stringf( "_%07i", m_world->GetStats().GetUpdate() ) + " = [ ...";
+  cString UpdateStr = cStringUtil::Stringf( "deme_%07i_%s_%07i = [ ...", deme_id, static_cast<const char*>(res.GetResName(i)), m_world->GetStats().GetUpdate() );
 
   df.WriteRaw(UpdateStr);
 
@@ -1619,21 +1782,79 @@
   int gridsize = sp_res.GetSize();
   int xsize = m_world->GetConfig().WORLD_X.Get();
 
-  // write grid to file
-
   for (int j = 0; j < gridsize; j++) {
     df.WriteBlockElement(sp_res.GetAmount(j), j, xsize);
   }
   df.WriteRaw("];");
+  df.Endl();
 }
 
+// Write spatial energy data to a file that can easily be read into Matlab
+void cPopulation::PrintDemeSpatialSleepData() const {
+  int cellID = 0;
+  cString tmpfilename = "deme_spacial_sleep.m";
+  cDataFile& df = m_world->GetDataFile(tmpfilename);
+  int update = m_world->GetStats().GetUpdate();
+  
+  for(int i = 0; i < m_world->GetPopulation().GetNumDemes(); i++) {
+    cString UpdateStr = cStringUtil::Stringf( "deme_%07i_sleep_%07i = [ ...", i, update);
+    df.WriteRaw(UpdateStr);
 
+    int gridsize = m_world->GetPopulation().GetDeme(i).GetSize();
+    int xsize = m_world->GetConfig().WORLD_X.Get();
 
+    // write grid to file
+    for (int j = 0; j < gridsize; j++) {
+      cPopulationCell cell = m_world->GetPopulation().GetCell(cellID);
+      if(cell.IsOccupied()) {
+        df.WriteBlockElement(cell.GetOrganism()->IsSleeping(), j, xsize);
+      } else {
+        df.WriteBlockElement(0.0, j, xsize);
+      }
+      cellID++;
+    }
+    df.WriteRaw("];");
+    df.Endl();
+  }
+}
+
+void cPopulation::PrintDemeTasks() {
+  cStats& stats = m_world->GetStats();
+  const int num_demes = deme_array.GetSize();
+  const int num_task = environment.GetNumTasks();
+  cDataFile & df_task = m_world->GetDataFile("deme_task.dat");
+  df_task.WriteComment("Num orgs doing each task for each deme in population");
+  df_task.WriteTimeStamp();
+  df_task.Write(stats.GetUpdate(), "update");
+
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    cString comment;
+    const cDeme & cur_deme = deme_array[deme_id];
+    tArray<cIntSum> single_deme_task(num_task);
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell].IsOccupied() == false) continue;
+      cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+      for (int j = 0; j < num_task; j++) {
+        // only interested if task is done once! 
+        if (phenotype.GetLastTaskCount()[j] > 0) {
+          single_deme_task[j].Add(1);
+        }
+      }
+    }
+    for (int j = 0; j < num_task; j++) {
+      comment.Set("Deme %d, Task %d", deme_id, j);
+      df_task.Write((int) single_deme_task[j].Sum(), comment);
+    }
+  }
+  df_task.Endl();
+}
+
 /**
 * This function is responsible for adding an organism to a given lineage,
  * and setting the organism's lineage label and the lineage pointer.
  **/
-
 void cPopulation::LineageSetupOrganism(cOrganism* organism, cLineage* lin, int lin_label, cGenotype* parent_genotype)
 {
   // If we have some kind of lineage control, adjust the default values passed in.
@@ -2650,8 +2871,8 @@
   
   cOrganism* new_organism = new cOrganism(m_world, ctx, new_genotype->GetGenome());
 	
-	//Coalescense Clade Setup
-	new_organism->SetCCladeLabel(-1);  
+  //Coalescense Clade Setup
+  new_organism->SetCCladeLabel(-1);  
   
   // Set the genotype...
   new_organism->SetGenotype(new_genotype);
@@ -2660,14 +2881,12 @@
   cPhenotype & phenotype = new_organism->GetPhenotype();
   phenotype.SetupInject(new_genotype->GetGenome());  //TODO  sets merit to lenght of genotype
   
-  if(m_world->GetConfig().ENERGY_ENABLED.Get()) {
-    double initial_energy = min(m_world->GetConfig().ENERGY_GIVEN_ON_INJECT.Get(), m_world->GetConfig().ENERGY_CAP.Get());
-    phenotype.SetEnergy(initial_energy);
+  if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
+    phenotype.SetMerit(cMerit(cMerit::EnergyToMerit(phenotype.GetStoredEnergy(), m_world)));
+  } else {
+    phenotype.SetMerit( cMerit(new_genotype->GetTestMerit(ctx)) );
   }
-  // BB - Don't need to fix metabolic rate here, only on birth
-
-  phenotype.SetMerit( cMerit(new_genotype->GetTestMerit(ctx)) );
-    
+  
   // @CAO are these really needed?
   phenotype.SetLinesCopied( new_genotype->GetTestCopiedSize(ctx) );
   phenotype.SetLinesExecuted( new_genotype->GetTestExecutedSize(ctx) );

Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cPopulation.h	2007-08-21 17:01:36 UTC (rev 1973)
@@ -151,6 +151,8 @@
   cPopulation(cWorld* world);
   ~cPopulation();
 
+  void InitiatePop();
+
   // Activate the offspring of an organism in the population
   bool ActivateOffspring(cAvidaContext& ctx, cGenome& child_genome, cOrganism& parent_organism);
   bool ActivateParasite(cOrganism& parent, const cCodeLabel& label, const cGenome& injected_code);
@@ -180,8 +182,23 @@
   void ResetDemes();
   void CopyDeme(int deme1_id, int deme2_id);
   void SpawnDeme(int deme1_id, int deme2_id=-1);
-  void PrintDemeStats();
-  void PrintDemeSpatialResData( cResourceCount res, const int i, const int deme_id);
+
+  // Deme-related stats methods
+  void PrintDemeAllStats();
+  void PrintDemeDonor();
+  void PrintDemeFitness();
+  void PrintDemeGestationTime();
+  void PrintDemeInstructions();
+  void PrintDemeLifeFitness();
+  void PrintDemeMerit();
+  void PrintDemeMutationRate();
+  void PrintDemeReceiver();
+  void PrintDemeResource();
+  void PrintDemeSpatialResData(cResourceCount res, const int i, const int deme_id) const;
+  void PrintDemeSpatialEnergyData() const;
+  void PrintDemeSpatialSleepData() const;
+  void PrintDemeTasks();
+
   
   // Print donation stats
   void PrintDonationStats();

Modified: development/source/main/cPopulationCell.cc
===================================================================
--- development/source/main/cPopulationCell.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cPopulationCell.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -31,6 +31,8 @@
 #include "cTools.h"
 #include "cWorld.h"
 #include "cEnvironment.h"
+#include "cPopulation.h"
+#include "cDeme.h"
 
 using namespace std;
 
@@ -167,4 +169,45 @@
   // Adjust the organism's attributes to match this cell.
   m_organism->GetOrgInterface().SetCellID(m_cell_id);
   m_organism->GetOrgInterface().SetDemeID(m_deme_id);
+  
+  if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1 && m_world->GetConfig().FRAC_ENERGY_TRANSFER.Get() > 0.0) {
+    // uptake all the cells energy
+    double uptake_energy = UptakeCellEnergy(1.0);
+    if(uptake_energy != 0.0) {
+      // update energy and merit
+      m_organism->GetPhenotype().ReduceEnergy(-1.0 * uptake_energy);
+      m_organism->GetPhenotype().SetMerit(cMerit(cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy(), m_world) * m_organism->GetPhenotype().GetExecutionRatio()));
+    }
+  }
 }
+
+cOrganism * cPopulationCell::RemoveOrganism()
+{
+  if (m_organism == NULL) return NULL;   // Nothing to do!
+
+  // For the moment, the cell doesn't keep track of much...
+  cOrganism * out_organism = m_organism;
+  if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1 && m_world->GetConfig().FRAC_ENERGY_TRANSFER.Get() > 0.0) {
+    m_world->GetPopulation().GetDeme(m_deme_id).GiveBackCellEnergy(m_cell_id, m_organism->GetPhenotype().GetStoredEnergy() * m_world->GetConfig().FRAC_ENERGY_TRANSFER.Get());
+  }
+  m_organism = NULL;
+  return out_organism;
+}
+
+double cPopulationCell::UptakeCellEnergy(double frac_to_uptake) {
+  assert(0.0 <= frac_to_uptake);
+  assert(frac_to_uptake <= 1.0);
+
+  double cell_energy = m_world->GetPopulation().GetDeme(m_deme_id).GetAndClearCellEnergy(m_cell_id);  
+  double uptakeAmount = cell_energy * frac_to_uptake;
+  cell_energy -= uptakeAmount;
+  m_world->GetPopulation().GetDeme(m_deme_id).GiveBackCellEnergy(m_cell_id, cell_energy);
+  return uptakeAmount;
+}
+
+
+bool cPopulationCell::OK()
+{
+  // Nothing for the moment...
+  return true;
+}

Modified: development/source/main/cPopulationCell.h
===================================================================
--- development/source/main/cPopulationCell.h	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cPopulationCell.h	2007-08-21 17:01:36 UTC (rev 1973)
@@ -64,7 +64,7 @@
 
   
   void InsertOrganism(cOrganism* new_org);
-  inline cOrganism* RemoveOrganism();
+  cOrganism* RemoveOrganism();
 
   
 public:
@@ -97,17 +97,12 @@
   inline int GetOrganismCount() const { return m_organism_count; }
 
   inline bool IsOccupied() const { return m_organism != NULL; }
-};
 
+  double UptakeCellEnergy(double frac_to_uptake);
 
-inline cOrganism* cPopulationCell::RemoveOrganism()
-{
-  cOrganism* out_organism = m_organism;
-  m_organism = NULL;
-  return out_organism;
-}
+  bool OK();
+};
 
-
 inline int cPopulationCell::GetInputAt(int& input_pointer)
 {
   input_pointer %= m_inputs.GetSize();

Modified: development/source/main/cResource.cc
===================================================================
--- development/source/main/cResource.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cResource.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -66,6 +66,7 @@
   , ydiffuse(1.0)
   , ygravity(0.0)
   , deme_resource(false)
+  , energy_resource(false)
 {
 }
 
@@ -94,11 +95,23 @@
   _deme_resource.ToLower();
   if ((_deme_resource == "false") || (_deme_resource == "0")) {
     deme_resource = false;
-    return(true);
+    return true;
   } else if ((_deme_resource == "true") || (_deme_resource == "1")) {
     deme_resource = true;
-    return(true);
-  } else {
-    return false;
+    return true;
   }
+  return false;
 }
+
+/* Set if the resource is a energy resource */
+bool cResource::SetEnergyResource(cString _energy_resource) {
+  _energy_resource.ToLower();
+  if ((_energy_resource == "false") || (_energy_resource == "0")) {
+    energy_resource = false;
+    return true;
+  } else if ((_energy_resource == "true") || (_energy_resource == "1")) {
+    energy_resource = true;
+    return true;
+  }
+  return false;
+}

Modified: development/source/main/cResource.h
===================================================================
--- development/source/main/cResource.h	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cResource.h	2007-08-21 17:01:36 UTC (rev 1973)
@@ -79,6 +79,7 @@
   double ydiffuse;
   double ygravity;
   bool deme_resource;
+  bool energy_resource;  // only implemented for spacial resource
   tArray<cCellResource> cell_list;
  
   
@@ -107,6 +108,7 @@
   double GetYDiffuse() const { return ydiffuse; }
   double GetYGravity() const { return ygravity; }
   bool GetDemeResource() const { return deme_resource; }
+  bool GetEnergyResource() const { return energy_resource; }
   tArray<cCellResource> *GetCellListPtr() { return &cell_list; }
 
 
@@ -127,6 +129,7 @@
   void SetYDiffuse(double _ydiffuse) { ydiffuse = _ydiffuse; }
   void SetYGravity(double _ygravity) { ygravity = _ygravity; }
   bool SetDemeResource(cString _deme_resource);
+  bool SetEnergyResource(cString _energy_resource);
   void AddCellResource(cCellResource new_cell) { cell_list.Push(new_cell); }
 };
 

Modified: development/source/main/cWorld.cc
===================================================================
--- development/source/main/cWorld.cc	2007-08-21 16:05:15 UTC (rev 1972)
+++ development/source/main/cWorld.cc	2007-08-21 17:01:36 UTC (rev 1973)
@@ -107,6 +107,7 @@
 		m_class_mgr->LoadCCladeFounders(m_conf->TRACK_CCLADES_IDS.Get());
   
 	m_pop = new cPopulation(this);
+        m_pop->InitiatePop();
   
   // Setup Event List
   m_event_list = new cEventList(this);




More information about the Avida-cvs mailing list