Skip to content

Commit 89420f1

Browse files
authored
Merge branch 'multicell-parasite' into master
2 parents 424d3b2 + 1074c32 commit 89420f1

File tree

80 files changed

+10340
-34
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+10340
-34
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SET(LIBRARY_OUTPUT_PATH
2626

2727

2828
ADD_SUBDIRECTORY(libs/apto)
29+
2930
if(NOT WIN32 AND NOT DEFINED ENV{AVIDA_DISABLE_BACKTRACE})
3031
ADD_SUBDIRECTORY(libs/backward-cpp)
3132
endif()

avida-core/source/actions/PopulationActions.cc

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -681,23 +681,31 @@ class cActionInjectParasite : public cAction
681681
cString m_label;
682682
int m_cell_start;
683683
int m_cell_end;
684+
int m_cell_stride;
685+
int m_only_if_parasites_extinct;
684686
public:
685-
cActionInjectParasite(cWorld* world, const cString& args, Feedback&) : cAction(world, args), m_cell_start(0), m_cell_end(-1)
687+
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)
686688
{
687689
cString largs(args);
688690
m_filename = largs.PopWord();
689691
m_label = largs.PopWord();
690692
if (largs.GetSize()) m_cell_start = largs.PopWord().AsInt();
691693
if (largs.GetSize()) m_cell_end = largs.PopWord().AsInt();
694+
if (largs.GetSize()) m_cell_stride = largs.PopWord().AsInt();
695+
if (largs.GetSize()) m_only_if_parasites_extinct = largs.PopWord().AsInt();
692696

693697
if (m_cell_end == -1) m_cell_end = m_cell_start + 1;
694698
}
695699

696-
static const cString GetDescription() { return "Arguments: <string filename> <string label> [int cell_start=0] [int cell_end=-1]"; }
700+
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]"; }
697701

698702
void Process(cAvidaContext& ctx)
699703
{
700-
if (m_cell_start < 0 || m_cell_end > m_world->GetPopulation().GetSize() || m_cell_start >= m_cell_end) {
704+
if (m_only_if_parasites_extinct && m_world->GetStats().GetNumParasites()) {
705+
return;
706+
}
707+
708+
if (m_cell_start < 0 || m_cell_end > m_world->GetPopulation().GetSize() || m_cell_start >= m_cell_end || m_cell_stride <= 0) {
701709
ctx.Driver().Feedback().Warning("InjectParasite has invalid range!");
702710
} else {
703711
GenomePtr genome;
@@ -714,7 +722,7 @@ class cActionInjectParasite : public cAction
714722
if (!genome) return;
715723
ConstInstructionSequencePtr seq;
716724
seq.DynamicCastFrom(genome->Representation());
717-
for (int i = m_cell_start; i < m_cell_end; i++) {
725+
for (int i = m_cell_start; i < m_cell_end; i+=m_cell_stride) {
718726
m_world->GetPopulation().InjectParasite(m_label, *seq, i);
719727
}
720728
m_world->GetPopulation().SetSyncEvents(true);
@@ -850,8 +858,6 @@ class cActionInjectParasitePair : public cAction
850858
Parameters:
851859
filename (string):
852860
The filename of the genotype to load.
853-
cell ID (integer) default: 0
854-
The grid-point into which the organism should be placed.
855861
merit (double) default: -1
856862
The initial merit of the organism. If set to -1, this is ignored.
857863
lineage label (integer) default: 0
@@ -5182,23 +5188,27 @@ class cActionKillWithinRadiusBelowResourceThresholdTestAll : public cAction {
51825188
51835189
Parameters:
51845190
- The percent of living organisms to kill (default: 0)
5191+
- The targeted deme to kill (default: -1, targets all demes)
51855192
*/
51865193

51875194
class cActionKillDemePercent : public cAction
51885195
{
51895196
private:
51905197
double m_pctkills;
5198+
int m_target_demeid;
51915199
public:
5192-
cActionKillDemePercent(cWorld* world, const cString& args, Feedback&) : cAction(world, args), m_pctkills(0)
5200+
cActionKillDemePercent(cWorld* world, const cString& args, Feedback&) : cAction(world, args), m_pctkills(0), m_target_demeid(-1)
51935201
{
51945202
cString largs(args);
51955203
if (largs.GetSize()) m_pctkills = largs.PopWord().AsDouble();
5204+
if (largs.GetSize()) m_target_demeid = largs.PopWord().AsInt();
51965205

51975206
assert(m_pctkills >= 0);
51985207
assert(m_pctkills <= 1);
5208+
assert(m_target_demeid >= -1);
51995209
}
52005210

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

52035213
void Process(cAvidaContext& ctx)
52045214
{
@@ -5208,8 +5218,13 @@ class cActionKillDemePercent : public cAction
52085218
long cells_scanned = 0;
52095219
long orgs_killed = 0;
52105220
long cells_empty = 0;
5211-
5212-
for (int d = 0; d < pop.GetNumDemes(); d++) {
5221+
5222+
const int start = (m_target_demeid == -1) ? 0 : m_target_demeid;
5223+
assert(start < pop.GetNumDemes());
5224+
const int stop = (
5225+
(m_target_demeid == -1) ? pop.GetNumDemes() : m_target_demeid + 1
5226+
);
5227+
for (int d = start; d < stop; d++) {
52135228

52145229
cDeme &deme = pop.GetDeme(d);
52155230

@@ -6061,6 +6076,7 @@ void RegisterPopulationActions(cActionLibrary* action_lib)
60616076
action_lib->Register<cActionKillDemePercent>("KillDemePercent");
60626077
action_lib->Register<cActionKillDemesHighestParasiteLoad>("KillDemesHighestParasiteLoad");
60636078
action_lib->Register<cActionReplicateDemesHighestBirthCount>("ReplicateDemesHighestBirthCount");
6079+
action_lib->Register<cActionSetDemeTreatmentAges>("SetDemeTreatmentAges");
60646080
action_lib->Register<cActionKillMeanBelowThresholdPaintable>("KillMeanBelowThresholdPaintable");
60656081

60666082
action_lib->Register<cActionDiffuseHGTGenomeFragments>("DiffuseHGTGenomeFragments");

avida-core/source/actions/PrintActions.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464

6565
#include <cmath>
6666
#include <cerrno>
67+
#include <cstdlib>
6768
#include <map>
6869
#include <algorithm>
6970

@@ -1074,6 +1075,25 @@ class cActionEcho : public cAction
10741075
}
10751076
};
10761077

1078+
class cActionShell : public cAction
1079+
{
1080+
private:
1081+
cString m_filename;
1082+
public:
1083+
cActionShell(cWorld* world, const cString& args, Feedback&) : cAction(world, args) { ; }
1084+
1085+
static const cString GetDescription() { return "Arguments: <cString message>"; }
1086+
1087+
void Process(cAvidaContext& ctx)
1088+
{
1089+
const int res = std::system(m_args);
1090+
std::stringstream ss;
1091+
ss << "Command `" << m_args << "` gave result " << res;
1092+
1093+
ctx.Driver().Feedback().Notify(ss.str().c_str());
1094+
}
1095+
};
1096+
10771097

10781098
class cActionPrintGenotypeAbundanceHistogram : public cAction
10791099
{
@@ -5662,6 +5682,7 @@ void RegisterPrintActions(cActionLibrary* action_lib)
56625682
action_lib->Register<cActionPrintParasiteDepthHistogram>("PrintParasiteDepthHistogram");
56635683
action_lib->Register<cActionPrintHostDepthHistogram>("PrintHostDepthHistogram");
56645684
action_lib->Register<cActionEcho>("Echo");
5685+
action_lib->Register<cActionShell>("Shell");
56655686
action_lib->Register<cActionPrintGenotypeAbundanceHistogram>("PrintGenotypeAbundanceHistogram");
56665687
// action_lib->Register<cActionPrintSpeciesAbundanceHistogram>("PrintSpeciesAbundanceHistogram");
56675688
// action_lib->Register<cActionPrintLineageTotals>("PrintLineageTotals");

avida-core/source/cpu/cHardwareTransSMT.cc

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
*/
2121

2222
#include "cHardwareTransSMT.h"
23+
#include "avida/core/Feedback.h"
24+
#include "avida/core/WorldDriver.h"
2325
#include "avida/systematics/Unit.h"
2426

2527
#include "cAvidaContext.h"
@@ -38,6 +40,8 @@
3840

3941
#include "AvidaTools.h"
4042

43+
#include <algorithm>
44+
#include <cstdio>
4145
#include <iomanip>
4246

4347
using namespace std;
@@ -1064,9 +1068,52 @@ void cHardwareTransSMT::Inject_DoMutations(cAvidaContext& ctx, double mut_multip
10641068
// Insert Mutations (per site)
10651069
num_mut = ctx.GetRandom().GetRandBinomial(injected_code.GetSize(),
10661070
m_organism->GetInjectInsProb());
1067-
// If would make creature to big, insert up to MAX_GENOME_LENGTH
1068-
if( num_mut + injected_code.GetSize() > MAX_GENOME_LENGTH )
1069-
num_mut = MAX_GENOME_LENGTH - injected_code.GetSize();
1071+
1072+
// use strongest restrictions
1073+
const int min_genome_size = std::max(
1074+
// don't need to account for unset cfg (i.e., 0) due to max
1075+
m_world->GetConfig().MIN_GENOME_SIZE.Get(),
1076+
MIN_GENOME_LENGTH // hardcoded implementation limit
1077+
);
1078+
const int max_genome_size = m_world->GetConfig().MAX_GENOME_SIZE.Get()
1079+
// MAX_GENOME_LENGTH is hardcoded implementation limit
1080+
? std::min(m_world->GetConfig().MAX_GENOME_SIZE.Get(), MAX_GENOME_LENGTH)
1081+
: MAX_GENOME_LENGTH
1082+
;
1083+
1084+
// @MAM
1085+
// (somehow) parasites shrink despite del and implicit muts being disabled
1086+
// so, enforce min genome size by growing up to min genome size if need be
1087+
if (min_genome_size && injected_code.GetSize() < min_genome_size) {
1088+
if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 1) {
1089+
num_mut = std::max(num_mut, min_genome_size - injected_code.GetSize());
1090+
// ctx.Driver().Feedback().Warning(
1091+
printf("warning: "
1092+
"Grew genome of size %d back to min genome size %d with %d inserts.\n",
1093+
injected_code.GetSize(), min_genome_size, num_mut
1094+
);
1095+
} else if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 2) {
1096+
printf("warning: "
1097+
"Sterilized too-small genome of size %d by setting insts to Nop-X.\n",
1098+
injected_code.GetSize()
1099+
);
1100+
for (int site = 0; site < injected_code.GetSize(); ++site) {
1101+
injected_code[site] = m_inst_set->GetInst("Nop-X");
1102+
}
1103+
} else if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 3) {
1104+
printf("warning: "
1105+
"Sterilized too-small genome of size %d by setting insts to Nop-A.\n",
1106+
injected_code.GetSize()
1107+
);
1108+
for (int site = 0; site < injected_code.GetSize(); ++site) {
1109+
injected_code[site] = m_inst_set->GetInst("Nop-A");
1110+
}
1111+
}
1112+
}
1113+
1114+
// If would make creature to big, insert up to max_genome_size
1115+
if( num_mut + injected_code.GetSize() > max_genome_size )
1116+
num_mut = max_genome_size - injected_code.GetSize();
10701117
// If we have lines to insert...
10711118
if( num_mut > 0 ){
10721119
// Build a list of the sites where mutations occured
@@ -1083,9 +1130,37 @@ void cHardwareTransSMT::Inject_DoMutations(cAvidaContext& ctx, double mut_multip
10831130
// Delete Mutations (per site)
10841131
num_mut = ctx.GetRandom().GetRandBinomial(injected_code.GetSize(),
10851132
m_organism->GetInjectDelProb());
1086-
// If would make creature too small, delete down to MIN_GENOME_LENGTH
1087-
if (injected_code.GetSize() - num_mut < MIN_GENOME_LENGTH) {
1088-
num_mut = injected_code.GetSize() - MIN_GENOME_LENGTH;
1133+
1134+
if (max_genome_size && injected_code.GetSize() > max_genome_size) {
1135+
if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 1) {
1136+
num_mut = std::max(num_mut, injected_code.GetSize() - max_genome_size);
1137+
// ctx.Driver().Feedback().Warning(
1138+
printf("warning: "
1139+
"Shrank genome of size %d back to max genome size %d with %d deletes.\n",
1140+
injected_code.GetSize(), max_genome_size, num_mut
1141+
);
1142+
} else if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 2) {
1143+
printf("warning: "
1144+
"Sterilized too-large genome of size %d by setting insts to Nop-X.\n",
1145+
injected_code.GetSize()
1146+
);
1147+
for (int site = 0; site < injected_code.GetSize(); ++site) {
1148+
injected_code[site] = m_inst_set->GetInst("Nop-X");
1149+
}
1150+
} else if (m_world->GetConfig().GENOME_SIZE_RECOVERY.Get() == 3) {
1151+
printf("warning: "
1152+
"Sterilized too-large genome of size %d by setting insts to Nop-A.\n",
1153+
injected_code.GetSize()
1154+
);
1155+
for (int site = 0; site < injected_code.GetSize(); ++site) {
1156+
injected_code[site] = m_inst_set->GetInst("Nop-A");
1157+
}
1158+
}
1159+
}
1160+
1161+
// If would make creature too small, delete down to min_genome_size
1162+
if (injected_code.GetSize() - num_mut < min_genome_size) {
1163+
num_mut = injected_code.GetSize() - min_genome_size;
10891164
}
10901165

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

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

11011174
// Parent Substitution Mutations (per site)
@@ -1656,6 +1729,15 @@ bool cHardwareTransSMT::Inst_ThreadKill(cAvidaContext&)
16561729
// into the complement template found in a neighboring organism.
16571730
bool cHardwareTransSMT::Inst_Inject(cAvidaContext& ctx)
16581731
{
1732+
const bool is_nonparasite = !(
1733+
ThreadGetOwner()->UnitSource().transmission_type == Systematics::HORIZONTAL
1734+
|| ThreadGetOwner()->UnitSource().transmission_type == Systematics::VERTICAL
1735+
);
1736+
if (
1737+
m_world->GetConfig().TRANSSMT_DISABLE_NONPARASITE_INJECT.Get()
1738+
&& is_nonparasite
1739+
) return true; // do nothing, successfully
1740+
16591741
ReadLabel(MAX_MEMSPACE_LABEL);
16601742

16611743
if(ThreadGetOwner()->UnitSource().transmission_type == Systematics::HORIZONTAL)

avida-core/source/main/cAvidaConfig.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ class cAvidaConfig {
393393
CONFIG_ADD_VAR(MIN_EXE_LINES, double, 0.5, "Code fraction that must be executed before divide");
394394
CONFIG_ADD_VAR(MIN_GENOME_SIZE, int, 0, "Minimum number of instructions allowed in a genome. 0 = OFF");
395395
CONFIG_ADD_VAR(MAX_GENOME_SIZE, int, 0, "Maximum number of instructions allowed in a genome. 0 = OFF");
396+
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.");
396397
CONFIG_ADD_VAR(MIN_CYCLES, int, 0, "Min number of CPU cycles (age) required before reproduction.");
397398
CONFIG_ADD_VAR(REQUIRE_ALLOCATE, int, 1, "(Original CPU Only) Require allocate before divide?");
398399
CONFIG_ADD_VAR(REQUIRED_TASK, int, -1, "Task ID required for successful divide");
@@ -439,6 +440,7 @@ class cAvidaConfig {
439440

440441
// -------- Parasite options --------
441442
CONFIG_ADD_GROUP(PARASITE_GROUP, "Parasite config options");
443+
CONFIG_ADD_VAR(LOG_PARASITE_INJECTIONS, bool, 0, "Log parasite replications?");
442444
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)");
443445
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).");
444446
CONFIG_ADD_ALIAS(INJECT_IS_TASK_SPECIFIC);
@@ -461,6 +463,7 @@ class cAvidaConfig {
461463
CONFIG_ADD_VAR(HOST_USE_GENOTYPE_FILE, int, 0, "Host Genotypes are loaded from a file rather than replicated from parent -- see LoadHostGenotypeList");
462464

463465
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.");
466+
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.");
464467

465468

466469
// -------- CPU Archetecture

avida-core/source/main/cDeme.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ int cDeme::GetSlotFlowRate() const
12361236
bool cDeme::IsTreatableAtAge(const int age)
12371237
{
12381238
if (isTreatable()) {
1239-
if (treatment_ages.size() == 0) { return false; } // implies treatable every update
1239+
if (treatment_ages.size() == 0) { return true; } // implies treatable every update
12401240
set<int>::iterator it;
12411241
it = treatment_ages.find(age);
12421242
if(it != treatment_ages.end()) return true;

0 commit comments

Comments
 (0)