Program Listing for File EfficientSymbiont.h

Return to documentation for file (source/efficient_mode/EfficientSymbiont.h)

#ifndef EFFSYM_H
#define EFFSYM_H

#include "../default_mode/Symbiont.h"
#include "EfficientWorld.h"
#include "EfficientHost.h"



class EfficientSymbiont: public Symbiont {
protected:

  double efficiency;

  double ht_mut_size = 0.002;

  double ht_mut_rate = 0;

  double eff_mut_rate = 0;

  emp::Ptr<EfficientWorld> my_world = NULL;
public:
  EfficientSymbiont(emp::Ptr<emp::Random> _random, emp::Ptr<EfficientWorld> _world, emp::Ptr<SymConfigBase> _config, double _intval=0.0, double _points = 0.0, double _efficient = 0.1) : Symbiont(_random, _world, _config, _intval, _points) {
    efficiency = _efficient;
    my_world = _world;
    if(my_config->HORIZ_MUTATION_RATE() < 0){
      ht_mut_rate = my_config->MUTATION_RATE();
    } else {
      ht_mut_rate = my_config->HORIZ_MUTATION_RATE();
    }
    if(my_config->HORIZ_MUTATION_SIZE() < 0) {
      ht_mut_size = my_config->MUTATION_SIZE();
    } else {
      ht_mut_size = my_config->HORIZ_MUTATION_SIZE();
    }
  }


  EfficientSymbiont(const EfficientSymbiont &) = default;


  EfficientSymbiont(EfficientSymbiont &&) = default;


  EfficientSymbiont() = default;

  std::string const GetName() {
    return  "EfficientSymbiont";
  }

  void SetEfficiency(double _in) {
    if(_in > 1 || _in < 0) throw "Invalid efficiency chance. Must be between 0 and 1 (inclusive)";
    efficiency = _in;
  }

  double GetEfficiency() {return efficiency;}


  void AddPoints(double _in) {points += (_in * efficiency);}


  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Woverloaded-virtual"
  void Mutate(std::string mode){
    double local_size;
    double local_rate;
    double int_rate;

    if(mode == "vertical"){
      local_rate = my_config->MUTATION_RATE();
      local_size = my_config->MUTATION_SIZE();
    } else if(mode == "horizontal") {
      local_rate = ht_mut_rate;
      local_size = ht_mut_size;
    } else {
      throw "Illegal argument passed to mutate in EfficientSymbiont";
    }

    if(my_config->EFFICIENCY_MUT_RATE() >= 0) {
      eff_mut_rate = my_config->EFFICIENCY_MUT_RATE();
    } else {
      eff_mut_rate = local_rate;
    }

    if(my_config->INT_VAL_MUT_RATE() >= 0) {
      int_rate = my_config->INT_VAL_MUT_RATE();
    } else {
      int_rate = local_rate;
    }

    if (random->GetDouble(0.0, 1.0) <= int_rate) {
      interaction_val += random->GetRandNormal(0.0, local_size);
      if(interaction_val < -1) interaction_val = -1;
      else if (interaction_val > 1) interaction_val = 1;

      //also modify infection chance, which is between 0 and 1
      if(my_config->FREE_LIVING_SYMS()){
        infection_chance += random->GetRandNormal(0.0, local_size);
        if (infection_chance < 0) infection_chance = 0;
        else if (infection_chance > 1) infection_chance = 1;
      }
    }
    if (random->GetDouble(0.0, 1.0) <= eff_mut_rate) {
      efficiency += random->GetRandNormal(0.0, local_size);
      if(efficiency < 0) efficiency = 0;
      else if (efficiency > 1) efficiency = 1;
    }
  }
  #pragma clang diagnostic pop



  emp::Ptr<Organism> MakeNew(){
    emp::Ptr<EfficientSymbiont> sym_baby = emp::NewPtr<EfficientSymbiont>(random, my_world, my_config, GetIntVal());
    sym_baby->SetInfectionChance(GetInfectionChance());
    sym_baby->SetEfficiency(GetEfficiency());
    return sym_baby;
  }

  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Woverloaded-virtual"
  emp::Ptr<Organism> Reproduce(std::string mode) {
    emp::Ptr<Organism> sym_baby = MakeNew();
    sym_baby->Mutate(mode);
    return sym_baby;
  }
  #pragma clang diagnostic pop


  void VerticalTransmission(emp::Ptr<Organism> host_baby) {
    if((my_world->WillTransmit()) && GetPoints() >= my_config->SYM_VERT_TRANS_RES()){ //if the world permits vertical tranmission and the sym has enough resources, transmit!
      emp::Ptr<Organism> sym_baby = Reproduce("vertical");
      host_baby->AddSymbiont(sym_baby);

      //vertical transmission data node
      emp::DataMonitor<int>& data_node_attempts_verttrans = my_world->GetVerticalTransmissionAttemptCount();
      data_node_attempts_verttrans.AddDatum(1);
    }
  }

  void HorizontalTransmission(emp::WorldPosition location) {
    if (my_config->HORIZ_TRANS()) { //non-lytic horizontal transmission enabled
      if(GetPoints() >= my_config->SYM_HORIZ_TRANS_RES()) {
        // symbiont reproduces independently (horizontal transmission) if it has enough resources
        // new symbiont in this host with mutated value
        SetPoints(0); //TODO: test just subtracting points instead of setting to 0
        emp::Ptr<Organism> sym_baby = Reproduce("horizontal");
        emp::WorldPosition new_pos = my_world->SymDoBirth(sym_baby, location);

        //horizontal transmission data nodes
        emp::DataMonitor<int>& data_node_attempts_horiztrans = my_world->GetHorizontalTransmissionAttemptCount();
        data_node_attempts_horiztrans.AddDatum(1);

        emp::DataMonitor<int>& data_node_successes_horiztrans = my_world->GetHorizontalTransmissionSuccessCount();
        if(new_pos.IsValid()){
          data_node_successes_horiztrans.AddDatum(1);
        }
      }
    }
  }
};
#endif