Skip to content

Commit 8f690e7

Browse files
committed
moved to SymDoBirth() and streamlined horizontal_trans_compatibility_check_functions
1 parent eda7289 commit 8f690e7

4 files changed

Lines changed: 26 additions & 74 deletions

File tree

source/sgp_mode/DevNotes.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* Move ProcessSymOutputBuffer into SGPSymbiont to parallel host
66
* Move SymDoMutation into SGPSymbiont to parallel host
77
* Look at whether can move SymDonateToHost and SymStealFromHost into SGPSym
8-
* Look at fun_host_sym_stress_trans_compatibility_check to try to reduce code duplication of task-profile setups, possibly with decorator pattern, but also definitely just in own file
98
* Move world properties back into protected and make necessary accesssors
109
* Rename "SetReproCount" to lineage length since it's confusing (or did I already?)
1110
* Look into what is going on with SGPHost local sgp_config not working
@@ -31,6 +30,8 @@
3130
- Decisions made: reproduce is shared between horizontal transmission and free-living sym reproduction. If free-living sym repro is on, then reproduce places offspring into sym pop (like in default), and then offspring can infect with Infect instruction (not yet implemented). If FLS is off, reproduce does horizontal transmission. Also decided that if HT is off, an "attempt" is not counted.
3231
[x] Try to fold ProcessStressEscapees into existing code/reduce duplication
3332
- Initially we attempted to turn ReproductionQueue into a birth queue, however this hurts performance. ReproductionQueue will skip organisms who have died and therefore should not reproduce before Reproduce() is called. With a birth queue, the children would already be constructed. This uses more memory and wastes resources on construction. Instead ProcessStressEscapees was moved into a signal.
33+
[x] Look at fun_host_sym_stress_trans_compatibility_check to try to reduce code duplication of task-profile setups, possibly with decorator pattern, but also definitely just in own file
34+
- Completed with above refactor. Now does not rely on parents as they may be dead at the time of reproduction (stress escapees). This change allowed processing escapees to be streamlined
3435

3536
# Journal
3637
4/15/26

source/sgp_mode/SGPW_InteractionMechanismSetup.cc

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ namespace sgpmode {
220220
struct StressEscapee {
221221
emp::Ptr<SGPWorld::sgp_sym_t> sym_offspring;
222222
emp::BitVector parent_task_profile;
223+
//^^^ why are we keeping track of this and not using sym profile?
223224
size_t escape_location;
224225

225226
StressEscapee() = default;
@@ -466,7 +467,6 @@ namespace sgpmode {
466467
exit(-1);
467468
}
468469

469-
// GABE TODO might want to put in a seperate function?
470470
after_reproduction_sig.AddAction(
471471
[this]() {
472472
// Process escapees in random order (to avoid strongly favoring all offspring from "late" escapee)
@@ -481,27 +481,10 @@ namespace sgpmode {
481481

482482
for (size_t esc_i : escapee_ids) {
483483
auto& escapee_info = symbiont_stress_escapees[esc_i];
484-
bool success = false;
485-
for (size_t attempt_i = 0; attempt_i < sgp_config.FIND_NEIGHBOR_HOST_ATTEMPTS(); ++attempt_i) {
486-
//test a possible location
487-
emp::WorldPosition candidate_pos(GetRandomNeighborPos(escapee_info.escape_location));
488-
if (candidate_pos.IsValid() && IsOccupied(candidate_pos)) {
489-
490-
emp::Ptr<Organism> prospective_org_ptr = GetOrgPtr(candidate_pos.GetIndex());
491-
emp_assert(prospective_org_ptr->IsHost());
492-
emp::Ptr<sgp_host_t> prospective_host_ptr = static_cast<sgp_host_t*>(prospective_org_ptr.Raw());
493-
494-
const bool can_infect = fun_host_sym_stress_trans_compatibility_check(
495-
*prospective_host_ptr,
496-
escapee_info.parent_task_profile
497-
);
498-
if (!can_infect) continue;
499-
prospective_host_ptr->AddSymbiont(escapee_info.sym_offspring);
500-
success = true;
501-
break;
502-
}
503-
}
504-
if (!success) {
484+
485+
emp::WorldPosition pos = SymDoBirth(escapee_info.sym_offspring, escapee_info.escape_location);
486+
487+
if (pos) {
505488
escapee_info.sym_offspring.Delete();
506489
}
507490
}

source/sgp_mode/SGPW_TaskProfileSetup.cc

Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -85,57 +85,31 @@ void SGPWorld::SetupTaskProfileCompatibilityMode() {
8585
void SGPWorld::SetupHorizontalTransmissionCompatibilityMode() {
8686
// Setup function that determines horizontal transmission compatibility based on task profiles
8787
if (sgp_config.HORIZONTAL_TRANSMISSION_COMPATIBILITY_MODE() == "always") {
88-
fun_host_sym_horizontal_trans_compatibility_check = [](
88+
fun_horizontal_trans_compatibility_check = [](
8989
sgp_host_t& host,
90-
sgp_sym_t& sym
91-
) -> bool { return true; };
92-
fun_host_sym_stress_trans_compatibility_check = [](
93-
sgp_host_t& host,
94-
const emp::BitVector& profile
90+
const emp::BitVector& sym_profile
9591
) -> bool { return true; };
9692
} else if (sgp_config.HORIZONTAL_TRANSMISSION_COMPATIBILITY_MODE() == "task-profile-compatible") {
97-
fun_host_sym_horizontal_trans_compatibility_check = [this](
93+
fun_horizontal_trans_compatibility_check = [this](
9894
sgp_host_t& host,
99-
sgp_sym_t& sym
95+
const emp::BitVector& sym_profile
10096
) -> bool {
10197
const auto& host_profile = fun_get_host_task_profile(host);
102-
const auto& sym_profile = fun_get_sym_task_profile(sym);
10398
return fun_task_profile_compatibility_check(host_profile, sym_profile);
10499
};
105-
fun_host_sym_stress_trans_compatibility_check = [this](
106-
sgp_host_t& host,
107-
const emp::BitVector& profile
108-
) -> bool {
109-
const auto& host_profile = fun_get_host_task_profile(host);
110-
return fun_task_profile_compatibility_check(host_profile, profile);
111-
};
112100
} else if (sgp_config.HORIZONTAL_TRANSMISSION_COMPATIBILITY_MODE() == "task-profile-strictly-stronger-match") {
113-
fun_host_sym_horizontal_trans_compatibility_check = [this](
101+
fun_horizontal_trans_compatibility_check = [this](
114102
sgp_host_t& host,
115-
sgp_sym_t& sym
103+
const emp::BitVector& sym_profile
116104
) -> bool {
117-
const emp::BitVector& incoming_sym_task_profile = fun_get_sym_task_profile(sym);
118-
return NoBetterOrEquallyMatchingSymbionts(host, incoming_sym_task_profile);
119-
};
120-
fun_host_sym_stress_trans_compatibility_check = [this](
121-
sgp_host_t& host,
122-
const emp::BitVector& profile
123-
) -> bool {
124-
return NoBetterOrEquallyMatchingSymbionts(host, profile);
105+
return NoBetterOrEquallyMatchingSymbionts(host, sym_profile);
125106
};
126107
} else if (sgp_config.HORIZONTAL_TRANSMISSION_COMPATIBILITY_MODE() == "task-profile-stronger-or-equal-match") {
127-
fun_host_sym_horizontal_trans_compatibility_check = [this](
128-
sgp_host_t& host,
129-
sgp_sym_t& sym
130-
) -> bool {
131-
const emp::BitVector& incoming_sym_task_profile = fun_get_sym_task_profile(sym);
132-
return NoBetterMatchingSymbionts(host, incoming_sym_task_profile);
133-
};
134-
fun_host_sym_stress_trans_compatibility_check = [this](
108+
fun_horizontal_trans_compatibility_check = [this](
135109
sgp_host_t& host,
136-
const emp::BitVector& profile
110+
const emp::BitVector& sym_profile
137111
) -> bool {
138-
return NoBetterMatchingSymbionts(host, profile);
112+
return NoBetterMatchingSymbionts(host, sym_profile);
139113
};
140114
} else {
141115
std::cout << "Unrecognized HORIZONTAL_TRANSMISSION_COMPATIBILITY_MODE: " << sgp_config.HORIZONTAL_TRANSMISSION_COMPATIBILITY_MODE() << std::endl;
@@ -146,7 +120,6 @@ void SGPWorld::SetupHorizontalTransmissionCompatibilityMode() {
146120

147121
void SGPWorld::SetupFindHostForHorizontalTransmission() {
148122
// Setup function that gets host neighbor (used for symbiont)
149-
// Excludes current host, since they really shouldn't be considered a neighbor
150123
// TODO - add different configuration options for this?
151124
fun_find_host_for_horizontal_trans = [this](
152125
size_t host_world_id, /* Parent's host location id in world (pops[0][id])*/
@@ -155,14 +128,15 @@ void SGPWorld::SetupFindHostForHorizontalTransmission() {
155128
for (size_t attempt_i = 0; attempt_i < sgp_config.FIND_NEIGHBOR_HOST_ATTEMPTS(); ++attempt_i) {
156129
emp::WorldPosition candidate_pos(GetRandomNeighborPos(host_world_id));
157130
if (candidate_pos.IsValid() && IsOccupied(candidate_pos) && candidate_pos.GetIndex() != host_world_id) {
158-
emp::Ptr<Organism> neighbor_org_ptr = GetOrgPtr(candidate_pos.GetIndex());
159-
emp_assert(neighbor_org_ptr->IsHost());
131+
emp::Ptr<Organism> prospective_org_ptr = GetOrgPtr(candidate_pos.GetIndex());
132+
emp_assert(prospective_org_ptr->IsHost());
160133
// Cast neighbor as sgp_host_t ptr.
161-
emp::Ptr<sgp_host_t> neighbor_host_ptr = static_cast<sgp_host_t*>(neighbor_org_ptr.Raw());
134+
emp::Ptr<sgp_host_t> prospective_host_ptr = static_cast<sgp_host_t*>(prospective_org_ptr.Raw());
135+
const emp::BitVector& endosym_task_profile = fun_get_sym_task_profile(*sym_parent_ptr);
162136
//TODO: Should this check be done during AddSymbiont instead of here?
163-
const bool compatible = fun_host_sym_horizontal_trans_compatibility_check(
164-
*neighbor_host_ptr,
165-
*sym_parent_ptr
137+
const bool compatible = fun_horizontal_trans_compatibility_check(
138+
*prospective_host_ptr,
139+
endosym_task_profile
166140
);
167141
if (compatible) {
168142
return std::optional<emp::WorldPosition>{candidate_pos};

source/sgp_mode/SGPWorld.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class SGPWorld : public SymWorld {
6666
// NOTE: arguments can't be const because necessary Host.h/Organism.h functions aren't const
6767
using fun_horizontal_transmission_compatibility_check_t = std::function<bool(
6868
sgp_host_t&,
69-
sgp_sym_t&
69+
const emp::BitVector&
7070
)>;
7171

7272
// Determines whether two task profiles are "compatible" with one another.
@@ -430,13 +430,7 @@ class SGPWorld : public SymWorld {
430430

431431
// Function to check compatibility between host and symbiont
432432
// - Used to check eligibility for vertical / horizontal transmission, etc.
433-
fun_horizontal_transmission_compatibility_check_t fun_host_sym_horizontal_trans_compatibility_check;
434-
435-
// Function used to check compatibility between host and symbiont that reproduced
436-
// via a stress event.
437-
// - Can't use same function as when checking horizontal transmission compatibility because
438-
// we no longer have access to the symbiont parent for a stress transmission event.
439-
std::function<bool(sgp_host_t&, const emp::BitVector&)> fun_host_sym_stress_trans_compatibility_check;
433+
fun_horizontal_transmission_compatibility_check_t fun_horizontal_trans_compatibility_check;
440434

441435
fun_task_profile_compatibility_t fun_task_profile_compatibility_check;
442436

0 commit comments

Comments
 (0)