[Avida-SVN] r3200 - in development: . Avida.xcodeproj source/cpu source/main source/tools

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Wed Apr 1 19:11:13 PDT 2009


Author: brysonda
Date: 2009-04-01 22:11:12 -0400 (Wed, 01 Apr 2009)
New Revision: 3200

Added:
   development/source/main/cBirthDemeHandler.cc
   development/source/main/cBirthDemeHandler.h
   development/source/main/cBirthEntry.h
   development/source/main/cBirthGenomeSizeHandler.cc
   development/source/main/cBirthGenomeSizeHandler.h
   development/source/main/cBirthGlobalHandler.cc
   development/source/main/cBirthGlobalHandler.h
   development/source/main/cBirthGridLocalHandler.cc
   development/source/main/cBirthGridLocalHandler.h
   development/source/main/cBirthMateSelectHandler.cc
   development/source/main/cBirthMateSelectHandler.h
   development/source/main/cBirthNeighborhoodHandler.cc
   development/source/main/cBirthNeighborhoodHandler.h
   development/source/main/cBirthSelectionHandler.cc
   development/source/main/cBirthSelectionHandler.h
Modified:
   development/Avida.xcodeproj/project.pbxproj
   development/CMakeLists.txt
   development/source/cpu/cHardwareBase.cc
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cTestCPUInterface.cc
   development/source/cpu/cTestCPUInterface.h
   development/source/main/cBirthChamber.cc
   development/source/main/cBirthChamber.h
   development/source/main/cOrgInterface.h
   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/cPopulationInterface.cc
   development/source/main/cPopulationInterface.h
   development/source/tools/cMerit.cc
   development/source/tools/cMerit.h
Log:
Rework the Birth Chamber. (for real this time...)

ATTENTION:
- Sexual reproduction in DEMES is very different (and has a caveat that will be fixed in a later commit), see below
- LOCAL NEIGHBORHOOD SEX reproduction is now handled more accurately by default (legacy support available), see below
- Sexual reproduction under the ENERGY model has been *fixed*
- cMerit::EnergyToMerit has moved to cPhenotype::ConvertEnergyToMerit 
- Sexual reproduction CONSISTENCY has changed due to a small bug in cPhenotype (original mate_select_id was set incorrectly to 0)

Details:
This is the start of *major* changes to the handling of sexual reproduction on the road to implementing support for multiple hardware and instruction sets. None of the changes for those features have been implemented yet. However, I have drastically restructured how offspring selection is done for sexual recombination.

Rather than if statements that call internal functions, the birth chamber now constructs handler objects (cBirthSelectionHandler subclasses) that do the task of storing waiting genomes and selecting them as needed.   This allows for a smaller memory footprint, since only objects necessary for the selected regime are constructed.  Once additional support for multiple queues of hardware types and instruction sets is implemented, this will become important.

More immediately, however, this structure allows for nested selection types, the primary use-case being demes.  With this commit, demes now honor the population level mate selection algorithm on a deme by deme basis.  The cBirthDemeHandler creates a sub-handler object of the correct type for each deme.  During replication, offspring a shuffled to the correct sub-handler, so that only organisms originating from the same deme can be selected for recombination.  Note that there is one important caveat with the current setup, when a deme is reset the birth chamber is not currently informed, thus potentially allowing recombination with an offspring from an earlier population that occupied the deme.  It is noteworthy that this is not particularly new, as it was similarly possible under the former method of deme mate selection.  I do, however, plan to fix this caveat in a future commit.

Local neighborhood sexual reproduction has been enhanced to properly honor the current population structure (i.e. the connection list).  Previously, and now when legacy local selection is enabled, the birth chamber would select an offspring waiting in the local 3x3 toroidal grid, without any regard for the current population structure.  If local placement strategies were selected, recombination could happen across deme or other barriers without restriction.  The new method gets the current connection list, searches for valid waiting offspring, then selects a random one for recombination.

Finally, there are is both a bug fix and a structural change in this commit that have implications for the energy model.  During the course of translating offspring storage routine, I noted that although cMerit::EnergyToMerit was being called, it was not actually storing the merit in the birth chamber entry (since cMerit::EnergyToMerit was a static method).  I believe all instances of this in the birth chamber were affected, meaning that merit was potentially undefined.  This bug only affects sexual reproduction.

The structural change to the energy model code comes from the movement of cMerit::EnergyToMerit to cPhenotype::ConvertEnergyToMerit.  Although its position in the code can be debated, cMerit is in the tools directory, thus should not reference any classes from the rest of Avida (with the exception of platform support, another form of tools).  Since cPhenotype has a local pointer to the world object and is available in the context of all current usage of MeritToEnergy, I chose to move it there.  More importantly, though, cMerit::EnergyToMerit was caching a configuration option in a static variable.  This is not a safe assumption, as it will eventually be possible to construct multiple worlds in a single Avida process.


New Configuration Options:
ALLOW_MATE_SELECTION - Toggles whether the birth chamber will honor organism specified mate_select_ids.  This feature requires instruction set support and is now off by default.
LEGACY_GRID_LOCAL_SELECTION - Can be used to enable the old style, connection-list agnostic local neighborhood selection method

Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/Avida.xcodeproj/project.pbxproj	2009-04-02 02:11:12 UTC (rev 3200)
@@ -182,6 +182,19 @@
 		704368D60C31991500A05ABA /* ASTree.cc in Sources */ = {isa = PBXBuildFile; fileRef = 704368CC0C3198F200A05ABA /* ASTree.cc */; };
 		70436B280C36C64400A05ABA /* cThread.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70436B230C36C64000A05ABA /* cThread.cc */; };
 		70436B6C0C36C98900A05ABA /* PlatformExpert.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70436B260C36C64000A05ABA /* PlatformExpert.cc */; };
+		70447BFE0F83B47900E1BF72 /* cBirthSelectionHandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70447BFD0F83B47900E1BF72 /* cBirthSelectionHandler.cc */; };
+		70447C4E0F83C55300E1BF72 /* cBirthNeighborhoodHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 70447C4C0F83C55300E1BF72 /* cBirthNeighborhoodHandler.h */; };
+		70447C4F0F83C55300E1BF72 /* cBirthNeighborhoodHandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70447C4D0F83C55300E1BF72 /* cBirthNeighborhoodHandler.cc */; };
+		70447C880F83D4C500E1BF72 /* cBirthGridLocalHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 70447C860F83D4C500E1BF72 /* cBirthGridLocalHandler.h */; };
+		70447C890F83D4C500E1BF72 /* cBirthGridLocalHandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70447C870F83D4C500E1BF72 /* cBirthGridLocalHandler.cc */; };
+		70447C950F83D72600E1BF72 /* cBirthGlobalHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 70447C930F83D72600E1BF72 /* cBirthGlobalHandler.h */; };
+		70447C960F83D72600E1BF72 /* cBirthGlobalHandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70447C940F83D72600E1BF72 /* cBirthGlobalHandler.cc */; };
+		70447CA30F83DB2900E1BF72 /* cBirthGenomeSizeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 70447CA10F83DB2900E1BF72 /* cBirthGenomeSizeHandler.h */; };
+		70447CA40F83DB2900E1BF72 /* cBirthGenomeSizeHandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70447CA20F83DB2900E1BF72 /* cBirthGenomeSizeHandler.cc */; };
+		70447CA70F83DB5600E1BF72 /* cBirthMateSelectHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 70447CA50F83DB5600E1BF72 /* cBirthMateSelectHandler.h */; };
+		70447CA80F83DB5600E1BF72 /* cBirthMateSelectHandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70447CA60F83DB5600E1BF72 /* cBirthMateSelectHandler.cc */; };
+		70447CAB0F83DBC100E1BF72 /* cBirthDemeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 70447CA90F83DBC100E1BF72 /* cBirthDemeHandler.h */; };
+		70447CAC0F83DBC100E1BF72 /* cBirthDemeHandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70447CAA0F83DBC100E1BF72 /* cBirthDemeHandler.cc */; };
 		7049F3560A66A8F500640512 /* instset-classic.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7049F3520A66A8F500640512 /* instset-classic.cfg */; };
 		7049F3570A66A8F500640512 /* instset-sex-classic.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7049F3530A66A8F500640512 /* instset-sex-classic.cfg */; };
 		7049F3580A66A8F500640512 /* instset-smt.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7049F3540A66A8F500640512 /* instset-smt.cfg */; };
@@ -466,6 +479,21 @@
 		70436B260C36C64000A05ABA /* PlatformExpert.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformExpert.cc; sourceTree = "<group>"; };
 		70436B270C36C64000A05ABA /* PlatformExpert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PlatformExpert.h; sourceTree = "<group>"; };
 		70447AA20F8010F100E1BF72 /* cMetaGenome.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cMetaGenome.h; sourceTree = "<group>"; };
+		70447BEA0F83B01000E1BF72 /* cBirthSelectionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBirthSelectionHandler.h; sourceTree = "<group>"; };
+		70447BFD0F83B47900E1BF72 /* cBirthSelectionHandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBirthSelectionHandler.cc; sourceTree = "<group>"; };
+		70447C300F83B7F400E1BF72 /* cBirthEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBirthEntry.h; sourceTree = "<group>"; };
+		70447C4C0F83C55300E1BF72 /* cBirthNeighborhoodHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBirthNeighborhoodHandler.h; sourceTree = "<group>"; };
+		70447C4D0F83C55300E1BF72 /* cBirthNeighborhoodHandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBirthNeighborhoodHandler.cc; sourceTree = "<group>"; };
+		70447C860F83D4C500E1BF72 /* cBirthGridLocalHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBirthGridLocalHandler.h; sourceTree = "<group>"; };
+		70447C870F83D4C500E1BF72 /* cBirthGridLocalHandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBirthGridLocalHandler.cc; sourceTree = "<group>"; };
+		70447C930F83D72600E1BF72 /* cBirthGlobalHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBirthGlobalHandler.h; sourceTree = "<group>"; };
+		70447C940F83D72600E1BF72 /* cBirthGlobalHandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBirthGlobalHandler.cc; sourceTree = "<group>"; };
+		70447CA10F83DB2900E1BF72 /* cBirthGenomeSizeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBirthGenomeSizeHandler.h; sourceTree = "<group>"; };
+		70447CA20F83DB2900E1BF72 /* cBirthGenomeSizeHandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBirthGenomeSizeHandler.cc; sourceTree = "<group>"; };
+		70447CA50F83DB5600E1BF72 /* cBirthMateSelectHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBirthMateSelectHandler.h; sourceTree = "<group>"; };
+		70447CA60F83DB5600E1BF72 /* cBirthMateSelectHandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBirthMateSelectHandler.cc; sourceTree = "<group>"; };
+		70447CA90F83DBC100E1BF72 /* cBirthDemeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBirthDemeHandler.h; sourceTree = "<group>"; };
+		70447CAA0F83DBC100E1BF72 /* cBirthDemeHandler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBirthDemeHandler.cc; sourceTree = "<group>"; };
 		7048A95E0EA417CD0087B7BD /* cASNativeObjectMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cASNativeObjectMethod.h; sourceTree = "<group>"; };
 		7048A9A40EA431140087B7BD /* cASCPPParameter_NativeObjectSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cASCPPParameter_NativeObjectSupport.h; sourceTree = "<group>"; };
 		7049F2D70A66859300640512 /* cHardwareTransSMT.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cHardwareTransSMT.cc; sourceTree = "<group>"; };
@@ -1469,6 +1497,7 @@
 		DCC310040762539D008F7A48 /* main */ = {
 			isa = PBXGroup;
 			children = (
+				70447BFD0F83B47900E1BF72 /* cBirthSelectionHandler.cc */,
 				709A1EE90EB6C42D006090AF /* cOrgMovementPredicate.h */,
 				709A1EEA0EB6C42D006090AF /* cResourceHistory.cc */,
 				B4FA259E0C5EB7600086D4B5 /* cPhenPlastGenotype.cc */,
@@ -1561,6 +1590,20 @@
 				709A1E540EB69DA6006090AF /* cResourceHistory.h */,
 				70310E690EDD09260044971B /* cStateGrid.h */,
 				70447AA20F8010F100E1BF72 /* cMetaGenome.h */,
+				70447BEA0F83B01000E1BF72 /* cBirthSelectionHandler.h */,
+				70447C300F83B7F400E1BF72 /* cBirthEntry.h */,
+				70447C4C0F83C55300E1BF72 /* cBirthNeighborhoodHandler.h */,
+				70447C4D0F83C55300E1BF72 /* cBirthNeighborhoodHandler.cc */,
+				70447C860F83D4C500E1BF72 /* cBirthGridLocalHandler.h */,
+				70447C870F83D4C500E1BF72 /* cBirthGridLocalHandler.cc */,
+				70447C930F83D72600E1BF72 /* cBirthGlobalHandler.h */,
+				70447C940F83D72600E1BF72 /* cBirthGlobalHandler.cc */,
+				70447CA10F83DB2900E1BF72 /* cBirthGenomeSizeHandler.h */,
+				70447CA20F83DB2900E1BF72 /* cBirthGenomeSizeHandler.cc */,
+				70447CA50F83DB5600E1BF72 /* cBirthMateSelectHandler.h */,
+				70447CA60F83DB5600E1BF72 /* cBirthMateSelectHandler.cc */,
+				70447CA90F83DBC100E1BF72 /* cBirthDemeHandler.h */,
+				70447CAA0F83DBC100E1BF72 /* cBirthDemeHandler.cc */,
 			);
 			path = main;
 			sourceTree = "<group>";
@@ -1751,6 +1794,12 @@
 				70211A5D0ECBD531004A293A /* cRCObject.h in Headers */,
 				70310E6B0EDD09260044971B /* cStateGrid.h in Headers */,
 				700D9C460F1A8F34002CC711 /* cModularityAnalysis.h in Headers */,
+				70447C4E0F83C55300E1BF72 /* cBirthNeighborhoodHandler.h in Headers */,
+				70447C880F83D4C500E1BF72 /* cBirthGridLocalHandler.h in Headers */,
+				70447C950F83D72600E1BF72 /* cBirthGlobalHandler.h in Headers */,
+				70447CA30F83DB2900E1BF72 /* cBirthGenomeSizeHandler.h in Headers */,
+				70447CA70F83DB5600E1BF72 /* cBirthMateSelectHandler.h in Headers */,
+				70447CAB0F83DBC100E1BF72 /* cBirthDemeHandler.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2110,6 +2159,13 @@
 				70AD4FA00F194F4D00AA50AC /* cGenotypeData.cc in Sources */,
 				700D9C470F1A8F34002CC711 /* cModularityAnalysis.cc in Sources */,
 				10479F2E0F1BC54B00AF9F6A /* cMutationSteps.cc in Sources */,
+				70447BFE0F83B47900E1BF72 /* cBirthSelectionHandler.cc in Sources */,
+				70447C4F0F83C55300E1BF72 /* cBirthNeighborhoodHandler.cc in Sources */,
+				70447C890F83D4C500E1BF72 /* cBirthGridLocalHandler.cc in Sources */,
+				70447C960F83D72600E1BF72 /* cBirthGlobalHandler.cc in Sources */,
+				70447CA40F83DB2900E1BF72 /* cBirthGenomeSizeHandler.cc in Sources */,
+				70447CA80F83DB5600E1BF72 /* cBirthMateSelectHandler.cc in Sources */,
+				70447CAC0F83DBC100E1BF72 /* cBirthDemeHandler.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: development/CMakeLists.txt
===================================================================
--- development/CMakeLists.txt	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/CMakeLists.txt	2009-04-02 02:11:12 UTC (rev 3200)
@@ -230,6 +230,13 @@
   ${MAIN_DIR}/avida.cc
   ${MAIN_DIR}/cAvidaConfig.cc
   ${MAIN_DIR}/cBirthChamber.cc
+  ${MAIN_DIR}/cBirthDemeHandler.cc
+  ${MAIN_DIR}/cBirthGenomeSizeHandler.cc
+  ${MAIN_DIR}/cBirthGlobalHandler.cc
+  ${MAIN_DIR}/cBirthGridLocalHandler.cc
+  ${MAIN_DIR}/cBirthMateSelectHandler.cc
+  ${MAIN_DIR}/cBirthNeighborhoodHandler.cc
+  ${MAIN_DIR}/cBirthSelectionHandler.cc
   ${MAIN_DIR}/cDeme.cc
   ${MAIN_DIR}/cDemeCellEvent.cc
   ${MAIN_DIR}/cEnvironment.cc

Modified: development/source/cpu/cHardwareBase.cc
===================================================================
--- development/source/cpu/cHardwareBase.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/cpu/cHardwareBase.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -857,24 +857,27 @@
 
 bool cHardwareBase::Inst_DoubleEnergyUsage(cAvidaContext& ctx)
 {
-  m_organism->GetPhenotype().DoubleEnergyUsage();
-  double newOrgMerit = cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy()  * m_organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+  cPhenotype& phenotype = m_organism->GetPhenotype();
+  phenotype.DoubleEnergyUsage();
+  double newOrgMerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy()  * phenotype.GetEnergyUsageRatio());
   m_organism->UpdateMerit(newOrgMerit);
   return true;
 }
 
 bool cHardwareBase::Inst_HalfEnergyUsage(cAvidaContext& ctx)
 {
-  m_organism->GetPhenotype().HalfEnergyUsage();
-  double newOrgMerit = cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy()  * m_organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+  cPhenotype& phenotype = m_organism->GetPhenotype();
+  phenotype.HalfEnergyUsage();
+  double newOrgMerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy()  * phenotype.GetEnergyUsageRatio());
   m_organism->UpdateMerit(newOrgMerit);
   return true;
 }
 
 bool cHardwareBase::Inst_DefaultEnergyUsage(cAvidaContext& ctx)
 {
-  m_organism->GetPhenotype().DefaultEnergyUsage();
-  double newOrgMerit = cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy()  * m_organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+  cPhenotype& phenotype = m_organism->GetPhenotype();
+  phenotype.DefaultEnergyUsage();
+  double newOrgMerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy()  * phenotype.GetEnergyUsageRatio());
   m_organism->UpdateMerit(newOrgMerit);
   return true;
 }

Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/cpu/cHardwareCPU.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -3665,21 +3665,23 @@
   assert(to_org != NULL);
 
   const double frac_energy_given = m_organism->GetFracEnergyDonating();
+  
+  cPhenotype& phenotype = m_organism->GetPhenotype();
 
-  double cur_energy = m_organism->GetPhenotype().GetStoredEnergy();
+  double cur_energy = phenotype.GetStoredEnergy();
   double energy_given = cur_energy * frac_energy_given;
   
   //update energy store and merit of donor
-  m_organism->GetPhenotype().ReduceEnergy(energy_given);
-  m_organism->GetPhenotype().IncreaseEnergyDonated(energy_given);
-  double senderMerit = cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy()  * m_organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+  phenotype.ReduceEnergy(energy_given);
+  phenotype.IncreaseEnergyDonated(energy_given);
+  double senderMerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy()  * phenotype.GetEnergyUsageRatio());
   m_organism->UpdateMerit(senderMerit);
-  m_organism->GetPhenotype().SetIsEnergyDonor();
+  phenotype.SetIsEnergyDonor();
   
   // update energy store and merit of donee
   to_org->GetPhenotype().ReduceEnergy(-1.0*energy_given);
   to_org->GetPhenotype().IncreaseEnergyReceived(energy_given);
-  double receiverMerit = cMerit::EnergyToMerit(to_org->GetPhenotype().GetStoredEnergy() * to_org->GetPhenotype().GetEnergyUsageRatio(), m_world);
+  double receiverMerit = to_org->GetPhenotype().ConvertEnergyToMerit(to_org->GetPhenotype().GetStoredEnergy() * to_org->GetPhenotype().GetEnergyUsageRatio());
   to_org->UpdateMerit(receiverMerit);
   to_org->GetPhenotype().SetIsEnergyReceiver();
 }
@@ -3707,21 +3709,23 @@
   assert(amount >= 0);
   assert(losspct >= 0);
   assert(losspct <= 1);
+
+  cPhenotype& phenotype = m_organism->GetPhenotype();
   
   const int update_metabolic = m_world->GetConfig().ENERGY_SHARING_UPDATE_METABOLIC.Get();
-  double energy_given = min(m_organism->GetPhenotype().GetStoredEnergy(), amount);
+  double energy_given = min(phenotype.GetStoredEnergy(), amount);
   double energy_received;
   
   //update energy store and merit of donor
-  m_organism->GetPhenotype().ReduceEnergy(energy_given);
-  m_organism->GetPhenotype().SetIsEnergyDonor();
-  m_organism->GetPhenotype().IncreaseEnergyDonated(energy_given);
-  m_organism->GetPhenotype().IncreaseNumEnergyDonations();
+  phenotype.ReduceEnergy(energy_given);
+  phenotype.SetIsEnergyDonor();
+  phenotype.IncreaseEnergyDonated(energy_given);
+  phenotype.IncreaseNumEnergyDonations();
   
   m_organism->GetDeme()->IncreaseEnergyDonated(energy_given);
   
   if(update_metabolic == 1) {
-    double senderMerit = cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy()  * m_organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+    double senderMerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy()  * phenotype.GetEnergyUsageRatio());
     m_organism->UpdateMerit(senderMerit);
   }
   
@@ -3737,7 +3741,7 @@
     to_org->GetPhenotype().ApplyDonatedEnergy();
 	  
 	  if(update_metabolic == 1) {
-      double receiverMerit = cMerit::EnergyToMerit(to_org->GetPhenotype().GetStoredEnergy() * to_org->GetPhenotype().GetEnergyUsageRatio(), m_world);
+      double receiverMerit = to_org->GetPhenotype().ConvertEnergyToMerit(to_org->GetPhenotype().GetStoredEnergy() * to_org->GetPhenotype().GetEnergyUsageRatio());
       to_org->UpdateMerit(receiverMerit);
 	  }
   }
@@ -3752,7 +3756,7 @@
                                              m_world->GetConfig().ENERGY_SHARING_METHOD.Get(),
                                              m_organism->GetID(),
                                              energy_given,
-                                             m_organism->GetPhenotype().GetStoredEnergy(),
+                                             phenotype.GetStoredEnergy(),
                                              to_org->GetID(),
                                              energy_received,
                                              to_org->GetPhenotype().GetStoredEnergy());
@@ -4258,16 +4262,17 @@
 //Move energy from an organism's received energy buffer into their energy store, recalculate merit
 bool cHardwareCPU::Inst_ReceiveDonatedEnergy(cAvidaContext& ctx)
 {
-  if(m_organism->GetCellID() < 0) {
+  if (m_organism->GetCellID() < 0) {
     return false;
   }
   
-  if(m_organism->GetPhenotype().GetEnergyInBufferAmount() > 0) {
-    m_organism->GetPhenotype().ApplyDonatedEnergy();
+  cPhenotype& phenotype = m_organism->GetPhenotype();
+  if (phenotype.GetEnergyInBufferAmount() > 0) {
+    phenotype.ApplyDonatedEnergy();
 	 
-	  if(m_world->GetConfig().ENERGY_SHARING_UPDATE_METABOLIC.Get() == 1) {
-        double receiverMerit = cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy() * m_organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
-        m_organism->UpdateMerit(receiverMerit);
+	  if (m_world->GetConfig().ENERGY_SHARING_UPDATE_METABOLIC.Get() == 1) {
+      double receiverMerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy() * phenotype.GetEnergyUsageRatio());
+      m_organism->UpdateMerit(receiverMerit);
   	}
   }
   
@@ -4315,7 +4320,8 @@
 //Update the organism's metabolic rate
 bool cHardwareCPU::Inst_UpdateMetabolicRate(cAvidaContext& ctx)
 {
-  double newmerit = cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy()  * m_organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+  cPhenotype& phenotype = m_organism->GetPhenotype();
+  double newmerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy()  * phenotype.GetEnergyUsageRatio());
   m_organism->UpdateMerit(newmerit);
   
   return true;
@@ -5912,10 +5918,12 @@
   }
   m_organism->SetSleeping(false);  //this instruction get executed at the end of a sleep cycle
   GetOrganism()->GetOrgInterface().GetDeme()->DecSleepingCount();
-  if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 2) {
-    m_organism->GetPhenotype().RefreshEnergy();
-    m_organism->GetPhenotype().ApplyToEnergyStore();
-    double newMerit = cMerit::EnergyToMerit(m_organism->GetPhenotype().GetStoredEnergy() * m_organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+
+  cPhenotype& phenotype = m_organism->GetPhenotype();
+  if (m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 2) {
+    phenotype.RefreshEnergy();
+    phenotype.ApplyToEnergyStore();
+    double newMerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy() * phenotype.GetEnergyUsageRatio());
     pop.UpdateMerit(cellID, newMerit);
   }
   return true;

Modified: development/source/cpu/cTestCPUInterface.cc
===================================================================
--- development/source/cpu/cTestCPUInterface.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/cpu/cTestCPUInterface.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -50,6 +50,11 @@
   return 0;
 }
 
+void cTestCPUInterface::GetNeighborhoodCellIDs(tArray<int>& list)
+{
+  
+}
+
 void cTestCPUInterface::Rotate(int direction)
 {
 }

Modified: development/source/cpu/cTestCPUInterface.h
===================================================================
--- development/source/cpu/cTestCPUInterface.h	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/cpu/cTestCPUInterface.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -66,6 +66,7 @@
   cOrganism* GetNeighbor();
   bool IsNeighborCellOccupied();
   int GetNumNeighbors();
+  void GetNeighborhoodCellIDs(tArray<int>& list);
   int GetNeighborCellContents() { return 0; }
   void Rotate(int direction = 1);
   void Breakpoint() { ; }

Modified: development/source/main/cBirthChamber.cc
===================================================================
--- development/source/main/cBirthChamber.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cBirthChamber.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -26,48 +26,52 @@
 #include "cBirthChamber.h"
 
 #include "cAvidaContext.h"
-#include "tArray.h"
-#include "functions.h"
+#include "cBirthDemeHandler.h"
+#include "cBirthGenomeSizeHandler.h"
+#include "cBirthGlobalHandler.h"
+#include "cBirthGridLocalHandler.h"
+#include "cBirthMateSelectHandler.h"
+#include "cBirthNeighborhoodHandler.h"
 #include "cClassificationManager.h"
-#include "cCPUMemory.h"
 #include "cGenomeUtil.h"
 #include "cGenotype.h"
 #include "cOrganism.h"
 #include "cTools.h"
 #include "cWorld.h"
 #include "cStats.h"
+#include "tArray.h"
+#include "functions.h"
 
 cBirthChamber::cBirthChamber(cWorld* world) : m_world(world)
 {
-  const int num_demes = m_world->GetConfig().NUM_DEMES.Get(); 
-  int num_orgs;
+  const int birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
 
-  num_orgs = m_world->GetConfig().BIOMIMETIC_K.Get();
-  if (0 >= num_orgs) {
-    num_orgs = m_world->GetConfig().WORLD_X.Get() * m_world->GetConfig().WORLD_Y.Get();
-  }
-
-  local_wait_entry.Resize(num_orgs);
-  deme_wait_entry.Resize(num_demes);
-}
-
-bool cBirthChamber::GetNeighborWaiting(const int & parent_id, int world_x, int world_y)
-{
-  for (int i=-1; i<=1; i++) {
-    for (int j=-1; j<=1; j++) { 
-      const int neighbor_id = GridNeighbor(parent_id, world_x, world_y, i, j);
-      if (local_wait_entry[neighbor_id].update_in >= 0) {
-        return true;
-      }
+  if (m_world->GetConfig().NUM_DEMES.Get() > 1) {
+    // Deme local takes priority, and manages the sub handlers
+    m_selection_handler = new cBirthDemeHandler(m_world, this);    
+  } else if (birth_method < NUM_LOCAL_POSITION_CHILD || birth_method == POSITION_CHILD_PARENT_FACING) { 
+    // ... else check if the birth method is one of the local ones... 
+    if (m_world->GetConfig().LEGACY_GRID_LOCAL_SELECTION.Get()) {
+      m_selection_handler = new cBirthGridLocalHandler(m_world, this);
+    } else {
+      m_selection_handler = new cBirthNeighborhoodHandler(m_world, this);
     }
+  } else if (m_world->GetConfig().SAME_LENGTH_SEX.Get() != 0) {
+    // ... else check if recombination must be with organisms of the same length
+    m_selection_handler = new cBirthGenomeSizeHandler(this);
+  } else if (m_world->GetConfig().ALLOW_MATE_SELECTION.Get()) {
+    // ... else check if we have mate selection
+    m_selection_handler = new cBirthMateSelectHandler(this);
+  } else {
+    // If everything failed until this point, use default global.
+    m_selection_handler = new cBirthGlobalHandler(this);
   }
-  return false;
 }
 
-bool cBirthChamber::EvaluateEntry(const cBirthEntry & entry) const
+bool cBirthChamber::ValidBirthEntry(const cBirthEntry& entry) const
 {
   // If there is no organism in the entry, return false.
-  if (entry.update_in == -1) return false;
+  if (entry.timestamp == -1) return false;
 
   // If there is an organism, determine if it is still alive.
   const int max_wait_time = m_world->GetConfig().MAX_BIRTH_WAIT_TIME.Get();
@@ -77,30 +81,29 @@
 
   // Otherwise, check if few enough updates have gone by...
   const int cur_update = m_world->GetStats().GetUpdate();
-  const int max_update = entry.update_in + max_wait_time;
+  const int max_update = entry.timestamp + max_wait_time;
 
   if (cur_update > max_update) return false;  // Too many updates...
 
   return true;
 }
 
-int cBirthChamber::PickRandRecGenome(cAvidaContext& ctx, const int& parent_id, int world_x, int world_y)
+void cBirthChamber::StoreAsEntry(const cMetaGenome& offspring_genome, cOrganism* parent, cBirthEntry& entry) const
 {
-  bool done = false; 
-  while (done ==false) {
-    int test_neighbor = (int) ctx.GetRandom().GetUInt(9); 
-    int i = test_neighbor / 3 - 1; 
-    int j = test_neighbor % 3 - 1;
-    int test_loc = GridNeighbor(parent_id,world_x, world_y, i, j); 		
-    if (local_wait_entry[test_loc].update_in >= 0) {
-      return test_loc;
-    }
+  cGenotype* parent_genotype = parent->GetGenotype();
+  parent_genotype->IncDeferAdjust();
+  entry.genome = offspring_genome;
+  if (m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
+    entry.energy4Offspring = parent->GetPhenotype().ExtractParentEnergy();
+    entry.merit = parent->GetPhenotype().ConvertEnergyToMerit(entry.energy4Offspring);
+  } else {
+    entry.merit = parent->GetPhenotype().GetMerit();
   }
-
-  return -1;
+  entry.parent_genotype = parent_genotype;
+  entry.timestamp = m_world->GetStats().GetUpdate();  
 }
 
-bool cBirthChamber::RegionSwap(cCPUMemory& genome0, cCPUMemory& genome1, int start0, int end0, int start1, int end1)
+bool cBirthChamber::RegionSwap(cGenome& genome0, cGenome& genome1, int start0, int end0, int start1, int end1)
 {
    assert( start0 >= 0  &&  start0 < genome0.GetSize() );
    assert( end0   >= 0  &&  end0   < genome0.GetSize() );
@@ -136,9 +139,9 @@
    return true;
 }
 
-void cBirthChamber::GenomeSwap(cCPUMemory& genome0, cCPUMemory& genome1, double& merit0, double& merit1)
+void cBirthChamber::GenomeSwap(cGenome& genome0, cGenome& genome1, double& merit0, double& merit1)
 {
-  cCPUMemory genome0_tmp = genome0;
+  cGenome genome0_tmp = genome0;
   genome0 = genome1; 
   genome1 = genome0_tmp; 
 
@@ -163,13 +166,13 @@
         
     // set child energy & merit
     child_array[0]->GetPhenotype().SetEnergy(child_energy);
-    merit_array[0] = cMerit::EnergyToMerit(child_array[0]->GetPhenotype().GetStoredEnergy(), m_world);
+    merit_array[0] = child_array[0]->GetPhenotype().ConvertEnergyToMerit(child_array[0]->GetPhenotype().GetStoredEnergy());
   } else {
     merit_array[0] = parent.GetPhenotype().GetMerit();
   }
 
   // Setup the genotype for the child
-  cGenotype * child_genotype = parent.GetGenotype();
+  cGenotype* child_genotype = parent.GetGenotype();
   
   if (parent.GetPhenotype().CopyTrue() == false) {
     // Add this genotype with only one parent since its asexual.
@@ -210,148 +213,9 @@
   return true;
 }
 
-cBirthChamber::cBirthEntry* cBirthChamber::FindSexSizeWaiting(const cMetaGenome& offspring_genome, cOrganism& parent)
-{
-  const int child_length = offspring_genome.GetSize();
 
-  // If this is a new largest genome, increase the array size.
-  if (size_wait_entry.GetSize() <= child_length) {
-    size_wait_entry.Resize(child_length + 1);
-  }
 
-  // Determine if we have an offspring of this length waiting already...
-  if ( EvaluateEntry(size_wait_entry[child_length]) == false ) {
-    cGenotype * parent_genotype = parent.GetGenotype();
-    parent_genotype->IncDeferAdjust();
-    size_wait_entry[child_length].genome = offspring_genome;
-    if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
-      size_wait_entry[child_length].energy4Offspring = parent.GetPhenotype().ExtractParentEnergy();
-      size_wait_entry[child_length].merit.EnergyToMerit(size_wait_entry[child_length].energy4Offspring, m_world);
-    } else {
-      size_wait_entry[child_length].merit = parent.GetPhenotype().GetMerit();
-    }
-    size_wait_entry[child_length].parent_genotype = parent_genotype;
-    size_wait_entry[child_length].update_in = m_world->GetStats().GetUpdate();
-    return NULL; 				
-  }
-
-  // There is already a child waiting -- do crossover between the two.
-  return &( size_wait_entry[child_length] ); 
-}
-
-cBirthChamber::cBirthEntry* cBirthChamber::FindSexMateSelectWaiting(const cMetaGenome& offspring_genome, cOrganism& parent)
-{
-  const int mate_id = parent.GetPhenotype().MateSelectID();
-
-  // If this is a new largest ID, increase the array size.
-  if (mate_select_wait_entry.GetSize() <= mate_id) {
-    mate_select_wait_entry.Resize(mate_id + 1);
-  }
-
-  // Determine if we have an offspring of this length waiting already...
-  if ( EvaluateEntry(mate_select_wait_entry[mate_id]) == false ) {
-    cGenotype * parent_genotype = parent.GetGenotype();
-    parent_genotype->IncDeferAdjust();
-    mate_select_wait_entry[mate_id].genome = offspring_genome;
-    if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
-      mate_select_wait_entry[mate_id].energy4Offspring = parent.GetPhenotype().ExtractParentEnergy();
-      mate_select_wait_entry[mate_id].merit.EnergyToMerit(mate_select_wait_entry[mate_id].energy4Offspring, m_world);
-    } else {
-      mate_select_wait_entry[mate_id].merit = parent.GetPhenotype().GetMerit();
-    }
-    mate_select_wait_entry[mate_id].parent_genotype = parent_genotype;
-    mate_select_wait_entry[mate_id].update_in = m_world->GetStats().GetUpdate();
-    return NULL;
-  }
-
-  // There is already a child waiting -- do crossover between the two.
-  return &( mate_select_wait_entry[mate_id] ); 
-}
-
-cBirthChamber::cBirthEntry* cBirthChamber::FindSexLocalWaiting(cAvidaContext& ctx, const cMetaGenome& offspring_genome,
-                                                               cOrganism& parent)
-{
-  // Collect some info for building the child.
-  const int world_x = m_world->GetConfig().WORLD_X.Get();
-  const int world_y = m_world->GetConfig().WORLD_Y.Get();
-  const int parent_id = parent.GetOrgInterface().GetCellID();
-  
-  // If nothing is waiting, store child locally.
-  if (GetNeighborWaiting(parent_id, world_x, world_y) == false) { 
-    cGenotype * parent_genotype = parent.GetGenotype();
-    parent_genotype->IncDeferAdjust();
-    local_wait_entry[parent_id].genome = offspring_genome;
-    if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
-      local_wait_entry[parent_id].energy4Offspring = parent.GetPhenotype().ExtractParentEnergy();
-      local_wait_entry[parent_id].merit.EnergyToMerit(local_wait_entry[parent_id].energy4Offspring, m_world);
-    } else {
-      local_wait_entry[parent_id].merit = parent.GetPhenotype().GetMerit();
-    }
-    local_wait_entry[parent_id].parent_genotype = parent_genotype;
-    local_wait_entry[parent_id].update_in = m_world->GetStats().GetUpdate();
-    return NULL; 				
-  }
-
-  // There is already a child waiting -- do crossover between the two.
-  int found_location = PickRandRecGenome(ctx, parent_id, world_x, world_y);
-  return &( local_wait_entry[found_location] ); 
-}
-
-cBirthChamber::cBirthEntry* cBirthChamber::FindSexDemeWaiting(const cMetaGenome& offspring_genome, cOrganism& parent)
-{
-  // Collect some info for building the child.
-  const int world_x = m_world->GetConfig().WORLD_X.Get();
-  const int world_y = m_world->GetConfig().WORLD_Y.Get();
-  const int num_demes = m_world->GetConfig().NUM_DEMES.Get();
-  const int parent_id = parent.GetOrgInterface().GetCellID();
-  
-  const int parent_deme = (int) parent_id/(world_y*world_x/num_demes);
-
-  // If nothing is waiting, store child locally.
-  if ( EvaluateEntry(deme_wait_entry[parent_deme]) == false ) { 
-    cGenotype * parent_genotype = parent.GetGenotype();
-    parent_genotype->IncDeferAdjust();
-    deme_wait_entry[parent_deme].genome = offspring_genome;
-    if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
-      deme_wait_entry[parent_deme].energy4Offspring = parent.GetPhenotype().ExtractParentEnergy();
-      deme_wait_entry[parent_deme].merit.EnergyToMerit(deme_wait_entry[parent_deme].energy4Offspring, m_world);
-    } else {
-      deme_wait_entry[parent_deme].merit = parent.GetPhenotype().GetMerit();
-    }
-    deme_wait_entry[parent_deme].parent_genotype = parent_genotype;
-    deme_wait_entry[parent_deme].update_in = m_world->GetStats().GetUpdate();
-    return NULL; 				
-  }
-
-  // There is already a child waiting -- do crossover between the two.
-  return &( deme_wait_entry[parent_deme] );
-
-}
-
-cBirthChamber::cBirthEntry* cBirthChamber::FindSexGlobalWaiting(const cMetaGenome& offspring_genome, cOrganism& parent)
-{
-  // If no other child is waiting, store this one.
-  if ( EvaluateEntry(global_wait_entry) == false ) {
-    cGenotype * parent_genotype = parent.GetGenotype();
-    parent_genotype->IncDeferAdjust();
-    global_wait_entry.genome = offspring_genome;
-    if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
-      global_wait_entry.energy4Offspring = parent.GetPhenotype().ExtractParentEnergy();
-      global_wait_entry.merit.EnergyToMerit(global_wait_entry.energy4Offspring, m_world);
-    } else {
-      global_wait_entry.merit = parent.GetPhenotype().GetMerit();
-    }
-    global_wait_entry.parent_genotype = parent_genotype;
-    global_wait_entry.update_in = m_world->GetStats().GetUpdate();
-    return NULL;
-  }
-
-  // There is already a child waiting -- do crossover between the two.
-
-  return &global_wait_entry;
-}
-
-void cBirthChamber::DoBasicRecombination(cAvidaContext& ctx, cCPUMemory& genome0, cCPUMemory& genome1,
+void cBirthChamber::DoBasicRecombination(cAvidaContext& ctx, cGenome& genome0, cGenome& genome1,
                                          double& merit0, double& merit1)
 {
   double start_frac = ctx.GetRandom().GetDouble();
@@ -380,7 +244,7 @@
   } 
 }
 
-void cBirthChamber::DoModularContRecombination(cAvidaContext& ctx, cCPUMemory& genome0, cCPUMemory& genome1,
+void cBirthChamber::DoModularContRecombination(cAvidaContext& ctx, cGenome& genome0, cGenome& genome1,
                                                double& merit0, double& merit1)
 {
   const int num_modules = m_world->GetConfig().MODULE_NUM.Get();
@@ -415,7 +279,7 @@
   } 
 }
 
-void cBirthChamber::DoModularNonContRecombination(cAvidaContext& ctx, cCPUMemory& genome0, cCPUMemory& genome1,
+void cBirthChamber::DoModularNonContRecombination(cAvidaContext& ctx, cGenome& genome0, cGenome& genome1,
                                                   double& merit0, double& merit1)
 {
   const int num_modules = m_world->GetConfig().MODULE_NUM.Get();
@@ -449,7 +313,7 @@
   } 
 }
 
-void cBirthChamber::DoModularShuffleRecombination(cAvidaContext& ctx, cCPUMemory& genome0, cCPUMemory& genome1,
+void cBirthChamber::DoModularShuffleRecombination(cAvidaContext& ctx, cGenome& genome0, cGenome& genome1,
                                                    double& merit0, double& merit1)
 {
   const int num_modules = m_world->GetConfig().MODULE_NUM.Get();
@@ -514,64 +378,35 @@
   child_genotype->IncDeferAdjust();
 }
 
-bool cBirthChamber::SubmitOffspring(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism& parent,
+bool cBirthChamber::SubmitOffspring(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism* parent,
                                     tArray<cOrganism*>& child_array, tArray<cMerit>& merit_array)
 {
-  cPhenotype& parent_phenotype = parent.GetPhenotype();
+  cPhenotype& parent_phenotype = parent->GetPhenotype();
 
   if (parent_phenotype.DivideSex() == false) {
-    return DoAsexBirth(ctx, offspring_genome, parent, child_array, merit_array);
+    return DoAsexBirth(ctx, offspring_genome, *parent, child_array, merit_array);
   }
 
   // If we make it this far, this must be a sexual or a "waiting" asexual
   // organism (which is the same as sexual with 0 recombination points)
-
-  const int birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
   
   // Find a waiting entry (locally or globally)
-  cBirthEntry * old_entry = NULL;
-  // First check if the birth method is one of the local ones... 
-  if (birth_method < NUM_LOCAL_POSITION_CHILD ||
-      birth_method == POSITION_CHILD_PARENT_FACING) { 
-    old_entry = FindSexLocalWaiting(ctx, offspring_genome, parent);
-  }
-  // ... then check if population is split into demes
-  else if (birth_method == POSITION_CHILD_DEME_RANDOM) {
-    old_entry = FindSexDemeWaiting(offspring_genome, parent);
-  }
+  cBirthEntry* old_entry = m_selection_handler->SelectOffspring(ctx, offspring_genome, parent);
 
-  // If none of the previous conditions were met, it must be global.
-  // ...check if recombination must be with organisms of the same length
-  else if (m_world->GetConfig().SAME_LENGTH_SEX.Get() != 0) {
-    old_entry = FindSexSizeWaiting(offspring_genome, parent);
-  }
-
-  // ...check if we have mate selection
-  else if (parent_phenotype.MateSelectID() >= 0) {
-    old_entry = FindSexMateSelectWaiting(offspring_genome, parent);
-  }
-
-  // If everything failed until this point, use default global.
-  else {
-    old_entry = FindSexGlobalWaiting(offspring_genome, parent);
-  }
-
   // If we couldn't find a waiting entry, this one was saved -- stop here!
-  if (old_entry == NULL) {
-    return false;
-  }
+  if (old_entry == NULL) return false;
 
   // We have now found a waiting entry.  Mark it no longer waiting and use it.
-  old_entry->update_in = -1;
+  old_entry->timestamp = -1;
 
   // If we are NOT recombining, handle that here.
   if (parent_phenotype.CrossNum() == 0 || 
       ctx.GetRandom().GetDouble() > m_world->GetConfig().RECOMBINATION_PROB.Get()) {
-    return DoPairAsexBirth(ctx, *old_entry, offspring_genome, parent, child_array, merit_array);
+    return DoPairAsexBirth(ctx, *old_entry, offspring_genome, *parent, child_array, merit_array);
   }
   // If we made it this far, RECOMBINATION will happen!
-  cCPUMemory genome0 = old_entry->genome.GetGenome();
-  cCPUMemory genome1 = offspring_genome.GetGenome();
+  cGenome genome0 = old_entry->genome.GetGenome();
+  cGenome genome1 = offspring_genome.GetGenome();
   double meritOrEnergy0;
   double meritOrEnergy1;
 
@@ -617,7 +452,7 @@
   const int two_fold_cost = m_world->GetConfig().TWO_FOLD_COST_SEX.Get();
 
   cGenotype* parent0_genotype = old_entry->parent_genotype;
-  cGenotype* parent1_genotype = parent.GetGenotype();
+  cGenotype* parent1_genotype = parent->GetGenotype();
   
   const int hw_type = offspring_genome.GetHardwareType();
   const int inst_set_id = offspring_genome.GetInstSetID();
@@ -630,8 +465,8 @@
     if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
       child_array[0]->GetPhenotype().SetEnergy(meritOrEnergy0);
       child_array[1]->GetPhenotype().SetEnergy(meritOrEnergy1);
-      meritOrEnergy0 = cMerit::EnergyToMerit(child_array[0]->GetPhenotype().GetStoredEnergy(), m_world);
-      meritOrEnergy1 = cMerit::EnergyToMerit(child_array[1]->GetPhenotype().GetStoredEnergy(), m_world);
+      meritOrEnergy0 = child_array[0]->GetPhenotype().ConvertEnergyToMerit(child_array[0]->GetPhenotype().GetStoredEnergy());
+      meritOrEnergy1 = child_array[1]->GetPhenotype().ConvertEnergyToMerit(child_array[1]->GetPhenotype().GetStoredEnergy());
     }
     
     merit_array.Resize(2);
@@ -651,7 +486,7 @@
       child_array[0] = new cOrganism(m_world, ctx, hw_type, inst_set_id, genome0);
       if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
         child_array[0]->GetPhenotype().SetEnergy(meritOrEnergy0);
-        meritOrEnergy0 = cMerit::EnergyToMerit(child_array[0]->GetPhenotype().GetStoredEnergy(), m_world);
+        meritOrEnergy0 = child_array[0]->GetPhenotype().ConvertEnergyToMerit(child_array[0]->GetPhenotype().GetStoredEnergy());
       }
       merit_array[0] = meritOrEnergy0;
 
@@ -662,7 +497,7 @@
       child_array[0] = new cOrganism(m_world, ctx, hw_type, inst_set_id, genome1);
       if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
         child_array[0]->GetPhenotype().SetEnergy(meritOrEnergy1);
-        meritOrEnergy1 = cMerit::EnergyToMerit(child_array[1]->GetPhenotype().GetStoredEnergy(), m_world);
+        meritOrEnergy1 = child_array[1]->GetPhenotype().ConvertEnergyToMerit(child_array[1]->GetPhenotype().GetStoredEnergy());
       }
       merit_array[0] = meritOrEnergy1;
 

Modified: development/source/main/cBirthChamber.h
===================================================================
--- development/source/main/cBirthChamber.h	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cBirthChamber.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -26,14 +26,10 @@
 #ifndef cBirthChamber_h
 #define cBirthChamber_h
 
-#ifndef cMerit_h
-#include "cMerit.h"
+#ifndef cBirthEntry_h
+#include "cBirthEntry.h"
 #endif
-#ifndef cMetaGenome_h
-#include "cMetaGenome.h"
-#endif
 
-
 /**
  * All genome-based organisms must go through the birth chamber, which will
  * handle any special modifications during the birth process, such as divide
@@ -43,99 +39,59 @@
  **/
 
 class cAvidaContext;
-class cCPUMemory;
+class cBirthSelectionHandler;
 class cGenome;
-class cGenotype;
 class cOrganism;
 template <class T> class tArray;
 class cWorld;
 
-class cBirthChamber {
+class cBirthChamber
+{
 private:
+  cWorld* m_world;
+  cBirthSelectionHandler* m_selection_handler;
 
-  class cBirthEntry {
-  public:
-    cMetaGenome genome;
-    double energy4Offspring;
-    cMerit merit;
-    cGenotype * parent_genotype;
-    int update_in;  // Update entry was created; Set to -1 if entry is empty.
+  tArray<cBirthEntry> m_deme_wait_entry;
 
-    cBirthEntry() : parent_genotype(NULL), update_in(-1) { ; }
-  };
   
-  cWorld* m_world;
+  cBirthChamber(); // @not_implemented
+  cBirthChamber(const cBirthChamber&); // @not_implemented
+  cBirthChamber& operator=(const cBirthChamber&); // @not_implemented
+  
 
-  cBirthEntry global_wait_entry;
-  tArray<cBirthEntry> local_wait_entry;
-  tArray<cBirthEntry> deme_wait_entry;
-  tArray<cBirthEntry> size_wait_entry;
-  tArray<cBirthEntry> mate_select_wait_entry;
+public:
+  cBirthChamber(cWorld* world);
+  ~cBirthChamber() { ; }
 
-  // mark whether that instruction has already been swapped 
-  // between two genomes; used in modular recombination
-  tArray<int> swapped0;
-  tArray<int> swapped1;
+  // Handle manipulations & tests of genome.  Return false if divide process
+  // should halt.  Place offspring in child_array.
+  bool SubmitOffspring(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism* parent,
+                       tArray<cOrganism*>& child_array, tArray<cMerit>& merit_array);  
 
+  bool ValidBirthEntry(const cBirthEntry& entry) const;
+  void StoreAsEntry(const cMetaGenome& offspring_genome, cOrganism* parent, cBirthEntry& entry) const;
 
-  // Private methods...
-  bool EvaluateEntry(const cBirthEntry & entry) const;
-
-  bool RegionSwap(cCPUMemory& genome0, cCPUMemory& genome1, int start0, int end0, int start1, int end1);
-  void GenomeSwap(cCPUMemory& genome0, cCPUMemory& genome1, double& merit0, double& merit1);
-
+private:
+  
+  bool RegionSwap(cGenome& genome0, cGenome& genome1, int start0, int end0, int start1, int end1);
+  void GenomeSwap(cGenome& genome0, cGenome& genome1, double& merit0, double& merit1);
+  
   bool DoAsexBirth(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism& parent,
                    tArray<cOrganism*>& child_array, tArray<cMerit>& merit_array);
   bool DoPairAsexBirth(cAvidaContext& ctx, const cBirthEntry& old_entry, const cMetaGenome& new_genome, cOrganism& parent,
                        tArray<cOrganism*>& child_array, tArray<cMerit>& merit_array);
   
-  cBirthEntry* FindSexLocalWaiting(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism& parent);
-  cBirthEntry* FindSexDemeWaiting(const cMetaGenome& offspring_genome, cOrganism& parent);
-  cBirthEntry* FindSexSizeWaiting(const cMetaGenome& offspring_genome, cOrganism& parent);
-  cBirthEntry* FindSexMateSelectWaiting(const cMetaGenome& offspring_genome, cOrganism& parent);
-  cBirthEntry* FindSexGlobalWaiting(const cMetaGenome& offspring_genome, cOrganism& parent);
 
-  void DoBasicRecombination(cAvidaContext& ctx, cCPUMemory& genome0, cCPUMemory& genome1, double& merit0, double& merit1);
-  void DoModularContRecombination(cAvidaContext& ctx, cCPUMemory& genome0, cCPUMemory& genome1,
+  void DoBasicRecombination(cAvidaContext& ctx, cGenome& genome0, cGenome& genome1, double& merit0, double& merit1);
+  void DoModularContRecombination(cAvidaContext& ctx, cGenome& genome0, cGenome& genome1,
                                   double& merit0, double& merit1);
-  void DoModularNonContRecombination(cAvidaContext& ctx, cCPUMemory& genome0, cCPUMemory& genome1,
+  void DoModularNonContRecombination(cAvidaContext& ctx, cGenome& genome0, cGenome& genome1,
                                      double& merit0, double& merit1);
-  void DoModularShuffleRecombination(cAvidaContext& ctx, cCPUMemory& genome0, cCPUMemory& genome1,
+  void DoModularShuffleRecombination(cAvidaContext& ctx, cGenome& genome0, cGenome& genome1,
                                      double& merit0, double& merit1);
-
-  void SetupGenotypeInfo(cOrganism* organism, cGenotype* parent0_genotype, cGenotype* parent1_genotype);
-
-  // Pick a random waiting genome from the nehighborhood for recombination
-  int PickRandRecGenome(cAvidaContext& ctx, const int& parent_id, int world_x, int world_y);
   
-
-  cBirthChamber(); // @not_implemented
-  cBirthChamber(const cBirthChamber&); // @not_implemented
-  cBirthChamber& operator=(const cBirthChamber&); // @not_implemented
-  
-public:
-  cBirthChamber(cWorld* world);
-  ~cBirthChamber() { ; }
-
-  // Handle manipulations & tests of genome.  Return false if divide process
-  // should halt.  Place offspring in child_array.
-  bool SubmitOffspring(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism& parent,
-                       tArray<cOrganism*>& child_array, tArray<cMerit>& merit_array);
-
-  // Check the neighborhood for waiting genomes
-  bool GetNeighborWaiting(const int & parent_id, int world_x, int world_y);
+  void SetupGenotypeInfo(cOrganism* organism, cGenotype* parent0_genotype, cGenotype* parent1_genotype);
 };
 
 
-#ifdef ENABLE_UNIT_TESTS
-namespace nBirthChamber {
-  /**
-   * Run unit tests
-   *
-   * @param full Run full test suite; if false, just the fast tests.
-   **/
-  void UnitTests(bool full = false);
-}
-#endif  
-
 #endif

Added: development/source/main/cBirthDemeHandler.cc
===================================================================
--- development/source/main/cBirthDemeHandler.cc	                        (rev 0)
+++ development/source/main/cBirthDemeHandler.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,66 @@
+/*
+ *  cBirthDemeHandler.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 "cBirthDemeHandler.h"
+
+#include "cBirthGenomeSizeHandler.h"
+#include "cBirthGlobalHandler.h"
+#include "cBirthGridLocalHandler.h"
+#include "cBirthMateSelectHandler.h"
+#include "cBirthNeighborhoodHandler.h"
+#include "cOrganism.h"
+#include "cWorld.h"
+
+
+cBirthDemeHandler::cBirthDemeHandler(cWorld* world, cBirthChamber* bc)
+{
+  int num_demes = world->GetConfig().NUM_DEMES.Get(); 
+  m_deme_handlers.Resize(num_demes);
+  
+  const int birth_method = world->GetConfig().BIRTH_METHOD.Get();
+  for (int i = 0; i < num_demes; i++) {
+    if (birth_method < NUM_LOCAL_POSITION_CHILD || birth_method == POSITION_CHILD_PARENT_FACING) { 
+      // ... else check if the birth method is one of the local ones... 
+      if (world->GetConfig().LEGACY_GRID_LOCAL_SELECTION.Get()) {
+        m_deme_handlers[i] = new cBirthGridLocalHandler(world, bc);
+      } else {
+        m_deme_handlers[i] = new cBirthNeighborhoodHandler(world, bc);
+      }
+    } else if (world->GetConfig().SAME_LENGTH_SEX.Get() != 0) {
+      // ... else check if recombination must be with organisms of the same length
+      m_deme_handlers[i] = new cBirthGenomeSizeHandler(bc);
+    } else if (world->GetConfig().ALLOW_MATE_SELECTION.Get()) {
+      // ... else check if we have mate selection
+      m_deme_handlers[i] = new cBirthMateSelectHandler(bc);
+    } else {
+      // If everything failed until this point, use default global.
+      m_deme_handlers[i] = new cBirthGlobalHandler(bc);
+    }
+  }
+}
+
+cBirthEntry* cBirthDemeHandler::SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent)
+{
+  return m_deme_handlers[parent->GetDemeID()]->SelectOffspring(ctx, offspring, parent);
+}

Added: development/source/main/cBirthDemeHandler.h
===================================================================
--- development/source/main/cBirthDemeHandler.h	                        (rev 0)
+++ development/source/main/cBirthDemeHandler.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,51 @@
+/*
+ *  cBirthDemeHandler.h
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 cBirthDemeHandler_h
+#define cBirthDemeHandler_h
+
+#ifndef cBirthSelectionHandler_h
+#include "cBirthSelectionHandler.h"
+#endif
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+class cBirthChamber;
+class cWorld;
+
+
+class cBirthDemeHandler : public cBirthSelectionHandler
+{
+private:
+  tArray<cBirthSelectionHandler*> m_deme_handlers;
+  
+  
+public:
+  cBirthDemeHandler(cWorld* world, cBirthChamber* bc);
+  
+  cBirthEntry* SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent);
+};
+
+#endif

Added: development/source/main/cBirthEntry.h
===================================================================
--- development/source/main/cBirthEntry.h	                        (rev 0)
+++ development/source/main/cBirthEntry.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,50 @@
+/*
+ *  cBirthEntry.h
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 cBirthEntry_h
+#define cBirthEntry_h
+
+#ifndef cMerit_h
+#include "cMerit.h"
+#endif
+#ifndef cMetaGenome_h
+#include "cMetaGenome.h"
+#endif
+
+class cGenotype;
+
+
+class cBirthEntry
+{
+public:
+  cMetaGenome genome;
+  double energy4Offspring;
+  cMerit merit;
+  cGenotype* parent_genotype;
+  int timestamp; // -1 if empty
+  
+  inline cBirthEntry() : parent_genotype(NULL), timestamp(-1) { ; }
+};
+
+#endif

Added: development/source/main/cBirthGenomeSizeHandler.cc
===================================================================
--- development/source/main/cBirthGenomeSizeHandler.cc	                        (rev 0)
+++ development/source/main/cBirthGenomeSizeHandler.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,45 @@
+/*
+ *  cBirthGenomeSizeHandler.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 "cBirthGenomeSizeHandler.h"
+
+#include "cBirthChamber.h"
+#include "cMetaGenome.h"
+
+
+cBirthEntry* cBirthGenomeSizeHandler::SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent)
+{
+  int offspring_length = offspring.GetSize();
+  
+  // If this is a new largest genome, increase the array size accordingly
+  if (m_entries.GetSize() <= offspring_length) m_entries.Resize(offspring_length + 1);
+  
+  // Determine if we have an offspring of this length waiting already...
+  if (!m_bc->ValidBirthEntry(m_entries[offspring_length])) {
+    m_bc->StoreAsEntry(offspring, parent, m_entries[offspring_length]);
+    return NULL; 				
+  }
+  
+  return &(m_entries[offspring_length]);
+}

Added: development/source/main/cBirthGenomeSizeHandler.h
===================================================================
--- development/source/main/cBirthGenomeSizeHandler.h	                        (rev 0)
+++ development/source/main/cBirthGenomeSizeHandler.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,55 @@
+/*
+ *  cBirthGenomeSizeHandler.h
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 cBirthGenomeSizeHandler_h
+#define cBirthGenomeSizeHandler_h
+
+#ifndef cBirthEntry_h
+#include "cBirthEntry.h"
+#endif
+#ifndef cBirthSelectionHandler_h
+#include "cBirthSelectionHandler.h"
+#endif
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+class cBirthChamber;
+
+
+class cBirthGenomeSizeHandler : public cBirthSelectionHandler
+{
+private:
+  cBirthChamber* m_bc;
+  tArray<cBirthEntry> m_entries;
+  
+  
+public:
+  cBirthGenomeSizeHandler(cBirthChamber* bc) : m_bc(bc) { ; }
+  
+  cBirthEntry* SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent);
+};
+
+#endif
+

Added: development/source/main/cBirthGlobalHandler.cc
===================================================================
--- development/source/main/cBirthGlobalHandler.cc	                        (rev 0)
+++ development/source/main/cBirthGlobalHandler.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,38 @@
+/*
+ *  cBirthGlobalHandler.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 "cBirthGlobalHandler.h"
+
+#include "cBirthChamber.h"
+
+
+cBirthEntry* cBirthGlobalHandler::SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent)
+{
+  if (!m_bc->ValidBirthEntry(m_entry)) {
+    m_bc->StoreAsEntry(offspring, parent, m_entry);
+    return NULL;
+  }
+  
+  return &m_entry;  
+}

Added: development/source/main/cBirthGlobalHandler.h
===================================================================
--- development/source/main/cBirthGlobalHandler.h	                        (rev 0)
+++ development/source/main/cBirthGlobalHandler.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,51 @@
+/*
+ *  cBirthGlobalHandler.h
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 cBirthGlobalHandler_h
+#define cBirthGlobalHandler_h
+
+#ifndef cBirthEntry_h
+#include "cBirthEntry.h"
+#endif
+#ifndef cBirthSelectionHandler_h
+#include "cBirthSelectionHandler.h"
+#endif
+
+class cBirthChamber;
+
+
+class cBirthGlobalHandler : public cBirthSelectionHandler
+{
+private:
+  cBirthChamber* m_bc;
+  cBirthEntry m_entry;
+
+  
+public:
+  cBirthGlobalHandler(cBirthChamber* bc) : m_bc(bc) { ; }
+  
+  cBirthEntry* SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent);
+};
+
+#endif

Added: development/source/main/cBirthGridLocalHandler.cc
===================================================================
--- development/source/main/cBirthGridLocalHandler.cc	                        (rev 0)
+++ development/source/main/cBirthGridLocalHandler.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,76 @@
+/*
+ *  cBirthGridLocalHandler.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 "cBirthGridLocalHandler.h"
+
+#include "cBirthChamber.h"
+#include "cOrganism.h"
+#include "cWorld.h"
+#include "functions.h"
+
+
+cBirthGridLocalHandler::cBirthGridLocalHandler(cWorld* world, cBirthChamber* bc)
+: m_world(world), m_bc(bc), m_world_x(m_world->GetConfig().WORLD_X.Get()), m_world_y(m_world->GetConfig().WORLD_Y.Get())
+{
+  m_entries.Resize(m_world_x * m_world_y);
+}
+
+
+cBirthEntry* cBirthGridLocalHandler::SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent)
+{
+  int parent_id = parent->GetOrgInterface().GetCellID();
+  
+  if (!hasNeighborWaiting(parent_id)) { 
+    m_bc->StoreAsEntry(offspring, parent, m_entries[parent_id]);
+    return NULL; 				
+  }
+  
+  return &(m_entries[selectRandomNeighbor(ctx, parent_id)]);
+}
+
+
+bool cBirthGridLocalHandler::hasNeighborWaiting(int parent_id)
+{
+  for (int i = -1; i <= 1; i++) {
+    for (int j = -1; j <= 1; j++) { 
+      if (m_entries[GridNeighbor(parent_id, m_world_x, m_world_y, i, j)].timestamp >= 0) return true;
+    }
+  }
+  return false;
+}
+
+
+int cBirthGridLocalHandler::selectRandomNeighbor(cAvidaContext& ctx, int parent_id)
+{
+  while (true) {
+    int test_neighbor = ctx.GetRandom().GetUInt(9);
+    int i = test_neighbor / 3 - 1; 
+    int j = test_neighbor % 3 - 1;
+    int test_loc = GridNeighbor(parent_id, m_world_x, m_world_y, i, j);
+    
+    if (m_entries[test_loc].timestamp >= 0) return test_loc;
+  }
+  
+  return -1;
+}

Added: development/source/main/cBirthGridLocalHandler.h
===================================================================
--- development/source/main/cBirthGridLocalHandler.h	                        (rev 0)
+++ development/source/main/cBirthGridLocalHandler.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,61 @@
+/*
+ *  cBirthGridLocalHandler.h
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 cBirthGridLocalHandler_h
+#define cBirthGridLocalHandler_h
+
+#ifndef cBirthSelectionHandler_h
+#include "cBirthSelectionHandler.h"
+#endif
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+
+class cWorld;
+class cBirthChamber;
+
+
+class cBirthGridLocalHandler : public cBirthSelectionHandler
+{
+private:
+  cWorld* m_world;
+  cBirthChamber* m_bc;
+  int m_world_x;
+  int m_world_y;
+  tArray<cBirthEntry> m_entries;
+  
+  
+public:
+  cBirthGridLocalHandler(cWorld* world, cBirthChamber* bc);
+  
+  cBirthEntry* SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent);
+  
+  
+private:
+  bool hasNeighborWaiting(int parent_id);
+  int selectRandomNeighbor(cAvidaContext& ctx, int parent_id);
+};
+
+#endif

Added: development/source/main/cBirthMateSelectHandler.cc
===================================================================
--- development/source/main/cBirthMateSelectHandler.cc	                        (rev 0)
+++ development/source/main/cBirthMateSelectHandler.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,55 @@
+/*
+ *  cBirthMateSelectHandler.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 "cBirthMateSelectHandler.h"
+
+#include "cBirthChamber.h"
+#include "cOrganism.h"
+
+
+cBirthEntry* cBirthMateSelectHandler::SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent)
+{
+  int mate_id = parent->GetPhenotype().MateSelectID();
+  
+  if (mate_id >= 0) {
+    // If this is a new mate id, increase the array size accordingly
+    if (m_entries.GetSize() <= mate_id) m_entries.Resize(mate_id + 1);
+    
+    // Determine if we have an offspring of this length waiting already...
+    if (!m_bc->ValidBirthEntry(m_entries[mate_id])) {
+      m_bc->StoreAsEntry(offspring, parent, m_entries[mate_id]);
+      return NULL; 				
+    }
+    return &(m_entries[mate_id]);
+  }
+  
+  // Non-mate select offspring handled globally
+  
+  if (!m_bc->ValidBirthEntry(m_non_ms_entry)) {
+    m_bc->StoreAsEntry(offspring, parent, m_non_ms_entry);
+    return NULL;
+  }
+  
+  return &m_non_ms_entry;
+}

Added: development/source/main/cBirthMateSelectHandler.h
===================================================================
--- development/source/main/cBirthMateSelectHandler.h	                        (rev 0)
+++ development/source/main/cBirthMateSelectHandler.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,56 @@
+/*
+ *  cBirthMateSelectHandler.h
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 cBirthMateSelectHandler_h
+#define cBirthMateSelectHandler_h
+
+#ifndef cBirthEntry_h
+#include "cBirthEntry.h"
+#endif
+#ifndef cBirthSelectionHandler_h
+#include "cBirthSelectionHandler.h"
+#endif
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+class cBirthChamber;
+
+
+class cBirthMateSelectHandler : public cBirthSelectionHandler
+{
+private:
+  cBirthChamber* m_bc;
+  tArray<cBirthEntry> m_entries;
+  cBirthEntry m_non_ms_entry;
+  
+  
+public:
+  cBirthMateSelectHandler(cBirthChamber* bc) : m_bc(bc) { ; }
+  
+  cBirthEntry* SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent);
+};
+
+#endif
+

Added: development/source/main/cBirthNeighborhoodHandler.cc
===================================================================
--- development/source/main/cBirthNeighborhoodHandler.cc	                        (rev 0)
+++ development/source/main/cBirthNeighborhoodHandler.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,65 @@
+/*
+ *  cBirthNeighborhoodHandler.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 "cBirthNeighborhoodHandler.h"
+
+#include "cBirthChamber.h"
+#include "cBirthEntry.h"
+#include "cOrganism.h"
+#include "cWorld.h"
+#include "functions.h"
+
+
+cBirthNeighborhoodHandler::cBirthNeighborhoodHandler(cWorld* world, cBirthChamber* bc) : m_bc(bc)
+{
+  m_entries.Resize(world->GetConfig().WORLD_X.Get() * world->GetConfig().WORLD_Y.Get());
+}
+
+
+cBirthEntry* cBirthNeighborhoodHandler::SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent)
+{
+  int parent_id = parent->GetOrgInterface().GetCellID();
+  
+  // Get all neighborhood cell ids
+  tArray<int> neighborhood;
+  parent->GetOrgInterface().GetNeighborhoodCellIDs(neighborhood);
+  
+  // Produce a list of all valid offspring waiting
+  tArray<int> valid(neighborhood.GetSize());
+  int valid_count = 0;
+  for (int i = 0; i < neighborhood.GetSize(); i++) {
+    // Store the cell id of valid birth entries in the valid list
+    if (m_bc->ValidBirthEntry(m_entries[neighborhood[i]])) valid[valid_count++] = neighborhood[i];
+  }
+  if (m_bc->ValidBirthEntry(m_entries[parent_id])) valid[valid_count++] = parent_id;
+  
+  // If no valid entries exist, store the current offspring
+  if (valid_count == 0) {
+    m_bc->StoreAsEntry(offspring, parent, m_entries[parent_id]);
+    return NULL; 				
+  }
+
+  // Select a random valid entry and return it
+  return &(m_entries[valid[ctx.GetRandom().GetUInt(valid_count)]]);
+}

Added: development/source/main/cBirthNeighborhoodHandler.h
===================================================================
--- development/source/main/cBirthNeighborhoodHandler.h	                        (rev 0)
+++ development/source/main/cBirthNeighborhoodHandler.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,53 @@
+/*
+ *  cBirthNeighborhoodHandler.h
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 cBirthNeighborhoodHandler_h
+#define cBirthNeighborhoodHandler_h
+
+#ifndef cBirthSelectionHandler_h
+#include "cBirthSelectionHandler.h"
+#endif
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+
+class cBirthChamber;
+class cWorld;
+
+
+class cBirthNeighborhoodHandler : public cBirthSelectionHandler
+{
+private:
+  cBirthChamber* m_bc;
+  tArray<cBirthEntry> m_entries;
+  
+  
+public:
+  cBirthNeighborhoodHandler(cWorld* world, cBirthChamber* bc);
+  
+  cBirthEntry* SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent);
+};
+
+#endif

Added: development/source/main/cBirthSelectionHandler.cc
===================================================================
--- development/source/main/cBirthSelectionHandler.cc	                        (rev 0)
+++ development/source/main/cBirthSelectionHandler.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,27 @@
+/*
+ *  cBirthSelectionHandler.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 "cBirthSelectionHandler.h"
+
+cBirthSelectionHandler::~cBirthSelectionHandler() { ; }

Added: development/source/main/cBirthSelectionHandler.h
===================================================================
--- development/source/main/cBirthSelectionHandler.h	                        (rev 0)
+++ development/source/main/cBirthSelectionHandler.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -0,0 +1,44 @@
+/*
+ *  cBirthSelectionHandler.h
+ *  Avida
+ *
+ *  Created by David Bryson on 4/1/09.
+ *  Copyright 2009 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 cBirthSelectionHandler_h
+#define cBirthSelectionHandler_h
+
+class cAvidaContext;
+class cBirthChamber;
+class cBirthEntry;
+class cMetaGenome;
+class cOrganism;
+
+
+class cBirthSelectionHandler
+{
+public:
+  cBirthSelectionHandler() { ; }
+  virtual ~cBirthSelectionHandler() = 0;
+  
+  virtual cBirthEntry* SelectOffspring(cAvidaContext& ctx, const cMetaGenome& offspring, cOrganism* parent) = 0;
+};
+
+#endif

Modified: development/source/main/cOrgInterface.h
===================================================================
--- development/source/main/cOrgInterface.h	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cOrgInterface.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -76,6 +76,7 @@
   virtual cOrganism* GetNeighbor() = 0;
   virtual bool IsNeighborCellOccupied() = 0;
   virtual int GetNumNeighbors() = 0;
+  virtual void GetNeighborhoodCellIDs(tArray<int>& list) = 0;
   virtual int GetFacing() = 0; //!< Returns the facing of this organism.
   virtual int GetNeighborCellContents() = 0;
   virtual void Rotate(int direction = 1) = 0;

Modified: development/source/main/cOrganism.cc
===================================================================
--- development/source/main/cOrganism.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cOrganism.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -402,7 +402,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() * GetPhenotype().GetEnergyUsageRatio(), m_world);
+    double newMerit = m_phenotype.ConvertEnergyToMerit(m_phenotype.GetStoredEnergy() * m_phenotype.GetEnergyUsageRatio());
     if(newMerit != -1) {
       m_interface->UpdateMerit(newMerit);
     }

Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cPhenotype.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -594,7 +594,7 @@
   // Setup child info...
   copy_true         = false;
   divide_sex        = false;
-  mate_select_id    = 0;
+  mate_select_id    = -1;
   cross_num         = 0;
   child_fertile     = true;
   last_child_fertile = true;
@@ -1431,7 +1431,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(cMerit::EnergyToMerit(GetStoredEnergy() * GetEnergyUsageRatio(), m_world));
+  cMerit parentMerit(ConvertEnergyToMerit(GetStoredEnergy() * GetEnergyUsageRatio()));
   SetMerit(parentMerit);
   
   return child_energy;
@@ -1716,3 +1716,14 @@
   }			 
 	
 } //End GetDiscreteEnergyLevel()
+
+
+double cPhenotype::ConvertEnergyToMerit(double energy) const
+{
+  assert(m_world->GetConfig().ENERGY_ENABLED.Get() == 1);
+  
+	double FIX_METABOLIC_RATE = m_world->GetConfig().FIX_METABOLIC_RATE.Get();
+	if (FIX_METABOLIC_RATE > 0.0) return 100 * FIX_METABOLIC_RATE;
+  
+  return 100 * energy / m_world->GetConfig().NUM_CYCLES_EXC_BEFORE_0_ENERGY.Get();
+}

Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cPhenotype.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -323,6 +323,8 @@
   int GetDiscreteEnergyLevel() const;
   double GetEnergyInBufferAmount() const { return energy_received_buffer; }
   
+  double ConvertEnergyToMerit(double energy) const;
+  
   //@MRR Organism-specific birth tracking
   double GetGMuExecTimeBorn() const {return gmu_exec_time_born;}
   int GetExecTimeBorn() const {return exec_time_born;}

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cPopulation.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -310,13 +310,13 @@
 // Activate the child, given information from the parent.
 // Return true if parent lives through this process.
 
-bool cPopulation::ActivateOffspring(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism& parent_organism)
+bool cPopulation::ActivateOffspring(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism* parent_organism)
 {
   if (m_world->GetConfig().FASTFORWARD_NUM_ORGS.Get() > 0 && GetNumOrganisms() >= m_world->GetConfig().FASTFORWARD_NUM_ORGS.Get())
   {
     return true;
   }
-  assert(&parent_organism != NULL);
+  assert(parent_organism != NULL);
   
   tArray<cOrganism*> child_array;
   tArray<cMerit> merit_array;
@@ -324,14 +324,14 @@
   // 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
-  cPhenotype& parent_phenotype = parent_organism.GetPhenotype();
-  parent_phenotype.DivideReset(parent_organism.GetGenome());
+  cPhenotype& parent_phenotype = parent_organism->GetPhenotype();
+  parent_phenotype.DivideReset(parent_organism->GetGenome());
   
   birth_chamber.SubmitOffspring(ctx, offspring_genome, parent_organism, child_array, merit_array);
   
   // First, setup the genotype of all of the offspring.
-  cGenotype* parent_genotype = parent_organism.GetGenotype();
-  const int parent_id = parent_organism.GetOrgInterface().GetCellID();
+  cGenotype* parent_genotype = parent_organism->GetGenotype();
+  const int parent_id = parent_organism->GetOrgInterface().GetCellID();
   assert(parent_id >= 0 && parent_id < cell_array.GetSize());
   cPopulationCell& parent_cell = cell_array[parent_id];
   
@@ -351,7 +351,7 @@
       child_array[i]->MutationRates().Copy(GetCell(target_cells[i]).MutationRates());
     } else {
       // Update the mutation rates of each child from its parent.
-      child_array[i]->MutationRates().Copy(parent_organism.MutationRates());
+      child_array[i]->MutationRates().Copy(parent_organism->MutationRates());
       // If there is a meta-mutation rate, do tests for it.
       if (child_array[i]->MutationRates().GetMetaCopyMutProb() > 0.0) {
         child_array[i]->MutationRates().DoMetaCopyMut(ctx);
@@ -364,11 +364,11 @@
     child_array[i]->GetPhenotype().SetMerit(merit_array[i]);
     
     // Do lineage tracking for the new organisms.
-    LineageSetupOrganism(child_array[i], parent_organism.GetLineage(),
-                         parent_organism.GetLineageLabel(), parent_genotype);
+    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());
+    child_array[i]->SetCCladeLabel(parent_organism->GetCCladeLabel());
   }
   
   // If we're not about to kill the parent, do some extra work on it.
@@ -382,7 +382,7 @@
         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
+        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());
         }
@@ -405,7 +405,7 @@
     }
     
     // Purge the mutations since last division
-    parent_organism.OffspringGenome().GetGenome().GetMutationSteps().Clear();
+    parent_organism->OffspringGenome().GetGenome().GetMutationSteps().Clear();
   }
   
   // Do any statistics on the parent that just gave birth...
@@ -423,7 +423,7 @@
     //@JEB - we may want to pass along some state information from parent to child
     if ( (m_world->GetConfig().EPIGENETIC_METHOD.Get() == EPIGENETIC_METHOD_OFFSPRING) 
          || (m_world->GetConfig().EPIGENETIC_METHOD.Get() == EPIGENETIC_METHOD_BOTH) ) {
-      child_array[i]->GetHardware().InheritState(parent_organism.GetHardware());
+      child_array[i]->GetHardware().InheritState(parent_organism->GetHardware());
     }
     
     cGenotype* child_genotype = child_array[i]->GetGenotype();
@@ -1560,8 +1560,8 @@
           cOrganism* organism = cell.GetOrganism(); 
           cPhenotype& phenotype = organism->GetPhenotype(); 
           phenotype.SetEnergy(phenotype.GetStoredEnergy() + offspring_deme_energy/static_cast<double>(target_deme.GetOrgCount())); 
-          phenotype.SetMerit(cMerit(cMerit::EnergyToMerit(phenotype.GetStoredEnergy() * phenotype.GetEnergyUsageRatio(), m_world))); 
-          totalEnergyInjectedIntoOrganisms += phenotype.GetStoredEnergy(); 
+          phenotype.SetMerit(cMerit(phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy() * phenotype.GetEnergyUsageRatio()))); 
+          totalEnergyInjectedIntoOrganisms += phenotype.GetStoredEnergy();
         } 
       } 
       target_deme.SetEnergyInjectedIntoOrganisms(totalEnergyInjectedIntoOrganisms); 
@@ -1576,7 +1576,7 @@
           cOrganism* organism = cell.GetOrganism(); 
           cPhenotype& phenotype = organism->GetPhenotype(); 
           phenotype.SetEnergy(phenotype.GetStoredEnergy() + parent_deme_energy/static_cast<double>(source_deme.GetOrgCount())); 
-          phenotype.SetMerit(cMerit(cMerit::EnergyToMerit(phenotype.GetStoredEnergy() * phenotype.GetEnergyUsageRatio(), m_world))); 
+          phenotype.SetMerit(cMerit(phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy() * phenotype.GetEnergyUsageRatio()))); 
           totalEnergyInjectedIntoOrganisms += phenotype.GetStoredEnergy(); 
         } 
       } 
@@ -4644,9 +4644,9 @@
   phenotype.SetupInject(new_genotype->GetGenome());  //TODO  sets merit to lenght of genotype
   
   if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
-    phenotype.SetMerit(cMerit(cMerit::EnergyToMerit(phenotype.GetStoredEnergy(), m_world)));
+    phenotype.SetMerit(cMerit(phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy())));
   } else {
-    phenotype.SetMerit( cMerit(new_genotype->GetTestMerit(ctx)) );
+    phenotype.SetMerit(cMerit(new_genotype->GetTestMerit(ctx)));
   }
   
   // @CAO are these really needed?

Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cPopulation.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -163,7 +163,7 @@
   void InitiatePop();
 
   // Activate the offspring of an organism in the population
-  bool ActivateOffspring(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism& parent_organism);
+  bool ActivateOffspring(cAvidaContext& ctx, const cMetaGenome& offspring_genome, cOrganism* parent_organism);
   bool ActivateParasite(cOrganism& parent, const cCodeLabel& label, const cGenome& injected_code);
   
   // Inject an organism from the outside world.

Modified: development/source/main/cPopulationCell.cc
===================================================================
--- development/source/main/cPopulationCell.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cPopulationCell.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -216,8 +216,9 @@
     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_organism->GetPhenotype().GetEnergyUsageRatio(), m_world)));
+      cPhenotype& phenotype = m_organism->GetPhenotype();
+      phenotype.ReduceEnergy(-1.0 * uptake_energy);
+      phenotype.SetMerit(cMerit(phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy() * phenotype.GetEnergyUsageRatio())));
     }
   }
 }

Modified: development/source/main/cPopulationInterface.cc
===================================================================
--- development/source/main/cPopulationInterface.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cPopulationInterface.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -59,7 +59,7 @@
 {
   assert(parent != NULL);
   assert(m_world->GetPopulation().GetCell(m_cell_id).GetOrganism() == parent);
-  return m_world->GetPopulation().ActivateOffspring(ctx, offspring_genome, *parent);
+  return m_world->GetPopulation().ActivateOffspring(ctx, offspring_genome, parent);
 }
 
 cOrganism* cPopulationInterface::GetNeighbor()
@@ -83,6 +83,17 @@
   return cell.ConnectionList().GetSize();
 }
 
+void cPopulationInterface::GetNeighborhoodCellIDs(tArray<int>& list)
+{
+  cPopulationCell& cell = m_world->GetPopulation().GetCell(m_cell_id);
+  assert(cell.IsOccupied());
+  
+  list.Resize(cell.ConnectionList().GetSize());
+  tConstListIterator<cPopulationCell> it(cell.ConnectionList());
+  int i = 0;
+  while (it.Next() != NULL) list[i++] = it.Get()->GetID();
+}
+
 int cPopulationInterface::GetFacing()
 {
 	cPopulationCell& cell = m_world->GetPopulation().GetCell(m_cell_id);

Modified: development/source/main/cPopulationInterface.h
===================================================================
--- development/source/main/cPopulationInterface.h	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/main/cPopulationInterface.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -80,6 +80,7 @@
   cOrganism* GetNeighbor();
   bool IsNeighborCellOccupied();
   int GetNumNeighbors();
+  void GetNeighborhoodCellIDs(tArray<int>& list);
   int GetFacing(); // Returns the facing of this organism.
   int GetNeighborCellContents();
   void Rotate(int direction = 1);

Modified: development/source/tools/cMerit.cc
===================================================================
--- development/source/tools/cMerit.cc	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/tools/cMerit.cc	2009-04-02 02:11:12 UTC (rev 3200)
@@ -9,7 +9,6 @@
  */
 
 #include "cMerit.h"
-#include "cWorld.h"
 
 using namespace std;
 
@@ -70,15 +69,6 @@
            test_value >= value / (1 + 1 / UINT_MAX)));
 }
 
-double cMerit::EnergyToMerit(const double orgEnergy, cWorld* m_world) {
-  assert(m_world->GetConfig().ENERGY_ENABLED.Get() == 1);
-	static double FIX_METABOLIC_RATE = m_world->GetConfig().FIX_METABOLIC_RATE.Get();
-	if(FIX_METABOLIC_RATE > 0.0)
-		return 100 * FIX_METABOLIC_RATE;
-  int inst_2_exc = m_world->GetConfig().NUM_CYCLES_EXC_BEFORE_0_ENERGY.Get();
-  return 100 * orgEnergy / (inst_2_exc);
-}
-
 ostream& operator<<(ostream& os, const cMerit& merit)
 {
   os << merit.GetDouble();

Modified: development/source/tools/cMerit.h
===================================================================
--- development/source/tools/cMerit.h	2009-04-02 02:08:26 UTC (rev 3199)
+++ development/source/tools/cMerit.h	2009-04-02 02:11:12 UTC (rev 3200)
@@ -98,26 +98,12 @@
 
   int GetNumBits() const { return bits; }
 
-  double CalcFitness(int gestation_time) const {
-    return ( gestation_time != 0 ) ? value / ((double) gestation_time) : 0; }
+  double CalcFitness(int gestation_time) const { return ( gestation_time != 0 ) ? value / ((double) gestation_time) : 0; }
 
-  static double EnergyToMerit(const double orgEnergy, cWorld* m_world);
-
   std::ostream& BinaryPrint(std::ostream& os = std::cout) const;
 };
 
 
-#ifdef ENABLE_UNIT_TESTS
-namespace nMerit {
-  /**
-   * Run unit tests
-   *
-   * @param full Run full test suite; if false, just the fast tests.
-   **/
-  void UnitTests(bool full = false);
-}
-#endif  
-
 std::ostream& operator<<(std::ostream& os, const cMerit & merit);
 
 #endif




More information about the Avida-cvs mailing list