[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