[Avida-SVN] r3093 - in development/source: actions classification main tools

ruppmatt at myxo.css.msu.edu ruppmatt at myxo.css.msu.edu
Thu Jan 8 11:48:54 PST 2009


Author: ruppmatt
Date: 2009-01-08 14:48:53 -0500 (Thu, 08 Jan 2009)
New Revision: 3093

Modified:
   development/source/actions/PrintActions.cc
   development/source/classification/cGenotype_BirthData.cc
   development/source/main/cEventList.cc
   development/source/main/cEventList.h
   development/source/main/cStats.cc
   development/source/main/cStats.h
   development/source/main/cWorld.cc
   development/source/main/cWorld.h
   development/source/tools/tList.h
Log:
Add ability to trigger events during an update based on tot_creatures.

Modified: development/source/actions/PrintActions.cc
===================================================================
--- development/source/actions/PrintActions.cc	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/actions/PrintActions.cc	2009-01-08 19:48:53 UTC (rev 3093)
@@ -87,6 +87,7 @@
 STATS_OUT_FILE(PrintReactionRewardData,     reaction_reward.dat );
 STATS_OUT_FILE(PrintCurrentReactionRewardData,     cur_reaction_reward.dat );
 STATS_OUT_FILE(PrintTimeData,               time.dat            );
+STATS_OUT_FILE(PrintExtendedTimeData,       xtime.dat           );
 STATS_OUT_FILE(PrintMutationRateData,       mutation_rates.dat  );
 STATS_OUT_FILE(PrintDivideMutData,          divide_mut.dat      );
 STATS_OUT_FILE(PrintParasiteData,           parasite.dat        );
@@ -2696,7 +2697,7 @@
   action_lib->Register<cActionPrintDominantData>("PrintDominantData");
   action_lib->Register<cActionPrintStatsData>("PrintStatsData");
   action_lib->Register<cActionPrintCountData>("PrintCountData");
-	action_lib->Register<cActionPrintMessageData>("PrintMessageData");
+  action_lib->Register<cActionPrintMessageData>("PrintMessageData");
   action_lib->Register<cActionPrintTotalsData>("PrintTotalsData");
   action_lib->Register<cActionPrintTasksData>("PrintTasksData");
   action_lib->Register<cActionPrintTasksExeData>("PrintTasksExeData");
@@ -2708,6 +2709,7 @@
   action_lib->Register<cActionPrintReactionRewardData>("PrintReactionRewardData");
   action_lib->Register<cActionPrintCurrentReactionRewardData>("PrintCurrentReactionRewardData");
   action_lib->Register<cActionPrintTimeData>("PrintTimeData");
+	action_lib->Register<cActionPrintExtendedTimeData>("PrintExtendedTimeData");
   action_lib->Register<cActionPrintMutationRateData>("PrintMutationRateData");
   action_lib->Register<cActionPrintDivideMutData>("PrintDivideMutData");
   action_lib->Register<cActionPrintParasiteData>("PrintParasiteData");
@@ -2740,7 +2742,7 @@
   // deme output files
   action_lib->Register<cActionPrintDemeAllStats>("PrintDemeAllStats");
   action_lib->Register<cActionPrintDemeAllStats>("PrintDemeStats"); //duplicate of previous
-	action_lib->Register<cActionPrintDemesTotalAvgEnergy>("PrintDemesTotalAvgEnergy");
+  action_lib->Register<cActionPrintDemesTotalAvgEnergy>("PrintDemesTotalAvgEnergy");
   action_lib->Register<cActionPrintDemeEnergySharingStats>("PrintDemeEnergySharingStats");
   action_lib->Register<cActionPrintDemeDonorStats>("PrintDemeDonorStats");
   action_lib->Register<cActionPrintDemeSpacialEnergy>("PrintDemeSpacialEnergyStats");

Modified: development/source/classification/cGenotype_BirthData.cc
===================================================================
--- development/source/classification/cGenotype_BirthData.cc	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/classification/cGenotype_BirthData.cc	2009-01-08 19:48:53 UTC (rev 3093)
@@ -31,6 +31,8 @@
   , gene_depth(0)
   , exec_born(-1)
   , generation_born(-1)
+  , birth_org_id(-1)
+  , death_org_id(-1)
   , update_deactivated(-1)
   , parent_genotype(NULL)
   , parent_species(NULL)

Modified: development/source/main/cEventList.cc
===================================================================
--- development/source/main/cEventList.cc	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/main/cEventList.cc	2009-01-08 19:48:53 UTC (rev 3093)
@@ -76,6 +76,10 @@
     }
     
     SyncEvent(entry);
+		
+		if (trigger == BIRTHS_INTERRUPT)  //Operates outside of usual event processing
+			QueueBirthInterruptEvent(start);
+		
     ++m_num_events;
     return true;
   }
@@ -133,6 +137,7 @@
   case GENERATION:
     t_val = m_world->GetStats().SumGeneration().Average();
     break;
+  case BIRTHS_INTERRUPT:
   case BIRTHS:
     t_val = m_world->GetStats().GetTotCreatures();
     break;
@@ -158,8 +163,11 @@
     if (entry->GetTrigger() == IMMEDIATE) {
       entry->GetAction()->Process(ctx);
       Delete(entry);
-    } else {
-      // Get the value of the appropriate trigger variable
+    } else if (entry->GetTrigger() != BIRTHS_INTERRUPT) {
+      //BIRTHS_INTERRUPT occur outside of update boundaries
+	  //and should not alter the behavior of other events.
+	  
+	  // Get the value of the appropriate trigger varile
       t_val = GetTriggerValue(entry->GetTrigger());
       
       if (t_val != DBL_MAX &&
@@ -187,13 +195,72 @@
              (entry->GetStart() < entry->GetStop() && entry->GetInterval() < 0)))
             Delete(entry);
       }
-    }  // end condition to do event
-    
+    } 
     entry = next_entry;
   }
 }
 
 
+/*
+   @MRR January 2007
+   I'm adding this method to have events in the population interrupt
+   mid-update to perform an event.  Right now, the only trigger is
+   when a particular value of tot_creatures is reached (BIRTHS).  At that point
+   this method will be called.  Although these events are stored in the
+   same queue as other events, they should not be processed at an
+   update boundary.  A set of events is kept and queried prior to determine
+   when this method should be called.  Some statistic values are not available
+   since they are not processed until the end of an update.
+*/
+void cEventList::ProcessInterrupt(cAvidaContext& ctx)
+{
+	double t_val = 0; // trigger value
+	
+	// Iterate through all entrys in event list
+	cEventListEntry* entry = m_head;
+	while (entry != NULL) {
+		cEventListEntry* next_entry = entry->GetNext();
+		
+		//BIRTHS_INTERRUPT occur outside of update boundaries
+		//and should not alter the behavior of other events.
+		if (entry->GetTrigger() == BIRTHS_INTERRUPT) {
+			
+			// Get the value of the appropriate trigger varile
+			t_val = GetTriggerValue(entry->GetTrigger());
+			
+			if (t_val == entry->GetStart() ) {  //This event *must* happen at this value
+				
+				// Process the Action
+				entry->GetAction()->Process(ctx);
+				
+				// Handle Interval Adjustment
+				if (entry->GetInterval() == TRIGGER_ALL) {
+					// Do Nothing
+				} else if (entry->GetInterval() == TRIGGER_ONCE) {
+					// If it is a onetime thing, remove it...
+					Delete(entry);
+					entry = NULL;
+				} else {
+					// There is an interval.. so add it
+					entry->NextInterval();
+				}
+				
+				// If the event can never happen now... excize it
+				if (entry != NULL && entry->GetStop() != TRIGGER_END &&
+					((entry->GetStart() > entry->GetStop() && entry->GetInterval() > 0) ||
+					 (entry->GetStart() < entry->GetStop() && entry->GetInterval() < 0))){
+					Delete(entry);
+				} else {
+					// We have to add this entry to the BirthInterrupt queue
+					QueueBirthInterruptEvent(entry->GetStart());
+				}
+			}
+		} 
+		entry = next_entry;
+	}
+}
+
+
 void cEventList::Sync()
 {
   cEventListEntry* entry = m_head;
@@ -257,6 +324,9 @@
       case BIRTHS:
         os << "births ";
         break;
+			case BIRTHS_INTERRUPT:
+					os << "birth_interrupt ";
+					break;
       default:
         os << "undefined ";
     }
@@ -283,6 +353,33 @@
 }
 
 
+// Dequeue a particular birth interrupt event
+void cEventList::DequeueBirthInterruptEvent(double t_val)
+{
+	double* ptr = m_birth_interrupt_queue.Remove(&t_val);
+	if (ptr != NULL) 
+		delete ptr;
+}
+
+
+// Add a birth event trigger time to avoid unnecessary processing
+void cEventList::QueueBirthInterruptEvent(double t_val)
+{
+	//See if the event is already queued; add if not
+	if (m_birth_interrupt_queue.Find(&t_val) == NULL){
+		double* val_ptr = new double(t_val);
+		m_birth_interrupt_queue.PushRear(val_ptr);
+	}
+}
+
+// Check to see whether or not a particular value is in the asynchronous
+// birth queue.
+bool cEventList::CheckBirthInterruptQueue(double t_val)
+{
+	return (m_birth_interrupt_queue.Find(&t_val) != NULL);
+}
+
+
 //// Parsing Event List File Format ////
 bool cEventList::AddEventFileFormat(const cString& in_line)
 {
@@ -315,7 +412,10 @@
   } else if (cur_word == "b" || cur_word == "births") {
     trigger = BIRTHS;
     cur_word = cur_line.PopWord();
-  } else {
+  } else if (cur_word == "o"  || cur_word == "org_id") {
+    trigger = BIRTHS_INTERRUPT;
+		cur_word = cur_line.PopWord();
+  }else {
     // If Trigger is skipped so assume IMMEDIATE
     trigger = IMMEDIATE;
   }

Modified: development/source/main/cEventList.h
===================================================================
--- development/source/main/cEventList.h	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/main/cEventList.h	2009-01-08 19:48:53 UTC (rev 3093)
@@ -36,7 +36,9 @@
 # endif
 #endif
 
+#include "tList.h"
 
+
 class cAvidaContext;
 class cString;
 class cWorld;
@@ -52,9 +54,21 @@
   tMemTrack<cEventList> mt;
 #endif
 public:
-  enum eTriggerType { UPDATE, GENERATION, IMMEDIATE, BIRTHS, UNDEFINED };
+
+  // Event Trigger Type ====================================================================
+  //  UPDATE occurs at the end of an update
+  //  GENERATION occurs at the end of an update for particular values of average generation, 
+  //             as evaluated at an update boundry
+  //  IMMEDIATE occurs at once
+  //  BIRTHS is triggered by values of tot_creatures (total creatures ever) in the stats object
+  //         as evaluated at an update boundary
+  //  UNDEFINED is undefined
+  //  BIRTH_INTERRUPT is triggered by tot_creatures values outside of update boundaries.
+  //                  Some statistical information gathered at the end of an update is not
+  //                  available or is incomplete with this option.
+  enum eTriggerType { UPDATE, GENERATION, IMMEDIATE, BIRTHS, UNDEFINED, BIRTHS_INTERRUPT };
   
-  static const double TRIGGER_BEGIN;
+  static const double TRIGGER_BEGIN;  //Are these unsafely defined? @MRR
   static const double TRIGGER_END;
   static const double TRIGGER_ALL;
   static const double TRIGGER_ONCE;
@@ -91,7 +105,7 @@
     void SetPrev(cEventListEntry* prev) { m_prev = prev; }
     void SetNext(cEventListEntry* next) { m_next = next; }
     
-    void NextInterval() { m_start += m_interval; }
+    void NextInterval(){ m_start += m_interval; }
     void Reset() { m_start = m_original_start; }
     
     // accessors
@@ -114,8 +128,12 @@
   cEventListEntry* m_head;
   cEventListEntry* m_tail;
   int m_num_events;
+  
+  tList<double> m_birth_interrupt_queue;
+  
+  void QueueBirthInterruptEvent(double t_val);
+  void DequeueBirthInterruptEvent(double t_val);
 
-
   void SyncEvent(cEventListEntry* event);
   double GetTriggerValue(eTriggerType trigger) const;
   void Delete(cEventListEntry* entry);
@@ -177,6 +195,24 @@
   void Sync(); // Get all events caught up.
 
   void PrintEventList(std::ostream& os = std::cout);
+  
+  /**
+   * Returns true if a particular org_id (or Stats::tot_creature) value is present
+   * in the interrupt queue.
+   *
+   * @param t_value The value being checked.
+   **/
+  bool CheckBirthInterruptQueue(double t_val);
+  
+  
+  /**
+    * This function is called to process an event outside of an update boundary.
+	* Some data may be missing, inaccurate, or incomplete if processing is required
+	* at the end of an update.
+	* 
+	* @param ctx  Avida context
+	**/
+  void cEventList::ProcessInterrupt(cAvidaContext& ctx);
 };
 
 

Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/main/cStats.cc	2009-01-08 19:48:53 UTC (rev 3093)
@@ -40,6 +40,7 @@
 #include "cOrgMessagePredicate.h"
 #include "cOrgMovementPredicate.h"
 #include "cReaction.h"
+#include "cEventList.h"
 
 #include "functions.h"
 
@@ -429,6 +430,11 @@
 
 void cStats::RecordBirth(int cell_id, int genotype_id, bool breed_true)
 {
+
+	
+	if (m_world->GetEventsList()->CheckBirthInterruptQueue(tot_organisms) == true)
+		m_world->GetEventsList()->ProcessInterrupt(m_world->GetDefaultContext());
+		
   tot_organisms++;
   num_births++;
 
@@ -1138,6 +1144,18 @@
 }
 
 
+//@MRR Add additional time information
+void cStats::PrintExtendedTimeData(const cString& filename)
+{
+	cDataFile& df = m_world->GetDataFile(filename);
+	df.WriteTimeStamp();
+	df.Write(m_update, "update");
+	df.Write(avida_time, "avida time");
+	df.Write(num_executed, "num_executed");
+	df.Write(tot_organisms, "num_organisms");
+	df.Endl();
+}
+
 void cStats::PrintMutationRateData(const cString& filename)
 {
   cDataFile& df = m_world->GetDataFile(filename);

Modified: development/source/main/cStats.h
===================================================================
--- development/source/main/cStats.h	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/main/cStats.h	2009-01-08 19:48:53 UTC (rev 3093)
@@ -766,7 +766,8 @@
   void PrintSleepData(const cString& filename);
   void PrintCompetitionData(const cString& filename);
   void PrintCellVisitsData(const cString& filename);
-
+  void PrintExtendedTimeData(const cString& filename);
+  
   // deme predicate stats
   void IncEventCount(int x, int y);
   void IncPredSat(int cell_id);

Modified: development/source/main/cWorld.cc
===================================================================
--- development/source/main/cWorld.cc	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/main/cWorld.cc	2009-01-08 19:48:53 UTC (rev 3093)
@@ -105,8 +105,6 @@
 	if (m_conf->TRACK_CCLADES.Get() > 0)
 		m_class_mgr->LoadCCladeFounders(m_conf->TRACK_CCLADES_IDS.Get());
   
-	m_pop = new cPopulation(this);
-        m_pop->InitiatePop();
   
   // Setup Event List
   m_event_list = new cEventList(this);
@@ -114,8 +112,10 @@
     cerr << "Error: Unable to load events" << endl;
     Avida::Exit(-1);
   }
+	
+	m_pop = new cPopulation(this);
+  m_pop->InitiatePop();
   
-  
   const bool revert_fatal = m_conf->REVERT_FATAL.Get() > 0.0;
   const bool revert_neg = m_conf->REVERT_DETRIMENTAL.Get() > 0.0;
   const bool revert_neut = m_conf->REVERT_NEUTRAL.Get() > 0.0;

Modified: development/source/main/cWorld.h
===================================================================
--- development/source/main/cWorld.h	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/main/cWorld.h	2009-01-08 19:48:53 UTC (rev 3093)
@@ -128,6 +128,8 @@
 
   // @DMB - Inherited from cAvidaDriver heritage
   void GetEvents(cAvidaContext& ctx);
+	
+	cEventList* GetEventsList() { return m_event_list; }
 
   // Save to archive 
   template<class Archive>

Modified: development/source/tools/tList.h
===================================================================
--- development/source/tools/tList.h	2009-01-07 13:59:54 UTC (rev 3092)
+++ development/source/tools/tList.h	2009-01-08 19:48:53 UTC (rev 3093)
@@ -262,6 +262,7 @@
   // Find by value
   T* Find(T* _in) const
   {
+		if (size == 0) return NULL;
     tListNode<T>* test = root.next;
     while (test != &root) {
       if ( *(test->data) == *(_in) ) return test->data;
@@ -418,6 +419,7 @@
   }
   
   
+  
 private:  
   template<typename V> bool FindNode(V (T::*fun)() const, V value, tListNode<T>*& node) const
   {
@@ -453,6 +455,12 @@
 
 
 
+
+
+
+
+
+
 template <class T> class tBaseIterator
 {
   friend class tList<T>;




More information about the Avida-cvs mailing list