Program Listing for File Phage.h¶
↰ Return to documentation for file (source/lysis_mode/Phage.h
)
#ifndef PHAGE_H
#define PHAGE_H
#include "../default_mode/Symbiont.h"
#include "LysisWorld.h"
class Phage: public Symbiont {
protected:
double burst_timer = 0;
bool lysogeny = false;
double incorporation_val = 0.0;
double chance_of_lysis = 1;
double induction_chance = 1;
emp::Ptr<LysisWorld> my_world = NULL;
public:
Phage(emp::Ptr<emp::Random> _random, emp::Ptr<LysisWorld> _world, emp::Ptr<SymConfigBase> _config, double _intval=0.0, double _points = 0.0) : Symbiont(_random, _world, _config, _intval, _points) {
chance_of_lysis = my_config->LYSIS_CHANCE();
induction_chance = my_config->CHANCE_OF_INDUCTION();
incorporation_val = my_config->PHAGE_INC_VAL();
if(chance_of_lysis == -1){
chance_of_lysis = random->GetDouble(0.0, 1.0);
}
if(induction_chance == -1){
induction_chance = random->GetDouble(0.0, 1.0);
}
if(incorporation_val == -1){
incorporation_val = random->GetDouble(0.0, 1.0);
}
my_world = _world;
}
Phage(const Phage &) = default;
Phage(Phage &&) = default;
Phage() = default;
std::string const GetName() {
return "Phage";
}
double GetBurstTimer() {return burst_timer;}
void IncBurstTimer() {burst_timer += random->GetRandNormal(1.0, 1.0);}
void SetBurstTimer(double _in) {burst_timer = _in;}
double GetLysisChance() {return chance_of_lysis;}
void SetLysisChance(double _in) {chance_of_lysis = _in;}
double GetIncVal() {return incorporation_val;}
void SetIncVal(double _in) {incorporation_val = _in;}
double GetInductionChance() {return induction_chance;}
void SetInductionChance(double _in) {induction_chance = _in;}
bool GetLysogeny() {return lysogeny;}
bool IsPhage() {return true;}
void UponInjection() {
double rand_chance = random->GetDouble(0.0, 1.0);
if (rand_chance <= chance_of_lysis){
lysogeny = false;
} else {
lysogeny = true;
}
}
void Mutate() {
Symbiont::Mutate();
double local_rate = my_config->MUTATION_RATE();
double local_size = my_config->MUTATION_SIZE();
if (random->GetDouble(0.0, 1.0) <= local_rate) {
//mutate chance of lysis/lysogeny, if enabled
if(my_config->MUTATE_LYSIS_CHANCE()){
chance_of_lysis += random->GetRandNormal(0.0, local_size);
if(chance_of_lysis < 0) chance_of_lysis = 0;
else if (chance_of_lysis > 1) chance_of_lysis = 1;
}
if(my_config->MUTATE_INDUCTION_CHANCE()){
induction_chance += random->GetRandNormal(0.0, local_size);
if(induction_chance < 0) induction_chance = 0;
else if (induction_chance > 1) induction_chance = 1;
}
if(my_config->MUTATE_INC_VAL()){
incorporation_val += random->GetRandNormal(0.0, local_size);
if(incorporation_val < 0) incorporation_val = 0;
else if (incorporation_val > 1) incorporation_val = 1;
}
}
}
emp::Ptr<Organism> MakeNew() {
emp::Ptr<Phage> sym_baby = emp::NewPtr<Phage>(random, my_world, my_config, GetIntVal());
// pass down parent's genome
sym_baby->SetIncVal(GetIncVal());
sym_baby->SetLysisChance(GetLysisChance());
sym_baby->SetInductionChance(GetInductionChance());
sym_baby->SetInfectionChance(GetInfectionChance());
return sym_baby;
}
void LysisBurst(emp::WorldPosition location){
emp::vector<emp::Ptr<Organism>>& repro_syms = my_host->GetReproSymbionts();
//Record the burst size and count
emp::DataMonitor<double>& data_node_burst_size = my_world->GetBurstSizeDataNode();
data_node_burst_size.AddDatum(repro_syms.size());
emp::DataMonitor<int>& data_node_burst_count = my_world->GetBurstCountDataNode();
data_node_burst_count.AddDatum(1);
emp::DataMonitor<int>& data_node_attempts_horiztrans = my_world->GetHorizontalTransmissionAttemptCount();
emp::DataMonitor<int>& data_node_successes_horiztrans = my_world->GetHorizontalTransmissionSuccessCount();
for(size_t r=0; r<repro_syms.size(); r++) {
emp::WorldPosition new_pos = my_world->SymDoBirth(repro_syms[r], location);
//horizontal transmission data nodes
data_node_attempts_horiztrans.AddDatum(1);
if(new_pos.IsValid()){
data_node_successes_horiztrans.AddDatum(1);
}
}
my_host->ClearReproSyms();
my_host->SetDead();
return;
}
void LysisStep(){
IncBurstTimer();
if(my_config->SYM_LYSIS_RES() == 0) {
std::cout << "Lysis with a sym_lysis_res of 0 leads to an \
infinite loop, please change" << std::endl;
std::exit(1);
}
while(GetPoints() >= my_config->SYM_LYSIS_RES()) {
emp::Ptr<Organism> sym_baby = Reproduce();
my_host->AddReproSym(sym_baby);
SetPoints(GetPoints() - my_config->SYM_LYSIS_RES());
}
}
void VerticalTransmission(emp::Ptr<Organism> host_baby){
//lysogenic phage have 100% chance of vertical transmission, lytic phage have 0% chance
if(lysogeny){
emp::Ptr<Organism> phage_baby = Reproduce();
host_baby->AddSymbiont(phage_baby);
//vertical transmission data node
emp::DataMonitor<int>& data_node_attempts_verttrans = my_world->GetVerticalTransmissionAttemptCount();
data_node_attempts_verttrans.AddDatum(1);
}
}
double ProcessResources(double host_donation, emp::Ptr<Organism> host = nullptr){
if(host == nullptr){
host = my_host;
}
if(lysogeny){
if(my_config->BENEFIT_TO_HOST()){
return host->ProcessLysogenResources(incorporation_val);
} else{
return 0;
}
}
else{
return Symbiont::ProcessResources(host_donation, host); //lytic phage do steal resources
}
}
void Process(emp::WorldPosition location) {
if(my_config->LYSIS() && !GetHost().IsNull()) { //lysis enabled and phage is in a host
if(!lysogeny){ //phage has chosen lysis
if(GetBurstTimer() >= my_config->BURST_TIME() ) { //time to lyse!
LysisBurst(location);
}
else { //not time to lyse
LysisStep();
}
}
else if(lysogeny){ //phage has chosen lysogeny
double rand_chance = random->GetDouble(0.0, 1.0);
if (rand_chance <= induction_chance){//phage has chosen to induce and turn lytic
lysogeny = false;
}
else if(random->GetDouble(0.0, 1.0) <= my_config->PROPHAGE_LOSS_RATE()){ //check if the phage's host should become susceptible again
SetDead();
}
}
}
else if (GetHost().IsNull() && my_config->FREE_LIVING_SYMS()) { //phage is free living
my_world->MoveFreeSym(location);
}
}
};
#endif