Agent removal / cell death

Hi, is there an example/demo somewhere to accomplish cell death? I.e. that the cell removes itself entirely from the simulation? Thanks

Hi @robauer , this is the very simple Apoptosis behaviour that I use in my simulations:

struct Apoptosis : public Behavior {  

  BDM_BEHAVIOR_HEADER(Apoptosis, Behavior, 1);

  Apoptosis() { AlwaysCopyToNew(); }

  void Run(Agent* so) override {
    if (auto* cell = dynamic_cast<AlvCell*>(so)) {
      auto* sim = Simulation::GetActive();
      auto* random = sim->GetRandom();
      auto* sparam = Simulation::GetActive()->GetParam()->Get<SimParam>();

      if (cell->GetCellType() == 1) {  // AEC1
        double AEC1_apoptosisRate =
            sparam->AEC1_apoptosis / (double)seconds_per_day_;  // s^(-1)

        if (random->Uniform() < AEC1_apoptosisRate) {
          cell->RemoveFromSimulation();
        }
      }
    }
  }
};

Cells that can undergo apoptosis are selected based on their type. For each cell type there’s a certain probability to undergo apoptosis at each type step and this is accomplished by sampling a random number between 0 and 1 and comparing it with a parameter stored in the bdm.toml file (AEC1_apoptosisRate in this case). Finally, with cell->RemoveFromSimulation(); the cell removes itself from the simulation.

1 Like

Thanks @nicogno , that is great!

1 Like

Do you also have an example of where a Behavior is killed, rather than the physical agent? Cheers

This is the code that I use to describe the differentiation of fibroblasts into myofibroblasts. If a certain condition is met, the fibroblast-specific behaviours are removed (or killed), including the one which is running (and I guess this is what you’re looking for), using “cell->RemoveBehavior(this);”:

    struct F_MF_Differentiation : public Behavior {
      BDM_BEHAVIOR_HEADER(F_MF_Differentiation, Behavior, 1);

      F_MF_Differentiation() { AlwaysCopyToNew(); }

      void Run(Agent* so) override {
        if (auto* cell = dynamic_cast<AlvCell*>(so)) {
          int old_type_ = 4, new_type_ = 11;

          if (cell->GetCellType() == old_type_) {
            // Define differentiation condition

            if (conditionIsMet) {
              const auto& bms = cell->GetAllBehaviors();
              // In the following I remove the Fibroblast-specific behaviours
              for (int i = 0; i < bms.size(); i++) {
                if (dynamic_cast<F_TGFbSecretion*>(bms[i])) {
                  cell->RemoveBehavior(bms[i]);
                }
                if (dynamic_cast<F_ECMSecretion*>(bms[i])) {
                  cell->RemoveBehavior(bms[i]);
                }
                if (dynamic_cast<F_Proliferate*>(bms[i])) {
                  cell->RemoveBehavior(bms[i]);
                }
                if (dynamic_cast<F_Grow*>(bms[i])) {
                  cell->RemoveBehavior(bms[i]);
                }
              }
              // Here the behaviour that is currently being executed is removed from the cell-specific list of behaviours
              cell->RemoveBehavior(this);
              // Here the new behaviours (myofibroblast-specific) are added
              cell->AddBehavior(new MF_ECMSecretion());

              // Set myofibroblasts-speficic features
              cell->SetCellType(new_type_);
              cell->SetDiameter(cell->GetCellDiameterType());
              cell->SetMass(cell->GetAlvCellMass());
              cell->SetCellAge(0);  // Newborn cell
            }
          }
        }
      }
    };

Cheers

1 Like

That is great, thanks @nicogno !

1 Like

dear @nicogno, do you reckon is necessary removing the “behavior” of an agent prior to deleting it?
in a demo BioDynaMo code i’ve generated to simulate cancer cell development, i do permit cell “removal” from the simulation using the “RemoveFromSimulation” but haven’t used the “RemoveBehavior” and nothing hangs, or haven’t noticed any memory issues… maybe I’m wrong. your thoughts?

Dear @VasVav , I agree with you. I don’t think it’s necessary to remove all the agent’s behaviours before removing the agent from the simulation, as the behaviours belong to the agent itself and removing it should result also in the removal of its behaviours (in the Agent class, “behaviours_” is an InlineVector, not a pointer, so I believe it’s freed when the Agent is destroyed).
I usually remove one or more behaviours when I simulate the differentiation and the new cell isn’t able to do anymore what the old one could.