[Avida-SVN] r2521 - in development/source: actions drivers main

barrick at myxo.css.msu.edu barrick at myxo.css.msu.edu
Mon Apr 7 10:54:19 PDT 2008


Author: barrick
Date: 2008-04-07 13:54:19 -0400 (Mon, 07 Apr 2008)
New Revision: 2521

Modified:
   development/source/actions/PrintActions.cc
   development/source/drivers/cDefaultRunDriver.cc
   development/source/main/cDeme.cc
   development/source/main/cDeme.h
   development/source/main/cPopulation.cc
   development/source/main/cPopulation.h
   development/source/main/cResource.h
   development/source/main/cStats.cc
   development/source/main/cStats.h
Log:
More germline propensity options. Stat file showing number of generations between founders in demes. Command line will print out number of occupied demes when > 1.


Modified: development/source/actions/PrintActions.cc
===================================================================
--- development/source/actions/PrintActions.cc	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/actions/PrintActions.cc	2008-04-07 17:54:19 UTC (rev 2521)
@@ -103,6 +103,7 @@
 STATS_OUT_FILE(PrintDemeOrgTasksExe,        deme_org_tasks_exe.dat  );
 STATS_OUT_FILE(PrintDemeOrgReactions,       deme_org_reactions.dat  );
 STATS_OUT_FILE(PrintGermlineData,           germline.dat        );
+STATS_OUT_FILE(PrintDemeGenPerFounder,      deme_gen_between_founders.dat );
 // @WRE: Added output event for collected visit counts
 STATS_OUT_FILE(PrintCellVisitsData,         visits.dat			);
 
@@ -2693,6 +2694,7 @@
   action_lib->Register<cActionPrintDemeOrgTasks>("PrintDemeOrgTasksData");
   action_lib->Register<cActionPrintDemeOrgTasksExe>("PrintDemeOrgTasksExeData");
   action_lib->Register<cActionPrintDemeOrgReactions>("PrintDemeOrgReactionData");
+  action_lib->Register<cActionPrintDemeGenPerFounder>("PrintDemeGenPerFounderData");
 
   //Coalescence Clade Actions
   action_lib->Register<cActionPrintCCladeCounts>("PrintCCladeCounts");

Modified: development/source/drivers/cDefaultRunDriver.cc
===================================================================
--- development/source/drivers/cDefaultRunDriver.cc	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/drivers/cDefaultRunDriver.cc	2008-04-07 17:54:19 UTC (rev 2521)
@@ -136,12 +136,13 @@
         << "Fit: " << setw(9) << setprecision(7) << stats.GetAveFitness() << "  "
       //  << "Energy: " << setw(9) << setprecision(7) << stats.GetAveEnergy() << "  "
 //        << "Merit: " << setw(9) << setprecision(7) << stats.GetAveMerit() << "  "
-        << "Orgs: " << setw(6) << population.GetNumOrganisms() << "  "
+        << "Orgs: " << setw(6) << population.GetNumOrganisms() << "  ";
 //        << "Spec: " << setw(6) << setprecision(4) << stats.GetAveSpeculative() << "  "
 //        << "SWst: " << setw(6) << setprecision(4) << (((double)stats.GetSpeculativeWaste() / (double)UD_size) * 100.0) << "%"
 //        << "Thrd: " << setw(6) << stats.GetNumThreads() << "  "
 //        << "Para: " << stats.GetNumParasites()
-        << endl;
+      if (m_world->GetPopulation().GetNumDemes() > 1) cout << "Demes: " << setw(4) << stats.GetNumOccupiedDemes() << " ";
+      cout << endl;
     }
     
     

Modified: development/source/main/cDeme.cc
===================================================================
--- development/source/main/cDeme.cc	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/main/cDeme.cc	2008-04-07 17:54:19 UTC (rev 2521)
@@ -166,8 +166,8 @@
 
 void cDeme::DivideReset(cDeme& parent_deme, bool resetResources, double deme_energy)
 {
-  // inherit last value from the parent
-  generations_per_lifetime = parent_deme.GetGenerationsPerLifetime();
+  // the parent might be us, so save this value...
+  double old_avg_founder_generation = parent_deme.GetAvgFounderGeneration();
 
   // update our average founder generation
   cDoubleSum gen;  
@@ -175,6 +175,9 @@
     gen.Add( m_founder_phenotypes[i].GetGeneration() );
   }
   avg_founder_generation = gen.Average();
+  
+  // update our generations per lifetime based on current founders and parents generation
+  generations_per_lifetime = avg_founder_generation - old_avg_founder_generation;
 
   //Save statistics according to parent before reset.
   generation = parent_deme.GetGeneration() + 1;
@@ -194,14 +197,14 @@
 
 // Given the input deme founders and original ones,
 // calculate how many generations this deme went through to divide.
-void cDeme::UpdateGenerationsPerLifetime(tArray<cPhenotype>& new_founder_phenotypes) 
+void cDeme::UpdateGenerationsPerLifetime(double old_avg_founder_generation, tArray<cPhenotype>& new_founder_phenotypes) 
 { 
   cDoubleSum gen;
   for (int i=0; i< new_founder_phenotypes.GetSize(); i++) {
     gen.Add( new_founder_phenotypes[i].GetGeneration() );
   }
   double new_avg_founder_generation = gen.Average();
-  generations_per_lifetime = new_avg_founder_generation - avg_founder_generation;
+  generations_per_lifetime = new_avg_founder_generation - old_avg_founder_generation;
 }
 
 /*! Check every cell in this deme for a living organism.  If found, kill it. */

Modified: development/source/main/cDeme.h
===================================================================
--- development/source/main/cDeme.h	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/main/cDeme.h	2008-04-07 17:54:19 UTC (rev 2521)
@@ -199,7 +199,7 @@
   tArray<int>& GetFounderGenotypeIDs() { return m_founder_genotype_ids; }
   tArray<cPhenotype>& GetFounderPhenotypes() { return m_founder_phenotypes; }
   double GetAvgFounderGeneration() { return avg_founder_generation; }        
-  void UpdateGenerationsPerLifetime(tArray<cPhenotype>& new_founder_phenotypes);   
+  void UpdateGenerationsPerLifetime(double old_avg_founder_generation, tArray<cPhenotype>& new_founder_phenotypes);   
   double GetGenerationsPerLifetime() { return generations_per_lifetime; }  
 
   // --- Germline management --- //

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/main/cPopulation.cc	2008-04-07 17:54:19 UTC (rev 2521)
@@ -1220,6 +1220,8 @@
     offspring_deme_energy = source_deme_energy * deme_energy_decay * m_world->GetConfig().FRAC_PARENT_ENERGY_GIVEN_TO_DEME_AT_BIRTH.Get();
   }
   
+  bool target_successfully_seeded = true;
+  
   // Are we using germlines?  If so, we need to mutate the germline to get the
   // genome that we're going to seed the target with.
   if(m_world->GetConfig().DEMES_USE_GERMLINE.Get() == 1) {
@@ -1302,12 +1304,12 @@
 
   } else {
     // Not using germlines; things are much simpler.  Seed the target from the source.
-    SeedDeme(source_deme, target_deme);
+    target_successfully_seeded = SeedDeme(source_deme, target_deme);
   }
 
   // The source's merit must be transferred to the target, and then the source has
   // to rotate its heritable merit to its current merit.
-  target_deme.UpdateDemeMerit(source_deme);
+  if (target_successfully_seeded) target_deme.UpdateDemeMerit(source_deme);
   source_deme.UpdateDemeMerit();
   
   bool source_deme_resource_reset(true), target_deme_resource_reset(true);
@@ -1334,11 +1336,11 @@
   // Must reset target first for stats to be correctly updated!
   if(m_world->GetConfig().ENERGY_ENABLED.Get()) {
     // Transfer energy from source to target if we're using the energy model.
-    target_deme.DivideReset(source_deme, target_deme_resource_reset, offspring_deme_energy);
+    if (target_successfully_seeded) target_deme.DivideReset(source_deme, target_deme_resource_reset, offspring_deme_energy);
     source_deme.DivideReset(source_deme, source_deme_resource_reset, parent_deme_energy);
   } else {
     // Default; reset both source and target.
-    target_deme.DivideReset(source_deme, target_deme_resource_reset);
+    if (target_successfully_seeded) target_deme.DivideReset(source_deme, target_deme_resource_reset);
     source_deme.DivideReset(source_deme, source_deme_resource_reset);
   }
 
@@ -1384,11 +1386,13 @@
 
 /*! Helper method to seed a target deme from the organisms in the source deme.
 All organisms in the target deme are terminated, and a subset of the organisms in
-the source will be cloned to the target.
+the source will be cloned to the target. Returns whether target deme was successfully seeded.
 */
-void cPopulation::SeedDeme(cDeme& source_deme, cDeme& target_deme) {
+bool cPopulation::SeedDeme(cDeme& source_deme, cDeme& target_deme) {
   cRandom& random = m_world->GetRandom();
-  
+
+  bool successfully_seeded = true;
+
   // Check to see if we're doing probabilistic organism replication from source
   // to target deme.
   if(m_world->GetConfig().DEMES_PROB_ORG_TRANSFER.Get() == 0.0) {
@@ -1535,12 +1539,15 @@
         }
         case 2: 
         case 3:
+        case 4:
+        case 5:
         { // Selection based on germline propensities.
           // 2: sum the germline propensities of all organisms
           // and pick TWO based on each organism getting a 
           // weighted probability of being germline
           // 3: treat germline propensities as zero or nonzero for picking
-          
+          // 4: same as 3: but replication to target fails if only one germ.
+          // 5: same as 3: but replication fails and source dies if fewer than two germs.
           if (source_deme.GetOrgCount() < 2) {
             m_world->GetDriver().RaiseFatalException(1, "Germline DEMES_ORGANISM_SELECTION method didn't find at least two organisms in deme.");
           }
@@ -1565,26 +1572,36 @@
             }
           }
           
-          //cout << "Germline Propensity Sum: " << gp_sum.Sum() << endl;
-          //cout << "Num prospective founders: " << prospective_founders.GetSize() << endl;
+          if (m_world->GetVerbosity() > VERBOSE_SILENT) cout << "Germline Propensity Sum: " << gp_sum.Sum() << endl;
+          if (m_world->GetVerbosity() > VERBOSE_SILENT) cout << "Num prospective founders: " << prospective_founders.GetSize() << endl;
           
           if (prospective_founders.GetSize() < 2) {
+          
             // there were not enough orgs with nonzero germlines
-            // pick additional orgs at random without replacement
+            // pick additional orgs at random without replacement,
+            // unless our method forbids this
+
+            // leave the founder list empty for method 5
+            if (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() != 5) {
             
-            founders = prospective_founders;
-            
-            while(founders.GetSize() < 2) {
-              int cellid = source_deme.GetCellID(random.GetUInt(source_deme.GetSize()));
-              if( cell_array[cellid].IsOccupied() ) {
-                cOrganism * org = cell_array[cellid].GetOrganism();
-                bool found = false;
-                for(int i=0; i< founders.GetSize(); i++) {
-                  if (founders[i] == org) found = true;
+              founders = prospective_founders;
+              
+              //do not add additional founders randomly for method 4
+              if (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() != 4) {
+              
+                while(founders.GetSize() < 2) {
+                  int cellid = source_deme.GetCellID(random.GetUInt(source_deme.GetSize()));
+                  if( cell_array[cellid].IsOccupied() ) {
+                    cOrganism * org = cell_array[cellid].GetOrganism();
+                    bool found = false;
+                    for(int i=0; i< founders.GetSize(); i++) {
+                      if (founders[i] == org) found = true;
+                    }
+                    if (!found) founders.Push(cell_array[cellid].GetOrganism());
+                  }
                 }
-                if (!found) founders.Push(cell_array[cellid].GetOrganism());
-              }
-            }   
+              }  
+            }
           } else {
           
           // pick two orgs based on germline propensities from prospective founders
@@ -1646,18 +1663,22 @@
       tArray<cOrganism*> target_founders = founders; // List of organisms we're going to transfer.
 
       if ( (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 2)
-        || (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 3) )
+        || (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 3)
+        || (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 4)
+        || (m_world->GetConfig().DEMES_ORGANISM_SELECTION.Get() == 5) )
       {
         source_founders.ResizeClear(0);
         target_founders.ResizeClear(0);
         
-        source_founders.Push(founders[0]);
-        target_founders.Push(founders[1]);
+        if (founders.GetSize() > 0) source_founders.Push(founders[0]);
+        if (founders.GetSize() > 1) target_founders.Push(founders[1]);
       }
       
+      
       // We'd better have at *least* one genome.
-      assert(source_founders.GetSize()>0);
-      assert(target_founders.GetSize()>0);
+      // Methods that require a germline can sometimes come up short...
+      //assert(source_founders.GetSize()>0);
+      //assert(target_founders.GetSize()>0);
 
       // We clear the deme, but trick cPopulation::KillOrganism
       // to NOT delete the organisms, by pretending 
@@ -1697,11 +1718,15 @@
         }
       }
       
-      // Clear the demes.
-      target_deme.ClearFounders();
-      target_deme.UpdateStats();
-      target_deme.KillAll();
-
+      // Clear the target deme (if we have successfully replaced it).
+      if (target_founders.GetSize() > 0) {
+        target_deme.ClearFounders();
+        target_deme.UpdateStats();
+        target_deme.KillAll();
+      } else {
+        successfully_seeded = false;
+      }
+      
       //cout << founders.GetSize() << " founders." << endl;
 
       // Now populate the target (and optionally the source) using InjectGenotype.
@@ -1764,13 +1789,14 @@
       }
       
       // Update *source* generations per lifetime by the founders we used to seed the *target*.
-      // and *source*, so that we average over them.
-      tArray<cPhenotype> new_phenotypes;
-      new_phenotypes = new_phenotypes + target_deme.GetFounderPhenotypes();
-      new_phenotypes = new_phenotypes + source_deme.GetFounderPhenotypes();
-      source_deme.UpdateGenerationsPerLifetime(new_phenotypes);
+      // and *source*, so that we average over them. At this point, the avg_founder_generation
+      // has not been updated, so we can use the old value from the source.
+
+//      source_deme.UpdateGenerationsPerLifetime( source_deme.GetAvgFounderGeneration(), source_deme.GetFounderPhenotypes() );
+//      if (successfully_seeded) {
+//        target_deme.UpdateGenerationsPerLifetime( source_deme.GetAvgFounderGeneration(), target_deme.GetFounderPhenotypes() );
+//      }
       
-                        
       /*
       // Debug Code
       //// Count the number of orgs in each deme.
@@ -1819,13 +1845,16 @@
       */
               
       // remember to delete the old target organisms and adjust their genotypes
-      for(int i=0; i<old_target_organisms.GetSize(); ++i) {
-        old_target_organisms[i]->SetRunning(false);
-        cGenotype * genotype = old_target_organisms[i]->GetGenotype();
-        genotype->DecDeferAdjust();
-        m_world->GetClassificationManager().AdjustGenotype(*genotype);
-        delete old_target_organisms[i];
-      }
+        for(int i=0; i<old_target_organisms.GetSize(); ++i) {
+          old_target_organisms[i]->SetRunning(false);
+          cGenotype * genotype = old_target_organisms[i]->GetGenotype();
+          genotype->DecDeferAdjust();
+          m_world->GetClassificationManager().AdjustGenotype(*genotype);
+          
+          // ONLY delete target orgs if seeding was successful
+          // otherwise they still exist int he population
+          if (successfully_seeded) delete old_target_organisms[i];
+        }
       
       for(int i=0; i<old_source_organisms.GetSize(); ++i) {
         old_source_organisms[i]->SetRunning(false);
@@ -1878,6 +1907,8 @@
       //}
     }
   }
+  
+  return successfully_seeded;
 }
 
 void cPopulation::InjectDemeFounder(int _cell_id, cGenotype& _genotype, cPhenotype* _phenotype)
@@ -1905,12 +1936,12 @@
     // and germline propensity.
     organism->GetPhenotype().SetPermanentGermlinePropensity( _phenotype->GetPermanentGermlinePropensity()  );
     
-    if (m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() > 0.0) {
+    if (m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() >= 0.0) {
       organism->GetPhenotype().SetPermanentGermlinePropensity( m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() );
     }
   }
   
-  /* It requires mcuh more than this to correctly implement, do later if needed @JEB
+  /* It requires much more than this to correctly implement, do later if needed @JEB
   //Optionally, set the first organism's merit to a constant value
   //actually, we need to add so the first organism is seeded this way too...
   if (m_world->GetConfig().DEMES_DEFAULT_MERIT.Get()) {
@@ -3220,12 +3251,16 @@
 
   stats.SumDemeGenerationsPerLifetime().Clear();
 
+  stats.ClearNumOccupiedDemes();
+
   for(int i = 0; i < GetNumDemes(); i++) {
     cDeme& deme = GetDeme(i);
     if(deme.IsEmpty())  // ignore empty demes
     { 
       continue;
     }
+    stats.IncNumOccupiedDemes();
+    
     stats.SumDemeAge().Add(deme.GetAge());
     stats.SumDemeBirthCount().Add(deme.GetBirthCount());
     stats.SumDemeOrgCount().Add(deme.GetOrgCount());
@@ -3903,7 +3938,7 @@
         (m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get());
         
         
-      if (m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() > 0.0) {
+      if (m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() >= 0.0) {
          GetCell(cell_id).GetOrganism()->GetPhenotype().SetPermanentGermlinePropensity
           ( m_world->GetConfig().DEMES_FOUNDER_GERMLINE_PROPENSITY.Get() );
       }

Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/main/cPopulation.h	2008-04-07 17:54:19 UTC (rev 2521)
@@ -203,7 +203,7 @@
   void SeedDeme(cDeme& _deme, cGenotype& _genotype);
   
   //! Helper method that seeds a target deme from the organisms in the source deme.
-  void SeedDeme(cDeme& source_deme, cDeme& target_deme);
+  bool SeedDeme(cDeme& source_deme, cDeme& target_deme);
 
   //! Helper method that adds a founder organism to a deme, and sets up its phenotype
   void InjectDemeFounder(int _cell_id, cGenotype& _genotype, cPhenotype* _phenotype = NULL);

Modified: development/source/main/cResource.h
===================================================================
--- development/source/main/cResource.h	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/main/cResource.h	2008-04-07 17:54:19 UTC (rev 2521)
@@ -53,9 +53,9 @@
   double GetInitial() const { return initial; }
   double GetInflow() const { return inflow; }
   double GetOutflow() const { return outflow; }
-  double SetInitial(double _initial) { initial = _initial; }
-  double SetInflow(double _inflow) { inflow = _inflow; }
-  double SetOutflow(double _outflow) { outflow = _outflow; }
+  void SetInitial(double _initial) { initial = _initial; }
+  void SetInflow(double _inflow) { inflow = _inflow; }
+  void SetOutflow(double _outflow) { outflow = _outflow; }
 };
 
 /* class to hold all information for a single resource */

Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/main/cStats.cc	2008-04-07 17:54:19 UTC (rev 2521)
@@ -1245,7 +1245,8 @@
       genotype_ids.push_back(cell.GetOrganism()->GetGenotype()->GetID());  
     }
   }
-  assert(genotype_ids.size()>0); // How did we get to replication otherwise?
+  //assert(genotype_ids.size()>0); // How did we get to replication otherwise?
+  //@JEB some germline methods can result in empty source demes if they didn't produce a germ)
   m_deme_founders[target_deme.GetID()] = genotype_ids;
 }
 
@@ -1449,3 +1450,22 @@
   df.Endl();
 }
 
+
+void cStats::PrintDemeGenPerFounder(const cString& filename){
+  cDataFile& df = m_world->GetDataFile(filename);
+	df.WriteComment("Avida org generations between deme founders");
+	df.WriteTimeStamp();
+  df.WriteComment("First column gives the current update, all further columns give the number");
+  df.WriteComment("number of generations that passed between the parent and current deme's founders");
+
+
+	df.Write(m_update,   "Update");
+  for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+    cDeme& deme = m_world->GetPopulation().GetDeme(i);
+    double val = deme.GetGenerationsPerLifetime();
+    if ( deme.IsEmpty() ) val = -1;
+    df.Write( val, cStringUtil::Stringf("deme.%i", i)  );
+  }
+  df.Endl();
+}
+

Modified: development/source/main/cStats.h
===================================================================
--- development/source/main/cStats.h	2008-04-07 01:49:58 UTC (rev 2520)
+++ development/source/main/cStats.h	2008-04-07 17:54:19 UTC (rev 2521)
@@ -275,6 +275,7 @@
   cDoubleSum sum_deme_normalized_time_used;
   cDoubleSum sum_deme_merit;
   cDoubleSum sum_deme_generations_per_lifetime;
+  int m_num_occupied_demes;
 
   // Speculative Execution Stats
   int m_spec_total;
@@ -727,6 +728,11 @@
   void PrintDemeOrgTasks(const cString& filename);
   void PrintDemeOrgTasksExe(const cString& filename);
   void PrintDemeOrgReactions(const cString& filename);
+  void PrintDemeGenPerFounder(const cString& filename);
+
+  void IncNumOccupiedDemes() { m_num_occupied_demes++; }
+  void ClearNumOccupiedDemes() { m_num_occupied_demes = 0; }
+  int GetNumOccupiedDemes() { return m_num_occupied_demes; }
   
 protected:
   int m_deme_num_repls; //!< Number of deme replications since last PrintDemeReplicationData.




More information about the Avida-cvs mailing list