Skip to content

Commit d9669c4

Browse files
Merge pull request #274 from K-Johnson-Horrigan/complex-syms-clean
Const bitset references + stress escapee data nodes
2 parents f965b17 + 8475e09 commit d9669c4

11 files changed

Lines changed: 244 additions & 81 deletions

File tree

source/default_mode/DataNodes.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,16 +195,13 @@ void SymWorld::WritePhylogenyFile(const std::string & filename) {
195195

196196

197197
/**
198-
* Input: The address of the string representing the suffixes for the files to be created.
198+
* Input: The reference of the datafile which is being constructed.
199199
*
200200
* Output: None.
201201
*
202-
* Purpose: To setup and write to the files that track the counts of attempted
203-
* tranmissions.
202+
* Purpose: To setup the columns tracking symbiont transmission.
204203
*/
205-
206-
emp::DataFile & SymWorld::SetUpTransmissionFile(const std::string & filename){
207-
auto & file = SetupFile(filename);
204+
void SymWorld::SetupTransmissionFileColumns(emp::DataFile& file){
208205
auto & node1 = GetHorizontalTransmissionAttemptCount();
209206
auto & node2 = GetHorizontalTransmissionSuccessCount();
210207
auto & node3 = GetVerticalTransmissionAttemptCount();
@@ -219,9 +216,20 @@ emp::DataFile & SymWorld::SetUpTransmissionFile(const std::string & filename){
219216
//vertical transmission
220217
file.AddTotal(node3, "attempts_verttrans", "Total number of vertical transmission attempts", true);
221218
file.AddTotal(node4, "successes_verttrans", "Total number of vertical transmission successes", true);
219+
}
222220

221+
/**
222+
* Input: The address of the string representing the file to be
223+
* created's name
224+
*
225+
* Output: The address of the DataFile that has been created.
226+
*
227+
* Purpose: To set up the file that will be used to track symbiont transmission
228+
*/
229+
emp::DataFile& SymWorld::SetUpTransmissionFile(const std::string& filename) {
230+
auto& file = SetupFile(filename);
231+
SetupTransmissionFileColumns(file);
223232
file.PrintHeaderKeys();
224-
225233
return file;
226234
}
227235

source/default_mode/SymWorld.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ class SymWorld : public emp::World<Organism>{
505505
emp::DataFile & SetupHostIntValFile(const std::string & filename);
506506
emp::DataFile & SetUpFreeLivingSymFile(const std::string & filename);
507507
emp::DataFile & SetUpTransmissionFile(const std::string & filename);
508+
virtual void SetupTransmissionFileColumns(emp::DataFile& file);
508509
virtual void SetupHostFileColumns(emp::DataFile & file);
509510
emp::DataMonitor<int>& GetHostCountDataNode();
510511
emp::DataMonitor<int>& GetSymCountDataNode();

source/native/symbulation_sgp.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,15 @@ int symbulation_main(int argc, char *argv[]) {
3636
config.Write(std::cout);
3737
emp::Random random(config.SEED());
3838

39-
TaskSet task_set = LogicTasks;
39+
const TaskSet* task_set;
4040
if(config.DIFFERENT_TASK_VALUES()) {
41-
task_set = LogicTasksDiff;
41+
task_set = &LogicTasksDiff;
42+
}
43+
else {
44+
task_set = &LogicTasks;
4245
}
4346

44-
SGPWorld world(random, &config, task_set);
47+
SGPWorld world(random, &config, *task_set);
4548

4649
world.Setup();
4750
world.CreateDataFiles();

source/sgp_mode/SGPDataNodes.h

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,25 @@ emp::DataFile &SGPWorld::SetupSymInstFile(const std::string &filename) {
8989
return file;
9090
}
9191

92+
/**
93+
* Input: The address of the file object
94+
*
95+
* Output: None
96+
*
97+
* Purpose: To add the stress repro escapee attempts and successes
98+
* as columns in the transmission file.
99+
*/
100+
void SGPWorld::SetupTransmissionFileColumns(emp::DataFile& file) {
101+
SymWorld::SetupTransmissionFileColumns(file);
102+
if (sgp_config->INTERACTION_MECHANISM() == STRESS && sgp_config->SYMBIONT_TYPE() == PARASITE && sgp_config->PARASITE_NUM_OFFSPRING_ON_STRESS_INTERACTION() > 0) {
103+
emp::DataMonitor<size_t>& escapee_attempts = GetStressEscapeeOffspringAttemptCount();
104+
emp::DataMonitor<size_t>& escapee_successes = GetStressEscapeeOffspringSuccessCount();
105+
106+
file.AddTotal(escapee_attempts, "stress_escapee_offspring_attempts", "Total number of stress offspring who attempted to escape", true);
107+
file.AddTotal(escapee_successes, "stress_escapee_offspring_successes", "Total number of stress offspring who succeeded in escaping (they were validly placed)", true);
108+
}
109+
}
110+
92111
/**
93112
* Input: The address of the string representing the file to be
94113
* created's name
@@ -107,9 +126,7 @@ void SGPWorld::WriteTaskCombinationsFile(const std::string& filename) {
107126
for (size_t i = 0; i < pop.size(); i++) {
108127
if (!IsOccupied(i)) continue;
109128
emp::Ptr<SGPHost> host = pop[i].DynamicCast<SGPHost>();
110-
std::string host_matching_tasks = (sgp_config->TRACK_PARENT_TASKS()) ?
111-
host->GetCPU().state.parent_tasks_performed->ToBinaryString() :
112-
host->GetCPU().state.tasks_performed->ToBinaryString();
129+
std::string host_matching_tasks = host->GetCPU().state.parent_tasks_performed->ToBinaryString();
113130
if (emp::Has(matching_task_counts, host_matching_tasks)) {
114131
matching_task_counts[host_matching_tasks][0]++;
115132
}
@@ -119,9 +136,7 @@ void SGPWorld::WriteTaskCombinationsFile(const std::string& filename) {
119136
}
120137
emp::vector<emp::Ptr<Organism>> syms = host->GetSymbionts();
121138
for (size_t j = 0; j < syms.size(); j++) {
122-
std::string sym_matching_tasks = (sgp_config->TRACK_PARENT_TASKS()) ?
123-
syms[j].DynamicCast<SGPSymbiont>()->GetCPU().state.parent_tasks_performed->ToBinaryString() :
124-
syms[j].DynamicCast<SGPSymbiont>()->GetCPU().state.tasks_performed->ToBinaryString();
139+
std::string sym_matching_tasks = syms[j].DynamicCast<SGPSymbiont>()->GetCPU().state.parent_tasks_performed->ToBinaryString();
125140
if (emp::Has(matching_task_counts, sym_matching_tasks)) {
126141
matching_task_counts[sym_matching_tasks][1]++;
127142
}
@@ -247,4 +262,35 @@ emp::DataMonitor<int> &SGPWorld::GetDonateCount() {
247262
return *data_node_donate_count;
248263
}
249264

265+
/**
266+
* Input: None
267+
*
268+
* Output: A reference to the data node storing the count of
269+
* stress escapee offspring (successful or not)
270+
*
271+
* Purpose: To set up and return the data node storing the count
272+
* of attempted stress escapee offspring
273+
*/
274+
emp::DataMonitor<size_t>& SGPWorld::GetStressEscapeeOffspringAttemptCount() {
275+
if (!data_node_stress_escapee_offspring_attempt_count) {
276+
data_node_stress_escapee_offspring_attempt_count.New();
277+
}
278+
return *data_node_stress_escapee_offspring_attempt_count;
279+
}
280+
281+
/**
282+
* Input: None
283+
*
284+
* Output: A reference to the data node storing the count of successful
285+
* stress escapee offspring
286+
*
287+
* Purpose: To set up and return the data node storing the count
288+
* of successful stress escapee offspring
289+
*/
290+
emp::DataMonitor<size_t>& SGPWorld::GetStressEscapeeOffspringSuccessCount() {
291+
if (!data_node_stress_escapee_offspring_success_count) {
292+
data_node_stress_escapee_offspring_success_count.New();
293+
}
294+
return *data_node_stress_escapee_offspring_success_count;
295+
}
250296
#endif

source/sgp_mode/SGPHost.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ emp::Ptr<Organism> SGPHost::Reproduce() {
1717
host_baby->SetReproCount(reproductions + 1);
1818
// This organism is reproducing, so it must have gotten off the queue
1919
cpu.state.in_progress_repro = -1;
20-
if (sgp_config->TRACK_PARENT_TASKS()) {
21-
host_baby->GetCPU().state.parent_tasks_performed->Import(*GetCPU().state.tasks_performed);
2220

21+
host_baby->GetCPU().state.parent_tasks_performed->Import(*GetCPU().state.tasks_performed);
22+
if (sgp_config->TRACK_PARENT_TASKS()) {
2323
for (int i = 0; i < CPU_BITSET_LENGTH; i++) {
2424
host_baby->GetCPU().state.task_change_lose[i] = cpu.state.task_change_lose[i];
2525
host_baby->GetCPU().state.task_change_gain[i] = cpu.state.task_change_gain[i];

source/sgp_mode/SGPSymbiont.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ class SGPSymbiont : public Symbiont {
201201
sym_baby->SetReproCount(reproductions + 1);
202202
// This organism is reproducing, so it must have gotten off the queue
203203
cpu.state.in_progress_repro = -1;
204+
sym_baby->GetCPU().state.parent_tasks_performed->Import(*GetCPU().state.tasks_performed);
204205
if (sgp_config->TRACK_PARENT_TASKS()) {
205-
sym_baby->GetCPU().state.parent_tasks_performed->Import(*GetCPU().state.tasks_performed);
206206
//inherit towards-from tracking
207207
for (int i = 0; i < CPU_BITSET_LENGTH; i++) {
208208

source/sgp_mode/SGPWorld.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
struct StressEscapeeOffspring{
1111
emp::Ptr<Organism> escapee_offspring;
1212
size_t parent_pos;
13-
emp::BitSet<CPU_BITSET_LENGTH> infection_tasks;
13+
const emp::BitSet<CPU_BITSET_LENGTH> infection_tasks;
1414

1515
StressEscapeeOffspring(
1616
emp::Ptr<Organism> sym,
1717
size_t loc,
18-
emp::BitSet<CPU_BITSET_LENGTH> _tasks
18+
const emp::BitSet<CPU_BITSET_LENGTH> _tasks
1919
) :
2020
escapee_offspring(sym),
2121
parent_pos(loc),
@@ -30,6 +30,8 @@ class SGPWorld : public SymWorld {
3030

3131
emp::Ptr<emp::DataMonitor<int>> data_node_steal_count;
3232
emp::Ptr<emp::DataMonitor<int>> data_node_donate_count;
33+
emp::Ptr<emp::DataMonitor<size_t>> data_node_stress_escapee_offspring_attempt_count;
34+
emp::Ptr<emp::DataMonitor<size_t>> data_node_stress_escapee_offspring_success_count;
3335
emp::vector<emp::DataMonitor<size_t>> data_node_host_tasks;
3436
emp::vector<emp::DataMonitor<size_t>> data_node_sym_tasks;
3537

@@ -45,7 +47,7 @@ class SGPWorld : public SymWorld {
4547
emp::vector<StressEscapeeOffspring> symbiont_stress_escapee_offspring;
4648

4749
// The task profile retriever function
48-
std::function< emp::BitSet<CPU_BITSET_LENGTH>& (const emp::Ptr<Organism>)> fun_get_task_profile;
50+
std::function<const emp::BitSet<CPU_BITSET_LENGTH>& (const emp::Ptr<Organism>)> fun_get_task_profile;
4951

5052
SGPWorld(emp::Random &r, emp::Ptr<SymConfigSGP> _config, TaskSet task_set)
5153
: SymWorld(r, _config),
@@ -59,6 +61,8 @@ class SGPWorld : public SymWorld {
5961
// data node deletes
6062
if (data_node_steal_count) data_node_steal_count.Delete();
6163
if (data_node_donate_count) data_node_donate_count.Delete();
64+
if (data_node_stress_escapee_offspring_attempt_count) data_node_stress_escapee_offspring_attempt_count.Delete();
65+
if (data_node_stress_escapee_offspring_success_count) data_node_stress_escapee_offspring_success_count.Delete();
6266

6367
// The vectors will delete themselves automatically
6468
for (auto escapee_data : symbiont_stress_escapee_offspring) {
@@ -138,12 +142,12 @@ class SGPWorld : public SymWorld {
138142

139143
// Prototypes for reproduction handling methods
140144
emp::WorldPosition SymDoBirth(emp::Ptr<Organism> sym_baby, emp::WorldPosition parent_pos) override;
141-
int GetNeighborHost(size_t source_id, emp::BitSet<CPU_BITSET_LENGTH>& symbiont_tasks);
142-
bool TaskMatchCheck(emp::BitSet<CPU_BITSET_LENGTH>& symbiont_tasks, emp::BitSet<CPU_BITSET_LENGTH>& host_tasks);
143-
bool PreferentialOustingAllowed(emp::BitSet<CPU_BITSET_LENGTH>& incoming_sym_tasks, emp::Ptr<Organism> host);
145+
int GetNeighborHost(size_t source_id, const emp::BitSet<CPU_BITSET_LENGTH>& symbiont_tasks);
146+
bool TaskMatchCheck(const emp::BitSet<CPU_BITSET_LENGTH>& symbiont_tasks, const emp::BitSet<CPU_BITSET_LENGTH>& host_tasks);
147+
bool PreferentialOustingAllowed(const emp::BitSet<CPU_BITSET_LENGTH>& incoming_sym_tasks, emp::Ptr<Organism> host);
144148

145149
// Prototypes for symbiont placement
146-
emp::WorldPosition PlaceSymbiontInHost(emp::Ptr<Organism> symbiont, emp::BitSet<CPU_BITSET_LENGTH>& symbiont_infection_tasks, size_t source_pos);
150+
emp::WorldPosition PlaceSymbiontInHost(emp::Ptr<Organism> symbiont, const emp::BitSet<CPU_BITSET_LENGTH>& symbiont_infection_tasks, size_t source_pos);
147151

148152
// Prototypes for sym transferring
149153
emp::WorldPosition SymFindHost(emp::Ptr<Organism> symbiont, emp::WorldPosition cur_pos);
@@ -155,13 +159,15 @@ class SGPWorld : public SymWorld {
155159
// Prototypes for data node methods
156160
emp::DataMonitor<int> &GetStealCount();
157161
emp::DataMonitor<int> &GetDonateCount();
162+
emp::DataMonitor<size_t>& GetStressEscapeeOffspringAttemptCount();
163+
emp::DataMonitor<size_t>& GetStressEscapeeOffspringSuccessCount();
158164

159165
void SetupTasksNodes();
160166

161167
emp::DataFile &SetUpOrgCountFile(const std::string &filename);
162168
emp::DataFile &SetupSymInstFile(const std::string &filename);
163-
164169
emp::DataFile &SetupTasksFile(const std::string &filename);
170+
void SetupTransmissionFileColumns(emp::DataFile& file);
165171
void WriteTaskCombinationsFile(const std::string& filename);
166172
void WriteOrgReproHistFile(const std::string& filename);
167173

source/sgp_mode/SGPWorldSetup.cc

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void SGPWorld::SetupSymbionts(unsigned long *total_syms) {
6565
*/
6666
void SGPWorld::SetupTaskProfileFun() {
6767
if (sgp_config->TRACK_PARENT_TASKS()) {
68-
fun_get_task_profile = [](const emp::Ptr<Organism> org) -> emp::BitSet<CPU_BITSET_LENGTH>&{
68+
fun_get_task_profile = [](const emp::Ptr<Organism> org) -> const emp::BitSet<CPU_BITSET_LENGTH>&{
6969
if (org->IsHost()) {
7070
return *org.DynamicCast<SGPHost>()->GetCPU().state.parent_tasks_performed;
7171
}
@@ -147,7 +147,7 @@ void SGPWorld::ProcessReproductionQueue() {
147147
*
148148
* Purpose: Searches through up to 10 hosts in the world to find a host that the symbiont can infect.
149149
*/
150-
int SGPWorld::GetNeighborHost (size_t source_id, emp::BitSet<CPU_BITSET_LENGTH>& symbiont_tasks){
150+
int SGPWorld::GetNeighborHost (size_t source_id, const emp::BitSet<CPU_BITSET_LENGTH>& symbiont_tasks){
151151
// Attempt to find host that matches some tasks
152152
for (int i = 0; i < 10; i++) {
153153
emp::WorldPosition neighbor = GetRandomNeighborPos(source_id);
@@ -170,7 +170,7 @@ int SGPWorld::GetNeighborHost (size_t source_id, emp::BitSet<CPU_BITSET_LENGTH>&
170170
*
171171
* Purpose: To check for task matching before transmission
172172
*/
173-
bool SGPWorld::TaskMatchCheck(emp::BitSet<CPU_BITSET_LENGTH>& symbiont_tasks, emp::BitSet<CPU_BITSET_LENGTH>& host_tasks) {
173+
bool SGPWorld::TaskMatchCheck(const emp::BitSet<CPU_BITSET_LENGTH>& symbiont_tasks, const emp::BitSet<CPU_BITSET_LENGTH>& host_tasks) {
174174
if (sgp_config->INTERACTION_MECHANISM() == NUTRIENT) {
175175
return true;
176176
}
@@ -230,10 +230,15 @@ emp::WorldPosition SGPWorld::SymDoBirth(emp::Ptr<Organism> sym_baby, emp::WorldP
230230
std::iota(e.begin(), e.end(), 0);
231231
emp::Shuffle(*random_ptr, e);
232232

233+
emp::DataMonitor<size_t>& escapee_sucess_data_node = GetStressEscapeeOffspringSuccessCount();
234+
233235
for (size_t escapee_i : e) {
234236
StressEscapeeOffspring& escapee_data = symbiont_stress_escapee_offspring[escapee_i];
235237
// TODO:stress escape data nodes
236-
PlaceSymbiontInHost(escapee_data.escapee_offspring, escapee_data.infection_tasks, escapee_data.parent_pos);
238+
emp::WorldPosition new_pos = PlaceSymbiontInHost(escapee_data.escapee_offspring, escapee_data.infection_tasks, escapee_data.parent_pos);
239+
if (new_pos.IsValid()) {
240+
escapee_sucess_data_node.AddDatum(1);
241+
}
237242
}
238243

239244
symbiont_stress_escapee_offspring.clear();
@@ -246,11 +251,11 @@ emp::WorldPosition SGPWorld::SymDoBirth(emp::Ptr<Organism> sym_baby, emp::WorldP
246251
*
247252
* Purpose: Calculate preferential ousting success
248253
*/
249-
bool SGPWorld::PreferentialOustingAllowed(emp::BitSet<CPU_BITSET_LENGTH>& incoming_sym_tasks, emp::Ptr<Organism> host){
250-
emp::BitSet<CPU_BITSET_LENGTH>& host_tasks = fun_get_task_profile(host);
254+
bool SGPWorld::PreferentialOustingAllowed(const emp::BitSet<CPU_BITSET_LENGTH>& incoming_sym_tasks, emp::Ptr<Organism> host){
255+
const emp::BitSet<CPU_BITSET_LENGTH>& host_tasks = fun_get_task_profile(host);
251256

252257
for(emp::Ptr<Organism> sym : host->GetSymbionts()){
253-
emp::BitSet<CPU_BITSET_LENGTH>& target_sym_tasks = fun_get_task_profile(sym);
258+
const emp::BitSet<CPU_BITSET_LENGTH>& target_sym_tasks = fun_get_task_profile(sym);
254259

255260
if(sgp_config->PREFERENTIAL_OUSTING() == 1){
256261
// if has worse task match with any hosted sym, fail
@@ -276,7 +281,7 @@ emp::WorldPosition SGPWorld::SymDoBirth(emp::Ptr<Organism> sym_baby, emp::WorldP
276281
*
277282
* Purpose: Place a symbiont based on the passed task set
278283
*/
279-
emp::WorldPosition SGPWorld::PlaceSymbiontInHost(emp::Ptr<Organism> symbiont, emp::BitSet<CPU_BITSET_LENGTH>& symbiont_infection_tasks, size_t source_pos) {
284+
emp::WorldPosition SGPWorld::PlaceSymbiontInHost(emp::Ptr<Organism> symbiont, const emp::BitSet<CPU_BITSET_LENGTH>& symbiont_infection_tasks, size_t source_pos) {
280285
int new_host_pos = GetNeighborHost(source_pos, symbiont_infection_tasks);
281286
if (new_host_pos > -1) { //-1 means no living neighbors
282287
if (sgp_config->OUSTING() && sgp_config->PREFERENTIAL_OUSTING() && (int)pop[new_host_pos]->GetSymbionts().size() == sgp_config->SYM_LIMIT()) {

source/sgp_mode/StressHost.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,9 @@ class StressHost : public SGPHost {
103103
}
104104
else if (sgp_config->SYMBIONT_TYPE() == PARASITE && sgp_config->PARASITE_NUM_OFFSPRING_ON_STRESS_INTERACTION() > 0) {
105105
for (size_t j = 0; j < syms.size(); j++) {
106-
emp::BitSet<CPU_BITSET_LENGTH>& sym_infection_tasks = my_world->fun_get_task_profile(syms[j]);
106+
const emp::BitSet<CPU_BITSET_LENGTH>& sym_infection_tasks = my_world->fun_get_task_profile(syms[j]);
107107
if (my_world->TaskMatchCheck(sym_infection_tasks, my_world->fun_get_task_profile(this))) {
108+
my_world->GetStressEscapeeOffspringAttemptCount().AddDatum(sgp_config->PARASITE_NUM_OFFSPRING_ON_STRESS_INTERACTION());
108109
for (size_t k = 0; k < sgp_config->PARASITE_NUM_OFFSPRING_ON_STRESS_INTERACTION(); k++) {
109110
my_world->symbiont_stress_escapee_offspring.emplace_back(StressEscapeeOffspring(syms[j]->Reproduce(), pos.GetIndex(), sym_infection_tasks));
110111
}

0 commit comments

Comments
 (0)