[avida-cvs] avida CVS commits: /current/source/cpu hardware_4stack.cc hardware_4stack.hh hardware_base.hh hardware_cpu.cc hardware_cpu.hh test_util.cc test_util.hh /current/source/event cPopulation.events cPopulation_construct_event_auto.ci cPopulation_descr.ci cPopulation_enums_auto.ci cPopulation_event_list cPopulation_name2enum_auto.ci cPopulation_process_auto.ci population_event_factory.cc /current/source/main Makefile.am avida.cc callback_util.cc callback_util.hh genebank.cc inject_genebank.cc inject_genebank.hh inject_genotype.cc inject_genotype.hh organism.cc organism.hh pop_interface.cc pop_interface.hh population.cc population.hh /current/source/support Makefile.am genesis.4stack inst_set.4stack /current/source/support/preset_organisms Makefile.am organism.4stack organism.parasite /current/source/viewers symbol_util.cc text_screen.hh

wisnelaw avida-cvs at alife.org
Fri Aug 8 04:24:20 PDT 2003


wisnelaw		Thu Aug  7 20:24:20 2003 EDT

  Added files:                 
    /avida/current/source/main	inject_genebank.cc inject_genebank.hh 
                              	inject_genotype.cc inject_genotype.hh 
    /avida/current/source/support	genesis.4stack inst_set.4stack 
    /avida/current/source/support/preset_organisms	organism.4stack 
                                                  	organism.parasite 

  Modified files:              
    /avida/current/source/cpu	hardware_4stack.cc hardware_4stack.hh 
                             	hardware_base.hh hardware_cpu.cc 
                             	hardware_cpu.hh test_util.cc test_util.hh 
    /avida/current/source/event	cPopulation.events 
                               	cPopulation_construct_event_auto.ci 
                               	cPopulation_descr.ci 
                               	cPopulation_enums_auto.ci 
                               	cPopulation_event_list 
                               	cPopulation_name2enum_auto.ci 
                               	cPopulation_process_auto.ci 
                               	population_event_factory.cc 
    /avida/current/source/main	Makefile.am avida.cc callback_util.cc 
                              	callback_util.hh genebank.cc organism.cc 
                              	organism.hh pop_interface.cc 
                              	pop_interface.hh population.cc 
                              	population.hh 
    /avida/current/source/support	Makefile.am 
    /avida/current/source/support/preset_organisms	Makefile.am 
    /avida/current/source/viewers	symbol_util.cc text_screen.hh 
  Log:
  added parasite tracking for 4-stack cpus
  added events "print_dom_parasite" and "detail_parasite_pop"
  fixed more problems with the ncurses viewer
  added default organisms and setting for the 4-stack cpu
  
  
  
-------------- next part --------------
Index: avida/current/source/cpu/hardware_4stack.cc
diff -u avida/current/source/cpu/hardware_4stack.cc:1.11 avida/current/source/cpu/hardware_4stack.cc:1.12
--- avida/current/source/cpu/hardware_4stack.cc:1.11	Thu Jul 31 15:34:27 2003
+++ avida/current/source/cpu/hardware_4stack.cc	Thu Aug  7 20:24:18 2003
@@ -51,6 +51,7 @@
      heads[i] = in_thread.heads[i];
    }
    input_pointer = in_thread.input_pointer;
+   owner = in_thread.owner;
 }
 
 cHardware4Stack_Thread::~cHardware4Stack_Thread() {}
@@ -67,6 +68,7 @@
   input_pointer = in_thread.input_pointer;
   input_buf = in_thread.input_buf;
   output_buf = in_thread.output_buf;
+  owner = in_thread.owner;
 }
 
 void cHardware4Stack_Thread::Reset(cHardwareBase * in_hardware, int _id)
@@ -82,11 +84,9 @@
   output_buf.Clear();
   read_label.Clear();
   next_label.Clear();
+  owner = NULL;
 }
 
-
-
-
 void cHardware4Stack_Thread::SaveState(ostream & fp){
   assert(fp.good());
   fp << "cHardware4Stack_Thread" << endl;
@@ -115,8 +115,6 @@
   next_label.SaveState(fp);
 }
 
-
-
 void cHardware4Stack_Thread::LoadState(istream & fp){
   assert(fp.good());
   cString foo;
@@ -962,9 +960,10 @@
 }
 
 // This is the code run by the INFECTED organism.  Its function is to SPREAD infection.
-bool cHardware4Stack::Inject_Parasite(int mem_space_used, double mut_multiplier)
+bool cHardware4Stack::InjectParasite(double mut_multiplier)
 {
   const int end_pos = GetHead(HEAD_WRITE).GetPosition();
+  const int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
 
   // Make sure the creature will still be above the minimum size,
   if (end_pos <= 0) {
@@ -984,20 +983,23 @@
 
   int inject_signal = false;
 
+  if(injected_code.GetSize()>0)
+    inject_signal = organism->InjectParasite(injected_code);
+  
   //************* CALL GOES HERE ******************//
   // spin around randomly (caution: possible organism dizziness)
-  const int num_neighbors = organism->GetNeighborhoodSize();
-  for(unsigned int i=0; i<g_random.GetUInt(num_neighbors); i++)
-    organism->Rotate(1);
+  //const int num_neighbors = organism->GetNeighborhoodSize();
+  //for(unsigned int i=0; i<g_random.GetUInt(num_neighbors); i++)
+  //  organism->Rotate(1);
 
   // If we don't have a host, stop here.
-  cOrganism * host_organism = organism->GetNeighbor();
+  //cOrganism * host_organism = organism->GetNeighbor();
   
  
-  if(host_organism!=NULL)
-    {
-      inject_signal = host_organism->GetHardware().Inject_Host(GetLabel(), injected_code);
-    }
+  //if(host_organism!=NULL)
+  //  {
+  //    
+  //  }
  
   //************** CALL ENDS HERE ******************//
 
@@ -1020,7 +1022,7 @@
 }
 
 //This is the code run by the TARGET of an injection.  This RECIEVES the infection.
-bool cHardware4Stack::Inject_Host(const cCodeLabel & in_label, const cGenome & inject_code)
+bool cHardware4Stack::InjectHost(const cCodeLabel & in_label, const cGenome & inject_code)
 {
   // Make sure the genome will be below max size after injection.
 
@@ -2349,10 +2351,9 @@
 
 bool cHardware4Stack::Inst_Inject()
 {
-  const int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace(); 
   double mut_multiplier = 1;
 
-  return Inject_Parasite(mem_space_used, mut_multiplier);
+  return InjectParasite(mut_multiplier);
 }
 
 
Index: avida/current/source/cpu/hardware_4stack.hh
diff -u avida/current/source/cpu/hardware_4stack.hh:1.7 avida/current/source/cpu/hardware_4stack.hh:1.8
--- avida/current/source/cpu/hardware_4stack.hh:1.7	Thu Jul 31 15:34:27 2003
+++ avida/current/source/cpu/hardware_4stack.hh	Thu Aug  7 20:24:18 2003
@@ -26,6 +26,7 @@
 class cInstLibBase;
 class cOrganism;
 class cMutation;
+class cInjectGenotype;
 
 //new-style constant declarations - law 
 static const int NUM_LOCAL_STACKS = 3;
@@ -59,6 +60,9 @@
   tBuffer<int> output_buf;
   cCodeLabel read_label;
   cCodeLabel next_label;
+  // If this thread was spawned by Inject, this will point to the genotype 
+  // of the parasite running the thread.  Otherwise, it will be NULL.
+  cInjectGenotype * owner;
 public:
   cHardware4Stack_Thread(cHardwareBase * in_hardware=NULL, int _id=-1);
   cHardware4Stack_Thread(const cHardware4Stack_Thread & in_thread, int _id=-1);
@@ -225,6 +229,8 @@
   inline void PrevThread(); // Shift the current thread in use.
   inline void NextThread();
   inline void SetThread(int value);
+  inline cInjectGenotype * GetThreadOwner(); 
+  inline void SetThreadOwner(cInjectGenotype * in_genotype);
 
   // --------  Tests  --------
 
@@ -252,8 +258,8 @@
   c4StackHead FindFullLabel(const cCodeLabel & in_label);
 
   int GetType() const { return HARDWARE_TYPE_CPU_4STACK; }
-  bool Inject_Parasite(int mem_space_used, double mut_multiplier);
-  bool Inject_Host(const cCodeLabel & in_label, const cGenome & injection);
+  bool InjectParasite(double mut_multiplier);
+  bool InjectHost(const cCodeLabel & in_label, const cGenome & injection);
   int InjectThread(const cCodeLabel &, const cGenome &) { return -1; }
   void Mutate(const int mut_point);
   int PointMutate(const double mut_rate);
@@ -426,8 +432,18 @@
 
 inline void cHardware4Stack::SetThread(int value)
 {
-     if (value>=0 && value < GetNumThreads())
-          cur_thread=value;
+  if (value>=0 && value < GetNumThreads())
+    cur_thread=value;
+}
+
+inline cInjectGenotype * cHardware4Stack::GetThreadOwner() 
+{ 
+  return threads[cur_thread].owner; 
+}
+
+inline void cHardware4Stack::SetThreadOwner(cInjectGenotype * in_genotype)
+{ 
+  threads[cur_thread].owner = in_genotype; 
 }
 
 /*inline void cHardware4Stack::StackFlip()
Index: avida/current/source/cpu/hardware_base.hh
diff -u avida/current/source/cpu/hardware_base.hh:1.19 avida/current/source/cpu/hardware_base.hh:1.20
--- avida/current/source/cpu/hardware_base.hh:1.19	Thu Jul 31 15:34:27 2003
+++ avida/current/source/cpu/hardware_base.hh	Thu Aug  7 20:24:18 2003
@@ -52,7 +52,7 @@
 
   // --------  Other Virtual Tools --------
   virtual int GetType() const = 0;
-  virtual bool Inject_Host(const cCodeLabel & in_label,
+  virtual bool InjectHost(const cCodeLabel & in_label,
 		      const cGenome & injection) = 0;
   virtual int InjectThread(const cCodeLabel & in_label,
 			   const cGenome & injection) = 0;
Index: avida/current/source/cpu/hardware_cpu.cc
diff -u avida/current/source/cpu/hardware_cpu.cc:1.54 avida/current/source/cpu/hardware_cpu.cc:1.55
--- avida/current/source/cpu/hardware_cpu.cc:1.54	Thu Jul 31 15:34:27 2003
+++ avida/current/source/cpu/hardware_cpu.cc	Thu Aug  7 20:24:18 2003
@@ -1090,7 +1090,7 @@
 }
 
 
-bool cHardwareCPU::Inject_Host(const cCodeLabel & in_label, const cGenome & injection)
+bool cHardwareCPU::InjectHost(const cCodeLabel & in_label, const cGenome & injection)
 {
   // Make sure the genome will be below max size after injection.
 
@@ -2764,7 +2764,7 @@
   GetLabel().Rotate(1, NUM_NOPS);
 
   const bool inject_signal =
-    host_organism->GetHardware().Inject_Host(GetLabel(), inject_code);
+    host_organism->GetHardware().InjectHost(GetLabel(), inject_code);
   if (inject_signal == 1) {
     Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
     return false; // Inject failed.
Index: avida/current/source/cpu/hardware_cpu.hh
diff -u avida/current/source/cpu/hardware_cpu.hh:1.33 avida/current/source/cpu/hardware_cpu.hh:1.34
--- avida/current/source/cpu/hardware_cpu.hh:1.33	Thu Jul 31 15:34:27 2003
+++ avida/current/source/cpu/hardware_cpu.hh	Thu Aug  7 20:24:18 2003
@@ -216,7 +216,7 @@
   cCPUHead FindFullLabel(const cCodeLabel & in_label);
 
   int GetType() const { return HARDWARE_TYPE_CPU_ORIGINAL; }
-  bool Inject_Host(const cCodeLabel & in_label, const cGenome & injection);
+  bool InjectHost(const cCodeLabel & in_label, const cGenome & injection);
   int InjectThread(const cCodeLabel & in_label, const cGenome & injection);
   void InjectCode(const cGenome & injection, const int line_num);
   void InjectCodeThread(const cGenome & injection, const int line_num);
Index: avida/current/source/cpu/test_util.cc
diff -u avida/current/source/cpu/test_util.cc:1.7 avida/current/source/cpu/test_util.cc:1.8
--- avida/current/source/cpu/test_util.cc:1.7	Sat May 17 14:23:25 2003
+++ avida/current/source/cpu/test_util.cc	Thu Aug  7 20:24:18 2003
@@ -12,6 +12,7 @@
 
 #include "../main/genome.hh"
 #include "../main/genotype.hh"
+#include "../main/inject_genotype.hh"
 #include "hardware_method.hh"
 #include "../main/inst_util.hh"
 #include "../main/organism.hh"
@@ -21,10 +22,8 @@
 #include "hardware_base.hh"
 #include "test_cpu.hh"
 
-
 using namespace std;
 
-
 void cTestUtil::PrintGenome(const cGenome & genome, cString filename,
 			    cGenotype * genotype, int update_out)
 {
@@ -121,6 +120,108 @@
   }
   fp << endl; // Skip line
 
+  // Display the genome
+  const cInstSet & inst_set =
+    test_info.GetTestOrganism()->GetHardware().GetInstSet();
+  cInstUtil::SaveGenome(fp, inst_set, genome);
+}
+
+void cTestUtil::PrintGenome(cInjectGenotype * inject_genotype, 
+			    const cGenome & genome, cString filename, int update_out)
+{
+  if (filename == "") filename.Set("p%03d-unnamed", genome.GetSize());
+
+  // Build the test info for printing.
+  cCPUTestInfo test_info;
+  test_info.TestThreads();
+  cTestCPU::TestGenome(test_info, genome);
+
+  // Open the file...
+
+  ofstream fp(filename());
+
+  // @CAO Fix!!!!!!
+  if( fp.good() == false ) {
+    cerr << "Unable to open output file '" <<  filename() << "'" <<
+    endl;
+    return;
+  }
+
+  // Print the useful info at the top...
+
+  fp << "# Filename........: " << filename << endl;
+
+  if (update_out >= 0) fp << "# Update Output...: " << update_out <<
+  endl;
+  else fp << "# Update Output...: N/A" << endl;
+
+  //fp << "# Is Viable.......: " << test_info.IsViable()
+  //<< endl
+  //   << "# Repro Cycle Size: " << test_info.GetMaxCycle()
+  //   << endl
+  //   << "# Depth to Viable.: " << test_info.GetDepthFound()
+  //   << endl;
+
+  if (inject_genotype != NULL) {
+    fp << "# Update Created..: " << inject_genotype->GetUpdateBorn()     <<
+       endl
+       << "# Genotype ID.....: " << inject_genotype->GetID()             <<
+       endl
+       << "# Parent Gen ID...: " << inject_genotype->GetParentID()       <<
+       endl
+       << "# Tree Depth......: " << inject_genotype->GetDepth()          <<
+       endl
+      //<< "# Parent Distance.: " << inject_genotype->GetParentDistance() <<
+      // endl
+      ;
+  }
+  fp << endl;
+
+  //const int num_levels = test_info.GetMaxDepth() + 1;
+  /*for (int j = 0; j < num_levels; j++) {
+    fp << "# Generation: " << j << endl;
+    cOrganism * organism = test_info.GetTestOrganism(j);
+    assert(organism != NULL);
+    cPhenotype & phenotype = organism->GetPhenotype();
+
+    fp << "# Merit...........: "
+       << setw(12) << setfill(' ') << phenotype.GetMerit() << endl;
+    fp << "# Gestation Time..: "
+       << setw(12) << setfill(' ') << phenotype.GetGestationTime() << endl;
+    fp << "# Fitness.........: "
+       << setw(12) << setfill(' ') << phenotype.GetFitness() << endl;
+    fp << "# Errors..........: "
+       << setw(12) << setfill(' ') << phenotype.GetLastNumErrors() << endl;
+    fp << "# Genome Size.....: "
+       << setw(12) << setfill(' ') << organism->GetGenome().GetSize() << endl;
+    fp << "# Copied Size.....: "
+       << setw(12) << setfill(' ') << phenotype.GetCopiedSize() << endl;
+    fp << "# Executed Size...: "
+       << setw(12) << setfill(' ') << phenotype.GetExecutedSize() << endl;
+
+    fp << "# Offspring.......: ";
+    if (phenotype.GetNumDivides() == 0)
+      fp << setw(12) << setfill(' ') << "NONE";
+    else if (phenotype.CopyTrue() == true)
+      fp << setw(12) << setfill(' ') << "SELF";
+    else if (test_info.GetCycleTo() != -1)
+      fp << setw(12) << setfill(' ') << test_info.GetCycleTo();
+    else
+      fp << setw(12) << setfill(' ') << (j+1);
+    fp << endl;
+
+    fp << endl;     // Skip line
+    }
+  
+  // Display the tasks performed...
+  cPhenotype & phenotype = test_info.GetTestOrganism()->GetPhenotype();
+  for (int i = 0; i < phenotype.GetEnvironment().GetTaskLib().GetSize(); i++) {
+    fp << "# "<< phenotype.GetEnvironment().GetTaskLib().GetTask(i).GetName()
+       << "\t" << phenotype.GetLastTaskCount()[i]
+       << endl;
+  }
+  fp << endl; // Skip line
+  */
   // Display the genome
   const cInstSet & inst_set =
     test_info.GetTestOrganism()->GetHardware().GetInstSet();
Index: avida/current/source/cpu/test_util.hh
diff -u avida/current/source/cpu/test_util.hh:1.2 avida/current/source/cpu/test_util.hh:1.3
--- avida/current/source/cpu/test_util.hh:1.2	Wed Dec  5 22:11:40 2001
+++ avida/current/source/cpu/test_util.hh	Thu Aug  7 20:24:18 2003
@@ -17,11 +17,14 @@
 
 class cGenome;
 class cGenotype;
+class cInjectGenotype;
 
 class cTestUtil {
 public:
   static void PrintGenome(const cGenome & genome, cString filename="",
 			  cGenotype * genotype=NULL, int update_out=-1);
+  static void PrintGenome(cInjectGenotype * genotype, const cGenome & genome, 
+			  cString filename="", int update_out=-1);
 };
 
 #endif
Index: avida/current/source/event/cPopulation.events
diff -u avida/current/source/event/cPopulation.events:1.41 avida/current/source/event/cPopulation.events:1.42
--- avida/current/source/event/cPopulation.events:1.41	Wed Jul 16 19:36:54 2003
+++ avida/current/source/event/cPopulation.events	Thu Aug  7 20:24:18 2003
@@ -77,8 +77,6 @@
   cAvidaDriver_Base::main_driver->SetDone();
 }
 
-
-
 echo
 :descr:
 /**
@@ -428,7 +426,36 @@
 cGenotype * dom = population->GetGenebank().GetBestGenotype();
 cString filename(in_filename);
 if (filename == "") filename.Set("genebank/%s", dom->GetName()());
-cTestUtil::PrintGenome(dom->GetGenome(), filename, dom, population->GetUpdate());
+cTestUtil::PrintGenome(dom->GetGenome(), filename, dom, population->GetUpdate()); 
+
+parasite_debug
+:descr:
+//midget
+:args:
+cString in_filename ""
+:body:
+population->ParasiteDebug();
+
+print_dom_parasite
+:descr:
+/**
+* Write the currently dominant injected genotype to disk.
+*
+* Parameters:
+* filename (string)
+*   The name under which the genotype should be saved. If no
+*   filename is given, the genotype is saved into the directory
+*   genebank, under the name that the genebank has associated with
+*   this genotype.
+**/
+:args:
+cString in_filename ""
+:body:
+cInjectGenotype * dom = population->GetInjectGenebank().GetBestInjectGenotype();
+if (dom!=NULL) {
+cString filename(in_filename);
+if (filename == "") filename.Set("genebank/%s", dom->GetName()());
+cTestUtil::PrintGenome(dom, dom->GetGenome(), filename, population->GetUpdate()); }
 
 print_genotype_map
 :descr:
@@ -557,6 +584,25 @@
 }
 ofstream fp(filename());
 population->GetGenebank().DumpDetailedSummary(fp);
+
+detail_parasite_pop
+:descr:
+/**
+* Like dump_pop, but more detailed data is written out.
+*
+* Parameters:
+* filename (string) default: "detail_pop.<update>"
+*   The name of the file into which the population dump should be written.
+**/
+:args:
+cString fname ""
+:body:
+cString filename;
+if( fname == "" ){
+  filename.Set("detail_parasite_pop.%d", population->GetUpdate());
+}
+//ofstream fp(filename());
+population->GetInjectGenebank().DumpDetailedSummary(filename, population->GetUpdate());
 
 dump_historic_pop
 :descr:
Index: avida/current/source/event/cPopulation_construct_event_auto.ci
diff -u avida/current/source/event/cPopulation_construct_event_auto.ci:1.3 avida/current/source/event/cPopulation_construct_event_auto.ci:1.4
--- avida/current/source/event/cPopulation_construct_event_auto.ci:1.3	Wed Jul 16 19:36:54 2003
+++ avida/current/source/event/cPopulation_construct_event_auto.ci	Thu Aug  7 20:24:18 2003
@@ -85,6 +85,12 @@
     case cPopulationEventFactory::EVENT_print_dom :
       event = new cPopulationEventprint_dom(arg_list);
       break;
+    case cPopulationEventFactory::EVENT_parasite_debug :
+      event = new cPopulationEventparasite_debug(arg_list);
+      break;
+    case cPopulationEventFactory::EVENT_print_dom_parasite :
+      event = new cPopulationEventprint_dom_parasite(arg_list);
+      break;
     case cPopulationEventFactory::EVENT_print_genotype_map :
       event = new cPopulationEventprint_genotype_map(arg_list);
       break;
@@ -108,6 +114,9 @@
       break;
     case cPopulationEventFactory::EVENT_detail_pop :
       event = new cPopulationEventdetail_pop(arg_list);
+      break;
+    case cPopulationEventFactory::EVENT_detail_parasite_pop :
+      event = new cPopulationEventdetail_parasite_pop(arg_list);
       break;
     case cPopulationEventFactory::EVENT_dump_historic_pop :
       event = new cPopulationEventdump_historic_pop(arg_list);
Index: avida/current/source/event/cPopulation_descr.ci
diff -u avida/current/source/event/cPopulation_descr.ci:1.3 avida/current/source/event/cPopulation_descr.ci:1.4
--- avida/current/source/event/cPopulation_descr.ci:1.3	Wed Jul 16 19:36:54 2003
+++ avida/current/source/event/cPopulation_descr.ci	Thu Aug  7 20:24:18 2003
@@ -28,6 +28,8 @@
   cEventEntry( "print_lineage_totals", "\n" ),
   cEventEntry( "print_lineage_counts", "\n" ),
   cEventEntry( "print_dom", "Write the currently dominant genotype to disk.\n\nParameters:\nfilename (string)\n  The name under which the genotype should be saved. If no\n  filename is given, the genotype is saved into the directory\n  genebank, under the name that the genebank has associated with\n  this genotype.\n" ),
+  cEventEntry( "parasite_debug", "\n" ),
+  cEventEntry( "print_dom_parasite", "Write the currently dominant injected genotype to disk.\n\nParameters:\nfilename (string)\n  The name under which the genotype should be saved. If no\n  filename is given, the genotype is saved into the directory\n  genebank, under the name that the genebank has associated with\n  this genotype.\n" ),
   cEventEntry( "print_genotype_map", "write a matrix of genotype ID's to a file (matlab format)\n" ),
   cEventEntry( "save_population", "Saves the full state of the population.\n\nParameters:\nfilename (string) default: save_pop.*\n  The name of the file into which the population should\n  be saved. If it is not given, then the name 'save_pop.*'\n  is used, with '*' replaced by the current update.\n" ),
   cEventEntry( "load_population", "Loads the full state of the population.\n\nParameters:\nfilename (string)\n  The name of the file to open.\n" ),
@@ -36,6 +38,7 @@
   cEventEntry( "load_dump_file", "Sets up a population based on a dump file such as written out by\ndetail_pop. It is also possible to append a history file to the dump\nfile, in order to preserve the history of a previous run.\n" ),
   cEventEntry( "dump_pop", "Writes out a line of data for each genotype in the current population. The\nline contains the genome as string, the number of organisms of that genotype,\nand the genotype ID.\n\nParameters:\nfilename (string) default: \"dump.<update>\"\n  The name of the file into which the population dump should be written.\n" ),
   cEventEntry( "detail_pop", "Like dump_pop, but more detailed data is written out.\n\nParameters:\nfilename (string) default: \"detail_pop.<update>\"\n  The name of the file into which the population dump should be written.\n" ),
+  cEventEntry( "detail_parasite_pop", "Like dump_pop, but more detailed data is written out.\n\nParameters:\nfilename (string) default: \"detail_pop.<update>\"\n  The name of the file into which the population dump should be written.\n" ),
   cEventEntry( "dump_historic_pop", "Similar to detail_pop. However, only genotypes that are not in the\ncurrent population anymore are included. Genotypes that are not in\nthe line of descent of any of the current genotypes to the ultimate\nancestor are excluded.\n\nParameters:\nfilename (string) default: \"historic_dump.<update>\"\n  The name of the file into which the historic dump should be written.\n" ),
   cEventEntry( "dump_memory", "Dump the current memory state of all CPUs to a file.\n" ),
   cEventEntry( "inject", "Injects a single organism into the population.\n\nParameters:\nfilename (string)\n  The filename of the genotype to load. If this is left empty, or the keyword\n  \"START_CREATURE\" is given, than the genotype specified in the genesis\n  file under \"START_CREATURE\" is used.\ncell ID (integer) default: 0\n  The grid-point into which the organism should be placed.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n" ),
@@ -82,5 +85,5 @@
   cEventEntry( "inject_resource", "Inject (add) a specified amount of a specified resource.\n" ),
   cEventEntry( "set_resource", "Set the resource amount to a specific level\n" ) };
 
-const int cEventDescrs::num_of_events = 82;
+const int cEventDescrs::num_of_events = 85;
 
Index: avida/current/source/event/cPopulation_enums_auto.ci
diff -u avida/current/source/event/cPopulation_enums_auto.ci:1.3 avida/current/source/event/cPopulation_enums_auto.ci:1.4
--- avida/current/source/event/cPopulation_enums_auto.ci:1.3	Wed Jul 16 19:36:54 2003
+++ avida/current/source/event/cPopulation_enums_auto.ci	Thu Aug  7 20:24:18 2003
@@ -28,6 +28,8 @@
   EVENT_print_lineage_totals,
   EVENT_print_lineage_counts,
   EVENT_print_dom,
+  EVENT_parasite_debug,
+  EVENT_print_dom_parasite,
   EVENT_print_genotype_map,
   EVENT_save_population,
   EVENT_load_population,
@@ -36,6 +38,7 @@
   EVENT_load_dump_file,
   EVENT_dump_pop,
   EVENT_detail_pop,
+  EVENT_detail_parasite_pop,
   EVENT_dump_historic_pop,
   EVENT_dump_memory,
   EVENT_inject,
Index: avida/current/source/event/cPopulation_event_list
diff -u avida/current/source/event/cPopulation_event_list:1.3 avida/current/source/event/cPopulation_event_list:1.4
--- avida/current/source/event/cPopulation_event_list:1.3	Wed Jul 16 19:36:54 2003
+++ avida/current/source/event/cPopulation_event_list	Thu Aug  7 20:24:18 2003
@@ -29,6 +29,8 @@
 print_lineage_totals  [cString fname="lineage_totals.dat"] [int verbose=1]
 print_lineage_counts  [cString fname="lineage_counts.dat"] [int verbose=0]
 print_dom  [cString in_filename=""]
+parasite_debug  [cString in_filename=""]
+print_dom_parasite  [cString in_filename=""]
 print_genotype_map  [cString fname="genotype_map.m"]
 save_population  [cString fname=""]
 load_population  <cString fname>
@@ -37,6 +39,7 @@
 load_dump_file  <cString fname> [int update=-1]
 dump_pop  [cString fname=""]
 detail_pop  [cString fname=""]
+detail_parasite_pop  [cString fname=""]
 dump_historic_pop  [cString fname=""]
 dump_memory  [cString fname=""]
 inject  [cString fname="START_CREATURE"] [int cell_id=0] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]
Index: avida/current/source/event/cPopulation_name2enum_auto.ci
diff -u avida/current/source/event/cPopulation_name2enum_auto.ci:1.3 avida/current/source/event/cPopulation_name2enum_auto.ci:1.4
--- avida/current/source/event/cPopulation_name2enum_auto.ci:1.3	Wed Jul 16 19:36:54 2003
+++ avida/current/source/event/cPopulation_name2enum_auto.ci	Thu Aug  7 20:24:18 2003
@@ -59,6 +59,10 @@
     return cPopulationEventFactory::EVENT_print_lineage_counts;
   }else if (name == "print_dom") {
     return cPopulationEventFactory::EVENT_print_dom;
+  }else if (name == "parasite_debug") {
+    return cPopulationEventFactory::EVENT_parasite_debug;
+  }else if (name == "print_dom_parasite") {
+    return cPopulationEventFactory::EVENT_print_dom_parasite;
   }else if (name == "print_genotype_map") {
     return cPopulationEventFactory::EVENT_print_genotype_map;
   }else if (name == "save_population") {
@@ -75,6 +79,8 @@
     return cPopulationEventFactory::EVENT_dump_pop;
   }else if (name == "detail_pop") {
     return cPopulationEventFactory::EVENT_detail_pop;
+  }else if (name == "detail_parasite_pop") {
+    return cPopulationEventFactory::EVENT_detail_parasite_pop;
   }else if (name == "dump_historic_pop") {
     return cPopulationEventFactory::EVENT_dump_historic_pop;
   }else if (name == "dump_memory") {
Index: avida/current/source/event/cPopulation_process_auto.ci
diff -u avida/current/source/event/cPopulation_process_auto.ci:1.3 avida/current/source/event/cPopulation_process_auto.ci:1.4
--- avida/current/source/event/cPopulation_process_auto.ci:1.3	Wed Jul 16 19:36:54 2003
+++ avida/current/source/event/cPopulation_process_auto.ci	Thu Aug  7 20:24:18 2003
@@ -792,7 +792,62 @@
     cGenotype * dom = population->GetGenebank().GetBestGenotype();
     cString filename(in_filename);
     if (filename == "") filename.Set("genebank/%s", dom->GetName()());
-    cTestUtil::PrintGenome(dom->GetGenome(), filename, dom, population->GetUpdate());
+    cTestUtil::PrintGenome(dom->GetGenome(), filename, dom, population->GetUpdate()); 
+  }
+};
+
+///// parasite_debug /////
+
+//midget
+
+
+class cPopulationEventparasite_debug : public cPopulationEvent {
+private:
+  cString in_filename;
+public:
+  cPopulationEventparasite_debug(const cString & in_args):
+   cPopulationEvent("parasite_debug", in_args) {
+
+    cString args(in_args);
+    if (args == "") in_filename=""; else in_filename=args.PopWord();
+  }
+///// parasite_debug /////
+  void Process(){
+    population->ParasiteDebug();
+  }
+};
+
+///// print_dom_parasite /////
+
+/**
+* Write the currently dominant injected genotype to disk.
+*
+* Parameters:
+* filename (string)
+*   The name under which the genotype should be saved. If no
+*   filename is given, the genotype is saved into the directory
+*   genebank, under the name that the genebank has associated with
+*   this genotype.
+**/
+
+
+class cPopulationEventprint_dom_parasite : public cPopulationEvent {
+private:
+  cString in_filename;
+public:
+  cPopulationEventprint_dom_parasite(const cString & in_args):
+   cPopulationEvent("print_dom_parasite", in_args) {
+
+    cString args(in_args);
+    if (args == "") in_filename=""; else in_filename=args.PopWord();
+  }
+///// print_dom_parasite /////
+  void Process(){
+    cInjectGenotype * dom = population->GetInjectGenebank().GetBestInjectGenotype();
+    if (dom!=NULL) {
+    cString filename(in_filename);
+    if (filename == "") filename.Set("genebank/%s", dom->GetName()());
+    cTestUtil::PrintGenome(dom, dom->GetGenome(), filename, population->GetUpdate()); }
   }
 };
 
@@ -1021,6 +1076,38 @@
     }
     ofstream fp(filename());
     population->GetGenebank().DumpDetailedSummary(fp);
+  }
+};
+
+///// detail_parasite_pop /////
+
+/**
+* Like dump_pop, but more detailed data is written out.
+*
+* Parameters:
+* filename (string) default: "detail_pop.<update>"
+*   The name of the file into which the population dump should be written.
+**/
+
+
+class cPopulationEventdetail_parasite_pop : public cPopulationEvent {
+private:
+  cString fname;
+public:
+  cPopulationEventdetail_parasite_pop(const cString & in_args):
+   cPopulationEvent("detail_parasite_pop", in_args) {
+
+    cString args(in_args);
+    if (args == "") fname=""; else fname=args.PopWord();
+  }
+///// detail_parasite_pop /////
+  void Process(){
+    cString filename;
+    if( fname == "" ){
+      filename.Set("detail_parasite_pop.%d", population->GetUpdate());
+    }
+    //ofstream fp(filename());
+    population->GetInjectGenebank().DumpDetailedSummary(filename, population->GetUpdate());
   }
 };
 
Index: avida/current/source/event/population_event_factory.cc
diff -u avida/current/source/event/population_event_factory.cc:1.6 avida/current/source/event/population_event_factory.cc:1.7
--- avida/current/source/event/population_event_factory.cc:1.6	Sat May 17 02:48:08 2003
+++ avida/current/source/event/population_event_factory.cc	Thu Aug  7 20:24:18 2003
@@ -14,6 +14,8 @@
 #include "../main/genebank.hh"
 #include "../main/genotype.hh"
 #include "../cpu/hardware_method.hh"
+#include "../main/inject_genebank.hh"
+#include "../main/inject_genotype.hh"
 #include "../main/inst_util.hh"
 #include "../main/landscape.hh"
 #include "../main/lineage_control.hh"
Index: avida/current/source/main/Makefile.am
diff -u avida/current/source/main/Makefile.am:1.31 avida/current/source/main/Makefile.am:1.32
--- avida/current/source/main/Makefile.am:1.31	Thu Jul 31 16:03:35 2003
+++ avida/current/source/main/Makefile.am	Thu Aug  7 20:24:19 2003
@@ -33,6 +33,8 @@
     genome.hh		genome.cc		\
     genome_util.hh		genome_util.cc		\
     genotype.hh		genotype.cc		\
+    inject_genebank.hh	inject_genebank.cc   	\
+    inject_genotype.hh  inject_genotype.cc	\
     inst.hh			inst.cc			\
     inst_set.hh		inst_set.cc		\
     inst_lib.hh \
Index: avida/current/source/main/avida.cc
diff -u avida/current/source/main/avida.cc:1.44 avida/current/source/main/avida.cc:1.45
--- avida/current/source/main/avida.cc:1.44	Wed Jul 16 19:36:54 2003
+++ avida/current/source/main/avida.cc	Thu Aug  7 20:24:19 2003
@@ -192,6 +192,8 @@
   default_interface.SetFun_GetResources(&cCallbackUtil::CB_GetResources);
   default_interface.SetFun_UpdateResources(&cCallbackUtil::CB_UpdateResources);
   default_interface.SetFun_KillCell(&cCallbackUtil::CB_KillCell);
+  default_interface.SetFun_SendMessage(&cCallbackUtil::CB_SendMessage);
+  default_interface.SetFun_InjectParasite(&cCallbackUtil::CB_InjectParasite);
 
   population = new cPopulation(default_interface, environment);
   cout << " ...done" << endl;
Index: avida/current/source/main/callback_util.cc
diff -u avida/current/source/main/callback_util.cc:1.22 avida/current/source/main/callback_util.cc:1.23
--- avida/current/source/main/callback_util.cc:1.22	Thu Jul 17 10:40:55 2003
+++ avida/current/source/main/callback_util.cc	Thu Aug  7 20:24:19 2003
@@ -196,3 +196,14 @@
   mess.SetRecipientID(cell.ConnectionList().GetFirst()->GetID());
   return cell.ConnectionList().GetFirst()->GetOrganism()->ReceiveMessage(mess);
 }
+
+bool cCallbackUtil::CB_InjectParasite(cPopulation * pop, int cell_id, cOrganism * parent,
+				      const cGenome & injected_code)
+{
+  assert(pop != NULL);
+  assert(parent != NULL);
+  assert(pop->GetCell(cell_id).GetOrganism() == parent);
+
+  return pop->ActivateInject(*parent, injected_code);
+}
+
Index: avida/current/source/main/callback_util.hh
diff -u avida/current/source/main/callback_util.hh:1.12 avida/current/source/main/callback_util.hh:1.13
--- avida/current/source/main/callback_util.hh:1.12	Thu Jul 17 10:40:55 2003
+++ avida/current/source/main/callback_util.hh	Thu Aug  7 20:24:19 2003
@@ -16,6 +16,7 @@
 class cPopulation;
 class cPopulationInterface;
 class cOrgMessage;
+class cCodeLabel;
 
 class cCallbackUtil {
 public:
@@ -40,6 +41,8 @@
 				 const tArray<double> & res_change);
   static void CB_KillCell(cPopulation * pop, int death_id);
   static bool CB_SendMessage(cPopulation * pop, int cell_id, cOrgMessage & mess);
+  static bool CB_InjectParasite(cPopulation * pop, int cell_id, cOrganism * parent,
+				const cGenome & injected_code);
 };
 
 #endif
Index: avida/current/source/main/genebank.cc
diff -u avida/current/source/main/genebank.cc:1.32 avida/current/source/main/genebank.cc:1.33
--- avida/current/source/main/genebank.cc:1.32	Thu Jul 31 16:03:35 2003
+++ avida/current/source/main/genebank.cc	Thu Aug  7 20:24:19 2003
@@ -716,8 +716,8 @@
     if (genotype_dom_time == cConfig::GetGenotypePrintDom()) {
       cString filename;
       filename.Set("genebank/%s", best_genotype->GetName()());
-      cTestUtil::PrintGenome(best_genotype->GetGenome(), filename,
-			     best_genotype, stats.GetUpdate());
+      cTestUtil::PrintGenome(best_genotype->GetGenome(), 
+			     filename, best_genotype, stats.GetUpdate());
     }
   }
 }
Index: avida/current/source/main/organism.cc
diff -u avida/current/source/main/organism.cc:1.26 avida/current/source/main/organism.cc:1.27
--- avida/current/source/main/organism.cc:1.26	Thu Jul 17 10:40:55 2003
+++ avida/current/source/main/organism.cc	Thu Aug  7 20:24:19 2003
@@ -10,7 +10,6 @@
 
 #include "../tools/functions.hh"
 #include "../tools/tArray.hh"
-//#include "../tools/message.hh"
 
 #include "config.hh"
 #include "inst_set.hh"
@@ -18,6 +17,7 @@
 #include "genome.hh"
 #include "genome_util.hh"
 #include "org_message.hh"
+#include "../main/inject_genotype.hh"
 
 #include "../cpu/cpu_defs.hh"
 #include "../cpu/hardware_base.hh"
@@ -116,6 +116,36 @@
 {
   inbox.Add(mess);
   return true;
+}
+
+bool cOrganism::InjectParasite(const cGenome & injected_code)
+{
+  return pop_interface.InjectParasite(this, injected_code);
+}
+
+bool cOrganism::InjectHost(const cCodeLabel & label, const cGenome & injected_code)
+{
+  return hardware->InjectHost(label, injected_code);
+}
+
+void cOrganism::AddParasite(cInjectGenotype * in_genotype)
+{
+  parasites.push_back(in_genotype);
+}
+
+cInjectGenotype & cOrganism::GetParasite(int x)
+{
+  return *parasites[x];
+}
+
+int cOrganism::GetNumParasites()
+{
+  return parasites.size();
+}
+
+void cOrganism::ClearParasites()
+{
+  parasites.clear();
 }
 
 int cOrganism::OK()
Index: avida/current/source/main/organism.hh
diff -u avida/current/source/main/organism.hh:1.23 avida/current/source/main/organism.hh:1.24
--- avida/current/source/main/organism.hh:1.23	Thu Jul 17 10:40:55 2003
+++ avida/current/source/main/organism.hh	Thu Aug  7 20:24:19 2003
@@ -9,10 +9,12 @@
 #define ORGANISM_HH
 
 #include <fstream>
+#include <deque>
 
 #include "../tools/merit.hh"
 #include "../tools/tBuffer.hh"
 #include "../tools/string.hh"
+#include "../tools/tList.hh"
 
 #include "../defs.hh"
 
@@ -20,6 +22,7 @@
 #include "mutations.hh"
 #include "pop_interface.hh"
 #include "phenotype.hh"
+//#include "../main/inject_genotype.hh"
 
 #include "../cpu/cpu_memory.hh"
 #include "../cpu/cpu_stats.hh"
@@ -30,6 +33,7 @@
 class cLineage;
 class cPopulation;
 class cOrgMessage;
+class cInjectGenotype;
 
 /**
  * The cOrganism class controls the running and manages all the statistics
@@ -42,7 +46,8 @@
   cGenotype * genotype;      // Information about organisms with this genome.
   cPhenotype phenotype;      // Descriptive attributes of organism.
   const cGenome initial_genome;        // Initial genome; can never be changed!
-
+  deque<cInjectGenotype *> parasites; // List of all parasites associated with
+                                    // this organism.
   cMutationRates mut_rates;            // Rate of all possible mutations.
   cLocalMutations mut_info;            // Info about possible mutations;
   cPopulationInterface pop_interface;  // Interface back to the population.
@@ -98,6 +103,13 @@
   void SendMessage(cOrgMessage & mess);
   bool ReceiveMessage(cOrgMessage & mess);
 
+  bool InjectParasite(const cGenome & genome);
+  bool InjectHost(const cCodeLabel & in_label, const cGenome & genome);
+  void AddParasite(cInjectGenotype * cur);
+  cInjectGenotype & GetParasite(int x);
+  int GetNumParasites();
+  void ClearParasites();
+		      
   int OK();
 
   double GetTestFitness();
@@ -158,12 +170,8 @@
   const cPopulationInterface & PopInterface() const { return pop_interface; }
   cPopulationInterface & PopInterface() { return pop_interface; }
   
-  // yes, this is a huge hack, but a lot of code uses the 
-  // original GetGenome() call - law 
-  //const tArray<cGenome> & GetGenomeArray() const;
   const cGenome & GetGenome() const { return initial_genome; }
-  //const tArray<cGenome> & GetGenome4Stack() const;
-
+  
   int GetCurGestation() const;
   const cPhenotype & GetPhenotype() const { return phenotype; }
   cPhenotype & GetPhenotype() { return phenotype; }
Index: avida/current/source/main/pop_interface.cc
diff -u avida/current/source/main/pop_interface.cc:1.13 avida/current/source/main/pop_interface.cc:1.14
--- avida/current/source/main/pop_interface.cc:1.13	Thu Jul 17 10:40:55 2003
+++ avida/current/source/main/pop_interface.cc	Thu Aug  7 20:24:19 2003
@@ -33,6 +33,7 @@
   , fun_update_resources(NULL)
   , fun_kill_cell(NULL)
     , fun_send_message(NULL)
+    , fun_inject_parasite(NULL)
 {
 }
 
@@ -59,6 +60,7 @@
   fun_update_resources = in_interface.fun_update_resources;
   fun_kill_cell        = in_interface.fun_kill_cell;
   fun_send_message     = in_interface.fun_send_message;
+  fun_inject_parasite  = in_interface.fun_inject_parasite;
 }
 
 cHardwareBase * cPopulationInterface::NewHardware(cOrganism * owner)
@@ -161,7 +163,6 @@
   (*fun_update_resources)(population, cell_id, res_change);
 }
 
-
 void cPopulationInterface::Die()
 {
   if (fun_kill_cell == NULL) return;
@@ -172,4 +173,11 @@
 {
   if (fun_send_message == NULL) return false;
   return (*fun_send_message)(population, cell_id, mess);
+}
+
+bool cPopulationInterface::InjectParasite(cOrganism * parent, 
+					  const cGenome & injected_code)
+{
+  if (fun_inject_parasite == NULL) return false;
+  return (*fun_inject_parasite)(population, cell_id, parent, injected_code);
 }
Index: avida/current/source/main/pop_interface.hh
diff -u avida/current/source/main/pop_interface.hh:1.11 avida/current/source/main/pop_interface.hh:1.12
--- avida/current/source/main/pop_interface.hh:1.11	Thu Jul 17 10:40:55 2003
+++ avida/current/source/main/pop_interface.hh	Thu Aug  7 20:24:19 2003
@@ -18,6 +18,7 @@
 class cOrganism;
 class cPopulation;
 class cOrgMessage;
+class cCodeLabel;
 
 typedef cHardwareBase * (*tFunNewHardware)(cPopulation *pop, cOrganism *owner);
 typedef void (*tFunRecycle)(cHardwareBase * out_hardware);
@@ -39,6 +40,8 @@
   (cPopulation * pop, int cell_id, const tArray<double> & res_change);
 typedef void (*tFunKillCell)(cPopulation * pop, int death_id);
 typedef bool (*tFunSendMessage)(cPopulation * pop, int cell_id, cOrgMessage & mess);
+typedef bool (*tFunInjectParasite)
+  (cPopulation * pop, int cell_id, cOrganism * parent, const cGenome & injected_code);
 
 class cPopulationInterface {
 private:
@@ -62,6 +65,7 @@
   tFunUpdateResources  fun_update_resources;
   tFunKillCell         fun_kill_cell;
   tFunSendMessage      fun_send_message;
+  tFunInjectParasite   fun_inject_parasite;
 public:
   cPopulationInterface();
   ~cPopulationInterface();
@@ -90,6 +94,7 @@
     { fun_update_resources = fun; }
   void SetFun_KillCell(tFunKillCell fun) { fun_kill_cell = fun; }
   void SetFun_SendMessage(tFunSendMessage fun) { fun_send_message = fun; }
+  void SetFun_InjectParasite(tFunInjectParasite fun) { fun_inject_parasite = fun; }
   void CopyCallbacks(cPopulationInterface & in_interface);
 
   // Activate callbacks...
@@ -110,6 +115,7 @@
   void UpdateResources(const tArray<double> & res_change);
   void Die();
   bool SendMessage(cOrgMessage & mess);
+  bool InjectParasite(cOrganism * parent, const cGenome & injected_code);
 };
 
 #endif
Index: avida/current/source/main/population.cc
diff -u avida/current/source/main/population.cc:1.112 avida/current/source/main/population.cc:1.113
--- avida/current/source/main/population.cc:1.112	Thu Aug  7 09:28:32 2003
+++ avida/current/source/main/population.cc	Thu Aug  7 20:24:19 2003
@@ -20,6 +20,8 @@
 #include "genebank.hh"
 #include "genome_util.hh"
 #include "genotype.hh"
+#include "inject_genebank.hh"
+#include "inject_genotype.hh"
 #include "inst_util.hh"
 #include "lineage.hh"
 #include "lineage_control.hh"
@@ -33,6 +35,7 @@
 #include "../cpu/hardware_base.hh"
 #include "../cpu/hardware_factory.hh"
 #include "../cpu/hardware_util.hh"
+#include "../cpu/hardware_4stack.hh"
 
 
 using namespace std;
@@ -51,6 +54,7 @@
 
   // Setup the genebank.
   genebank = new cGenebank(stats);
+  inject_genebank = new cInjectGenebank(stats);
 
   // are we logging lineages?
   if (cConfig::GetLogLineages()) {
@@ -231,6 +235,7 @@
 
   if ( lineage_control != NULL ) delete lineage_control;
   delete genebank;
+  delete inject_genebank;
   delete schedule;
 }
 
@@ -341,6 +346,100 @@
   return parent_alive;
 }
 
+bool cPopulation::ActivateInject(cOrganism & parent, const cGenome & injected_code)
+{
+  assert(&parent != NULL);
+  
+  if(injected_code.GetSize() ==0)
+    return false;
+
+  cHardware4Stack & parent_cpu = (cHardware4Stack &) parent.GetHardware();
+  cInjectGenotype * parent_genotype = parent_cpu.GetThreadOwner();
+  
+  const int parent_id = parent.PopInterface().GetCellID();
+  assert(parent_id >= 0 && parent_id < cell_array.GetSize());
+  cPopulationCell & parent_cell = cell_array[ parent_id ];
+
+  int num_neighbors = parent.GetNeighborhoodSize();
+  cOrganism * target_organism = 
+    parent_cell.connection_list.GetPos(g_random.GetUInt(num_neighbors))->GetOrganism();
+
+  if(target_organism==NULL)
+    return false;
+
+  cHardware4Stack & child_cpu = (cHardware4Stack &) target_organism->GetHardware();
+  
+  if(child_cpu.GetNumThreads()==cConfig::GetMaxCPUThreads())
+    return false;
+
+  cInjectGenotype * child_genotype = parent_genotype;
+
+  if(target_organism->InjectHost(parent_cpu.GetLabel(), injected_code)) {
+    // If the parent genotype is not correct for the child, adjust it.
+    if (parent_genotype == NULL || !(parent_genotype->GetGenome() == injected_code)) {
+      child_genotype = inject_genebank->AddInjectGenotype(injected_code, parent_genotype);
+    }
+    
+    target_organism->AddParasite(child_genotype);
+    child_genotype->AddParasite();
+    //if(parent_genotype!=NULL)
+    //  parent_genotype->RemoveParasite();
+    inject_genebank->AdjustInjectGenotype(*child_genotype);
+  }
+  else
+    return false;
+
+  return true;
+
+  // And set the genotype now that we know it.
+  //child_array[i]->SetGenotype(child_genotype);
+  //parent_genotype->SetBreedStats(*child_genotype);
+  
+  // We want to make sure that the child's genotype is not deleted from the
+  // genebank before the child is placed.
+  //child_genotype->IncDeferAdjust();
+  
+  // **THIS WILL BE NECESSARY IF/WHEN WE IMPLEMENT PARASITE LINEAGES.**
+  // Do lineage tracking for the new creature, if necessary.  Must occur
+  // before old organism is removed.
+  //LineageSetupOrganism( child_array[i], parent_organism.GetLineage(),
+  //			  parent_organism.GetLineageLabel(), parent_genotype );
+  
+  // **THIS WILL BE NECESSARY ONCE WE IMPLEMENT PARASITE MUTATION RATES.**
+  //child_array[i]->MutationRates().
+  //  Copy(GetCell(target_cells[i]).MutationRates());
+  
+  // Do any statistics on the parent that just gave birth...
+  //parent_genotype->AddGestationTime( parent_phenotype.GetGestationTime() );
+  //parent_genotype->AddFitness(       parent_phenotype.GetFitness()       );
+  //parent_genotype->AddMerit(         parent_phenotype.GetMerit()         );
+  //parent_genotype->AddCopiedSize(    parent_phenotype.GetCopiedSize()    );
+  //parent_genotype->AddExecutedSize(  parent_phenotype.GetExecutedSize()  );
+
+  // Place all of the offspring...
+  /*for (int i = 0; i < child_array.GetSize(); i++) {
+    ActivateOrganism(child_array[i], GetCell(target_cells[i]));
+    cGenotype * child_genotype = child_array[i]->GetGenotype();
+    child_genotype->DecDeferAdjust();
+    genebank->AdjustGenotype(*child_genotype);
+    }*/
+}
+
+bool cPopulation::ActivateInject(const int cell_id, const cGenome & injected_code)
+{
+  cInjectGenotype * child_genotype = inject_genebank->AddInjectGenotype(injected_code);
+
+  if(cell_array[cell_id].GetOrganism()->InjectHost(cCodeLabel(), injected_code))
+    {
+      cell_array[cell_id].GetOrganism()->AddParasite(child_genotype);
+      child_genotype->AddParasite();
+      inject_genebank->AdjustInjectGenotype(*child_genotype);
+    }
+  else
+    return false;
+
+  return true;
+}
 
 void cPopulation::ActivateOrganism(cOrganism * in_organism,
 				   cPopulationCell & target_cell)
@@ -397,7 +496,6 @@
 		      in_organism->GetPhenotype().ParentTrue());
 }
 
-
 void cPopulation::KillOrganism(cPopulationCell & in_cell)
 {
   // do we actually have something to kill?
@@ -420,11 +518,15 @@
   // Do statistics
   num_organisms--;
 
-  if (organism->GetPhenotype().IsParasite() == true) {
-    genotype->AddParasite();
-  }
+  //if (organism->GetPhenotype().IsParasite() == true) {
+  //  genotype->AddParasite();
+  //}
   genotype->RemoveOrganism();
-
+  
+  for(int i=0; i<organism->GetNumParasites(); i++) {
+    organism->GetParasite(i).RemoveParasite();
+  }
+      
   // And clear it!
   in_cell.RemoveOrganism();
   delete organism;
@@ -436,7 +538,6 @@
   genebank->AdjustGenotype(*genotype);
 }
 
-
 /**
  * This function is responsible for adding an organism to a given lineage,
  * and setting the organism's lineage label and the lineage pointer.
@@ -1146,12 +1247,11 @@
   }
   else
     {
-      GetCell(cell_id).GetOrganism()->GetHardware().Inject_Host(cCodeLabel(), genome);
+      ActivateInject(cell_id, genome);
     }
       
 }
 
-
 cPopulationCell & cPopulation::GetCell(int in_num)
 {
   return cell_array[in_num];
@@ -1354,4 +1454,25 @@
     transfer_pool[j] = transfer_pool.back();
     transfer_pool.pop_back();
   }
+}
+
+void cPopulation::ParasiteDebug()
+{
+  ofstream outfile;
+  outfile.open("debug.out", ofstream::app);
+  outfile << stats.GetUpdate() << endl;
+  int total=0;
+  for(int x=0; x<cell_array.GetSize(); x++)
+    {
+      if(cell_array[x].GetOrganism()!=NULL)
+	{
+	  assert(cell_array[x].GetOrganism()->GetNumParasites()>=0 && 
+		 cell_array[x].GetOrganism()->GetNumParasites()<=1);
+	  total+=cell_array[x].GetOrganism()->GetNumParasites();
+	  if(cell_array[x].GetOrganism()->GetNumParasites())
+	    outfile << x << " ";
+	}
+    }
+  outfile << endl << total << endl;
+  outfile.close();
 }
Index: avida/current/source/main/population.hh
diff -u avida/current/source/main/population.hh:1.56 avida/current/source/main/population.hh:1.57
--- avida/current/source/main/population.hh:1.56	Wed Jul 16 19:36:55 2003
+++ avida/current/source/main/population.hh	Thu Aug  7 20:24:19 2003
@@ -26,6 +26,7 @@
 class cGenebank;
 class cGenome;
 class cGenotype;
+class cInjectGenebank;
 class cLineage;
 class cLineageControl;
 class cOrganism;
@@ -33,7 +34,6 @@
 class sReproData;
 class cSchedule;
 
-
 class cPopulation {
 private:
   // Components...
@@ -45,6 +45,7 @@
   // Data Tracking...
   cStats stats;                      // Main statistics object...
   cGenebank * genebank;                // Tracks genotypes
+  cInjectGenebank * inject_genebank;   // Tracks all injected code
   cLineageControl * lineage_control;   // Tracks Linages
   tList<cPopulationCell> reaper_queue; // Death order in some mass-action runs
 
@@ -100,7 +101,10 @@
   // Activate the offspring of an organism in the population
   bool ActivateOffspring(cGenome & child_genome, cOrganism & parent_organism);
 
-  // Inject and organism from the outside world.
+  bool ActivateInject(cOrganism & parent, const cGenome & injected_code);
+  bool ActivateInject(const int cell_id, const cGenome & injected_code);
+
+  // Inject an organism from the outside world.
   void Inject(const cGenome & genome, int cell_id=-1, double merit=-1,
 	      int lineage_label=0, double neutral_metric=0, int mem_space=0 );
 
@@ -149,12 +153,14 @@
 
   cStats & GetStats() { return stats; }
   cGenebank & GetGenebank() { return *genebank; }
+  cInjectGenebank & GetInjectGenebank() { return *inject_genebank; }
   cLineageControl * GetLineageControl() { return lineage_control; }
   cEnvironment & GetEnvironment() { return environment; }
   int GetNumOrganisms() { return num_organisms; }
 
   bool GetSyncEvents() { return sync_events; }
   void SetSyncEvents(bool _in) { sync_events = _in; }
+  void ParasiteDebug();
 };
 
 #endif
Index: avida/current/source/support/Makefile.am
diff -u avida/current/source/support/Makefile.am:1.11 avida/current/source/support/Makefile.am:1.12
--- avida/current/source/support/Makefile.am:1.11	Thu May 22 11:58:53 2003
+++ avida/current/source/support/Makefile.am	Thu Aug  7 20:24:19 2003
@@ -4,7 +4,9 @@
 	events.cfg \
 	genesis \
 	inst_set.default \
-	organism.default 
+	organism.default \
+	inst_set.4stack \
+	genesis.4stack
 
 SUBDIRS = preset_organisms
 
Index: avida/current/source/support/preset_organisms/Makefile.am
diff -u avida/current/source/support/preset_organisms/Makefile.am:1.2 avida/current/source/support/preset_organisms/Makefile.am:1.3
--- avida/current/source/support/preset_organisms/Makefile.am:1.2	Thu May 22 11:58:53 2003
+++ avida/current/source/support/preset_organisms/Makefile.am	Thu Aug  7 20:24:19 2003
@@ -1,6 +1,8 @@
 
 presetsdir = $(datadir)/preset_organisms
 
-presets_DATA = dummy
+presets_DATA = dummy /
+	organism.4stack /
+	organism.parasite
 
 EXTRA_DIST = $(presets_DATA)
Index: avida/current/source/viewers/symbol_util.cc
diff -u avida/current/source/viewers/symbol_util.cc:1.5 avida/current/source/viewers/symbol_util.cc:1.6
--- avida/current/source/viewers/symbol_util.cc:1.5	Wed Jul 16 19:36:55 2003
+++ avida/current/source/viewers/symbol_util.cc	Thu Aug  7 20:24:19 2003
@@ -50,8 +50,8 @@
   // 'B' = Both         '-' = Neither
 
   if (modifier == true && modified == true)  return 'B';
-  if (modifier == true) return 'I';
-  if (modified == true) return 'H';
+  if (modifier == true) return 'I'-6;
+  if (modified == true) return 'H'-6;
   return '-';
 }
 
Index: avida/current/source/viewers/text_screen.hh
diff -u avida/current/source/viewers/text_screen.hh:1.11 avida/current/source/viewers/text_screen.hh:1.12
--- avida/current/source/viewers/text_screen.hh:1.11	Wed Jul 16 19:36:55 2003
+++ avida/current/source/viewers/text_screen.hh	Thu Aug  7 20:24:19 2003
@@ -209,7 +209,7 @@
     break;
   case '0':
   default:
-    SetBoldColor(COLOR_OFF);
+    SetColor(COLOR_WHITE);
     break;
   }
 }

Index: avida/current/source/main/inject_genebank.cc
+++ avida/current/source/main/inject_genebank.cc
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2003 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#include <fstream>

#include "inject_genebank.hh"

#include "inject_genotype.hh"
#include "config.hh"
#include "stats.hh"

#include "../cpu/test_util.hh"

using namespace std;

/////////////////////
//  cInjectGenotypeQueue
/////////////////////

cInjectGenotypeQueue::cInjectGenotypeQueue()
{
  size = 0;
  root.SetNext(&root);
  root.SetPrev(&root);
}


cInjectGenotypeQueue::~cInjectGenotypeQueue()
{
  while (root.GetNext() != &root) {
    Remove(root.GetNext());
  }
}

bool cInjectGenotypeQueue::OK()
{
  bool result = true;
  int count = 0;

  for (cInjectGenotypeElement * temp_element = root.GetNext();
       temp_element != &root;
       temp_element = temp_element->GetNext()) {
    assert (temp_element->GetNext()->GetPrev() == temp_element);
    assert (temp_element->GetInjectGenotype()->GetID() >= 0);

    count++;
    assert (count <= size);
  }

  assert (count == size);

  return result;
}

void cInjectGenotypeQueue::Insert(cInjectGenotype & in_inject_genotype)
{
  cInjectGenotypeElement * new_element = new cInjectGenotypeElement(&in_inject_genotype);
  new_element->SetNext(root.GetNext());
  new_element->SetPrev(&root);
  root.GetNext()->SetPrev(new_element);
  root.SetNext(new_element);
  size++;
}

void cInjectGenotypeQueue::Remove(cInjectGenotype & in_inject_genotype)
{
  cInjectGenotypeElement * cur_element;

  for (cur_element = root.GetNext();
       cur_element != &root;
       cur_element = cur_element->GetNext()) {
    if (cur_element->GetInjectGenotype() == &in_inject_genotype) break;
  }

  assert (cur_element != &root);

  Remove(cur_element);
}

void cInjectGenotypeQueue::Remove(cInjectGenotypeElement * in_element)
{
  in_element->GetPrev()->SetNext(in_element->GetNext());
  in_element->GetNext()->SetPrev(in_element->GetPrev());
  in_element->SetNext(NULL);
  in_element->SetPrev(NULL);
  delete(in_element);

  size--;
}

cInjectGenotype * cInjectGenotypeQueue::Find(const cGenome & in_genome) const
{
  for (cInjectGenotypeElement * cur_element = root.GetNext();
       cur_element != &root;
       cur_element = cur_element->GetNext()) {
    if (cur_element->GetInjectGenotype()->GetGenome() == in_genome) {
      return cur_element->GetInjectGenotype();
    }
  }

  return NULL;
}


////////////////////////////
//  cInjectGenotypeControl
////////////////////////////

cInjectGenotypeControl::cInjectGenotypeControl(cInjectGenebank & in_gb) : genebank(in_gb)
{
  size = 0;
  best = NULL;
  coalescent = NULL;
  for (int i = 0; i < INJECTGENOTYPE_THREADS; i++) threads[i] = NULL;

  historic_list = NULL;
  historic_count = 0;
}

cInjectGenotypeControl::~cInjectGenotypeControl()
{
}

bool cInjectGenotypeControl::OK()
{
  int ret_value = true;

  // Cycle through the list, making sure all connections are proper, size
  // is correct, and all genotypes are OK().

  cInjectGenotype * cur_pos = best;
  for (int i = 0; i < size; i++) {
    if (!cur_pos->OK()) ret_value = false;
    assert (cur_pos->GetNext()->GetPrev() == cur_pos);
    cur_pos = cur_pos->GetNext();
  }

  assert (cur_pos == best);

  return ret_value;
}

void cInjectGenotypeControl::Insert(cInjectGenotype & in_inject_genotype, cInjectGenotype * prev_genotype)
{
  if (prev_genotype == NULL) {
    assert(size == 0); // Destroying a full genotype queue...

    best = &in_inject_genotype;
    best->SetNext(best);
    best->SetPrev(best);
  }
  else {
    in_inject_genotype.SetPrev(prev_genotype);
    in_inject_genotype.SetNext(prev_genotype->GetNext());
    prev_genotype->SetNext(&in_inject_genotype);
    in_inject_genotype.GetNext()->SetPrev(&in_inject_genotype);
  }

  size++;
}

void cInjectGenotypeControl::Remove(cInjectGenotype & in_inject_genotype)
{
  if (size == 1) {
    best = NULL;
  }
  if (&in_inject_genotype == best) {
    best = best->GetNext();
  }

  in_inject_genotype.GetNext()->SetPrev(in_inject_genotype.GetPrev());
  in_inject_genotype.GetPrev()->SetNext(in_inject_genotype.GetNext());
  in_inject_genotype.SetNext(NULL);
  in_inject_genotype.SetPrev(NULL);

  size--;
}

void cInjectGenotypeControl::RemoveHistoric(cInjectGenotype & in_inject_genotype)
{
  if (historic_count == 1) {
    historic_list = NULL;
  }
  if (&in_inject_genotype == historic_list) {
    historic_list = historic_list->GetNext();
  }

  in_inject_genotype.GetNext()->SetPrev(in_inject_genotype.GetPrev());
  in_inject_genotype.GetPrev()->SetNext(in_inject_genotype.GetNext());
  in_inject_genotype.SetNext(NULL);
  in_inject_genotype.SetPrev(NULL);

  historic_count--;
}

void cInjectGenotypeControl::InsertHistoric(cInjectGenotype & in_inject_genotype)
{
  if (historic_count == 0) {
    in_inject_genotype.SetNext(&in_inject_genotype);
    in_inject_genotype.SetPrev(&in_inject_genotype);
  }
  else {
    in_inject_genotype.SetPrev(historic_list->GetPrev());
    in_inject_genotype.SetNext(historic_list);
    historic_list->GetPrev()->SetNext(&in_inject_genotype);
    historic_list->SetPrev(&in_inject_genotype);
  }

  historic_list = &in_inject_genotype;
  historic_count++;
}

/*int cInjectGenotypeControl::UpdateCoalescent()
{
  // Test to see if any updating needs to be done...
  // Don't update active coalescent genotype, or if there is more than
  // one offspring.
  if (coalescent != NULL &&
      (coalescent->GetNumInjected() > 0) ||
      coalescent->GetNumOffspringGenotypes() > 1) ) {
    return coalescent->GetDepth();
  }

  // If there is no best, there is nothing to search through...
  if (best == NULL) return -1;

  // Find the new point...
  cInjectGenotype * test_gen = best;
  cInjectGenotype * found_gen = best;
  cInjectGenotype * parent_gen = best->GetParentGenotype();

  while (parent_gen != NULL) {
    // See if this genotype should be the new found genotype...
    if (test_gen->GetNumOrganisms() > 0 ||
	test_gen->GetNumOffspringGenotypes() > 1) {
      found_gen = test_gen;
    }

    // Move to the next genotype...
    test_gen = parent_gen;
    parent_gen = test_gen->GetParentGenotype();
  }

  coalescent = found_gen;

  return coalescent->GetDepth();
}*/


bool cInjectGenotypeControl::CheckPos(cInjectGenotype & in_inject_genotype)
{
  int next_OK = false;
  int prev_OK = false;

  if (in_inject_genotype.GetNumInjected() >= in_inject_genotype.GetNext()->GetNumInjected()) {
    next_OK =true;
  }
  if (in_inject_genotype.GetNumInjected() <= in_inject_genotype.GetPrev()->GetNumInjected()) {
    prev_OK =true;
  }

  if ((&in_inject_genotype == best && next_OK) ||
      (next_OK && prev_OK) ||
      (&in_inject_genotype == best->GetPrev() && prev_OK)) {
    return true;
  }

  return false;
}

void cInjectGenotypeControl::Insert(cInjectGenotype & new_genotype)
{
  // If there is nothing in the list, add this.

  if (size == 0) {
    Insert(new_genotype, NULL);
  }

  // Otherwise tack it on the end.

  else {
    Insert(new_genotype, best->GetPrev());
  }
}

bool cInjectGenotypeControl::Adjust(cInjectGenotype & in_inject_genotype)
{
  //if (in_inject_genotype.GetDeferAdjust() == true) return true;

  cInjectGenotype * cur_inject_genotype = in_inject_genotype.GetPrev();

  // Check to see if this genotype should be removed completely.

  if (in_inject_genotype.GetNumInjected() == 0) {
    genebank.RemoveInjectGenotype(in_inject_genotype);
    return false;
  }

  // Do not adjust if this was and still is the best genotype, or is
  // otherwise in the proper spot...

  if (CheckPos(in_inject_genotype)) {
    return true;
  }

  // Otherwise, remove it from the queue for just the moment.

  Remove(in_inject_genotype);

  // Also, if this genotype is the best, put it there.

  if (in_inject_genotype.GetNumInjected() > best->GetNumInjected()) {
    Insert(in_inject_genotype, best->GetPrev());
    best = &in_inject_genotype;
    return true;
  }

  // Finally, find out where this genotype *does* go.

  while (cur_inject_genotype->GetNumInjected() >= in_inject_genotype.GetNumInjected() &&
	 cur_inject_genotype != best->GetPrev()) {
    cur_inject_genotype = cur_inject_genotype->GetNext();
  }
  while (cur_inject_genotype->GetNumInjected() < in_inject_genotype.GetNumInjected() &&
	 cur_inject_genotype != best) {
    cur_inject_genotype = cur_inject_genotype->GetPrev();
  }

  Insert(in_inject_genotype, cur_inject_genotype);

  return true;
}


cInjectGenotype * cInjectGenotypeControl::Find(const cGenome & in_genome) const
{
  int i;
  cInjectGenotype * cur_inject_genotype = best;

  for (i = 0; i < size; i++) {
    if (in_genome == cur_inject_genotype->GetGenome()) {
      return cur_inject_genotype;
    }
    cur_inject_genotype = cur_inject_genotype->GetNext();
  }

  return NULL;
}

int cInjectGenotypeControl::FindPos(cInjectGenotype & in_inject_genotype, int max_depth)
{
  cInjectGenotype * temp_genotype = best;
  if (max_depth < 0 || max_depth > size) max_depth = size;

  for (int i = 0; i < max_depth; i++) {
    if (temp_genotype == &in_inject_genotype) return i;
    temp_genotype = temp_genotype->GetNext();
  }

  return -1;
}

cInjectGenotype * cInjectGenotypeControl::Next(int thread)
{
  return threads[thread] = threads[thread]->GetNext();
}

cInjectGenotype * cInjectGenotypeControl::Prev(int thread)
{
  return threads[thread] = threads[thread]->GetPrev();
}

////////////////////
//  cInjectGenebank
////////////////////

cInjectGenebank::cInjectGenebank(cStats & in_stats)
  : stats(in_stats)
{
  for (int i = 0; i < MAX_CREATURE_SIZE; i++) {
    inject_genotype_count[i] = 0;
  }

  inject_genotype_control = new cInjectGenotypeControl(*this);

}

cInjectGenebank::~cInjectGenebank()
{
  delete inject_genotype_control;
}

void cInjectGenebank::UpdateReset()
{
  static int genotype_dom_time = 0;
  static int prev_dom = -1;

  cInjectGenotype * best_inject_genotype = GetBestInjectGenotype();

  if (best_inject_genotype && best_inject_genotype->GetID() != prev_dom) {
    genotype_dom_time = 0;
    prev_dom = best_inject_genotype->GetID();
  }
  else {
    genotype_dom_time++;
    if (genotype_dom_time == cConfig::GetGenotypePrintDom()) {
      cString filename;
      filename.Set("genebank/%s", best_inject_genotype->GetName()());
      cTestUtil::PrintGenome(best_inject_genotype, best_inject_genotype->GetGenome(), 
			     filename, stats.GetUpdate());
    }
  }
}

cString cInjectGenebank::GetLabel(int in_size, int in_num)
{
  char alpha[6];
  char full_name[12];
  int i;

  for (i = 4; i >= 0; i--) {
    alpha[i] = (in_num % 26) + 'a';
    in_num /= 26;
  }
  alpha[5] = '\0';

  sprintf(full_name, "p%03d-%s", in_size, alpha);

  return full_name;
}

void cInjectGenebank::AddInjectGenotype(cInjectGenotype * in_inject_genotype, int in_list_num)
{
  assert( in_inject_genotype != 0 );
  
  if ( in_list_num < 0 )
    in_list_num = FindCRC(in_inject_genotype->GetGenome()) % INJECTGENOTYPE_HASH_SIZE;
  
  active_inject_genotypes[in_list_num].Insert(*in_inject_genotype);
  inject_genotype_control->Insert(*in_inject_genotype);
  //stats.AddGenotype(in_inject_genotype->GetID());
}


cInjectGenotype * cInjectGenebank::AddInjectGenotype(const cGenome & in_genome,
				   cInjectGenotype * parent_genotype)
{
  int list_num = FindCRC(in_genome) % INJECTGENOTYPE_HASH_SIZE;
  cInjectGenotype * found_genotype;

  found_genotype = active_inject_genotypes[list_num].Find(in_genome);

  if (!found_genotype) {
    found_genotype = new cInjectGenotype();
    found_genotype->SetGenome(in_genome);
    found_genotype->SetParent(parent_genotype);
    
    AddInjectGenotype( found_genotype, list_num );
  }

  return found_genotype;
}

cInjectGenotype * cInjectGenebank::FindInjectGenotype(const cGenome & in_genome) const
{
  int list_num = FindCRC(in_genome) % INJECTGENOTYPE_HASH_SIZE;
  return active_inject_genotypes[list_num].Find(in_genome);
}

void cInjectGenebank::RemoveInjectGenotype(cInjectGenotype & in_inject_genotype)
{
  // If this genotype is still active, mark it no longer active and
  // take it out of the hash table so it doesn't have any new organisms
  // assigned to it.

  if (in_inject_genotype.GetActive() == true) {
    int list_num = FindCRC(in_inject_genotype.GetGenome()) % INJECTGENOTYPE_HASH_SIZE;
    active_inject_genotypes[list_num].Remove(in_inject_genotype);
    inject_genotype_control->Remove(in_inject_genotype);
    //in_inject_genotype.Deactivate(stats.GetUpdate());
    if (cConfig::GetTrackMainLineage()) {
      inject_genotype_control->InsertHistoric(in_inject_genotype);
    }
  }

  // If we are tracking the main lineage, we only want to delete a
  // genotype when all of its decendents have also died out.

  /*if (cConfig::GetTrackMainLineage()) {
    // If  there are more offspring genotypes, hold off on deletion...
    if (in_inject_genotype.GetNumOffspringGenotypes() != 0) return;

    // If this is a dead end, delete it and recurse up...
    cInjectGenotype * parent = in_inject_genotype.GetParentGenotype();
    if (parent != NULL) {
      parent->RemoveOffspringGenotype();

      // Test to see if we need to update the coalescent genotype.
      const int new_coal = inject_genotype_control->UpdateCoalescent();
      stats.SetCoalescentGenotypeDepth(new_coal);
      // cout << "Set coalescent to " << found_gen->GetDepth() << endl;

      if (parent->GetNumInjected() == 0) {
	// Regardless, run RemoveGenotype on the parent.
	RemoveGenotype(*parent);
      }
    }

    inject_genotype_control->RemoveHistoric(in_inject_genotype);
  }

  // Handle the relevent statistics...
  stats.RemoveGenotype(in_inject_genotype.GetID(),
	      in_inject_genotype.GetParentID(), in_inject_genotype.GetParentDistance(),
	      in_inject_genotype.GetDepth(), in_inject_genotype.GetTotalOrganisms(),
              in_inject_genotype.GetTotalParasites(),
	      stats.GetUpdate() - in_inject_genotype.GetUpdateBorn(),
              in_inject_genotype.GetLength());
  if (in_inject_genotype.GetThreshold()) {
  stats.RemoveThreshold(in_inject_genotype.GetID());
  }*/

  delete &in_inject_genotype;
}

void cInjectGenebank::ThresholdInjectGenotype(cInjectGenotype & in_inject_genotype)
{
  in_inject_genotype.SetName( GetLabel(in_inject_genotype.GetLength(),
				inject_genotype_count[in_inject_genotype.GetLength()]++) );
  in_inject_genotype.SetThreshold();

  //stats.AddThreshold(in_inject_genotype.GetID(), in_inject_genotype.GetName()());
  
  // Print the genotype?

  if (cConfig::GetGenotypePrint()) {
    cString filename;
    filename.Set("genebank/%s", in_inject_genotype.GetName()());
    //cTestUtil::PrintGenome(in_inject_genotype.GetGenome(), filename,
    //			   &in_inject_genotype, stats.GetUpdate());
  }
}

bool cInjectGenebank::AdjustInjectGenotype(cInjectGenotype & in_inject_genotype)
{
  if (!inject_genotype_control->Adjust(in_inject_genotype)) return false;

  if ((in_inject_genotype.GetNumInjected() >= cConfig::GetThreshold() ||
       &in_inject_genotype == inject_genotype_control->GetBest()) &&
      !(in_inject_genotype.GetThreshold())) {
    ThresholdInjectGenotype(in_inject_genotype);
  }

  return true;
}

bool cInjectGenebank::SaveClone(ofstream & fp)
{
  // This method just save the counts at each size-class of genotypes.
  // The rest is reconstructable.

  // Save the numbers of organisms we're up to at each size.
  fp << MAX_CREATURE_SIZE << " ";
  for (int i = 0; i < MAX_CREATURE_SIZE; i++) {
    fp << inject_genotype_count[i] << " ";
  }

  return true;
}

bool cInjectGenebank::LoadClone(ifstream & fp)
{
  // This method just restores the counts at each size-class of genotypes.
  // The rest of the loading process should be handled elsewhere.

  // Load the numbers of organisms we're up to at each size.
  int max_size;
  fp >> max_size;
  assert (max_size <= MAX_CREATURE_SIZE); // MAX_CREATURE_SIZE too small
  for (int i = 0; i < max_size && i < MAX_CREATURE_SIZE; i++) {
    fp >> inject_genotype_count[i];
  }

  return true;
}

bool cInjectGenebank::DumpTextSummary(ofstream & fp)
{
  inject_genotype_control->Reset(0);
  for (int i = 0; i < inject_genotype_control->GetSize(); i++) {
    cInjectGenotype * genotype = inject_genotype_control->Get(0);
    fp << genotype->GetGenome().AsString() << " "
       << genotype->GetNumInjected() << " "
       << genotype->GetID() << endl;
    inject_genotype_control->Next(0);
  }

  return true;
}

bool cInjectGenebank::DumpDetailedSummary(const cString & file, int update)
{
  inject_genotype_control->Reset(0);
  for (int i = 0; i < inject_genotype_control->GetSize(); i++) {
    DumpDetailedEntry(inject_genotype_control->Get(0), file, update);
    inject_genotype_control->Next(0);
  }
  return true;
}

/*bool cInjectGenebank::DumpHistoricSummary(ofstream & fp)
{
  inject_genotype_control->ResetHistoric(0);
  for (int i = 0; i < inject_genotype_control->GetHistoricCount(); i++) {
    DumpDetailedEntry(inject_genotype_control->Get(0), fp);
    inject_genotype_control->Next(0);
  }

  return true;
}*/

void cInjectGenebank::DumpDetailedEntry(cInjectGenotype * genotype, const cString & filename, int update)
{
  /*fp << genotype->GetID() << " "                //  1
     << genotype->GetParentID() << " "          //  2
    //     << genotype->GetParentDistance() << " "    //  3
     << genotype->GetNumInjected() << " "      //  4
     << genotype->GetTotalInjected() << " "    //  5
     << genotype->GetLength() << " "            //  6
    // << genotype->GetMerit() << " "             //  7
    // << genotype->GetGestationTime() << " "     //  8
    // << genotype->GetFitness() << " "           //  9
     << genotype->GetUpdateBorn() << " "        // 10
     << genotype->GetUpdateDeactivated() << " " // 11
     << genotype->GetDepth() << " "             // 12
     << genotype->GetGenome().AsString() << " " // 13
     << endl;*/

  cDataFile & df = stats.GetDataFile(filename);

  df.WriteComment( "Avida parasite dump data" );
  df.WriteComment( "UPDATE " + update);
  df.WriteTimeStamp();

  //df.Write( update,                            "update");
  df.Write( genotype->GetID(),                 "parasite genotype ID");
  df.Write( genotype->GetName(),              "parasite genotype name");
  df.Write( genotype->GetParentID(),           "parasite parent ID");
  df.Write( genotype->GetNumInjected(),        "current number of injected creatures with this genotype");
  df.Write( genotype->GetTotalInjected(),      "total number of injected creatures with this genotype");
  df.Write( genotype->GetLength(),             "genotype length");
  df.Write( genotype->GetUpdateBorn(),         "update this genotype was born");
  df.Write( genotype->GetUpdateDeactivated(),  "update this genotype was deactivated");
  df.Write( genotype->GetDepth(),              "genotype depth");
  df.Write( genotype->GetGenome().AsString(),  "genome of this genotype");
  df.Endl();
}

bool cInjectGenebank::OK()
{
  bool ret_value = true;
  int i;

  // Check components...

  if (!inject_genotype_control->OK()) {
    ret_value = false;
  }

  // Loop through all of the reference lists for matching genotypes...

  for (i = 0; i < INJECTGENOTYPE_HASH_SIZE; i++) {
    assert (active_inject_genotypes[i].OK());
  }

  assert (ret_value == true);

  return ret_value;
}

int cInjectGenebank::CountNumCreatures()
{
  int i;
  int total = 0;

  inject_genotype_control->Reset(0);
  for (i = 0; i < inject_genotype_control->GetSize(); i++) {
    total += inject_genotype_control->Get(0)->GetNumInjected();
    inject_genotype_control->Next(0);
  }

  return total;
}


unsigned int cInjectGenebank::FindCRC(const cGenome & in_genome) const
{
  unsigned int total = 13;
  int i;

  for (i = 0; i < in_genome.GetSize(); i++) {
    total *= in_genome[i].GetOp() + 10 + i << 6;
    total += 3;
  }

  return total;
}


Index: avida/current/source/main/inject_genebank.hh
+++ avida/current/source/main/inject_genebank.hh
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2003 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#ifndef INJECT_GENEBANK_HH
#define INJECT_GENEBANK_HH

#include "../tools/string.hh"
#include "../defs.hh"

// porting to gcc 3.1 -- k
//class std::ofstream;
//class std::ifstream;

class cInjectGenebank;
class cInjectGenotype;
class cGenome;
class cSpecies;
class cStats;

#define INJECTGENOTYPE_HASH_SIZE 307    // @CAO Is this an optimal number?
#define SPECIES_HASH_SIZE 101
#define INJECTGENOTYPE_THREADS 2

#define SPECIES_RECORD_OFF     0
#define SPECIES_RECORD_FULL    1
#define SPECIES_RECORD_LIMITED 2

class cInjectGenotypeElement {
private:
  cInjectGenotype * inject_genotype;
  cInjectGenotypeElement * next;
  cInjectGenotypeElement * prev;
public:
  inline cInjectGenotypeElement(cInjectGenotype * in_gen=NULL) : inject_genotype(in_gen) {
    next = NULL;  prev = NULL;
  }
  inline ~cInjectGenotypeElement() { ; }

  inline cInjectGenotype * GetInjectGenotype() const { return inject_genotype; }
  inline cInjectGenotypeElement * GetNext() const { return next; }
  inline cInjectGenotypeElement * GetPrev() const { return prev; }

  inline void SetNext(cInjectGenotypeElement * in_next) { next = in_next; }
  inline void SetPrev(cInjectGenotypeElement * in_prev) { prev = in_prev; }
};

class cInjectGenotypeQueue {
private:
  int size;
  cInjectGenotypeElement root;

  void Remove(cInjectGenotypeElement * in_element);
public:
  cInjectGenotypeQueue();
  ~cInjectGenotypeQueue();

  bool OK();

  void Insert(cInjectGenotype & in_inject_genotype);
  void Remove(cInjectGenotype & in_inject_genotype);
  cInjectGenotype * Find(const cGenome & in_genome) const;
};

class cInjectGenotypeControl {
private:
  int size;
  cInjectGenotype * best;
  cInjectGenotype * coalescent;
  cInjectGenotype * threads[INJECTGENOTYPE_THREADS];
  cInjectGenebank & genebank;

  cInjectGenotype * historic_list;
  int historic_count;

  void Insert(cInjectGenotype & in_inject_genotype, cInjectGenotype * prev_inject_genotype);
  bool CheckPos(cInjectGenotype & in_inject_genotype);
public:
  cInjectGenotypeControl(cInjectGenebank & in_gb);
  ~cInjectGenotypeControl();

  bool OK();
  void Remove(cInjectGenotype & in_inject_genotype);
  void Insert(cInjectGenotype & new_inject_genotype);
  bool Adjust(cInjectGenotype & in_inject_genotype);

  void RemoveHistoric(cInjectGenotype & in_inject_genotype);
  void InsertHistoric(cInjectGenotype & in_inject_genotype);
  int GetHistoricCount() { return historic_count; }

  int UpdateCoalescent();

  inline int GetSize() const { return size; }
  inline cInjectGenotype * GetBest() const { return best; }
  inline cInjectGenotype * GetCoalescent() const { return coalescent; }

  cInjectGenotype * Find(const cGenome & in_genome) const;
  int FindPos(cInjectGenotype & in_inject_genotype, int max_depth = -1);

  inline cInjectGenotype * Get(int thread) const { return threads[thread]; }
  inline cInjectGenotype * Reset(int thread)
    { return threads[thread] = best; }
  inline cInjectGenotype * ResetHistoric(int thread)
    { return threads[thread] = historic_list; }
  cInjectGenotype * Next(int thread);
  cInjectGenotype * Prev(int thread);
};

class cInjectGenebank {
private:
  unsigned int inject_genotype_count[MAX_CREATURE_SIZE];
  cInjectGenotypeQueue active_inject_genotypes[INJECTGENOTYPE_HASH_SIZE];
  cInjectGenotypeControl * inject_genotype_control;
  cStats & stats;

private:
  cString GetLabel(int in_size, int in_num);

public:
  cInjectGenebank(cStats & stats);
  ~cInjectGenebank();

  void UpdateReset();

  /** 
   * This function can be used to add a injectgenotype that was created
   * outside the genebank. In this case, the parameter in_list_num
   * should not be given. Normally, injectgenotypes are added through the 
   * function AddInjectGenotype(const cGenome & in_genome, 
   * cInjectGenotype * parent_injectgenotype = NULL), which then calls this one.
   **/
  void AddInjectGenotype(cInjectGenotype *in_inject_genotype, int in_list_num = -1 );
  cInjectGenotype * AddInjectGenotype(const cGenome & in_genome,
			  cInjectGenotype * parent_inject_genotype = NULL);
  cInjectGenotype * FindInjectGenotype(const cGenome & in_genome) const;
  void RemoveInjectGenotype(cInjectGenotype & in_inject_genotype);
  void ThresholdInjectGenotype(cInjectGenotype & in_inject_genotype);
  bool AdjustInjectGenotype(cInjectGenotype & in_inject_genotype);

  bool SaveClone(std::ofstream & fp);
  bool LoadClone(std::ifstream & fp);
  bool DumpTextSummary(std::ofstream & fp);
  //bool DumpDetailedSummary(std::ofstream & fp);
  bool DumpDetailedSummary(const cString & file, int update);
  bool DumpHistoricSummary(std::ofstream & fp);
  //void DumpDetailedEntry(cInjectGenotype * inject_genotype, std::ofstream & fp);
  void DumpDetailedEntry(cInjectGenotype * inject_genotype, const cString & file, int update);
  bool OK();

  inline int GetSize() const { return inject_genotype_control->GetSize(); }
  inline cInjectGenotype * GetBestInjectGenotype() const
    { return inject_genotype_control->GetBest(); }
  inline cInjectGenotype * GetCoalescentInjectGenotype() const
    { return inject_genotype_control->GetCoalescent(); }
  
  inline cInjectGenotype * GetInjectGenotype(int thread) const
    { return inject_genotype_control->Get(thread); }
  inline cInjectGenotype * NextInjectGenotype(int thread) {
    cInjectGenotype * next = inject_genotype_control->Next(thread);
    return (next == inject_genotype_control->GetBest()) ? (cInjectGenotype*)NULL : next;
  }
  inline cInjectGenotype * ResetThread(int thread)
    { return inject_genotype_control->Reset(thread); }

  int CountNumCreatures();
  inline int FindPos(cInjectGenotype & in_inject_genotype, int max_depth = -1)
    { return inject_genotype_control->FindPos(in_inject_genotype, max_depth); }
   unsigned int FindCRC(const cGenome & in_genome) const;
};

#endif

Index: avida/current/source/main/inject_genotype.cc
+++ avida/current/source/main/inject_genotype.cc
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2003 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#include <fstream>

#include "inject_genotype.hh"

#include "../tools/tools.hh"
#include "../tools/merit.hh"

#include "stats.hh"
#include "config.hh"
#include "genome_util.hh"
#include "../cpu/hardware_method.hh"
#include "organism.hh"
#include "phenotype.hh"

#include "../cpu/test_cpu.hh"


using namespace std;

/////////////////////////
//  cInjectGenotype_BirthData
/////////////////////////

cInjectGenotype_BirthData::cInjectGenotype_BirthData(int in_update_born)
  : update_born(in_update_born)
  , parent_id(-1)
  , gene_depth(0)
  , update_deactivated(-1)
  , parent_genotype(NULL)
  , num_offspring_genotypes(0)
{
}

cInjectGenotype_BirthData::~cInjectGenotype_BirthData()
{
}


///////////////////////////
//  cInjectGenotype
///////////////////////////

cInjectGenotype::cInjectGenotype(int in_update_born, int in_id)
  : genome(1)
  , name("p001-no_name")
  , flag_threshold(false)
  , is_active(true)
  , defer_adjust(0)
  , symbol(0)
  , birth_data(in_update_born)
  , num_injected(0)
  , last_num_injected(0)
  , total_injected(0)
  , next(NULL)
  , prev(NULL)
{
  static int next_id = 1;
  
  if ( in_id >= 0 )
    next_id = in_id;
  
  id_num = next_id++;
}

cInjectGenotype::~cInjectGenotype()
{
  // Reset some of the variables to make sure program will crash if a deleted
  // cell is read!
  symbol = '!';

  num_injected = -1;
  total_injected = -1;

  next = NULL;
  prev = NULL;
}

bool cInjectGenotype::SaveClone(ofstream & fp)
{
  fp << id_num         << " ";
  fp << genome.GetSize() << " ";

  for (int i = 0; i < genome.GetSize(); i++) {
    fp << ((int) genome[i].GetOp()) << " ";
  }

  return true;
}

bool cInjectGenotype::LoadClone(ifstream & fp)
{
  int genome_size = 0;

  fp >> id_num;
  fp >> genome_size;

  genome = cGenome(genome_size);
  for (int i = 0; i < genome_size; i++) {
    cInstruction temp_inst;
    int inst_op;
    fp >> inst_op;
    temp_inst.SetOp((UCHAR) inst_op);
    genome[i] = temp_inst;
    // @CAO add something here to load arguments for instructions.
  }

  return true;
}

bool cInjectGenotype::OK()
{
  bool ret_value = true;

  // Check the components...

  if (!genome.OK()) ret_value = false;

  // And the statistics
  assert( id_num >= 0 && num_injected >= 0 && total_injected >= 0 );
  assert( birth_data.update_born >= -1);

  return ret_value;
};

void cInjectGenotype::SetParent(cInjectGenotype * parent)
{
  birth_data.parent_genotype = parent;

  // If we have a real parent genotype, collect other data about parent.
  if (parent == NULL) return;
  birth_data.parent_id = parent->GetID();
  birth_data.gene_depth = parent->GetDepth() + 1;
  parent->AddOffspringGenotype();
}

void cInjectGenotype::Mutate()  // Check each location to be mutated.
{
  int i;

  for (i = 0; i < genome.GetSize(); i++) {
      genome[i].SetOp(g_random.GetUInt(cConfig::GetNumInstructions()));
    }
  
}

void cInjectGenotype::UpdateReset()
{
  last_num_injected = num_injected;
  birth_data.birth_track.Next();
  birth_data.death_track.Next();
}

void cInjectGenotype::SetGenome(const cGenome & in_genome)
{
  genome = in_genome;

  name.Set("p%03d-no_name", genome.GetSize());
}

void cInjectGenotype::Deactivate(int update)
{
  is_active = false;
  birth_data.update_deactivated = update;
}

int cInjectGenotype::AddParasite()
{
  total_injected++;
  return num_injected++;
}

int cInjectGenotype::RemoveParasite()
{
  //birth_data.death_track.Inc();
  return num_injected--;
}


Index: avida/current/source/main/inject_genotype.hh
+++ avida/current/source/main/inject_genotype.hh
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2003 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#ifndef INJECT_GENOTYPE_HH
#define INJECT_GENOTYPE_HH

#include "../tools/string.hh"
#include "../tools/stat.hh"

#include "genome.hh"

// porting to gcc 3.1 -- k
//class ofstream;
//class ifstream;

class cSpecies;
class cMerit;
class cInjectGenotype;

/*class cInjectGenotype_TestData {
public:
  cGenotype_TestData();
  ~cGenotype_TestData();

  bool is_viable;

  double fitness;
  double merit;
  int gestation_time;
  int executed_size;
  int copied_size;
  double colony_fitness;
  int generations;
  };*/

class cInjectGenotype_BirthData {
public:
  cInjectGenotype_BirthData(int in_update_born);
  ~cInjectGenotype_BirthData();

  cCountTracker birth_track;
  cCountTracker death_track;
  //cCountTracker breed_in_track;
  //cCountTracker breed_true_track;
  //cCountTracker breed_out_track;

  int update_born;      // Update genotype was first created
  int parent_id;        // ID of parent genotype
  //int parent_distance;  // Genetic distance from parent genotype
  int gene_depth;       // depth in the phylogenetic tree from ancestor

  int update_deactivated;      // If not, when did it get deactivated?
  cInjectGenotype * parent_genotype; // Pointer to parent genotype...
  //cSpecies * parent_species;
  int num_offspring_genotypes; // Num offspring genotypes still in memory.
};

class cInjectGenotype {
private:
  cGenome genome;
  cString name;
  bool flag_threshold;
  bool is_active;      // Is this genotype still alive?
  int defer_adjust;    // Don't adjust in the genebank until all are cleared.

  int id_num;
  char symbol;

  //mutable cGenotype_TestData test_data;
  cInjectGenotype_BirthData birth_data;

  // Statistical info

  int num_injected;
  int last_num_injected;
  int total_injected;
  //int total_parasites;

  //cSpecies * species;

  // Data Structure stuff...
  cInjectGenotype * next;
  cInjectGenotype * prev;


  ////// Statistical info //////

  // Collected on Divides
  //cDoubleSum sum_copied_size;
  //cDoubleSum sum_exe_size;

  //cDoubleSum sum_gestation_time;
  //cDoubleSum sum_repro_rate;  // should make gestation obsolete (not new)

  //cDoubleSum sum_merit;
  //cDoubleSum sum_fitness;

  // Temporary (Approx stats used before any divides done)
  // Set in "SetParent"
  //cDoubleSum tmp_sum_copied_size;
  //cDoubleSum tmp_sum_exe_size;

  //cDoubleSum tmp_sum_gestation_time;
  //cDoubleSum tmp_sum_repro_rate;

  //cDoubleSum tmp_sum_merit;
  //cDoubleSum tmp_sum_fitness;

  void CalcTestStats() const;
public:
  /**
   * Constructs an empty genotype. Normally, in_id should not specified as
   * parameter, because cGenotype keeps track of the last id given out, and
   * choses a new one based on that. However, in some cases it is necessary
   * to specify an id (e.g., when loading a history file from disk). Note 
   * that in this case, cGenotype does not check if the id has already been 
   * used before.
   **/
  cInjectGenotype(int in_update_born = 0, int in_id = -1);
  ~cInjectGenotype();

  bool SaveClone(std::ofstream & fp);
  bool LoadClone(std::ifstream & fp);
  bool OK();
  void Mutate();
  void UpdateReset();

  void SetGenome(const cGenome & in_genome);
  //void SetSpecies(cSpecies * in_species);

  // Test CPU info -- only used with limited options on.
  //bool GetTestViable() const;
  //double GetTestFitness() const;
  //double GetTestMerit() const;
  //int GetTestGestationTime() const;
  //int GetTestExecutedSize() const;
  //int GetTestCopiedSize() const;
  //double GetTestColonyFitness() const;
  //int GetTestGenerations() const;

  void SetParent(cInjectGenotype * parent);
  void SetName(cString in_name)     { name = in_name; }
  void SetNext(cInjectGenotype * in_next) { next = in_next; }
  void SetPrev(cInjectGenotype * in_prev) { prev = in_prev; }
  void SetSymbol(char in_symbol) { symbol = in_symbol; }
  inline void SetThreshold();
  void IncDeferAdjust() { defer_adjust++; }
  void DecDeferAdjust() { defer_adjust--; assert(defer_adjust >= 0); }

  // Setting New Stats
  //void AddCopiedSize      (int in)   { sum_copied_size.Add(in); }
  //void AddExecutedSize         (int in)   { sum_exe_size.Add(in); }
  //void AddGestationTime   (int in)   { sum_gestation_time.Add(in);
  //                            sum_repro_rate.Add(1/(double)in); }
//void AddMerit      (const cMerit & in);
//void RemoveMerit   (const cMerit & in);
//void AddFitness    (double in){
//  assert(in >= 0.0);
//  sum_fitness.Add(in);
//}
//void RemoveFitness (double in){
//  assert(in >= 0.0);
//  sum_fitness.Subtract(in);
//}

  //// Properties Native to Genotype ////
  cGenome & GetGenome()             { return genome; }
  const cGenome & GetGenome() const { return genome; }
  int GetLength()             const { return genome.GetSize(); }

//int GetBirths()    const { return birth_data.birth_track.GetTotal(); }
//int GetBreedOut()  const { return birth_data.breed_out_track.GetTotal(); }
//int GetBreedTrue() const { return birth_data.breed_true_track.GetTotal(); }
//int GetBreedIn()   const { return birth_data.breed_in_track.GetTotal(); }

//int GetThisBirths()    const { return birth_data.birth_track.GetCur(); }
//int GetThisBreedOut()  const { return birth_data.breed_out_track.GetCur(); }
//int GetThisBreedTrue() const { return birth_data.breed_true_track.GetCur(); }
//int GetThisBreedIn()   const { return birth_data.breed_in_track.GetCur(); }

//int GetThisDeaths() const { return birth_data.death_track.GetCur(); }

//int GetLastNumOrganisms() const { return last_num_organisms; }
//int GetLastBirths()    const { return birth_data.birth_track.GetLast(); }
//int GetLastBreedOut()  const { return birth_data.breed_out_track.GetLast(); }
//int GetLastBreedTrue() const { return birth_data.breed_true_track.GetLast();}
//int GetLastBreedIn()   const { return birth_data.breed_in_track.GetLast(); }

//inline void SetBreedStats(cGenotype & daughter); // called by ActivateChild

  //// Properties Averaged Over Creatues ////
  //double GetCopiedSize()    const { return (sum_copied_size.Count()>0) ?
//   sum_copied_size.Average() : tmp_sum_copied_size.Average(); }
//double GetExecutedSize()  const { return (sum_exe_size.Count()>0) ?
//   sum_exe_size.Average() : tmp_sum_exe_size.Average(); }
//double GetGestationTime() const { return (sum_gestation_time.Count()>0) ?
//   sum_gestation_time.Average() : tmp_sum_gestation_time.Average(); }
//double GetReproRate()     const { return (sum_repro_rate.Count()>0) ?
//   sum_repro_rate.Average() : tmp_sum_repro_rate.Average(); }
//double GetMerit()         const { return (sum_merit.Count()>0) ?
//   sum_merit.Average() : tmp_sum_merit.Average(); }
//double GetFitness()       const { return (sum_fitness.Count()>0) ?
//   sum_fitness.Average() : tmp_sum_fitness.Average(); }


  // For tracking the genotype line back to the ancestor...
  cInjectGenotype * GetParentGenotype() { return birth_data.parent_genotype; }
  int GetNumOffspringGenotypes() const
    { return birth_data.num_offspring_genotypes; }
  void AddOffspringGenotype() { birth_data.num_offspring_genotypes++; }
  void RemoveOffspringGenotype() { birth_data.num_offspring_genotypes--; }
  bool GetActive() const { return is_active; }
// bool GetDeferAdjust() const { return defer_adjust > 0; }
  int GetUpdateDeactivated() { return birth_data.update_deactivated; }
  void Deactivate(int update);

  int GetUpdateBorn()           { return birth_data.update_born; }
  int GetParentID()             { return birth_data.parent_id; }
//int GetParentDistance()       { return birth_data.parent_distance; }
  int GetDepth()                { return birth_data.gene_depth; }
  cString & GetName()           { return name; }
  cInjectGenotype * GetNext()         { return next; }
  cInjectGenotype * GetPrev()         { return prev; }
  bool GetThreshold() const     { return flag_threshold; }
  int GetID() const             { return id_num; }
  char GetSymbol() const        { return symbol; }

  int AddParasite();
  int RemoveParasite();
//int AddParasite()        { return ++total_parasites; }
//void SwapOrganism()      { total_organisms++; }
  int GetNumInjected()    { return num_injected; }
  int GetTotalInjected()  { return total_injected; }
//int GetTotalParasites()  { return total_parasites; }
};

// The genotype pointer template...



// All the inline stuff...

  ////////////////
 //  cGenotype //
////////////////

inline void cInjectGenotype::SetThreshold()
{
  flag_threshold = true;
  if (symbol == '.') symbol = '+';
}

/*
inline void cGenotype::SetBreedStats(cGenotype & daughter)
{
  birth_data.birth_track.Inc();
  if (daughter.id_num == id_num) {
    birth_data.breed_true_track.Inc();
  } else {
    birth_data.breed_out_track.Inc();
    daughter.birth_data.breed_in_track.Inc();
  }
}*/

#endif

Index: avida/current/source/support/genesis.4stack
+++ avida/current/source/support/genesis.4stack
#############################################################################
# This file includes all the basic run-time defines for avida.
# For more information, see doc/genesis.html
#############################################################################

VERSION_ID 2.0b1		# Do not change this value!

### Architecture Variables ###
MAX_UPDATES  -1         # Maximum updates to run simulation (-1 = no limit)
MAX_GENERATIONS -1      # Maximum generations to run simulation (-1 = no limit)
END_CONDITION_MODE 0	# End run when ...
			# 0 = MAX_UPDATES _OR_ MAX_GENERATIONS is reached
			# 1 = MAX_UPDATES _AND_ MAX_GENERATIONS is reached
WORLD-X 60		# Width of the world in Avida mode.
WORLD-Y 60		# Height of the world in Avida mode.
RANDOM_SEED 0		# Random number seed. (0 for based on time)
HARDWARE_TYPE 1		# 0 = Original CPUs
			# 1 = New, Stack-based CPUs
MAX_CPU_THREADS 1	# Number of Threads CPUs can spawn

### Configuration Files ###
DEFAULT_DIR ../work/              # Directory in which config files are found
INST_SET inst_set.4stack          # File containing instruction set
EVENT_FILE events.cfg             # File containing list of events during run
ANALYZE_FILE analyze.cfg          # File used for analysis mode
ENVIRONMENT_FILE environment.cfg  # File that describes the environment
START_CREATURE organism.4stack    # Organism to seed the soup

### Reproduction ###
BIRTH_METHOD 4   # 0 = Replace random organism in neighborhood
		  # 1 = Replace oldest organism in neighborhood
		  # 2 = Replace largest Age/Merit in neighborhood
		  # 3 = Place only in empty cells in neighborhood
		  # 4 = Replace random from entire population (Mass Action)
		  # 5 = Replace oldest in entire population (like Tierra)
DEATH_METHOD 0    # 0 = Never die of old age.
		  # 1 = Die when inst executed = AGE_LIMIT (with deviation)
		  # 2 = Die when inst executed = length * AGE_LIMIT (+ dev.)
AGE_LIMIT 5000    # Modifies DEATH_METHOD
AGE_DEVIATION 0   # Modified DEATH_METHOD
ALLOC_METHOD 0    # 0 = Allocated space is set to default instruction.
                  # 1 = Set to section of dead genome (Necrophilia)
                  # 2 = Allocated space is set to random instruction.
DIVIDE_METHOD 2   # 0 = Divide leaves state of mother untouched.
                  # 1 = Divide resets state of mother
                  #     (after the divide, we have 2 children)
		  # 2 = Divide resets only the current thread of the mother
		  #     (useful in 4-stack CPU w/ parasites)

GENERATION_INC_METHOD 0 # 0 = Only the generation of the child is
                        #     increased on divide.
			# 1 = Both the generation of the mother and child are
			#     increased on divide (good with DIVIDE_METHOD 1).

### Divide Restrictions ####
CHILD_SIZE_RANGE 2.0	# Maximal differential between child and parent sizes.
MIN_COPIED_LINES 0.5    # Code fraction which must be copied before divide.
MIN_EXE_LINES    0.5    # Code fraction which must be executed before divide.
REQUIRE_ALLOCATE   1    # Is a an allocate required before a divide? (0/1)
REQUIRED_TASK -1  # Number of task required for successful divide.

### Mutations ###

# mutations that occur during execution..
POINT_MUT_PROB  0.0     # Mutation rate (per-location per update)
COPY_MUT_PROB   0.0075  # Mutation rate (per copy).

# mutations that occur on divide...
INS_MUT_PROB    0.0     # Insertion rate (per site, applied on divide).
DEL_MUT_PROB    0.0     # Deletion rate (per site, applied on divide).
DIV_MUT_PROB    0.0     # Mutation rate (per site, applied on divide).
DIVIDE_MUT_PROB 0.0     # Mutation rate (per divide).
DIVIDE_INS_PROB 0.05    # Insertion rate (per divide).
DIVIDE_DEL_PROB 0.05    # Deletion rate (per divide).
PARENT_MUT_PROB 0.0     # Per-site, in parent, on divide

# heads based mutations
# READ_SHIFT_PROB   0.0
# READ INS_PROB     0.0
# READ_DEL_PROB     0.0
# WRITE_SHIFT_PROB  0.0
# WRITE_INS_PROB    0.0
# WRITE_DEL_PROB    0.0


### Mutation reversions ###
# these slow down avida a lot, and should be set to 0 normally.
REVERT_FATAL       0.0  # Should any mutations be reverted on birth?
REVERT_DETRIMENTAL 0.0  #   0.0 to 1.0; Probability of reversion.
REVERT_NEUTRAL     0.0
REVERT_BENEFICIAL  0.0

STERILIZE_FATAL       0.0  # Should any mutations clear (kill) the organism?
STERILIZE_DETRIMENTAL 0.0  #   0.0 to 1.0; Probability of reset.
STERILIZE_NEUTRAL     0.0
STERILIZE_BENEFICIAL  0.0

FAIL_IMPLICIT     0	# Should copies that failed *not* due to mutations
			# be eliminated?

### Time Slicing ###
AVE_TIME_SLICE 30
SLICING_METHOD 2	# 0 = CONSTANT: all organisms get default...
			# 1 = PROBABILISTIC: Run _prob_ proportional to merit.
			# 2 = INTEGRATED: Perfectly integrated deterministic.
SIZE_MERIT_METHOD 4	# 0 = off (merit is independent of size)
			# 1 = Merit proportional to copied size
			# 2 = Merit prop. to executed size
			# 3 = Merit prop. to full size
			# 4 = Merit prop. to min of executed or copied size
			# 5 = Merit prop. to sqrt of the minimum size
TASK_MERIT_METHOD 1	# 0 = No task bonuses
			# 1 = Bonus just equals the task bonus
THREAD_SLICING_METHOD 1 # 0 = One thread executed per time slice.
			# 1 = All threads executed each time slice.
 			# Formula for an organism's thread slicing: 
			# 1 + (num_organism_threads-1) * THREAD_SLICING_METHOD

MAX_LABEL_EXE_SIZE 1	# Max nops marked as executed when labels are used
MERIT_TIME 1            # 0 = Merit Calculated when task completed
		        # 1 = Merit Calculated on Divide
MAX_NUM_TASKS_REWARDED -1  # -1 = Unlimited

### Genotype Info ###
THRESHOLD 3		# Number of organisms in a genotype needed for it
			#   to be considered viable.
GENOTYPE_PRINT 0	# 0/1 (off/on) Print out all threshold genotypes?
GENOTYPE_PRINT_DOM 0	# Print out a genotype if it stays dominant for
                        #   this many updates. (0 = off)
SPECIES_THRESHOLD 2     # max failure count for organisms to be same species
SPECIES_RECORDING 0	# 1 = full, 2 = limited search (parent only)
SPECIES_PRINT 0		# 0/1 (off/on) Print out all species?
TEST_CPU_TIME_MOD 20    # Time allocated in test CPUs (multiple of length)
TRACK_MAIN_LINEAGE 1    # Track primary lineage leading to final population?

### Log Files ###
LOG_CREATURES 0		# 0/1 (off/on) toggle to print file.
LOG_GENOTYPES 0		# 0 = off, 1 = print ALL, 2 = print threshold ONLY.
LOG_THRESHOLD 0		# 0/1 (off/on) toggle to print file.
LOG_SPECIES 0		# 0/1 (off/on) toggle to print file.
LOG_LANDSCAPE 0		# 0/1 (off/on) toggle to print file.

LOG_LINEAGES 0          # 0/1 (off/on) to log advantageous mutations
# This one can slow down avida a lot. It is used to get an idea of how
# often an advantageous mutation arises, and where it goes afterwards.
# See also LINEAGE_CREATION_METHOD.

LINEAGE_CREATION_METHOD 0
# Lineage creation options are.  Works only when LOG_LINEAGES is set to 1.
#   0 = manual creation (on inject, use successive integers as lineage labels).
#   1 = when a child's (potential) fitness is higher than that of its parent.
#   2 = when a child's (potential) fitness is higher than max in population.
#   3 = when a child's (potential) fitness is higher than max in dom. lineage
#	*and* the child is in the dominant lineage, or (2)
#   4 = when a child's (potential) fitness is higher than max in dom. lineage
#	(and that of its own lineage)
#   5 = same as child's (potential) fitness is higher than that of the
#       currently dominant organism, and also than that of any organism
#       currently in the same lineage.
#   6 = when a child's (potential) fitness is higher than any organism
#       currently in the same lineage.
#   7 = when a child's (potential) fitness is higher than that of any
#       organism in its line of descent

### END ###



Index: avida/current/source/support/inst_set.4stack
+++ avida/current/source/support/inst_set.4stack
Nop-A      	1	#1 	(a)	
Nop-B      	1  	#2	(b)
Nop-C      	1   	#3	(c)
Nop-D		1	#4	(d)
#Nop-X		1	#	
Val-Shift-R    	1	#5	(e)
Val-Shift-L    	1   	#6	(f)
Val-Nand      	1   	#7	(g)
Val-Add        	1   	#8	(h)
Val-Sub        	1   	#9	(i)
Val-Mult	1	#10	(j)
Val-Div		1	#11	(k)
SetMemory    	1   	#12	(l)
Divide   	1   	#13 	(m)
Inst-Read	1	#14	(n)
Inst-Write	1	#15	(o)
#Inst-Copy     	1   	     	()
If-Equal	1	#16	(p)
If-Not-Equal  	1	#17	(q)
If-Less    	1   	#18	(r)
If-Greater	1	#19	(s)
Head-Push	1	#20	(t)
Head-Pop	1	#21	(u)
Head-Move   	1   	#22   	(v)
Search   	1   	#23  	(w)
Push-Next	1	#24	(x)
Push-Prev	1	#25	(y)
Push-Comp	1	#26	(z)
Val-Delete	1	#27	(A)
Val-Copy	1	#28	(B)
#ThreadFork	1	#29	()
#if-label   	1   		()
Val-Inc		1	#30	(C)
Val-Dec		1	#31 	(D)
Val-Mod		1	#32	(E)
#ThreadKill	1	#33	()
IO		1	#34	(F)
Inject		1	#35	(G)
Index: avida/current/source/support/preset_organisms/organism.4stack
+++ avida/current/source/support/preset_organisms/organism.4stack
# SAMPLE ORGANISM:
#
Search       #  1:  Find organism end.
Nop-C        #  2:  - Match CD:AB
Nop-D
#ThreadFork   #  3:
#Nop-D	     #  4:
Push-Prev    #  5:  Move end position to Stack-A
SetMemory    #  6:  Place FLOW-head in memory space for offspring
Head-Move    #  7:  Move Write head to flow head position
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Search       #  9:  Drop flow head at start of copy loop
Inst-Read    # 10:
Inst-Write   # 11: 
Head-Push    # 12:  Get current position of...
Nop-C        # 13:  - Read-Head
If-Equal     # 14:  Test if we are done copying...
Divide       # 15:  ...If so, divide.
Head-Move    # 16:  ...If not, continue with loop.
Nop-A        # 17:
Nop-B		
Index: avida/current/source/support/preset_organisms/organism.parasite
+++ avida/current/source/support/preset_organisms/organism.parasite
Search       #  1:  Find organism end.
Nop-D        #  2:  - Match A:A
Push-Prev    #  5:  Move end position to Stack-A
SetMemory    #  6:  Place FLOW-head in memory space for offspring
Head-Move    #  7:  Move Write head to flow head position
Nop-C        #  8:
Search       #  9:  Drop flow head at start of copy loop
Inst-Read    # 10:
Inst-Write   # 11: 
Head-Push    # 12:  Get current position of...
Nop-C        # 13:  - Read-Head
If-Equal     # 14:  Test if we are done copying...
Inject       # 15:  ...If so, inject.
Head-Move    # 16:  ...If not, continue with loop.
Nop-A        # 17:
Nop-B        # 18:


More information about the Avida-cvs mailing list