Skip to content

Commit

Permalink
Merge branch 'multicell-parasite' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
mmore500 authored Nov 15, 2023
2 parents 424d3b2 + 1074c32 commit 89420f1
Show file tree
Hide file tree
Showing 80 changed files with 10,340 additions and 34 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ SET(LIBRARY_OUTPUT_PATH


ADD_SUBDIRECTORY(libs/apto)

if(NOT WIN32 AND NOT DEFINED ENV{AVIDA_DISABLE_BACKTRACE})
ADD_SUBDIRECTORY(libs/backward-cpp)
endif()
Expand Down
36 changes: 26 additions & 10 deletions avida-core/source/actions/PopulationActions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -681,23 +681,31 @@ class cActionInjectParasite : public cAction
cString m_label;
int m_cell_start;
int m_cell_end;
int m_cell_stride;
int m_only_if_parasites_extinct;
public:
cActionInjectParasite(cWorld* world, const cString& args, Feedback&) : cAction(world, args), m_cell_start(0), m_cell_end(-1)
cActionInjectParasite(cWorld* world, const cString& args, Feedback&) : cAction(world, args), m_cell_start(0), m_cell_end(-1), m_cell_stride(1), m_only_if_parasites_extinct(0)
{
cString largs(args);
m_filename = largs.PopWord();
m_label = largs.PopWord();
if (largs.GetSize()) m_cell_start = largs.PopWord().AsInt();
if (largs.GetSize()) m_cell_end = largs.PopWord().AsInt();
if (largs.GetSize()) m_cell_stride = largs.PopWord().AsInt();
if (largs.GetSize()) m_only_if_parasites_extinct = largs.PopWord().AsInt();

if (m_cell_end == -1) m_cell_end = m_cell_start + 1;
}

static const cString GetDescription() { return "Arguments: <string filename> <string label> [int cell_start=0] [int cell_end=-1]"; }
static const cString GetDescription() { return "Arguments: <string filename> <string label> [int cell_start=0] [int cell_end=-1] [int cell_stride=1] [int only_if_parasites_extinct=0]"; }

void Process(cAvidaContext& ctx)
{
if (m_cell_start < 0 || m_cell_end > m_world->GetPopulation().GetSize() || m_cell_start >= m_cell_end) {
if (m_only_if_parasites_extinct && m_world->GetStats().GetNumParasites()) {
return;
}

if (m_cell_start < 0 || m_cell_end > m_world->GetPopulation().GetSize() || m_cell_start >= m_cell_end || m_cell_stride <= 0) {
ctx.Driver().Feedback().Warning("InjectParasite has invalid range!");
} else {
GenomePtr genome;
Expand All @@ -714,7 +722,7 @@ class cActionInjectParasite : public cAction
if (!genome) return;
ConstInstructionSequencePtr seq;
seq.DynamicCastFrom(genome->Representation());
for (int i = m_cell_start; i < m_cell_end; i++) {
for (int i = m_cell_start; i < m_cell_end; i+=m_cell_stride) {
m_world->GetPopulation().InjectParasite(m_label, *seq, i);
}
m_world->GetPopulation().SetSyncEvents(true);
Expand Down Expand Up @@ -850,8 +858,6 @@ class cActionInjectParasitePair : public cAction
Parameters:
filename (string):
The filename of the genotype to load.
cell ID (integer) default: 0
The grid-point into which the organism should be placed.
merit (double) default: -1
The initial merit of the organism. If set to -1, this is ignored.
lineage label (integer) default: 0
Expand Down Expand Up @@ -5182,23 +5188,27 @@ class cActionKillWithinRadiusBelowResourceThresholdTestAll : public cAction {
Parameters:
- The percent of living organisms to kill (default: 0)
- The targeted deme to kill (default: -1, targets all demes)
*/

class cActionKillDemePercent : public cAction
{
private:
double m_pctkills;
int m_target_demeid;
public:
cActionKillDemePercent(cWorld* world, const cString& args, Feedback&) : cAction(world, args), m_pctkills(0)
cActionKillDemePercent(cWorld* world, const cString& args, Feedback&) : cAction(world, args), m_pctkills(0), m_target_demeid(-1)
{
cString largs(args);
if (largs.GetSize()) m_pctkills = largs.PopWord().AsDouble();
if (largs.GetSize()) m_target_demeid = largs.PopWord().AsInt();

assert(m_pctkills >= 0);
assert(m_pctkills <= 1);
assert(m_target_demeid >= -1);
}

static const cString GetDescription() { return "Arguments: [double pctkills=0.0]"; }
static const cString GetDescription() { return "Arguments: [double pctkills=0.0] [int target_demeid=-1]"; }

void Process(cAvidaContext& ctx)
{
Expand All @@ -5208,8 +5218,13 @@ class cActionKillDemePercent : public cAction
long cells_scanned = 0;
long orgs_killed = 0;
long cells_empty = 0;

for (int d = 0; d < pop.GetNumDemes(); d++) {

const int start = (m_target_demeid == -1) ? 0 : m_target_demeid;
assert(start < pop.GetNumDemes());
const int stop = (
(m_target_demeid == -1) ? pop.GetNumDemes() : m_target_demeid + 1
);
for (int d = start; d < stop; d++) {

cDeme &deme = pop.GetDeme(d);

Expand Down Expand Up @@ -6061,6 +6076,7 @@ void RegisterPopulationActions(cActionLibrary* action_lib)
action_lib->Register<cActionKillDemePercent>("KillDemePercent");
action_lib->Register<cActionKillDemesHighestParasiteLoad>("KillDemesHighestParasiteLoad");
action_lib->Register<cActionReplicateDemesHighestBirthCount>("ReplicateDemesHighestBirthCount");
action_lib->Register<cActionSetDemeTreatmentAges>("SetDemeTreatmentAges");
action_lib->Register<cActionKillMeanBelowThresholdPaintable>("KillMeanBelowThresholdPaintable");

action_lib->Register<cActionDiffuseHGTGenomeFragments>("DiffuseHGTGenomeFragments");
Expand Down
21 changes: 21 additions & 0 deletions avida-core/source/actions/PrintActions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@

#include <cmath>
#include <cerrno>
#include <cstdlib>
#include <map>
#include <algorithm>

Expand Down Expand Up @@ -1074,6 +1075,25 @@ class cActionEcho : public cAction
}
};

class cActionShell : public cAction
{
private:
cString m_filename;
public:
cActionShell(cWorld* world, const cString& args, Feedback&) : cAction(world, args) { ; }

static const cString GetDescription() { return "Arguments: <cString message>"; }

void Process(cAvidaContext& ctx)
{
const int res = std::system(m_args);
std::stringstream ss;
ss << "Command `" << m_args << "` gave result " << res;

ctx.Driver().Feedback().Notify(ss.str().c_str());
}
};


class cActionPrintGenotypeAbundanceHistogram : public cAction
{
Expand Down Expand Up @@ -5662,6 +5682,7 @@ void RegisterPrintActions(cActionLibrary* action_lib)
action_lib->Register<cActionPrintParasiteDepthHistogram>("PrintParasiteDepthHistogram");
action_lib->Register<cActionPrintHostDepthHistogram>("PrintHostDepthHistogram");
action_lib->Register<cActionEcho>("Echo");
action_lib->Register<cActionShell>("Shell");
action_lib->Register<cActionPrintGenotypeAbundanceHistogram>("PrintGenotypeAbundanceHistogram");
// action_lib->Register<cActionPrintSpeciesAbundanceHistogram>("PrintSpeciesAbundanceHistogram");
// action_lib->Register<cActionPrintLineageTotals>("PrintLineageTotals");
Expand Down
98 changes: 90 additions & 8 deletions avida-core/source/cpu/cHardwareTransSMT.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*/

#include "cHardwareTransSMT.h"
#include "avida/core/Feedback.h"
#include "avida/core/WorldDriver.h"
#include "avida/systematics/Unit.h"

#include "cAvidaContext.h"
Expand All @@ -38,6 +40,8 @@

#include "AvidaTools.h"

#include <algorithm>
#include <cstdio>
#include <iomanip>

using namespace std;
Expand Down Expand Up @@ -1064,9 +1068,52 @@ void cHardwareTransSMT::Inject_DoMutations(cAvidaContext& ctx, double mut_multip
// Insert Mutations (per site)
num_mut = ctx.GetRandom().GetRandBinomial(injected_code.GetSize(),
m_organism->GetInjectInsProb());
// If would make creature to big, insert up to MAX_GENOME_LENGTH
if( num_mut + injected_code.GetSize() > MAX_GENOME_LENGTH )
num_mut = MAX_GENOME_LENGTH - injected_code.GetSize();

// use strongest restrictions
const int min_genome_size = std::max(
// don't need to account for unset cfg (i.e., 0) due to max
m_world->GetConfig().MIN_GENOME_SIZE.Get(),
MIN_GENOME_LENGTH // hardcoded implementation limit
);
const int max_genome_size = m_world->GetConfig().MAX_GENOME_SIZE.Get()
// MAX_GENOME_LENGTH is hardcoded implementation limit
? std::min(m_world->GetConfig().MAX_GENOME_SIZE.Get(), MAX_GENOME_LENGTH)
: MAX_GENOME_LENGTH
;

// @MAM
// (somehow) parasites shrink despite del and implicit muts being disabled
// so, enforce min genome size by growing up to min genome size if need be
if (min_genome_size && injected_code.GetSize() < min_genome_size) {
if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 1) {
num_mut = std::max(num_mut, min_genome_size - injected_code.GetSize());
// ctx.Driver().Feedback().Warning(
printf("warning: "
"Grew genome of size %d back to min genome size %d with %d inserts.\n",
injected_code.GetSize(), min_genome_size, num_mut
);
} else if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 2) {
printf("warning: "
"Sterilized too-small genome of size %d by setting insts to Nop-X.\n",
injected_code.GetSize()
);
for (int site = 0; site < injected_code.GetSize(); ++site) {
injected_code[site] = m_inst_set->GetInst("Nop-X");
}
} else if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 3) {
printf("warning: "
"Sterilized too-small genome of size %d by setting insts to Nop-A.\n",
injected_code.GetSize()
);
for (int site = 0; site < injected_code.GetSize(); ++site) {
injected_code[site] = m_inst_set->GetInst("Nop-A");
}
}
}

// If would make creature to big, insert up to max_genome_size
if( num_mut + injected_code.GetSize() > max_genome_size )
num_mut = max_genome_size - injected_code.GetSize();
// If we have lines to insert...
if( num_mut > 0 ){
// Build a list of the sites where mutations occured
Expand All @@ -1083,9 +1130,37 @@ void cHardwareTransSMT::Inject_DoMutations(cAvidaContext& ctx, double mut_multip
// Delete Mutations (per site)
num_mut = ctx.GetRandom().GetRandBinomial(injected_code.GetSize(),
m_organism->GetInjectDelProb());
// If would make creature too small, delete down to MIN_GENOME_LENGTH
if (injected_code.GetSize() - num_mut < MIN_GENOME_LENGTH) {
num_mut = injected_code.GetSize() - MIN_GENOME_LENGTH;

if (max_genome_size && injected_code.GetSize() > max_genome_size) {
if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 1) {
num_mut = std::max(num_mut, injected_code.GetSize() - max_genome_size);
// ctx.Driver().Feedback().Warning(
printf("warning: "
"Shrank genome of size %d back to max genome size %d with %d deletes.\n",
injected_code.GetSize(), max_genome_size, num_mut
);
} else if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 2) {
printf("warning: "
"Sterilized too-large genome of size %d by setting insts to Nop-X.\n",
injected_code.GetSize()
);
for (int site = 0; site < injected_code.GetSize(); ++site) {
injected_code[site] = m_inst_set->GetInst("Nop-X");
}
} else if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 3) {
printf("warning: "
"Sterilized too-large genome of size %d by setting insts to Nop-A.\n",
injected_code.GetSize()
);
for (int site = 0; site < injected_code.GetSize(); ++site) {
injected_code[site] = m_inst_set->GetInst("Nop-A");
}
}
}

// If would make creature too small, delete down to min_genome_size
if (injected_code.GetSize() - num_mut < min_genome_size) {
num_mut = injected_code.GetSize() - min_genome_size;
}

// If we have lines to delete...
Expand All @@ -1094,8 +1169,6 @@ void cHardwareTransSMT::Inject_DoMutations(cAvidaContext& ctx, double mut_multip
injected_code.Remove(site);
}

int max_genome_size = m_world->GetConfig().MAX_GENOME_SIZE.Get();
int min_genome_size = m_world->GetConfig().MIN_GENOME_SIZE.Get();
cCPUMemory& memory = GetMemory();

// Parent Substitution Mutations (per site)
Expand Down Expand Up @@ -1656,6 +1729,15 @@ bool cHardwareTransSMT::Inst_ThreadKill(cAvidaContext&)
// into the complement template found in a neighboring organism.
bool cHardwareTransSMT::Inst_Inject(cAvidaContext& ctx)
{
const bool is_nonparasite = !(
ThreadGetOwner()->UnitSource().transmission_type == Systematics::HORIZONTAL
|| ThreadGetOwner()->UnitSource().transmission_type == Systematics::VERTICAL
);
if (
m_world->GetConfig().TRANSSMT_DISABLE_NONPARASITE_INJECT.Get()
&& is_nonparasite
) return true; // do nothing, successfully

ReadLabel(MAX_MEMSPACE_LABEL);

if(ThreadGetOwner()->UnitSource().transmission_type == Systematics::HORIZONTAL)
Expand Down
3 changes: 3 additions & 0 deletions avida-core/source/main/cAvidaConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ class cAvidaConfig {
CONFIG_ADD_VAR(MIN_EXE_LINES, double, 0.5, "Code fraction that must be executed before divide");
CONFIG_ADD_VAR(MIN_GENOME_SIZE, int, 0, "Minimum number of instructions allowed in a genome. 0 = OFF");
CONFIG_ADD_VAR(MAX_GENOME_SIZE, int, 0, "Maximum number of instructions allowed in a genome. 0 = OFF");
CONFIG_ADD_VAR(GENOME_SIZE_RECOVERY, int, 0, "How should genomes that arise outside the too-small or too-large size bounds be corrected? 0: do nothing, 1: use standard indel mutations to put within size bounds, 2: sterilize by replaceing all insts with Nop-X, 3: sterilize by replaceing all insts with Nop-A.");
CONFIG_ADD_VAR(MIN_CYCLES, int, 0, "Min number of CPU cycles (age) required before reproduction.");
CONFIG_ADD_VAR(REQUIRE_ALLOCATE, int, 1, "(Original CPU Only) Require allocate before divide?");
CONFIG_ADD_VAR(REQUIRED_TASK, int, -1, "Task ID required for successful divide");
Expand Down Expand Up @@ -439,6 +440,7 @@ class cAvidaConfig {

// -------- Parasite options --------
CONFIG_ADD_GROUP(PARASITE_GROUP, "Parasite config options");
CONFIG_ADD_VAR(LOG_PARASITE_INJECTIONS, bool, 0, "Log parasite replications?");
CONFIG_ADD_VAR(INJECT_METHOD, int, 0, "What should happen to a parasite when it gives birth?\n0 = Leave the parasite thread state untouched.\n1 = Resets the state of the calling thread (for SMT parasites, this must be 1)");
CONFIG_ADD_VAR(INFECTION_MECHANISM, int, 1, "0: Infection always succeeds. \n1: Infection succeeds if parasite matches at least one host task.\n2: Infection succeeds if parasite does NOT match at least one task.\n3: Parasite tasks must match host tasks exactly (Matching Alleles).");
CONFIG_ADD_ALIAS(INJECT_IS_TASK_SPECIFIC);
Expand All @@ -461,6 +463,7 @@ class cAvidaConfig {
CONFIG_ADD_VAR(HOST_USE_GENOTYPE_FILE, int, 0, "Host Genotypes are loaded from a file rather than replicated from parent -- see LoadHostGenotypeList");

CONFIG_ADD_VAR(FULL_VERTICAL_TRANS, double, 0.0, "Determines if offspring of infected host is automatically infected. 0 for no, 1 for yes. If you want to keep parent infected as well, you need to set DIVIDE_METHOD to 2.");
CONFIG_ADD_VAR(TRANSSMT_DISABLE_NONPARASITE_INJECT, double, 0.0, "Should inject instruction be a no-op for non-parasites? Prevents host-generated pseudo-parasites. 0 for no, 1 for yes.");


// -------- CPU Archetecture
Expand Down
2 changes: 1 addition & 1 deletion avida-core/source/main/cDeme.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@ int cDeme::GetSlotFlowRate() const
bool cDeme::IsTreatableAtAge(const int age)
{
if (isTreatable()) {
if (treatment_ages.size() == 0) { return false; } // implies treatable every update
if (treatment_ages.size() == 0) { return true; } // implies treatable every update
set<int>::iterator it;
it = treatment_ages.find(age);
if(it != treatment_ages.end()) return true;
Expand Down
Loading

0 comments on commit 89420f1

Please sign in to comment.