[Avida-SVN] r2033 - development/source/analyze

kaben at myxo.css.msu.edu kaben at myxo.css.msu.edu
Sat Sep 1 19:06:22 PDT 2007


Author: kaben
Date: 2007-09-01 22:06:22 -0400 (Sat, 01 Sep 2007)
New Revision: 2033

Added:
   development/source/analyze/cAnalyzeGenotypeTreeStats.cc
   development/source/analyze/cAnalyzeGenotypeTreeStats.h
Modified:
   development/source/analyze/cAnalyze.cc
Log:
Added coded for the analyze command PRINT_TREE_STATS.
It's used like so:

SET_BATCH 0
PURGE_BATCH
LOAD detail-fake.pop
LOAD historic-fake.pop
PRINT_TREE_STATS

producing a file "data/tree_stats.dat" reading, for example

# Legend:
# 1: Average cumulative stemminess
0.311842

Caveats: until I add error-checks, the detail and historic files must describe
a phylogenetic tree (otherwise Avida will crash). I will work on this tomorrow.



Modified: development/source/analyze/cAnalyze.cc
===================================================================
--- development/source/analyze/cAnalyze.cc	2007-09-01 00:21:15 UTC (rev 2032)
+++ development/source/analyze/cAnalyze.cc	2007-09-02 02:06:22 UTC (rev 2033)
@@ -40,6 +40,7 @@
 #include "cAnalyzeFlowCommandDef.h"
 #include "cAnalyzeFunction.h"
 #include "cAnalyzeGenotype.h"
+#include "cAnalyzeGenotypeTreeStats.h"
 #include "tAnalyzeJob.h"
 #include "cAvidaContext.h"
 #include "cDataFile.h"
@@ -3220,97 +3221,113 @@
   // Load in the variables...
   cString filename("tree_stats.dat");
   if (cur_string.GetSize() != 0) filename = cur_string.PopWord();
+
+  ofstream& fp = m_world->GetDataFileOFStream(filename);
+
+  fp << "# Legend:" << endl;
+  fp << "# 1: Average cumulative stemminess" << endl;
+  fp << endl;
   
-  
-  cAnalyzeGenotype * genotype = NULL;
-  tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
-  const int num_gens = batch[cur_batch].List().GetSize();
-  
-  // Put all of the genotypes in an array for easy reference and collect
-  // other information on them as we process them.
-  tArray<cAnalyzeGenotype *> gen_array(num_gens);
-  tHashTable<int, int> id_hash;  // Store array pos for each id.
-  tArray<int> id_array(num_gens), pid_array(num_gens);
-  tArray<int> depth_array(num_gens), birth_array(num_gens);
-  int array_pos = 0;
-  while ((genotype = batch_it.Next()) != NULL) {
-    // Put the genotype in an array.
-    gen_array[array_pos] = genotype;
-    id_hash.Add(genotype->GetID(), array_pos);
-    id_array[array_pos] = genotype->GetID();
-    pid_array[array_pos] = genotype->GetParentID();
-    depth_array[array_pos] = genotype->GetDepth();
-    birth_array[array_pos] = genotype->GetUpdateBorn();
-    array_pos++;
-  }
-  
-  // Now collect information about the offspring of each individual.
-  tArray<int> ppos_array(num_gens), offspring_count(num_gens);
-  offspring_count.SetAll(0);
-  for (int pos = 0; pos < num_gens; pos++) {
-    int parent_id = gen_array[pos]->GetParentID();
-    if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
-      ppos_array[pos] = -1;
-      continue;
-    }
-    int parent_pos = -1;
-    id_hash.Find(parent_id, parent_pos);
-    ppos_array[pos] = parent_pos;
-    offspring_count[parent_pos]++;
-  }
-  
-  // For each genotype, figure out how far back you need to go to get to a
-  // branch point.
-  tArray<int> branch_dist_array(num_gens);
-  tArray<int> branch_pos_array(num_gens);
-  branch_dist_array.SetAll(-1);
-  branch_pos_array.SetAll(-1);
-  bool found = true;
-  int loop_count = 0;
-  while (found == true) {
-    found = false;
-    for (int pos = 0; pos < num_gens; pos++) {
-      if (branch_dist_array[pos] > -1) continue; // continue if its set.
-      found = true;
-      int parent_pos = ppos_array[pos];
-      if (parent_pos == -1) branch_dist_array[pos] = 0;  // Org is root.
-      else if (offspring_count[parent_pos] > 1) {        // Parent is branch.
-        branch_dist_array[pos] = 1;
-        branch_pos_array[pos] = parent_pos;
-      }
-      else if (branch_dist_array[parent_pos] > -1) {     // Parent calculated.
-        branch_dist_array[pos] = branch_dist_array[parent_pos]+1;
-        branch_pos_array[pos] = branch_pos_array[parent_pos];
-      }
-      // Otherwise, we are not yet ready to calculate this entry.
-    }
-    loop_count++;
-  }
-  
-  
-  // Cumulative Stemminess
-  for (int pos = 0; pos < num_gens; pos++) {
-    // We're only interested in internal n-furcating nodes.
-    if (pid_array[pos] == -1) continue;  // Don't want root.
-    if (offspring_count[pos] <= 1) continue; // No leaves or nonfurcating nodes
-    
-    // @CAO Find distance to all children.
-    // @CAO Find distance to parent branch.
-    // @CAO DO math.
-  }
-  
-  
-  cout << "LOOP COUNT:" << loop_count << endl;
-  for (int i = 0; i < num_gens; i++) {
-    int branch_pos = branch_pos_array[i];
-    int branch_id = (branch_pos == -1) ? -1 : id_array[branch_pos];
-    cout << i << " "
-      << id_array[i] << " "
-      << offspring_count[i] << " "
-      << branch_dist_array[i] << " "
-      << branch_id << " "
-      << endl;
-  }
+  cAnalyzeGenotypeTreeStats agts;
+  agts.AnalyzeBatchTree(batch[cur_batch].List());
+
+  fp << agts.AverageStemminess();
+  fp << endl;
+
+  /*
+  Below is the original implementation by Ofria.
+  -- kgn
+  */
+
+  //cAnalyzeGenotype * genotype = NULL;
+  //tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
+  //const int num_gens = batch[cur_batch].List().GetSize();
+  //
+  //// Put all of the genotypes in an array for easy reference and collect
+  //// other information on them as we process them.
+  //tArray<cAnalyzeGenotype *> gen_array(num_gens);
+  //tHashTable<int, int> id_hash;  // Store array pos for each id.
+  //tArray<int> id_array(num_gens), pid_array(num_gens);
+  //tArray<int> depth_array(num_gens), birth_array(num_gens);
+  //int array_pos = 0;
+  //while ((genotype = batch_it.Next()) != NULL) {
+  //  // Put the genotype in an array.
+  //  gen_array[array_pos] = genotype;
+  //  id_hash.Add(genotype->GetID(), array_pos);
+  //  id_array[array_pos] = genotype->GetID();
+  //  pid_array[array_pos] = genotype->GetParentID();
+  //  depth_array[array_pos] = genotype->GetDepth();
+  //  birth_array[array_pos] = genotype->GetUpdateBorn();
+  //  array_pos++;
+  //}
+  //
+  //// Now collect information about the offspring of each individual.
+  //tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+  //offspring_count.SetAll(0);
+  //for (int pos = 0; pos < num_gens; pos++) {
+  //  int parent_id = gen_array[pos]->GetParentID();
+  //  if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
+  //    ppos_array[pos] = -1;
+  //    continue;
+  //  }
+  //  int parent_pos = -1;
+  //  id_hash.Find(parent_id, parent_pos);
+  //  ppos_array[pos] = parent_pos;
+  //  offspring_count[parent_pos]++;
+  //}
+  //
+  //// For each genotype, figure out how far back you need to go to get to a
+  //// branch point.
+  //tArray<int> branch_dist_array(num_gens);
+  //tArray<int> branch_pos_array(num_gens);
+  //branch_dist_array.SetAll(-1);
+  //branch_pos_array.SetAll(-1);
+  //bool found = true;
+  //int loop_count = 0;
+  //while (found == true) {
+  //  found = false;
+  //  for (int pos = 0; pos < num_gens; pos++) {
+  //    if (branch_dist_array[pos] > -1) continue; // continue if its set.
+  //    found = true;
+  //    int parent_pos = ppos_array[pos];
+  //    if (parent_pos == -1) branch_dist_array[pos] = 0;  // Org is root.
+  //    else if (offspring_count[parent_pos] > 1) {        // Parent is branch.
+  //      branch_dist_array[pos] = 1;
+  //      branch_pos_array[pos] = parent_pos;
+  //    }
+  //    else if (branch_dist_array[parent_pos] > -1) {     // Parent calculated.
+  //      branch_dist_array[pos] = branch_dist_array[parent_pos]+1;
+  //      branch_pos_array[pos] = branch_pos_array[parent_pos];
+  //    }
+  //    // Otherwise, we are not yet ready to calculate this entry.
+  //  }
+  //  loop_count++;
+  //}
+  //
+  //
+  //// Cumulative Stemminess
+  //for (int pos = 0; pos < num_gens; pos++) {
+  //  // We're only interested in internal n-furcating nodes.
+  //  if (pid_array[pos] == -1) continue;  // Don't want root.
+  //  if (offspring_count[pos] <= 1) continue; // No leaves or nonfurcating nodes
+  //  
+  //  // @CAO Find distance to all children.
+  //  // @CAO Find distance to parent branch.
+  //  // @CAO DO math.
+  //}
+  //
+  //
+  //cout << "LOOP COUNT:" << loop_count << endl;
+  //for (int i = 0; i < num_gens; i++) {
+  //  int branch_pos = branch_pos_array[i];
+  //  int branch_id = (branch_pos == -1) ? -1 : id_array[branch_pos];
+  //  cout << i << " "
+  //    << id_array[i] << " "
+  //    << offspring_count[i] << " "
+  //    << branch_dist_array[i] << " "
+  //    << branch_id << " "
+  //    << endl;
+  //}
 }
 
 

Added: development/source/analyze/cAnalyzeGenotypeTreeStats.cc
===================================================================
--- development/source/analyze/cAnalyzeGenotypeTreeStats.cc	                        (rev 0)
+++ development/source/analyze/cAnalyzeGenotypeTreeStats.cc	2007-09-02 02:06:22 UTC (rev 2033)
@@ -0,0 +1,288 @@
+
+#include "cAnalyzeGenotypeTreeStats.h"
+
+#include "cAnalyzeGenotype.h"
+#include "tHashTable.h"
+
+void cAnalyzeGenotypeTreeStats::AnalyzeBatchTree(tList<cAnalyzeGenotype> &genotype_list){
+  cAnalyzeGenotype * genotype = NULL;
+  tListIterator<cAnalyzeGenotype> batch_it(genotype_list);
+  const int num_gens = genotype_list.GetSize();
+
+  int array_pos = 0;
+
+  /*
+  Put all of the genotypes in an array for easy reference and collect other information on them as we process them. {{{4
+  */
+  tArray<cAnalyzeGenotype *> gen_array(num_gens);
+  tHashTable<int, int> id_hash;  // Store array pos for each id.
+  tArray<int> id_array(num_gens), pid_array(num_gens);
+  tArray<int> depth_array(num_gens), birth_array(num_gens);
+
+  array_pos = 0;
+  batch_it.Reset();
+  while ((genotype = batch_it.Next()) != NULL) {
+    id_hash.Add(genotype->GetID(), array_pos);
+    array_pos++;
+  }
+
+  m_agl.Resize(num_gens);
+  array_pos = 0;
+  batch_it.Reset();
+  while ((genotype = batch_it.Next()) != NULL) {
+    // Put the genotype in an array.
+    m_agl[array_pos].genotype = genotype;
+    m_agl[array_pos].id = genotype->GetID();
+    m_agl[array_pos].pid = genotype->GetParentID();
+    m_agl[array_pos].depth = genotype->GetDepth();
+    m_agl[array_pos].birth = genotype->GetUpdateBorn();
+    array_pos++;
+  }
+
+  //// Now collect information about the offspring of each individual. {{{4
+  tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+  offspring_count.SetAll(0);
+
+  // For each genotype, figure out how far back you need to go to get to a branch point. {{{4
+  tArray<int> anc_branch_dist_array(num_gens);
+  tArray<int> anc_branch_pos_array(num_gens);
+  anc_branch_dist_array.SetAll(-1);
+  anc_branch_pos_array.SetAll(-1);
+  bool found = true;
+  int loop_count = 0;
+
+  /*
+  Link each offspring to its parent. {{{4
+  */
+  for (int pos = 0; pos < num_gens; pos++) {
+    //cAnalyzeGenotype * genotype = gen_array[pos];
+    cAnalyzeGenotype * genotype = m_agl[pos].genotype;
+    int parent_id = genotype->GetParentID();
+    if (-1 != parent_id){
+      id_hash.Find(parent_id, m_agl[pos].ppos);
+      int parent_position = m_agl[pos].ppos;
+      m_agl[parent_position].offspring_positions.Push(pos);
+      /* XXX I think I'll be able to remove this. */
+      cAnalyzeGenotype * parent_genotype = m_agl[parent_position].genotype;
+      genotype->LinkParent(parent_genotype);
+    }
+  }
+
+  /*
+  Count offspring of each parent. {{{4
+  */
+  for (int pos = 0; pos < num_gens; pos++) {
+    m_agl[pos].offspring_count = m_agl[pos].offspring_positions.GetSize();
+  }
+
+
+  /*
+  For each genotype, figure out how far back you need to go to get to a branch point. {{{4
+  */
+  found = true;
+  loop_count = 0;
+  while (found == true) {
+    found = false;
+    for (int pos = 0; pos < num_gens; pos++) {
+      if (m_agl[pos].anc_branch_dist > -1) continue; // continue if its set.
+      found = true;
+      int parent_pos = m_agl[pos].ppos;
+      if (parent_pos == -1) {
+        m_agl[pos].anc_branch_dist = 0;  // Org is root.
+      } else if (m_agl[parent_pos].offspring_count > 1) {        // Parent is branch.
+        m_agl[pos].anc_branch_dist = 1;
+        m_agl[pos].anc_branch_id = m_agl[parent_pos].id;
+        m_agl[pos].anc_branch_pos = parent_pos;
+      } else if (m_agl[parent_pos].anc_branch_dist > -1) {     // Parent calculated.
+        m_agl[pos].anc_branch_dist = m_agl[parent_pos].anc_branch_dist + 1;
+        m_agl[pos].anc_branch_id = m_agl[parent_pos].anc_branch_id;
+        m_agl[pos].anc_branch_pos = m_agl[parent_pos].anc_branch_pos;
+      }
+      // Otherwise, we are not yet ready to calculate this entry.
+    }
+    loop_count++;
+  }
+
+  // compute number of subtree nodes.
+  int branch_tree_size = 0;
+  for (int pos = 0; pos < num_gens; pos++) {
+    if(m_agl[pos].offspring_count != 1){
+      branch_tree_size++;
+    }
+  }
+
+  m_agl2.Resize(branch_tree_size);  // Store agl data for each id.
+  tHashTable<int, int> id_hash_2;
+  int array_pos_2 = 0;
+  if (true) for (int pos = 0; pos < num_gens; pos++) {
+    int offs_count = m_agl[pos].offspring_count;
+    if (offs_count != 1){
+      m_agl2[array_pos_2].id = m_agl[pos].id;
+      m_agl2[array_pos_2].pid = m_agl[pos].pid;
+      m_agl2[array_pos_2].depth = m_agl[pos].depth;
+      m_agl2[array_pos_2].birth = m_agl[pos].birth;
+      m_agl2[array_pos_2].anc_branch_dist = m_agl[pos].anc_branch_dist;
+      m_agl2[array_pos_2].anc_branch_id = m_agl[pos].anc_branch_id;
+      /*
+      missing still are ppos (skip this), offspring_count (redundant),
+      anc_branch_pos, off_branch_dist_acc (to be calculated),
+      offspring_positions
+      */
+      id_hash_2.Add(m_agl2[array_pos_2].id, array_pos_2);
+      array_pos_2++;
+    }
+  }
+
+  // find branch ancestor positions. {{{4
+  for (int pos = 0; pos < branch_tree_size; pos++){
+    int anc_branch_id = m_agl2[pos].anc_branch_id;
+    id_hash_2.Find(anc_branch_id, m_agl2[pos].anc_branch_pos);
+    int anc_branch_pos = m_agl2[pos].anc_branch_pos;
+    if(0 <= anc_branch_pos){
+      m_agl2[anc_branch_pos].offspring_positions.Push(pos);
+    }
+  }
+  
+  /*
+  For DFS of branch tree, locate root. {{{4
+  */
+  cAGLData *root = 0;
+  for (int pos = 0; pos < branch_tree_size; pos++){
+    m_agl2[pos].traversal_visited = false;
+    /*
+    root : anc_branch_dist: 0 anc_branch_id: -1 anc_branch_pos: -1 
+
+    Only one of these conditions should be needed. I'm mixing-in a
+    sanity check here. I ought to move it...
+    */
+    if( (m_agl2[pos].anc_branch_dist == 0)
+      ||(m_agl2[pos].anc_branch_id == -1)
+      ||(m_agl2[pos].anc_branch_pos == -1)
+    ){
+      root = &(m_agl2[pos]);
+      /* Sanity check. */
+      if(!( (m_agl2[pos].anc_branch_dist == 0)
+          &&(m_agl2[pos].anc_branch_id == -1)
+          &&(m_agl2[pos].anc_branch_pos == -1)
+        )
+      ){
+        // FIXME : ERROR("while looking for root of subtree, found inconsistencies -");
+        return;
+      }
+    }
+  }
+
+  /*
+  DFS of branch tree, to accumulate branch distances. {{{4
+  */
+  tList<cAGLData> dfs_stack;
+  if(0 != root){
+    /* DFS. */
+    dfs_stack.Push(root);
+    cAGLData *node = 0;
+    while (0 < dfs_stack.GetSize()){
+      node = dfs_stack.Pop();
+      if (0 != node){
+        if (! node->traversal_visited){
+          dfs_stack.Push(node);
+          node->off_branch_dist_acc = 0;
+          for (int i = 0; i < node->offspring_positions.GetSize(); i++){
+            int pos = node->offspring_positions[i];
+            if (! m_agl2[pos].traversal_visited){
+              dfs_stack.Push(&(m_agl2[pos]));
+            }
+          }
+          node->traversal_visited = true;
+        } else {
+          /*
+          Child nodes, if any, have been visited and have added their
+          off_branch_dist_acc to this node.
+          */
+          if(0 <= node->anc_branch_pos){
+            /*
+            Only accumulate to parent if there is a parent (i.e., this
+            is not the root.)
+            */
+            m_agl2[node->anc_branch_pos].off_branch_dist_acc += node->anc_branch_dist;
+            m_agl2[node->anc_branch_pos].off_branch_dist_acc += node->off_branch_dist_acc;
+          }
+        }
+      }
+    }
+  } else {
+    // FIXME : ERROR("couldn't find root of subtree -");
+    return;
+  }
+
+  /*
+  Compute cumulative stemminesses. {{{4
+  */
+  for (int pos = 0; pos < branch_tree_size; pos++){
+    if (0 == m_agl2[pos].anc_branch_dist){
+      /* Correct stemminess for root... */
+      /*
+      Let me rephrase that. If anc_branch_dist is zero and all is well,
+      we're dealing with the root.
+      */
+      m_agl2[pos].cumulative_stemminess = 0.0;
+    } else {
+      m_agl2[pos].cumulative_stemminess =
+        (double)(m_agl2[pos].anc_branch_dist)
+        /
+        (
+          (double)(m_agl2[pos].off_branch_dist_acc) + (double)(m_agl2[pos].anc_branch_dist)
+        )
+        ;
+    }
+  }
+
+  /*
+  Compute average cumulative stemminess. {{{4
+  */
+  m_stemminess_sum = 0.0;
+  m_average_stemminess = 0.0;
+  m_inner_nodes = 0;
+  if (1 < branch_tree_size) {
+    for (int pos = 0; pos < branch_tree_size; pos++){
+      bool not_leaf = true;
+      if (m_should_exclude_leaves) {
+        not_leaf = (0 < m_agl2[pos].off_branch_dist_acc);
+      }
+      bool not_root = (0 < m_agl2[pos].anc_branch_id);
+      if (not_leaf && not_root){
+        m_stemminess_sum += m_agl2[pos].cumulative_stemminess;
+        m_inner_nodes++;
+      }
+    }
+  }
+  if(0 < m_inner_nodes){
+    m_average_stemminess = m_stemminess_sum / (m_inner_nodes);
+  }
+
+  /*
+  Print branch tree. {{{4
+  Use to get expected data for making following test.
+  */
+
+  if (true){
+    for (int pos = 0; pos < branch_tree_size; pos++){
+      cout << "id: " << m_agl2[pos].id;
+      cout << " offspring_count: " << m_agl2[pos].offspring_positions.GetSize();
+      cout << " anc_branch_id: " << m_agl2[pos].anc_branch_id;
+      cout << " anc_branch_dist: " << m_agl2[pos].anc_branch_dist;
+      cout << " off_branch_dist_acc: " << m_agl2[pos].off_branch_dist_acc;
+      cout << " cumulative_stemminess: " << m_agl2[pos].cumulative_stemminess;
+      cout << endl;
+      if (0 < m_agl2[pos].offspring_positions.GetSize()) {
+        cout << "  offspring ids:";
+        for (int i = 0; i < m_agl2[pos].offspring_positions.GetSize(); i++){
+          cout << " " << m_agl2[pos].offspring_positions[i];
+        }
+        cout << endl;
+      }
+    }
+    cout << "m_stemminess_sum: " << m_stemminess_sum << endl;
+    cout << "m_average_stemminess: " << m_average_stemminess << endl;
+    cout << "m_inner_nodes: " << m_inner_nodes << endl;
+  }
+}

Added: development/source/analyze/cAnalyzeGenotypeTreeStats.h
===================================================================
--- development/source/analyze/cAnalyzeGenotypeTreeStats.h	                        (rev 0)
+++ development/source/analyze/cAnalyzeGenotypeTreeStats.h	2007-09-02 02:06:22 UTC (rev 2033)
@@ -0,0 +1,92 @@
+#ifndef cAnalyzeGenotypeTreeStats_h
+#define cAnalyzeGenotypeTreeStats_h
+
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+#ifndef tList_h
+#include "tList.h"
+#endif
+
+
+class cAnalyzeGenotype;
+
+
+/*
+Convenience class cAGLData serves to collect various data I found I needed
+while building the class cAnalyzeGenotypeTreeStats.
+*/
+class cAGLData {
+public:
+  cAnalyzeGenotype *genotype;
+  int id;
+  int pid;
+  int depth;
+  int birth;
+  int ppos;
+  int offspring_count;
+  int anc_branch_dist;
+  int anc_branch_id;
+  int anc_branch_pos;
+  int off_branch_dist_acc;
+  double cumulative_stemminess;
+  bool traversal_visited;
+  tArray<int> offspring_positions;
+
+  cAGLData()
+  : genotype(0)
+  , id(-1)
+  , pid(-1)
+  , depth(-1)
+  , birth(-1)
+  , ppos(-1)
+  , offspring_count(-1)
+  , anc_branch_dist(-1)
+  , anc_branch_id(-1)
+  , anc_branch_pos(-1)
+  , off_branch_dist_acc(-1)
+  , cumulative_stemminess(-1.)
+  , traversal_visited(false)
+  , offspring_positions(0)
+  {}
+};
+
+/*
+class cAnalyzeGenotypeTreeStats
+
+This class will eventually collect various kinds of statistics about various
+kinds of trees (e.g., phylogenetic).
+
+For now it only figures out "average cumulative stemminess".
+*/
+class cAnalyzeGenotypeTreeStats {
+public:
+  tArray<cAGLData> m_agl;
+  tArray<cAGLData> m_agl2;
+
+  double m_stemminess_sum;
+  double m_average_stemminess;
+  int m_inner_nodes;
+  bool m_should_exclude_leaves;
+
+public:
+  cAnalyzeGenotypeTreeStats()
+  : m_agl(0)
+  , m_agl2(0)
+  , m_stemminess_sum(0.0)
+  , m_average_stemminess(0.0)
+  , m_inner_nodes(0)
+  , m_should_exclude_leaves(true)
+  {}
+
+  tArray<cAGLData> &AGL(){ return m_agl; }
+  tArray<cAGLData> &AGL2(){ return m_agl2; }
+  double StemminessSum(){ return m_stemminess_sum; }
+  double AverageStemminess(){ return m_average_stemminess; }
+  int InnerNodes(){ return m_inner_nodes; }
+  bool ExcludesLeaves(){ return m_should_exclude_leaves; }
+
+  void AnalyzeBatchTree(tList<cAnalyzeGenotype> &genotype_list);
+};
+
+#endif




More information about the Avida-cvs mailing list