Skip to content

Commit

Permalink
Add individual-based phylogeny
Browse files Browse the repository at this point in the history
  • Loading branch information
emilydolson committed Mar 26, 2024
1 parent f0bbd25 commit 878fce4
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 20 deletions.
1 change: 1 addition & 0 deletions avida-core/source/main/cAvidaConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ class cAvidaConfig {
CONFIG_ADD_VAR(POP_CAP_ELDEST, int, 0, "Carrying capacity in number of organisms (use 0 for no cap). Will kill oldest organism in population, but still use birth method to place new offspring.");
CONFIG_ADD_VAR(FILTER_TIME, int, 10000, "How long does a lineage need to survive to pass the coalesence filter?");
CONFIG_ADD_VAR(OEE_RES, int, 1000, "How often should we print OEE stats?");
CONFIG_ADD_VAR(TRACK_INDIVIDUALS, bool, 0, "Should we track phylogeny based on individuals or genomes (default)?");
CONFIG_ADD_VAR(PHYLOGENY_SNAPSHOT_RES, int, 1000, "How often should we print phylogeny stats?");
CONFIG_ADD_VAR(SYSTEMATICS_RES, int, 1000, "How often should we print phylodiversity stats?");

Expand Down
3 changes: 2 additions & 1 deletion avida-core/source/main/cPopulation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,8 @@ bool cPopulation::ActivateOrganism(cAvidaContext& ctx, cOrganism* in_organism, c
InstructionSequence* nseq = new InstructionSequence(*seq);
m_world->curr_genome = in_organism->GetGenome();
m_world->next_cell_id = target_cell.GetID();
m_world->offspring_ready_sig.Trigger(*nseq);

m_world->offspring_ready_sig.Trigger(*in_organism);

delete nseq;

Expand Down
37 changes: 28 additions & 9 deletions avida-core/source/main/cWorld.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,13 @@ cWorld::cWorld(cAvidaConfig* cfg, const cString& wd)
return test_info.GetGenotypeFitness();
};

eval_fun = [this](emp::Ptr<taxon_t> tax){
eval_fun = [this](emp::Ptr<taxon_t> tax, cOrganism & org){
// std::cout << "evaluating" << tax << std::endl;

Avida::Genome gen(curr_genome.HardwareType(), curr_genome.Properties(), GeneticRepresentationPtr(new InstructionSequence(tax->GetInfo())));
// Avida::GeneticRepresentation rep = *(org.GetGenome().Representation());
// GeneticRepresentationPtr(org.GetGenome().Representation())
Avida::Genome gen(curr_genome.HardwareType(), curr_genome.Properties(), GeneticRepresentationPtr(new InstructionSequence(tax->GetData().GetPhenotype().genotype)));
// Avida::Genome gen(curr_genome.HardwareType(), curr_genome.Properties(), );
// cAnalyzeGenotype genotype(this, gen);
// genotype.Recalculate(*m_ctx);
cCPUTestInfo test_info;
Expand All @@ -90,6 +93,11 @@ cWorld::cWorld(cAvidaConfig* cfg, const cString& wd)
for (int i = 0; i < tasks.GetSize(); i++) {
p.final_task_count.push_back(tasks[i]);
}
ConstInstructionSequencePtr seq;
seq.DynamicCastFrom(org.GetGenome().Representation());

p.genotype = Avida::InstructionSequence(*seq);

tax->GetData().RecordPhenotype(p);
};

Expand Down Expand Up @@ -256,20 +264,31 @@ bool cWorld::setup(World* new_world, cUserFeedback* feedback, const Apto::Map<Ap

// std::cout << "Got hardware manager" << std::endl;
// emp_assert(false);
skel_fun = [this, null_inst](const Avida::InstructionSequence & seq){
skel_fun = [this, null_inst](emp::Ptr<taxon_t> tax){
// std::cout << "Skeletonizing" <<std::endl;

std::stringstream ss;
Avida::InstructionSequence seq = tax->GetData().GetPhenotype().genotype;
emp::vector<Avida::Instruction> skel = emp::Skeletonize(seq, null_inst, fit_fun);
for (auto inst : skel) {
ss << inst.GetSymbol();
}
return ss.str();
};
// std::cout << "About to make sys" << std::endl;
systematics_manager.New([](const Avida::InstructionSequence & seq){return Avida::InstructionSequence(seq);});
if (m_conf->TRACK_INDIVIDUALS.Get()) {
systematics_manager.New([](cOrganism & org){return emp::to_string(org.GetID());});
} else {
systematics_manager.New([](cOrganism & org){
ConstInstructionSequencePtr seq;
seq.DynamicCastFrom(org.GetGenome().Representation());

return Avida::InstructionSequence(*seq).AsString().GetCString();
});
}
systematics_manager->PrintStatus();
systematics_manager->AddSnapshotFun([](const taxon_t & tax) {
return emp::to_string(tax.GetInfo().AsString().GetCString());
return emp::to_string(tax.GetData().GetPhenotype().genotype.AsString().GetCString());
}, "sequence", "Avida instruction sequence for this taxon.");

if (m_conf->OEE_RES.Get() != 0) {
Expand All @@ -284,18 +303,18 @@ bool cWorld::setup(World* new_world, cUserFeedback* feedback, const Apto::Map<Ap
// std::cout << systematics_manager->GetTaxonAt(pos)->GetID();
// }
systematics_manager->SetNextParent(pos);});
OnOffspringReady([this](Avida::InstructionSequence seq){
OnOffspringReady([this](cOrganism & org){
// std::cout << "on ready" << std::endl;
systematics_manager->AddOrg(seq, emp::WorldPosition(next_cell_id,0), GetStats().GetUpdate());
systematics_manager->AddOrg(org, emp::WorldPosition(next_cell_id,0));
emp::Ptr<taxon_t> tax = systematics_manager->GetMostRecent();
if (tax->GetData().GetPhenotype().gestation_time == -1) {
eval_fun(tax);
eval_fun(tax, org);
}
// std::cout << "Done with on ready" << std::endl;
});
OnOrgDeath([this](int pos){
// std::cout << "on death " << std::endl;
systematics_manager->RemoveOrgAfterRepro(emp::WorldPosition(pos, 0), GetStats().GetUpdate());});
systematics_manager->RemoveOrgAfterRepro(emp::WorldPosition(pos, 0));});
if (m_conf->OEE_RES.Get() != 0) {
OnUpdate([this](int ud){
// std::cout << "On update" << std::endl;
Expand Down
20 changes: 11 additions & 9 deletions avida-core/source/main/cWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class cUserFeedback;
template<class T> class tDataEntry;

struct Phenotype {
Avida::InstructionSequence genotype;
int gestation_time = -1;
int start_generation = -1;
emp::vector<int> final_task_count;
Expand Down Expand Up @@ -170,8 +171,8 @@ class cWorld
// Signals triggered by the world.
emp::SignalControl control; // Setup the world to control various signals.
emp::Signal<void(int)> before_repro_sig; // Trigger: Immediately prior to producing offspring
emp::Signal<void(Avida::InstructionSequence)> offspring_ready_sig; // Trigger: Offspring about to enter population
emp::Signal<void(const Avida::InstructionSequence*)> inject_ready_sig; // Trigger: New org about to be added to population
emp::Signal<void(cOrganism &)> offspring_ready_sig; // Trigger: Offspring about to enter population
emp::Signal<void(cOrganism &)> inject_ready_sig; // Trigger: New org about to be added to population
emp::Signal<void(int)> org_placement_sig; // Trigger: Organism has been added to population
emp::Signal<void(int)> org_death_sig; // Trigger: Organism has been added to population
emp::Signal<void(int)> on_update_sig; // Trigger: New update is starting.
Expand All @@ -183,15 +184,18 @@ class cWorld
emp::DataFile lineage_file;
emp::DataFile dom_file;

std::function<double(const Avida::InstructionSequence&)> fit_fun;
std::function<std::string(const Avida::InstructionSequence&)> skel_fun;
using systematics_t = emp::Systematics<cOrganism, std::string, emp::datastruct::mut_landscape_info<Phenotype>>;
using taxon_t = emp::Taxon< std::string, emp::datastruct::mut_landscape_info<Phenotype>>;

std::function<double(Avida::InstructionSequence&)> fit_fun;
std::function<std::string(emp::Ptr<taxon_t>)> skel_fun;

emp::SignalKey OnBeforeRepro(const std::function<void(int)> & fun) { return before_repro_sig.AddAction(fun); }
emp::SignalKey OnOffspringReady(const std::function<void(Avida::InstructionSequence)> & fun) { return offspring_ready_sig.AddAction(fun); }
emp::SignalKey OnOffspringReady(const std::function<void(cOrganism &)> & fun) { return offspring_ready_sig.AddAction(fun); }
emp::SignalKey OnOrgPlacement(const std::function<void(int)> & fun) { return org_placement_sig.AddAction(fun); }
emp::SignalKey OnOrgDeath(const std::function<void(int)> & fun) { return org_death_sig.AddAction(fun); }
emp::SignalKey OnUpdate(const std::function<void(int)> & fun) { return on_update_sig.AddAction(fun); }
emp::SignalKey OnInjectReady(const std::function<void(const Avida::InstructionSequence*)> & fun) { return inject_ready_sig.AddAction(fun); }
emp::SignalKey OnInjectReady(const std::function<void(cOrganism &)> & fun) { return inject_ready_sig.AddAction(fun); }

void SetDriver(WorldDriver* driver, bool take_ownership = false);

Expand All @@ -214,11 +218,9 @@ class cWorld
bool all_tasks = false;
int latest_gen = -1; // Force time to go forward

using systematics_t = emp::Systematics<Avida::InstructionSequence, Avida::InstructionSequence, emp::datastruct::mut_landscape_info<Phenotype>>;
using taxon_t = emp::Taxon< Avida::InstructionSequence, emp::datastruct::mut_landscape_info<Phenotype>>;
emp::Ptr<taxon_t> best_tax;

std::function<void(emp::Ptr<taxon_t>)> eval_fun;
std::function<void(emp::Ptr<taxon_t>, cOrganism&)> eval_fun;
const emp::vector<std::string> MUTATION_TYPES = {"substitution", "insertion", "deletion"};

using mut_count_t = std::unordered_map<std::string, double>;
Expand Down
2 changes: 1 addition & 1 deletion libs/Empirical

0 comments on commit 878fce4

Please sign in to comment.