[Avida-SVN] r3546 - development/source/main
dk at myxo.css.msu.edu
dk at myxo.css.msu.edu
Sat Dec 5 09:58:06 PST 2009
Author: dk
Date: 2009-12-05 12:58:06 -0500 (Sat, 05 Dec 2009)
New Revision: 3546
Modified:
development/source/main/cAvidaConfig.h
development/source/main/cGenome.cc
development/source/main/cGenome.h
development/source/main/cGenomeUtil.cc
development/source/main/cGenomeUtil.h
development/source/main/cPopulationCell.cc
development/source/main/cPopulationInterface.cc
development/source/main/cPopulationInterface.h
development/source/main/cStats.cc
development/source/main/cStats.h
Log:
hgt updates. modularized fragment selection, added unbiased substring match.
Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cAvidaConfig.h 2009-12-05 17:58:06 UTC (rev 3546)
@@ -664,13 +664,14 @@
// -------- Horizontal Gene Transfer (HGT) config options --------
CONFIG_ADD_GROUP(HGT_GROUP, "Horizontal gene transfer settings");
CONFIG_ADD_VAR(ENABLE_HGT, int, 0, "Whether HGT is enabled; 0=false (default),\n 1=true.");
+ CONFIG_ADD_VAR(HGT_FRAGMENT_SELECTION, int, 0, "Method used to select fragments for HGT mutation (0=random [default]\n1=trimmed selection).");
CONFIG_ADD_VAR(HGT_FRAGMENT_SIZE_MEAN, double, 10, "Mean size of fragments (drawn from a normal\ndist., default=10).");
CONFIG_ADD_VAR(HGT_FRAGMENT_SIZE_VARIANCE, double, 2, "Variance of fragments (drawn from a normal\ndist., default=2).");
CONFIG_ADD_VAR(HGT_MAX_FRAGMENTS_PER_CELL, int, 100, "Max. allowed number of fragments\nper cell (default=100).");
CONFIG_ADD_VAR(HGT_DIFFUSION_METHOD, int, 0, "Method to use for diffusion of genome\nfragments (0=none [default]).");
CONFIG_ADD_VAR(HGT_MUTATION_P, double, 0.0, "Probability that an HGT mutation will occur on divide (default=0.0).");
CONFIG_ADD_VAR(HGT_INSERTION_MUT_P, double, 0.5, "Probability that an HGT mutation will result in an insertion (default=0.5); replacement if false.");
-
+
CONFIG_ADD_GROUP(INST_RES_GROUP, "Resource-Dependent Instructions Settings");
CONFIG_ADD_VAR(INST_RES, cString, "", "Resource upon which the execution of certain instruction depends");
CONFIG_ADD_VAR(INST_RES_FLOOR, double, 0.0, "Assumed lower level of resource in environment. Used for probability dist.");
Modified: development/source/main/cGenome.cc
===================================================================
--- development/source/main/cGenome.cc 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cGenome.cc 2009-12-05 17:58:06 UTC (rev 3546)
@@ -189,7 +189,78 @@
for (int i = 0; i < genome.GetSize(); i++) m_genome[i + pos] = genome[i];
}
+/*! Replace [begin, end) instructions in this genome with g, respecting genome circularity.
+
+ This method replaces [begin,end) instructions in this genome with those in g. Begin and end
+ follow STL-iterator semantics, which is to say that end "points" to **one past** the last
+ instruction that will be replaced.
+
+ Also, circularity of the genome is respected, which means that if end < begin
+ (the instructions that are being replaced wrap-around the end of the genome), then
+ the replacement will too.
+
+ Caveat: if length([begin,end)) != length(g), all size changes are made at end.
+ */
+void cGenome::Replace(const cGenome& g, int begin, int end) {
+ if(begin == end) {
+ // we're actually doing an insertion...
+ Insert(begin, g);
+ } else if(begin < end) {
+ // no wrap-around
+ Replace(begin, end-begin, g);
+ } else {
+ // replacement wraps around the end. two different replacements to do now:
+ // [begin, size) and [0, end).
+
+ // first, replace the [begin, size) region of this genome with as much of g
+ // as we can get.
+ int tail_size = std::min(GetSize()-begin, g.GetSize());
+ cGenome tail(&g[0], &g[0]+tail_size);
+ Replace(begin, GetSize()-begin, tail);
+ // now, replace the [0, end) region or remove it if the whole fragment
+ // was already copied in:
+ if(tail_size != g.GetSize()) {
+ cGenome head(&g[0]+tail_size, &g[0]+g.GetSize());
+ Replace(0, end, head);
+ } else if(end > 0) {
+ Remove(0, end);
+ }
+ }
+}
+
+/*! Rotate this genome forward n instructions.
+
+ "Rotation" in this sense means to move instructions from begin->end, with instructions
+ at the end wrapping around to the beginning. Specifically, given a genome
+ [0... n... m-n... m], Rotate(n) moves instructions to create [m-n... m, 0... n].
+
+ Negative rotation is supported, and moves instructions from the beginning to the end.
+ */
+void cGenome::Rotate(int n) {
+ assert(n < m_active_size);
+ if(n==0) { return; }
+
+ cInstruction* begin = &operator[](0);
+ cInstruction* end = &operator[](0) + GetSize();
+
+ if(n > 0) {
+ // forward
+ cGenome head(end-n, end);
+ cGenome tail(begin, end-n);
+ head.Append(tail);
+ operator=(head);
+ } else {
+ assert(false);
+ // backward
+ cGenome head(begin, begin-n); // n is < 0, so this is addition.
+ cGenome tail(begin-n, end);
+ tail.Append(head);
+ operator=(tail);
+ }
+}
+
+
void cGenome::operator=(const cGenome& other_genome)
{
m_active_size = other_genome.m_active_size;
Modified: development/source/main/cGenome.h
===================================================================
--- development/source/main/cGenome.h 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cGenome.h 2009-12-05 17:58:06 UTC (rev 3546)
@@ -81,6 +81,10 @@
virtual void Insert(int pos, const cGenome& genome);
virtual void Remove(int pos, int num_sites = 1);
virtual void Replace(int pos, int num_sites, const cGenome& genome);
+ //! Replace [begin, end) instructions in this genome with g, respecting genome circularity.
+ virtual void Replace(const cGenome& g, int begin, int end);
+ //! Rotate this genome forward n instructions.
+ virtual void Rotate(int n);
inline void Append(const cInstruction& in_inst) { Insert(GetSize(), in_inst); }
inline void Append(const cGenome& in_genome) { Insert(GetSize(), in_genome); }
Modified: development/source/main/cGenomeUtil.cc
===================================================================
--- development/source/main/cGenomeUtil.cc 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cGenomeUtil.cc 2009-12-05 17:58:06 UTC (rev 3546)
@@ -29,6 +29,7 @@
#include "cGenome.h"
#include "cInitFile.h"
#include "cInstSet.h"
+#include "cRandom.h"
#include "functions.h"
#include <algorithm>
#include <string.h>
@@ -245,6 +246,61 @@
}
+/*! Distance between begin and end.
+ */
+std::size_t cGenomeUtil::substring_match::distance() {
+ std::size_t d=0;
+ if(begin <= end) {
+ d = end - begin;
+ } else {
+ d = size - begin + end;
+ }
+ return d;
+}
+
+
+/*! Resize to n (preserve the absolute distance between begin and end, based around begin).
+ */
+void cGenomeUtil::substring_match::resize(std::size_t n) {
+ // fixup begin and end if they're negative or point beyond the current size
+ if(begin < 0) { begin = size - (-begin) % size; }
+ if(end < 0) { end = size - (-end) % size; }
+ begin %= size;
+ end %= size;
+
+ // our work is done if there's no change in size...
+ if(size == n) { return; }
+
+ // if this is triggered, it means that the current begin index would
+ // be truncated by the new, smaller string.
+ assert(begin < static_cast<int>(n));
+
+ // distance between begin and end:
+ std::size_t d=distance();
+
+ // if this is triggered, it means that the new size is smaller than the
+ // region described by this match.
+ assert(d < n);
+
+ size = n;
+ end = (begin + d) % size;
+}
+
+
+/*! Rotate around a size of n.
+ */
+void cGenomeUtil::substring_match::rotate(int r, std::size_t n) {
+ if(r < 0) {
+ r = -((-r) % n);
+ } else {
+ r %= n;
+ }
+ begin += r;
+ end += r;
+ resize(n); // fixup the indices
+}
+
+
/*! Find (one of) the best substring matches of substring in base.
The algorithm here is based on the well-known dynamic programming approach to
@@ -265,22 +321,69 @@
for(int i=1; i<rows; ++i) {
c[0].cost = i;
- c[0].begin = 0;
for(int j=1; j<cols; ++j) {
substring_match l[3] = {p[j-1], p[j], c[j-1]};
- substring_match* s = std::min_element(l,l+3);
+ substring_match* s = &l[0]; // default match is to the upper left.
+ if(substring[i-1] == base[j-1]) {
+ // if the characters match, take the default
+ c[j].cost = s->cost;
+ } else {
+ // otherwise, find the minimum cost, add 1.
+ s = std::min_element(l,l+3);
+ c[j].cost = s->cost + 1;
+ }
+
+ // update the beginning and end of the match.
c[j].begin = s->begin;
c[j].end = j;
- c[j].cost = s->cost + (substring[i-1] != base[j-1]);
}
std::swap(c,p);
}
- return *std::min_element(p, p+cols);
+ substring_match* min = std::min_element(p, p+cols);
+ min->size = base.GetSize();
+ return *min;
}
+/*! Find (one of) the best unbiased matches of substring in base, respecting genome circularity.
+
+ Substring matches are inherently biased towards matching near to the left-hand side of the string
+ (lower indices). This method removes that bias by rotating the string prior to performing the
+ match.
+
+ Genomes in Avida are logically (not physically) circular, but substring matches in general do not
+ respect circularity. To respect the logical circularity of genomes in Avida, we append the base
+ string with substring-size instructions from the beginning of the base string. This guarantees
+ that circular matches are detected.
+
+ The return value here is de-circularfied and de-rotated such that [begin,end) are correct
+ for the base string (note that, due to circularity, begin could be > end).
+ */
+cGenomeUtil::substring_match cGenomeUtil::FindUnbiasedCircularMatch(cAvidaContext& ctx, const cGenome& base, const cGenome& substring) {
+ // create a copy of the genome:
+ cGenome circ(base);
+
+ // rotate it so that we remove bias for matching at the front of the genome:
+ const int rotate = ctx.GetRandom().GetInt(circ.GetSize());
+ circ.Rotate(rotate);
+
+ // need to take circularity of the genome into account.
+ // we can do this by appending the genome with a copy of its first substring-size instructions.
+ cGenome head(&circ[0],&circ[0]+substring.GetSize());
+ circ.Append(head);
+
+ // find the location within the circular genome that best matches substring:
+ cGenomeUtil::substring_match location = FindSubstringMatch(circ, substring);
+
+ // unwind the resizing & rotation:
+ location.resize(base.GetSize());
+ location.rotate(-rotate, base.GetSize());
+ return location;
+}
+
+
cGenome cGenomeUtil::Crop(const cGenome & in_genome, int start, int end)
{
assert(end > start); // Must have a positive length clip!
Modified: development/source/main/cGenomeUtil.h
===================================================================
--- development/source/main/cGenomeUtil.h 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cGenomeUtil.h 2009-12-05 17:58:06 UTC (rev 3546)
@@ -67,18 +67,37 @@
the base string is [begin, end). (End points to the element immediately following
the match).
*/
+ //! Substring match record.
struct substring_match {
//! Default constructor.
- substring_match() : begin(0), end(0), cost(0) { }
- //! Operator< overload to support std::min_element.
- bool operator<(const substring_match& sm) { return cost < sm.cost; }
+ substring_match() : begin(0), end(0), cost(0), size(0) { }
+ //! Initializing constructor.
+ substring_match(int b, int e, int c=0, std::size_t s=0) : begin(b), end(e), cost(c), size(s) { }
+ //! Convenience method to set all values of a substring match.
+ void set(int b, int e, int c, std::size_t s) { begin = b; end = e; cost = c; size = s; }
+ //! Operator< overload.
+ bool operator<(const substring_match& that) const { return cost < that.cost; }
+ //! Operator== overload (to support testing)
+ bool operator==(const substring_match& that) const {
+ return (begin == that.begin) && (end == that.end) && (cost == that.cost) && (size == that.size);
+ }
+ //! Distance between begin and end.
+ std::size_t distance();
+ //! Resize to n (preserve the absolute distance between begin and end, based around begin).
+ void resize(std::size_t n);
+ //! Rotate around a size of n.
+ void rotate(int r, std::size_t n);
+
int begin; //!< Beginning of the substring match.
int end; //!< Ending of the substring match.
int cost; //!< Cost (edit distance) of this match.
+ std::size_t size; //!< Size of the base string.
};
- //! Find (one of) the best substring matches of substring in base.
- static substring_match FindSubstringMatch(const cGenome& base, const cGenome& substring);
+ //! Find (one of) the best matches of substring in base.
+ static substring_match FindSubstringMatch(const cGenome& base, const cGenome& substring);
+ //! Find (one of) the best unbiased matches of substring in base, respecting genome circularity.
+ static substring_match FindUnbiasedCircularMatch(cAvidaContext& ctx, const cGenome& base, const cGenome& substring);
// ===== Construction methods =====
static cGenome Crop(const cGenome& genome, int start, int end);
Modified: development/source/main/cPopulationCell.cc
===================================================================
--- development/source/main/cPopulationCell.cc 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cPopulationCell.cc 2009-12-05 17:58:06 UTC (rev 3546)
@@ -315,13 +315,21 @@
m_world->GetPopulation().AdjustHGTResource(genome.GetSize());
+ // copy & rotate this genome to remove bais for the beginning and end of the genome:
+ cGenome g(genome);
+ g.Rotate(m_world->GetRandom().GetInt(g.GetSize()));
+
// chop this genome up into pieces, add each to the back of this cell's buffer.
- int remaining_size=genome.GetSize();
- const cInstruction* i=&genome[0];
+ int remaining_size=g.GetSize();
+ const cInstruction* i=&g[0];
do {
- int fsize = std::min(remaining_size,
- (int)floor(m_world->GetRandom().GetRandNormal(m_world->GetConfig().HGT_FRAGMENT_SIZE_MEAN.Get(),
- m_world->GetConfig().HGT_FRAGMENT_SIZE_VARIANCE.Get())));
+ int fsize=0;
+ while(!fsize) {
+ fsize = std::min(remaining_size,
+ static_cast<int>(floor(fabs(m_world->GetRandom().GetRandNormal(m_world->GetConfig().HGT_FRAGMENT_SIZE_MEAN.Get(),
+ m_world->GetConfig().HGT_FRAGMENT_SIZE_VARIANCE.Get())))));
+ }
+
m_hgt->fragments.push_back(cGenome(i, i+fsize));
i+=fsize;
remaining_size-=fsize;
Modified: development/source/main/cPopulationInterface.cc
===================================================================
--- development/source/main/cPopulationInterface.cc 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cPopulationInterface.cc 2009-12-05 17:58:06 UTC (rev 3546)
@@ -28,13 +28,11 @@
#include "cDeme.h"
#include "cEnvironment.h"
#include "cGenotype.h"
-#include "cGenomeUtil.h"
#include "cHardwareManager.h"
#include "cOrganism.h"
#include "cOrgSinkMessage.h"
#include "cOrgMessage.h"
#include "cPopulation.h"
-#include "cPopulationCell.h"
#include "cStats.h"
#include "cTestCPU.h"
@@ -627,14 +625,12 @@
/*! Perform an HGT mutation on this offspring.
- HGT mutations are location-dependent, hence they are implemented here as opposed to
- the CPU or organism.
+ HGT mutations are location-dependent, hence they are piped through the populatin
+ interface as opposed to being implemented in the CPU or organism.
If this method is called, an HGT mutation of some kind is imminent. All that's left
is to actually *do* the mutation. We only do *one* HGT mutation each time this method
is called.
-
- \todo HGT should prefer more similar and older fragments.
*/
void cPopulationInterface::DoHGTMutation(cAvidaContext& ctx, cGenome& offspring) {
// get this organism's cell:
@@ -642,62 +638,79 @@
// do we have any fragments available?
if(cell.CountGenomeFragments() == 0) { return; }
+
+ // select the fragment and figure out where we're putting it:
+ fragment_list_type::iterator selected;
+ cGenomeUtil::substring_match location;
+ switch(m_world->GetConfig().HGT_FRAGMENT_SELECTION.Get()) {
+ case 0: { // random selection
+ HGTRandomFragmentSelection(ctx, offspring, cell.GetFragments(), selected, location);
+ break;
+ }
+ case 1: { // random selection with redundant instruction trimming
+ HGTTrimmedFragmentSelection(ctx, offspring, cell.GetFragments(), selected, location);
+ break;
+ }
+ default: { // error
+ m_world->GetDriver().RaiseFatalException(1, "HGT_FRAGMENT_SELECTION is set to an invalid value.");
+ break;
+ }
+ }
- // randomly select the genome fragment for HGT:
- typedef cPopulationCell::fragment_list_type fragment_list_type;
- fragment_list_type& fragments = cell.GetFragments();
- fragment_list_type::iterator f=fragments.begin();
- std::advance(f, ctx.GetRandom().GetInt(fragments.size()));
-
- // need to take circularity of the genome into account.
- // we can do this by appending the genome with a copy of its first fragment-size
- // instructions. handling insertions and replacements gets complicated after this...
- cGenome circ(offspring);
- for(int i=0; i<f->GetSize(); ++i) {
- circ.Append(offspring[i]);
+ // do the mutation; we currently support insertions and replacements, but this can
+ // be extended in the same way as fragment selection if need be.
+ if(ctx.GetRandom().P(m_world->GetConfig().HGT_INSERTION_MUT_P.Get())) {
+ // insert the fragment just after the final location:
+ offspring.Insert(location.end, *selected);
+ } else {
+ // replacement: replace [begin,end) instructions in the genome with the fragment,
+ // respecting circularity.
+ offspring.Replace(*selected, location.begin, location.end);
}
+ // resource utilization, cleanup, and stats tracking:
+ m_world->GetPopulation().AdjustHGTResource(-selected->GetSize());
+ m_world->GetStats().GenomeFragmentInserted(cell.GetOrganism(), *selected, location);
+ cell.GetFragments().erase(selected);
+}
+
+
+/*! Randomly select the fragment used for HGT mutation.
+ */
+void cPopulationInterface::HGTRandomFragmentSelection(cAvidaContext& ctx, const cGenome& offspring,
+ fragment_list_type& fragments, fragment_list_type::iterator& selected,
+ substring_match& location) {
+ // randomly select the genome fragment for HGT:
+ selected=fragments.begin();
+ std::advance(selected, ctx.GetRandom().GetInt(fragments.size()));
+
// find the location within the offspring's genome that best matches the selected fragment:
- cGenomeUtil::substring_match ssm = cGenomeUtil::FindSubstringMatch(circ, *f);
+ location = cGenomeUtil::FindUnbiasedCircularMatch(ctx, offspring, *selected);
+}
- // did we match any part of the circular portion of the genome? if so, adjust
- // begin & end to suit.
- if(ssm.begin > offspring.GetSize()) { ssm.begin -= offspring.GetSize(); }
- if(ssm.end > offspring.GetSize()) { ssm.end -= offspring.GetSize(); }
- // there are (currently) two supported types of HGT mutations: insertions & replacements.
- // which one are we doing?
- if(ctx.GetRandom().P(m_world->GetConfig().HGT_INSERTION_MUT_P.Get())) {
- // insertion: insert the fragment just after the final location of the match:
- offspring.Insert(ssm.end, *f);
- } else {
- // replacement: replace [begin,end) instructions in the genome with the fragment.
- if(ssm.begin <= ssm.end) {
- // match didn't wrap around the end, things are easy:
- offspring.Replace(ssm.begin, std::max(ssm.end-ssm.begin, 1), *f);
- } else {
- // match wrapped around the end. two different replacements to do now:
- // [ssm.begin, offspring.end) and [0, ssm.end).
-
- // first, replace the [ssm.begin, offspring.end) region; we'll try to
- // preserve the size of this region:
- int tail_size = std::min(offspring.GetSize()-ssm.begin, f->GetSize());
- cGenome tail(&(*f)[0], &(*f)[0]+tail_size);
- offspring.Replace(ssm.begin, tail_size, tail);
-
- // now, replace the [0, ssm.end) region or remove it if the whole fragment
- // was already copied in:
- if(tail_size != f->GetSize()) {
- cGenome head(&(*f)[0]+tail_size, &(*f)[0]+f->GetSize());
- offspring.Replace(0, ssm.end, head);
- } else {
- offspring.Remove(0, ssm.end);
- }
- }
+/*! Randomly select the fragment used for HGT mutation, trimming redundant instructions.
+
+ In this fragment selection method, the fragment itself is selected randomly, but the
+ match location within the genome is calculated on a "trimmed" fragment. Specifically,
+ the trimmed fragment has all duplicate instructions at its end removed prior to the match.
+
+ Mutations to the offspring are still performed using the entire fragment, so this effectively
+ increases the insertion rate. E.g., hgt(abcde, abcccc) -> abccccde.
+ */
+void cPopulationInterface::HGTTrimmedFragmentSelection(cAvidaContext& ctx, const cGenome& offspring,
+ fragment_list_type& fragments, fragment_list_type::iterator& selected,
+ substring_match& location) {
+ // randomly select the genome fragment for HGT:
+ selected=fragments.begin();
+ std::advance(selected, ctx.GetRandom().GetInt(fragments.size()));
+
+ // copy the selected fragment, trimming redundant instructions at the end:
+ cGenome trimmed(*selected);
+ while((trimmed.GetSize() >= 2) && (trimmed[trimmed.GetSize()-1] == trimmed[trimmed.GetSize()-2])) {
+ trimmed.Remove(trimmed.GetSize()-1);
}
- // resource utilization, cleanup, and stats tracking:
- m_world->GetPopulation().AdjustHGTResource(-f->GetSize());
- m_world->GetStats().GenomeFragmentInserted(cell.GetOrganism(), *f);
- fragments.erase(f);
+ // find the location within the offspring's genome that best matches the selected fragment:
+ location = cGenomeUtil::FindUnbiasedCircularMatch(ctx, offspring, trimmed);
}
Modified: development/source/main/cPopulationInterface.h
===================================================================
--- development/source/main/cPopulationInterface.h 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cPopulationInterface.h 2009-12-05 17:58:06 UTC (rev 3546)
@@ -35,12 +35,13 @@
#ifndef cWorldDriver_h
#include "cWorldDriver.h"
#endif
+#include "cGenomeUtil.h"
+#include "cPopulationCell.h"
class cAvidaContext;
class cDeme;
class cGenome;
class cPopulation;
-class cPopulationCell;
class cOrgMessage;
class cPopulationInterface : public cOrgInterface
@@ -141,8 +142,21 @@
// -------- HGT support --------
public:
+ //! Container type for fragments used during HGT.
+ typedef cPopulationCell::fragment_list_type fragment_list_type;
+ //! Match record, used to indicate the region within a genome that should be mutated.
+ typedef cGenomeUtil::substring_match substring_match;
//! Perform an HGT mutation on this offspring.
void DoHGTMutation(cAvidaContext& ctx, cGenome& offspring);
+protected:
+ //! Random selection of the fragment used for HGT mutation.
+ void HGTRandomFragmentSelection(cAvidaContext& ctx, const cGenome& offspring,
+ fragment_list_type& fragments, fragment_list_type::iterator& selected,
+ substring_match& location);
+ //! Random selection of the fragment used for HGT mutation, with redundant instructions trimmed.
+ void HGTTrimmedFragmentSelection(cAvidaContext& ctx, const cGenome& offspring,
+ fragment_list_type& fragments, fragment_list_type::iterator& selected,
+ substring_match& location);
};
Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cStats.cc 2009-12-05 17:58:06 UTC (rev 3546)
@@ -2952,7 +2952,9 @@
m_hgt_metabolized.Add(fragment.GetSize());
}
-void cStats::GenomeFragmentInserted(cOrganism* organism, const cGenome& fragment) {
+/*! Called when a fragment is inserted into an offspring's genome via HGT.
+ */
+void cStats::GenomeFragmentInserted(cOrganism* organism, const cGenome& fragment, const cGenomeUtil::substring_match& location) {
m_hgt_inserted.Add(fragment.GetSize());
}
Modified: development/source/main/cStats.h
===================================================================
--- development/source/main/cStats.h 2009-12-02 22:00:03 UTC (rev 3545)
+++ development/source/main/cStats.h 2009-12-05 17:58:06 UTC (rev 3546)
@@ -67,6 +67,7 @@
#include "nGeometry.h"
#endif
#include "cGenome.h"
+#include "cGenomeUtil.h"
#if USE_tMemTrack
# ifndef tMemTrack_h
@@ -1031,7 +1032,7 @@
//! Called when an organism metabolizes a genome fragment.
void GenomeFragmentMetabolized(cOrganism* organism, const cGenome& fragment);
//! Called when an organism inserts a genome fragment.
- void GenomeFragmentInserted(cOrganism* organism, const cGenome& fragment);
+ void GenomeFragmentInserted(cOrganism* organism, const cGenome& fragment, const cGenomeUtil::substring_match& location);
//! Print HGT statistics.
void PrintHGTData(const cString& filename);
};
More information about the Avida-cvs
mailing list