[avida-cvs] avida CVS commits: /current/source/cpu hardware_util.cc /current/source/main config.cc config.hh mutations.cc mutations.hh /current/source/tools file.cc file.hh string_list.hh tList.hh

mercere99 avida-cvs at alife.org
Mon May 26 08:53:39 PDT 2003


mercere99		Mon May 26 00:53:39 2003 EDT

  Modified files:              
    /avida/current/source/cpu	hardware_util.cc 
    /avida/current/source/main	config.cc config.hh mutations.cc 
                              	mutations.hh 
    /avida/current/source/tools	file.cc file.hh string_list.hh tList.hh 
  Log:
  Setup Avida to print out a genesis file if none exists.
  
  This is done by actually creating a data structure inside of cConfig that
  knows about all of its variables, what genesis setting they are associated
  with, what their default values are, and a brief description of that setting.
  The settings are placed into groups.  If genesis does not exist, it is
  created, fully commented and broken down into the proper groups.
  
  This provides a lot more flexible of an interface to cConfig, and could
  be useful with the viewer.  Note that its different to add a genesis setting
  now, but no more difficult, and the database will automatically be updated
  so that this new setting will be included in the default genesis file when
  its printed.
  
  Unfortunately, avida stops right after creating genesis and needs to be
  restarted.  I'm going to figure this out tomorrow.
  
  I also removed some of the genesis settings that seem not to be used anywhere
  in the code anymore.  I think I got them all nicely.
  
  
-------------- next part --------------
Index: avida/current/source/cpu/hardware_util.cc
diff -u avida/current/source/cpu/hardware_util.cc:1.26 avida/current/source/cpu/hardware_util.cc:1.27
--- avida/current/source/cpu/hardware_util.cc:1.26	Sun May 25 09:46:30 2003
+++ avida/current/source/cpu/hardware_util.cc	Mon May 26 00:53:37 2003
@@ -65,7 +65,7 @@
 
     // If this is not the default filename, give and error and stop.
     else {
-      cerr << "Error: Could not file instruction set '" << filename
+      cerr << "Error: Could not open instruction set '" << filename
 	   << "'.  Halting." << endl;
       exit(1);
     }
Index: avida/current/source/main/config.cc
diff -u avida/current/source/main/config.cc:1.56 avida/current/source/main/config.cc:1.57
--- avida/current/source/main/config.cc:1.56	Sun May 25 09:46:31 2003
+++ avida/current/source/main/config.cc	Mon May 26 00:53:37 2003
@@ -16,7 +16,7 @@
 
 using namespace std;
 
-
+tList<cConfig::cConfigGroup> cConfig::group_list;
 bool cConfig::analyze_mode;
 bool cConfig::primitive_mode;
 cString cConfig::default_dir;
@@ -43,9 +43,6 @@
 double cConfig::divide_ins_prob;
 double cConfig::divide_del_prob;
 double cConfig::parent_mut_prob;
-double cConfig::crossover_prob;
-double cConfig::aligned_cross_prob;
-double cConfig::exe_err_prob;
 int cConfig::num_instructions;
 int cConfig::hardware_type;
 int cConfig::max_cpu_threads;
@@ -54,7 +51,6 @@
 int cConfig::base_size_merit;
 int cConfig::task_merit_method;
 int cConfig::max_label_exe_size;
-int cConfig::max_num_tasks_rewarded;
 int cConfig::merit_time;
 int cConfig::num_tasks;
 int cConfig::num_reactions;
@@ -93,139 +89,260 @@
 int cConfig::test_cpu_time_mod;
 int cConfig::track_main_lineage;
 bool cConfig::log_threshold_only;
-bool cConfig::log_breed_count;
 bool cConfig::log_creatures;
-bool cConfig::log_phylogeny;
 bool cConfig::log_genotypes;
 bool cConfig::log_threshold;
 bool cConfig::log_species;
 bool cConfig::log_landscape;
-bool cConfig::log_mutations;
 bool cConfig::log_lineages;
 int cConfig::debug_level;
 int cConfig::view_mode;
-int cConfig::viewer_type;
 
 
 
 void cConfig::Setup(int argc, char * argv[])
 {
+  // Start with the Architecture variables...
+  cConfigGroup * arch_group = new cConfigGroup("Architecture Variables");
+  group_list.PushRear(arch_group);
+  
+  arch_group->Add(max_updates, "-1", "MAX_UPDATES",
+		  "Maximum updates to run experiment (-1 = no limit)");
+  arch_group->Add(max_generations, "-1", "MAX_GENERATIONS",
+		  "Maximum generations to run experiment (-1 = no limit)");
+  arch_group->Add(end_condition_mode, "0", "END_CONDITION_MODE",
+		  "End run when ...\n0 = MAX_UPDATES _OR_ MAX_GENERATIONS is reached\n1 = MAX_UPDATES _AND_ MAX_GENERATIONS is reached");
+  arch_group->Add(world_x, "100", "WORLD-X",
+		  "Width of the Avida world");
+  arch_group->Add(world_y, "100", "WORLD-Y",
+		  "Height of the Avida world");
+  arch_group->Add(rand_seed, "0", "RANDOM_SEED",
+		  "Random number seed (0 for based on time)");
+  arch_group->Add(hardware_type, "0", "HARDWARE_TYPE",
+		  "0 = Original CPUs\n1 = New, Stack-based CPUs");
+
+  // Configuration file group.
+  cConfigGroup * file_group = new cConfigGroup("Configuration Files");
+  group_list.PushRear(file_group);
+  
+  file_group->Add(default_dir, DEFAULT_DIR, "DEFAULT_DIR",
+		  "Directory in which config files are found");
+  file_group->Add(inst_filename, "inst_set.default", "INST_SET",
+		  "File containing instruction set");
+  file_group->Add(event_filename, "events.cfg", "EVENT_FILE",
+		  "File containing list of events during run");
+  file_group->Add(analyze_filename, "analyze.cfg", "ANALYZE_FILE",
+		  "File used for analysis mode");
+  file_group->Add(env_filename, "environment.cfg", "ENVIRONMENT_FILE",
+		  "File that describes the environment");
+  file_group->Add(start_creature, "organism.default", "START_CREATURE",
+		  "Organism to seed the soup");
+
+  // Reproduction group.
+  cConfigGroup * repro_group = new cConfigGroup("Birth and Death");
+  group_list.PushRear(repro_group);
+  
+  repro_group->Add(birth_method, "4", "BIRTH_METHOD",
+		   "0 = Replace random organism in neighborhood\n1 = Replace oldest organism in neighborhood\n2 = Replace largest Age/Merit in neighborhood\n3 = Place only in empty cells in neighborhood\n4 = Replace random from population (Mass Action)\n5 = Replace oldest in entire population (like Tierra)");
+  repro_group->Add(death_method, "0", "DEATH_METHOD",
+		   "0 = Never die of old age.\n1 = Die when inst executed = AGE_LIMIT (+deviation)\n2 = Die when inst executed = length*AGE_LIMIT (+dev)");
+  repro_group->Add(age_limit, "5000", "AGE_LIMIT",
+		   "Modifies DEATH_METHOD");
+  repro_group->Add(age_deviation, "0", "AGE_DEVIATION",
+		   "Creates a distribution around AGE_LIMIT");
+  repro_group->Add(alloc_method, "0", "ALLOC_METHOD",
+		   "0 = Allocated space is set to default instruction.\n1 = Set to section of dead genome (Necrophilia)\n2 = Allocated space is set to random instruction.");
+  repro_group->Add(divide_method, "1", "DIVIDE_METHOD",
+		   "0 = Divide leaves state of mother untouched.\n1 = Divide resets state of mother\n    (after the divide, we have 2 children)");
+  repro_group->Add(generation_inc_method, "1", "GENERATION_INC_METHOD",
+		   "0 = Only the generation of the child is\n    increased on divide.\n1 = Both the generation of the mother and child are\n    increased on divide (good with DIVIDE_METHOD 1).");
+
+
+  // Divide Restrictions Group.
+  cConfigGroup * div_group = new cConfigGroup("Divide Restrictions");
+  group_list.PushRear(div_group);
+  
+  div_group->Add(child_size_range, "2.0", "CHILD_SIZE_RANGE",
+		 "Maximal differential between child and parent sizes.");
+  div_group->Add(min_copied_lines, "0.5", "MIN_COPIED_LINES",
+		 "Code fraction which must be copied before divide.");
+  div_group->Add(min_exe_lines, "0.5", "MIN_EXE_LINES",
+		 "Code fraction which must be executed before divide.");
+  div_group->Add(require_allocate, "1", "REQUIRE_ALLOCATE",
+		 "Is a an allocate required before a divide? (0/1)");
+  div_group->Add(required_task, "-1", "REQUIRED_TASK",
+		 "Task ID required for successful divide.");
+
+
+  // Mutations Group
+  cConfigGroup * muts_group = new cConfigGroup("Mutations");
+  group_list.PushRear(muts_group);
+
+  muts_group->Add(point_mut_prob, "0.0", "POINT_MUT_PROB",
+		  "Mutation rate (per-location per update)");
+  muts_group->Add(copy_mut_prob, "0.0075", "COPY_MUT_PROB",
+		  "Mutation rate (per copy)");
+  muts_group->Add(ins_mut_prob, "0.0", "INS_MUT_PROB",
+		  "Insertion rate (per site, applied on divide)");
+  muts_group->Add(del_mut_prob, "0.0", "DEL_MUT_PROB",
+		  "Deletion rate (per site, applied on divide)");
+  muts_group->Add(div_mut_prob, "0.0", "DIV_MUT_PROB",
+		  "Mutation rate (per site, applied on divide)");
+  muts_group->Add(divide_mut_prob, "0.0", "DIVIDE_MUT_PROB",
+		  "Mutation rate (per divide)");
+  muts_group->Add(divide_ins_prob, "0.05", "DIVIDE_INS_PROB",
+		  "Insertion rate (per divide)");
+  muts_group->Add(divide_del_prob, "0.05", "DIVIDE_DEL_PROB",
+		  "Deletion rate (per divide)");
+  muts_group->Add(parent_mut_prob, "0.0", "PARENT_MUT_PROB",
+		  "Per-site, in parent, on divide");
+
+  
+  // Mutation reversions group
+  cConfigGroup * rev_group = new cConfigGroup("Mutation Reversion");
+  rev_group->SetComment("These slow down avida a lot, and should be set to 0.0 normally.");
+  group_list.PushRear(rev_group);
+
+  rev_group->Add(revert_fatal, "0.0", "REVERT_FATAL",
+		 "Should any mutations be reverted on birth?");
+  rev_group->Add(revert_neg, "0.0", "REVERT_DETRIMENTAL",
+		 "  0.0 to 1.0; Probability of reversion.");
+  rev_group->Add(revert_neut, "0.0", "REVERT_NEUTRAL",
+		 "");
+  rev_group->Add(revert_pos, "0.0", "REVERT_BENEFICIAL",
+		 "");
+  rev_group->Add(sterilize_fatal, "0.0", "STERILIZE_FATAL",
+		 "Should any mutations clear (kill) the organism?");
+  rev_group->Add(sterilize_neg, "0.0", "STERILIZE_DETRIMENTAL",
+		 "  0.0 to 1.0; Probability of reset.");
+  rev_group->Add(sterilize_neut, "0.0", "STERILIZE_NEUTRAL",
+		 "");
+  rev_group->Add(sterilize_pos, "0.0", "STERILIZE_BENEFICIAL",
+		 "");
+  rev_group->Add(fail_implicit, "0", "FAIL_IMPLICIT",
+		 "Should copies that failed *not* due to mutations\nbe eliminated?");
+
+
+  // Time slicing group
+  cConfigGroup * time_group = new cConfigGroup("Time Slicing");
+  group_list.PushRear(time_group);
+
+  time_group->Add(ave_time_slice, "30", "AVE_TIME_SLICE",
+		  "Ave number of insts per org per update");
+  time_group->Add(slicing_method, "2", "SLICING_METHOD",
+		  "0 = CONSTANT: all organisms get default...\n1 = PROBABILISTIC: Run _prob_ proportional to merit.\n2 = INTEGRATED: Perfectly integrated deterministic.");
+  time_group->Add(size_merit_method, "0", "SIZE_MERIT_METHOD",
+		  "0 = off (merit is independent of size)\n1 = Merit proportional to copied size\n2 = Merit prop. to executed size\n3 = Merit prop. to full size\n4 = Merit prop. to min of executed or copied size\n5 = Merit prop. to sqrt of the minimum size");
+  time_group->Add(task_merit_method, "1", "TASK_MERIT_METHOD",
+		  "0 = No task bonuses\n1 = Bonus just equals the task bonus");
+  time_group->Add(max_cpu_threads, "1", "MAX_CPU_THREADS",
+		  "Number of Threads a CPU can spawn");
+  time_group->Add(thread_slicing_method, "0", "THREAD_SLICING_METHOD",
+		  "0 = One thread executed per time slice.\n1 = All threads executed each time slice.");
+  time_group->Add(max_label_exe_size, "1", "MAX_LABEL_EXE_SIZE",
+		  "Max nops marked as executed when labels are used");
+  time_group->Add(base_size_merit, "0", "BASE_SIZE_MERIT",
+		  "Base merit when size is *not* used");
+  time_group->Add(merit_time, "0", "MERIT_TIME",
+		  "0 = Merit Calculated when task completed\n1 = Merit Calculated on Divide");
+
+
+  // Geneology group
+  cConfigGroup * gen_group = new cConfigGroup("Geneology");
+  group_list.PushRear(gen_group);
+
+  gen_group->Add(track_main_lineage, "0", "TRACK_MAIN_LINEAGE",
+		 "Track primary lineage leading to final population?");
+  gen_group->Add(threshold, "3", "THRESHOLD",
+		 "Number of organisms in a genotype needed for it\n  to be considered viable.");
+  gen_group->Add(genotype_print, "0", "GENOTYPE_PRINT",
+		 "0/1 (off/on) Print out all threshold genotypes?");
+  gen_group->Add(genotype_print_dom, "0", "GENOTYPE_PRINT_DOM",
+		 "Print out a genotype if it stays dominant for\n  this many updates. (0 = off)");
+  gen_group->Add(species_threshold, "2", "SPECIES_THRESHOLD",
+		 "max failure count for organisms to be same species");
+  gen_group->Add(species_recording, "0", "SPECIES_RECORDING",
+		 "1 = full, 2 = limited search (parent only)");
+  gen_group->Add(species_print, "0", "SPECIES_PRINT",
+		 "0/1 (off/on) Print out all species?");
+  gen_group->Add(test_cpu_time_mod, "20", "TEST_CPU_TIME_MOD",
+		 "Time allocated in test CPUs (multiple of length)");
+  
+
+  // Log Files group
+  cConfigGroup * log_group = new cConfigGroup("Log Files");
+  group_list.PushRear(log_group);
+
+  log_group->Add(log_creatures, "0", "LOG_CREATURES",
+		 "0/1 (off/on) toggle to print file.");
+  log_group->Add(log_genotypes, "0", "LOG_GENOTYPES",
+		 "0 = off, 1 = print ALL, 2 = print threshold ONLY.");
+  log_group->Add(log_threshold, "0", "LOG_THRESHOLD",
+		 "0/1 (off/on) toggle to print file.");
+  log_group->Add(log_species, "0", "LOG_SPECIES",
+		 "0/1 (off/on) toggle to print file.");
+  log_group->Add(log_landscape, "0", "LOG_LANDSCAPE",
+		 "0/1 (off/on) toggle to print file.");
+
+
+  // Viewer group
+  cConfigGroup * view_group = new cConfigGroup("Viewer Settings");
+  group_list.PushRear(view_group);
+
+  view_group->Add(view_mode, "0", "VIEW_MODE",
+		  "Initial viewer screen");
+
+  // Lineages group
+  cConfigGroup * lin_group = new cConfigGroup("Lineage");
+  lin_group->SetComment("NOTE: This should probably be called \"Clade\"\nThis one can slow down avida a lot. It is used to get an idea of how\noften an advantageous mutation arises, and where it goes afterwards.\nLineage creation options are.  Works only when LOG_LINEAGES is set to 1.\n  0 = manual creation (on inject, use successive integers as lineage labels).\n  1 = when a child's (potential) fitness is higher than that of its parent.\n  2 = when a child's (potential) fitness is higher than max in population.\n  3 = when a child's (potential) fitness is higher than max in dom. lineage\n*and* the child is in the dominant lineage, or (2)\n  4 = when a child's (potential) fitness is higher than max in dom. lineage\n(and that of its own lineage)\n  5 = same as child's (potential) fitness is higher than that of the\n      currently dominant organism, and also than that of any organism\n      currently in the same lineage.\n  6 = when a child's (potential) fitness is higher than any organism\n      currently in the same lineage.\n  7 = when a child's (potential) fitness is higher than that of any\n      organism in its line of descent");
+
+  group_list.PushRear(lin_group);
+
+  lin_group->Add(log_lineages, "0", "LOG_LINEAGES",
+		 "");
+  lin_group->Add(lineage_creation_method, "0", "LINEAGE_CREATION_METHOD",
+		 "");
+
+  /***
+   * Load all of the variables from genesis.
+   ***/
+
   default_dir = DEFAULT_DIR;
 
   cGenesis genesis;
   genesis.SetVerbose();
   ProcessConfiguration(argc, argv, genesis);
+  
+  tListIterator<cConfigGroup> group_it(group_list);
+  cConfigGroup * cur_group;
+  while ((cur_group = group_it.Next()) != NULL) {
+    cur_group->LoadValues(genesis);
+  }
+
+  /***
+   * Handle any special modifications to any of the variables now that
+   * they've been loaded.
+   ***/
 
-  // Load the default directory...
-  default_dir = genesis.ReadString("DEFAULT_DIR", DEFAULT_DIR);
+  // The default directory should end in a '/'.
   char dir_tail = default_dir[default_dir.GetSize() - 1];
   if (dir_tail != '\\' && dir_tail != '/') default_dir += "/";
 
-  // Input files...
-  inst_filename  = genesis.ReadString("INST_SET");
-  event_filename = genesis.ReadString("EVENT_FILE", "events.cfg");
-  analyze_filename = genesis.ReadString("ANALYZE_FILE", "analyze.cfg");
-  env_filename = genesis.ReadString("ENVIRONMENT_FILE", "environment.cfg");
-  start_creature = genesis.ReadString("START_CREATURE");
-
-
-  // Load Archetecture...
-  max_updates     = genesis.ReadInt("MAX_UPDATES", -1);
-  max_generations = genesis.ReadInt("MAX_GENERATIONS", -1);
-  end_condition_mode = genesis.ReadInt("END_CONDITION_MODE", 0);
-  world_x         = genesis.ReadInt("WORLD-X");
-  world_y         = genesis.ReadInt("WORLD-Y");
-  hardware_type   = genesis.ReadInt("HARDWARE_TYPE");
-
-  birth_method   = genesis.ReadInt("BIRTH_METHOD", POSITION_CHILD_AGE);
-  death_method   = genesis.ReadInt("DEATH_METHOD", DEATH_METHOD_OFF);
-  alloc_method   = genesis.ReadInt("ALLOC_METHOD", ALLOC_METHOD_DEFAULT);
-  divide_method  = genesis.ReadInt("DIVIDE_METHOD", DIVIDE_METHOD_SPLIT);
-  required_task   = genesis.ReadInt("REQUIRED_TASK", -1);
-  lineage_creation_method =
-    genesis.ReadInt("LINEAGE_CREATION_METHOD", 0);
-  generation_inc_method =
-    genesis.ReadInt("GENERATION_INC_METHOD", GENERATION_INC_BOTH);
-  age_limit      = genesis.ReadInt("AGE_LIMIT", -1);
-  age_deviation    = genesis.ReadFloat("AGE_DEVIATION", 0);
-  child_size_range = genesis.ReadFloat("CHILD_SIZE_RANGE", 2.0);
-  min_copied_lines = genesis.ReadFloat("MIN_COPIED_LINES", 0.5);
-  min_exe_lines    = genesis.ReadFloat("MIN_EXE_LINES", 0.5);
-  require_allocate = genesis.ReadInt("REQUIRE_ALLOCATE", 1);
-
-  revert_fatal = genesis.ReadFloat("REVERT_FATAL", 0.0);
-  revert_neg   = genesis.ReadFloat("REVERT_DETRIMENTAL", 0.0);
-  revert_neut  = genesis.ReadFloat("REVERT_NEUTRAL", 0.0);
-  revert_pos   = genesis.ReadFloat("REVERT_BENEFICIAL", 0.0);
-  sterilize_fatal = genesis.ReadFloat("STERILIZE_FATAL", 0.0);
-  sterilize_neg   = genesis.ReadFloat("STERILIZE_DETRIMENTAL", 0.0);
-  sterilize_neut  = genesis.ReadFloat("STERILIZE_NEUTRAL", 0.0);
-  sterilize_pos   = genesis.ReadFloat("STERILIZE_BENEFICIAL", 0.0);
+  // Determine if any variables were set that require test CPUs to be run
+  // at every divide.
   test_on_divide = (revert_fatal > 0.0) || (revert_neg > 0.0) ||
     (revert_neut > 0.0) || (revert_pos > 0.0) || (sterilize_fatal > 0.0) ||
     (sterilize_neg > 0.0) || (sterilize_neut > 0.0) || (sterilize_pos > 0.0);
-  fail_implicit = genesis.ReadInt("FAIL_IMPLICIT", 0);
-
-  // Genealogy
-  species_threshold  = genesis.ReadInt("SPECIES_THRESHOLD");
-  threshold          = genesis.ReadInt("THRESHOLD");
-  genotype_print     = genesis.ReadInt("GENOTYPE_PRINT");
-  species_print      = genesis.ReadInt("SPECIES_PRINT");
-  species_recording  = genesis.ReadInt("SPECIES_RECORDING");
-  genotype_print_dom = genesis.ReadInt("GENOTYPE_PRINT_DOM");
-  test_cpu_time_mod  = genesis.ReadInt("TEST_CPU_TIME_MOD", 20);
-  track_main_lineage = genesis.ReadInt("TRACK_MAIN_LINEAGE", 0);
-
-  // Thread Info
-  max_cpu_threads = genesis.ReadInt("MAX_CPU_THREADS", 1);
-  thread_slicing_method = genesis.ReadInt("THREAD_SLICING_METHOD", 0);
-  
-
-  // Time Slicing Info
-  slicing_method = genesis.ReadInt("SLICING_METHOD", SLICE_CONSTANT);
-  size_merit_method = genesis.ReadInt("SIZE_MERIT_METHOD", 0);
-  base_size_merit   = genesis.ReadInt("BASE_SIZE_MERIT", 0);
-  ave_time_slice = genesis.ReadInt("AVE_TIME_SLICE", 30);
-  merit_time = genesis.ReadInt("MERIT_TIME", 0);
-
-  // Task Merit Method
-  task_merit_method = genesis.ReadInt("TASK_MERIT_METHOD", TASK_MERIT_NORMAL);
-  max_num_tasks_rewarded = genesis.ReadInt("MAX_NUM_TASKS_REWARDED", -1);
-  max_label_exe_size = genesis.ReadInt("MAX_LABEL_EXE_SIZE", 1);
-
-  // Load Mutation Info
-  point_mut_prob  = genesis.ReadFloat("POINT_MUT_PROB");
-  copy_mut_prob   = genesis.ReadFloat("COPY_MUT_PROB");
-  ins_mut_prob    = genesis.ReadFloat("INS_MUT_PROB");
-  del_mut_prob    = genesis.ReadFloat("DEL_MUT_PROB");
-  div_mut_prob    = genesis.ReadFloat("DIV_MUT_PROB");
-  divide_mut_prob = genesis.ReadFloat("DIVIDE_MUT_PROB");
-  divide_ins_prob = genesis.ReadFloat("DIVIDE_INS_PROB");
-  divide_del_prob = genesis.ReadFloat("DIVIDE_DEL_PROB");
-  parent_mut_prob = genesis.ReadFloat("PARENT_MUT_PROB");
-  crossover_prob  = genesis.ReadFloat("CROSSOVER_PROB");
-  aligned_cross_prob = genesis.ReadFloat("ALIGNED_CROSS_PROB");
-  exe_err_prob    = genesis.ReadFloat("EXE_ERROR_PROB");
-
-  // Load Viewer Info...
-  view_mode = genesis.ReadInt("VIEW_MODE");
-  viewer_type = genesis.ReadInt("VIEWER_TYPE",0);
-
-  log_breed_count = genesis.ReadInt("LOG_BREED_COUNT", 0);
-  log_creatures   = genesis.ReadInt("LOG_CREATURES", 0);
-  log_phylogeny   = genesis.ReadInt("LOG_PHYLOGENY", 0);
 
-  log_genotypes = genesis.ReadInt("LOG_GENOTYPES", 0);
+  // Determine if we are only logging threshold genotypes...
   log_threshold_only = false;
   if (log_genotypes > 1) log_threshold_only = true;
 
-  log_threshold = genesis.ReadInt("LOG_THRESHOLD", 0);
-  log_species   = genesis.ReadInt("LOG_SPECIES", 0);
-  log_landscape = genesis.ReadInt("LOG_LANDSCAPE", 0);
-  log_mutations = genesis.ReadInt("LOG_MUTATIONS", 0);
-  log_lineages = genesis.ReadInt("LOG_LINEAGES", 0);
-
+  // Warn if there are settings in the genesis file that have not been read.
   genesis.WarnUnused();
+
+  // Test printing... @CAO
+  //  PrintGenesis("genesis.test");
 }
 
 void cConfig::SetupMS()
@@ -251,6 +368,71 @@
 #endif
 }
 
+void cConfig::PrintGenesis(const cString & filename)
+{
+  ofstream fp(filename);
+
+  // Print out the generic header, including the version ID.
+  fp << "#############################################################################" << endl
+     << "# This file includes all the basic run-time defines for avida." << endl
+     << "# For more information, see doc/genesis.html" << endl
+     << "#############################################################################" << endl
+     << endl
+     << "VERSION_ID " << AVIDA_VERSION << "   # Do not change this value."
+     << endl;
+
+  // Loop through the groups, and print out all of the variables.
+  
+  tListIterator<cConfigGroup> group_it(group_list);
+  cConfigGroup * cur_group;
+  while ((cur_group = group_it.Next()) != NULL) {
+    // Print out the group name...
+    fp << endl;
+    fp << "### " << cur_group->GetName() << " ###" << endl;
+
+    // If we have a comment about the current group, include it.
+    for (int i = 0; i < cur_group->GetComment().GetSize(); i++) {
+      fp << "# " << cur_group->GetComment().GetLine(i) << endl;
+    }
+
+    // Print out everything for this group...
+    tListIterator<cConfigEntryBase> entry_it(cur_group->GetEntries());
+    cConfigEntryBase * cur_entry;
+
+    // First, figure out the widest entry so we know where to put comments.
+    int max_width = 0;
+    while ((cur_entry = entry_it.Next()) != NULL) {
+      int cur_width = cur_entry->GetTag().GetSize() +
+	cur_entry->GetDefault().GetSize() + 1;
+      if (cur_width > max_width) max_width = cur_width;
+    }
+
+    // Now, make a second pass printing everything.
+    entry_it.Reset();
+    while ((cur_entry = entry_it.Next()) != NULL) {
+      int cur_width = cur_entry->GetTag().GetSize() +
+ 	cur_entry->GetDefault().GetSize() + 1;
+      // Print the variable and its setting...
+      fp << cur_entry->GetTag() << " " << cur_entry->GetDefault();
+
+      // Print some spaces before the description.
+      for (int i = cur_width; i < max_width; i++) fp << " ";
+
+      // Print the first line of the description.
+      if (cur_entry->GetDesc().GetSize() == 0) {
+	fp << "  # " << endl;
+      } else {
+	fp << "  # " << cur_entry->GetDesc().GetLine(0) << endl;
+      }
+
+      // Print the remaining lines of a description.
+      for (int i = 1; i < cur_entry->GetDesc().GetSize(); i++) {
+	for (int j = 0; j < max_width; j++) fp << " ";
+	fp << "  # " << cur_entry->GetDesc().GetLine(i) << endl;
+      }
+    }
+  }
+}
 
 //  void cConfig::PerturbTaskSet(double max_factor)
 //  {
@@ -274,7 +456,9 @@
 
 void cConfig::ProcessConfiguration(int argc, char * argv[], cGenesis & genesis)
 {
-  genesis_filename = "genesis"; // Name of genesis file.
+  const cString default_filename = "genesis";
+  genesis_filename = default_filename;
+
   int arg_num = 1;              // Argument number being looked at.
   analyze_mode = false;         // Initialize analyze_mode tp be off.
   primitive_mode = false;       // Initialize primitive_mode tp be off.
@@ -299,6 +483,16 @@
   // Open and verify the genesis file.
 
   genesis.Open(genesis_filename);
+
+  // If we failed to open the genesis file, and we are using the default,
+  // try creating it.
+  if (genesis.IsOpen() == false && genesis_filename == default_filename) {
+    cerr << "Warning: Unable to find file '" << genesis_filename
+ 	 << "'.  Creating." << endl;
+    PrintGenesis(genesis_filename);
+    genesis.Open(genesis_filename);
+  }
+  
   cString version_id = genesis.ReadString("VERSION_ID", "Unknown");
   if (genesis.IsOpen() == true && version_id != AVIDA_VERSION) {
     cerr << "/  WARNING   WARNING   WARNING   WARNING   WARNING  \\" << endl
@@ -390,16 +584,6 @@
       cString value(cur_arg);
       cout << "SET " << name() << " = " << value() << endl;
       genesis.AddInput(name(), value());
-    } else if (cur_arg == "-viewer") {
-      if (arg_num + 1 == argc || args[arg_num + 1][0] == '-') {
-	cerr<<"Must include viewer type"<<endl;
-	exit(0);
-      } else {
-	arg_num++;  if (arg_num < argc) cur_arg = args[arg_num];
-	viewer_type = cur_arg.AsInt();
-      }
-      genesis.AddInput("VIEWER_TYPE", viewer_type);
-
 
     } else if (cur_arg == "-g" || cur_arg == "-genesis") {
       cerr << "Error: -g[enesis] option must be listed first." << endl;
Index: avida/current/source/main/config.hh
diff -u avida/current/source/main/config.hh:1.48 avida/current/source/main/config.hh:1.49
--- avida/current/source/main/config.hh:1.48	Tue May 20 07:42:28 2003
+++ avida/current/source/main/config.hh	Mon May 26 00:53:38 2003
@@ -57,6 +57,90 @@
 
 class cConfig {
 protected:
+  class cConfigEntryBase {
+  protected:
+    const cString genesis_tag;
+    const cString default_value;
+    const cStringList description;
+  public:
+    cConfigEntryBase(const cString & _tag, const cString & _def,
+		     const cString & _desc)
+      : genesis_tag(_tag), default_value(_def), description(_desc, '\n') { ; }
+
+    const cString & GetTag() { return genesis_tag; }
+    const cString & GetDefault() { return default_value; }
+    const cStringList & GetDesc() { return description; }
+
+    virtual bool LoadValue(cGenesis & genesis) = 0;
+  };
+
+  template <class T> class tConfigEntry : public cConfigEntryBase {
+  private:
+    T & variable;
+  public:
+    tConfigEntry(T & _var, const cString & _def, const cString & _tag,
+		 const cString _desc)
+      : cConfigEntryBase(_tag, _def, _desc), variable(_var)
+    { ; }
+
+    bool LoadValue(cGenesis & genesis) {
+      genesis.Read(variable, genesis_tag, default_value);
+      return true;
+    }
+  };
+
+  class cConfigGroup {
+  private:
+    const cString group_name;
+    cStringList comment;
+    tList<cConfigEntryBase> group_entries;
+  public:
+    cConfigGroup(const cString & _name) : group_name(_name) { ; }
+    ~cConfigGroup() {
+      while (group_entries.GetSize() > 0) delete group_entries.Pop();
+    }
+
+    void SetComment(const cString & _comment) { comment.Load(_comment, '\n'); }
+
+    const cString & GetName() { return group_name; }
+    const cStringList & GetComment() { return comment; }
+    tList<cConfigEntryBase> & GetEntries() { return group_entries; }
+
+    void LoadValues(cGenesis & genesis) {
+      tListIterator<cConfigEntryBase> group_it(group_entries);
+      cConfigEntryBase * cur_entry;
+      while ((cur_entry = group_it.Next()) != NULL) {
+	cur_entry->LoadValue(genesis);
+      }
+    };
+
+    void Add(int & _var, const cString &  _def, const cString & _tag,
+	     const cString & _desc)
+    {
+      group_entries.PushRear(new tConfigEntry<int>(_var,_def,_tag,_desc));
+    }
+
+    void Add(double & _var, const cString & _def, const cString & _tag,
+	     const cString & _desc)
+    {
+      group_entries.PushRear(new tConfigEntry<double>(_var,_def,_tag,_desc));
+    }
+
+    void Add(cString & _var, const cString & _def, const cString & _tag,
+	     const cString & _desc)
+    {
+      group_entries.PushRear(new tConfigEntry<cString>(_var,_def,_tag,_desc));
+    }
+
+    void Add(bool & _var, const cString & _def, const cString & _tag,
+	     const cString & _desc)
+    {
+      group_entries.PushRear(new tConfigEntry<bool>(_var,_def,_tag,_desc));
+    }
+  };
+
+  // Collection of genesis groups...
+  static tList<cConfigGroup> group_list;
 
   // Major Configurations
   static bool analyze_mode;     // Should avida do only analysis work?
@@ -92,9 +176,6 @@
   static double divide_ins_prob;
   static double divide_del_prob;
   static double parent_mut_prob;
-  static double crossover_prob;
-  static double aligned_cross_prob;
-  static double exe_err_prob;
 
   // CPU Configutation
   static int num_instructions;
@@ -114,7 +195,6 @@
 
   // Task Merit Method
   static int task_merit_method;
-  static int max_num_tasks_rewarded;
 
   static int merit_time;
 
@@ -160,9 +240,7 @@
   // Log files...
   static bool log_threshold_only;
 
-  static bool log_breed_count;
   static bool log_creatures;
-  static bool log_phylogeny;
   static bool log_genotypes;
   static bool log_threshold;
   static bool log_species;
@@ -175,13 +253,13 @@
 
   // Viewer
   static int view_mode;
-  static int viewer_type;
 
   // Other functions...
   static void ProcessConfiguration(int argc, char* argv[], cGenesis & genesis);
 public:
   static void Setup(int argc, char * argv[]);
   static void SetupMS();
+  static void PrintGenesis(const cString & filename);
 
   // ``Get''
   static bool GetAnalyzeMode() { return analyze_mode; }
@@ -221,9 +299,6 @@
   static double GetDivideInsProb() { return divide_ins_prob; }
   static double GetDivideDelProb() { return divide_del_prob; }
   static double GetParentMutProb() { return parent_mut_prob; }
-  static double GetCrossoverProb() { return crossover_prob; }
-  static double GetAlignedCrossProb() { return aligned_cross_prob; }
-  static double GetExeErrProb()    { return exe_err_prob; }
 
   static int GetNumInstructions() { return num_instructions; }
   static int GetHardwareType() { return hardware_type; }
@@ -233,7 +308,6 @@
   static int GetSizeMeritMethod() { return size_merit_method; }
   static int GetBaseSizeMerit()  { return base_size_merit; }
   static int GetTaskMeritMethod() { return task_merit_method; }
-  static int GetMaxNumTasksRewarded() { return max_num_tasks_rewarded; }
   static int GetMaxLabelExeSize() { return max_label_exe_size; }
 
   static int GetMeritTime() { return merit_time; }
@@ -282,20 +356,16 @@
 
   static bool GetLogThresholdOnly()  { return log_threshold_only; }
 
-  static bool GetLogBreedCount() { return log_breed_count; }
   static bool GetLogCreatures() { return log_creatures; }
-  static bool GetLogPhylogeny() { return log_phylogeny; }
   static bool GetLogGenotypes() { return log_genotypes; }
   static bool GetLogThreshold() { return log_threshold; }
   static bool GetLogSpecies()   { return log_species; }
   static bool GetLogLandscape() { return log_landscape; }
-  static bool GetLogMutations() { return log_mutations; }
   static bool GetLogLineages()  { return log_lineages; }
 
   static int GetDebugLevel() { return debug_level; }
 
   static int GetViewMode() { return view_mode; }
-  static int GetViewerType() { return viewer_type; }
 
 
   // ``Set''
Index: avida/current/source/main/mutations.cc
diff -u avida/current/source/main/mutations.cc:1.7 avida/current/source/main/mutations.cc:1.8
--- avida/current/source/main/mutations.cc:1.7	Sat May 17 02:48:09 2003
+++ avida/current/source/main/mutations.cc	Mon May 26 00:53:38 2003
@@ -119,7 +119,6 @@
 void cMutationRates::Clear()
 {
   exec.point_mut_prob = 0.0;
-  exec.exe_err_prob = 0.0;
   copy.copy_mut_prob = 0.0;
   divide.ins_mut_prob = 0.0;
   divide.del_mut_prob = 0.0;
@@ -135,7 +134,6 @@
 void cMutationRates::Copy(const cMutationRates & in_muts)
 {
   exec.point_mut_prob = in_muts.exec.point_mut_prob;
-  exec.exe_err_prob = in_muts.exec.exe_err_prob;
   copy.copy_mut_prob = in_muts.copy.copy_mut_prob;
   divide.ins_mut_prob = in_muts.divide.ins_mut_prob;
   divide.del_mut_prob = in_muts.divide.del_mut_prob;
@@ -153,11 +151,6 @@
 bool cMutationRates::TestPointMut() const
 {
   return g_random.P(exec.point_mut_prob);
-}
-
-bool cMutationRates::TestExeErr() const
-{
-  return g_random.P(exec.exe_err_prob);
 }
 
 bool cMutationRates::TestCopyMut() const
Index: avida/current/source/main/mutations.hh
diff -u avida/current/source/main/mutations.hh:1.7 avida/current/source/main/mutations.hh:1.8
--- avida/current/source/main/mutations.hh:1.7	Sat May 17 12:33:53 2003
+++ avida/current/source/main/mutations.hh	Mon May 26 00:53:38 2003
@@ -102,7 +102,6 @@
   // ...anytime during execution...
   struct sExecMuts {
     double point_mut_prob;
-    double exe_err_prob;
   };
   sExecMuts exec;
 
@@ -137,7 +136,6 @@
   void Copy(const cMutationRates & in_muts);
 
   bool TestPointMut() const;
-  bool TestExeErr() const;
   bool TestCopyMut() const;
   bool TestDivideMut() const;
   bool TestDivideIns() const;
@@ -147,7 +145,6 @@
   bool TestAlignedCrossover() const;
 
   double GetPointMutProb() const     { return exec.point_mut_prob; }
-  double GetExeErrProb() const       { return exec.exe_err_prob; }
   double GetCopyMutProb() const      { return copy.copy_mut_prob; }
   double GetInsMutProb() const       { return divide.ins_mut_prob; }
   double GetDelMutProb() const       { return divide.del_mut_prob; }
@@ -160,7 +157,6 @@
   double GetAlignedCrossProb() const { return divide.aligned_cross_prob; }
 
   void SetPointMutProb(double in_prob)  { exec.point_mut_prob  = in_prob; }
-  void SetExeErrProb(double in_prob)    { exec.exe_err_prob    = in_prob; }
   void SetCopyMutProb(double in_prob)   { copy.copy_mut_prob   = in_prob; }
   void SetInsMutProb(double in_prob)    { divide.ins_mut_prob    = in_prob; }
   void SetDelMutProb(double in_prob)    { divide.del_mut_prob    = in_prob; }
Index: avida/current/source/tools/file.cc
diff -u avida/current/source/tools/file.cc:1.19 avida/current/source/tools/file.cc:1.20
--- avida/current/source/tools/file.cc:1.19	Mon May 19 21:07:33 2003
+++ avida/current/source/tools/file.cc	Mon May 26 00:53:38 2003
@@ -387,6 +387,9 @@
   }
 
   int base_ret = cFile::Open(_filename, mode);
+  
+  if (IsOpen() == false) return base_ret;  // Failed to open!
+
   Load();
   Compress();
   Close();
Index: avida/current/source/tools/file.hh
diff -u avida/current/source/tools/file.hh:1.17 avida/current/source/tools/file.hh:1.18
--- avida/current/source/tools/file.hh:1.17	Mon May 19 21:07:33 2003
+++ avida/current/source/tools/file.hh	Mon May 26 00:53:38 2003
@@ -278,7 +278,23 @@
      * @param base The default value.
      * @param warn Warn user if not set?
      **/
-    double ReadFloat (const cString & name, float base=0.0, bool warn=true) const;
+     double ReadFloat (const cString & name, float base=0.0, bool warn=true) const;
+
+  void Read(cString & _var, const cString & _name, const cString & _def="") {
+    _var = ReadString(_name, _def);
+  }
+
+  void Read(int & _var, const cString & _name, const cString & _def="0") {
+    _var = ReadInt(_name, _def.AsInt());
+  }
+
+  void Read(double & _var, const cString & _name, const cString & _def="0.0") {
+    _var = ReadFloat(_name, _def.AsDouble());
+  }
+
+  void Read(bool & _var, const cString & _name, const cString & _def="0.0") {
+    _var = ReadInt(_name, _def.AsInt()) != 0;
+  }
 };
 
 #endif
Index: avida/current/source/tools/string_list.hh
diff -u avida/current/source/tools/string_list.hh:1.3 avida/current/source/tools/string_list.hh:1.4
--- avida/current/source/tools/string_list.hh:1.3	Thu Feb 14 07:57:41 2002
+++ avida/current/source/tools/string_list.hh	Mon May 26 00:53:38 2003
@@ -42,7 +42,7 @@
   cStringList & operator=(const cStringList & _list);
 
   int GetSize() const { return string_list.GetSize(); }
-  cString GetLine(int line_num) { return *(string_list.GetPos(line_num)); }
+  cString GetLine(int line_num) const { return *(string_list.GetPos(line_num)); }
   const tList<cString> & GetList() const { return string_list; }
 
   bool HasString(const cString & test_string) const;
Index: avida/current/source/tools/tList.hh
diff -u avida/current/source/tools/tList.hh:1.8 avida/current/source/tools/tList.hh:1.9
--- avida/current/source/tools/tList.hh:1.8	Thu Feb 14 07:57:41 2002
+++ avida/current/source/tools/tList.hh	Mon May 26 00:53:38 2003
@@ -1,5 +1,5 @@
 //////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2001 California Institute of Technology             //
+// 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.     //
@@ -185,6 +185,13 @@
   T * GetLast()              { return root.prev->data; }
 
   T * GetPos(int pos) {
+    if (pos >= GetSize()) return NULL;
+    tListNode<T> * test_node = root.next;
+    for (int i = 0; i < pos; i++) test_node = test_node->next;
+    return test_node->data;
+  }
+
+  const T * GetPos(int pos) const {
     if (pos >= GetSize()) return NULL;
     tListNode<T> * test_node = root.next;
     for (int i = 0; i < pos; i++) test_node = test_node->next;


More information about the Avida-cvs mailing list