Chaste  Build::
Owen2011OxygenBasedCellCycleModel.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34  */
35 
36 #include "Owen2011OxygenBasedCellCycleModel.hpp"
37 #include "WildTypeCellMutationState.hpp"
38 #include "CancerCellMutationState.hpp"
39 #include "QuiescentCancerCellMutationState.hpp"
40 #include "ApoptoticCellProperty.hpp"
41 #include "TipCellMutationState.hpp"
42 #include "StalkCellMutationState.hpp"
43 #include "CellPropertyRegistry.hpp"
44 #include "CellLabel.hpp"
45 #include "Exception.hpp"
46 #include "SimulationTime.hpp"
47 #include "CellCycleModelOdeHandler.hpp"
48 #include "CvodeAdaptor.hpp"
49 #include "RandomNumberGenerator.hpp"
50 #include "AbstractPhaseBasedCellCycleModel.hpp"
51 #include "Secomb04Parameters.hpp"
52 #include "GenericParameters.hpp"
53 #include "Owen11Parameters.hpp"
54 #include "BaseUnits.hpp"
55 
56 Owen2011OxygenBasedCellCycleModel::Owen2011OxygenBasedCellCycleModel(boost::shared_ptr<AbstractCellCycleModelOdeSolver> pOdeSolver)
57 : AbstractOdeBasedPhaseBasedCellCycleModel(SimulationTime::Instance()->GetTime(), pOdeSolver),
58  mOdeIntegrationTimeStep(30.0*unit::minutes),
59  sOnset(0.4),
60  g2Onset(0.6),
61  mOnset(0.9),
62  mReferenceTimeScale(BaseUnits::Instance()->GetReferenceTimeScale()),
63  mReferenceConcentrationScale(BaseUnits::Instance()->GetReferenceConcentrationScale()),
64  mMaxRandInitialPhase(0.99),
65  mCurrentQuiescentDuration(0.0*unit::seconds),
66  mCurrentQuiescenceOnsetTime(0.0*unit::seconds),
67  mEnterQuiescenceOxygenConcentration(Owen11Parameters::mpOxygenPartialPressureAtQuiescence->GetValue("Owen2011OxygenBasedCellCycleModel")),
68  mLeaveQuiescenceOxygenConcentration(Owen11Parameters::mpOxygenPartialPressureLeaveQuiescence->GetValue("Owen2011OxygenBasedCellCycleModel")),
69  mCriticalQuiescentDuration(Owen11Parameters::mpTimeToDeathDueToQuiescence->GetValue("Owen2011OxygenBasedCellCycleModel")),
70  mp53ThresholdForApoptosisOfNormalCellsInHealthyMicroenvironment(0.8),
71  mp53ThresholdForApoptosisOfNormalCellsInTumourMicroenvironment(0.08),
72  mthresholdFractionOfNormalCellNeighbours(0.75)
73 {
74  if (!mpOdeSolver)
75  {
76  mpOdeSolver = CellCycleModelOdeSolver<Owen2011OxygenBasedCellCycleModel, CvodeAdaptor>::Instance();
77  mpOdeSolver->Initialise();
78  }
79 
81 
83  Secomb04Parameters::mpOxygenVolumetricSolubility->GetValue("Owen2011OxygenBasedCellCycleOdeSystem") *
84  GenericParameters::mpGasConcentrationAtStp->GetValue("Owen2011OxygenBasedCellCycleOdeSystem");
85 }
86 
88 {
89  // Pass this time step's oxygen concentration into the solver as a constant over this timestep
90  mpOdeSystem->rGetStateVariables()[3] = mpCell->GetCellData()->GetItem("oxygen");
91 
92  // Use the cell's current mutation status as another input
93  static_cast<Owen2011OxygenBasedCellCycleOdeSystem*>(mpOdeSystem)->SetMutationState(mpCell->GetMutationState());
94 }
95 
97 {
98  assert(mpCell->GetMutationState()->IsType<CancerCellMutationState>() || mpCell->GetMutationState()->IsType<WildTypeCellMutationState>());
99 
100  // Get cell's oxygen concentration
101  units::quantity<unit::concentration> oxygen_concentration = mpCell->GetCellData()->GetItem("oxygen")*mReferenceConcentrationScale;
102  if (mpCell->GetMutationState()->IsType<CancerCellMutationState>())
103  {
105  {
106  mpCell->SetMutationState(CellPropertyRegistry::Instance()->Get<QuiescentCancerCellMutationState>());
107  assert(mpCell->GetMutationState()->IsType<QuiescentCancerCellMutationState>());
108  assert(!(mpCell->GetMutationState()->IsType<CancerCellMutationState>()));
109  mCurrentQuiescenceOnsetTime = SimulationTime::Instance()->GetTime()*mReferenceTimeScale;
110  mCurrentCellCyclePhase = G_ZERO_PHASE;
111  }
112  }
113  else
114  {
115  double p53_concentration = mpCell->GetCellData()->GetItem("p53");
116  double p53threshold = 0.0;
117  unsigned number_of_normal_neighbours = mpCell->GetCellData()->GetItem("Number_of_normal_neighbours");
118  unsigned number_of_cancerous_neighbours = mpCell->GetCellData()->GetItem("Number_of_cancerous_neighbours");
119  double normal_neighbour_fraction = double(number_of_normal_neighbours)/double(number_of_cancerous_neighbours+number_of_normal_neighbours);
120  if (normal_neighbour_fraction > mthresholdFractionOfNormalCellNeighbours)
121  {
123  }
124  else
125  {
127  }
128  if(p53_concentration > p53threshold)
129  {
130  assert(mpCell->GetMutationState()->IsType<WildTypeCellMutationState>());
131  mpCell->AddCellProperty(CellPropertyRegistry::Instance()->Get<ApoptoticCellProperty>());
132  }
133  }
134 }
135 
137 {
138  // Create a new cell-cycle model
140  /*
141  * Set each member variable of the new cell-cycle model that inherits
142  * its value from the parent.
143  *
144  * Note 1: some of the new cell-cycle model's member variables (namely
145  * mBirthTime, mCurrentCellCyclePhase, mReadyToDivide, mDt, mpOdeSolver)
146  * will already have been correctly initialized in its constructor.
147  *
148  * Note 2: one or more of the new cell-cycle model's member variables
149  * may be set/overwritten as soon as InitialiseDaughterCell() is called on
150  * the new cell-cycle model.
151  */
152  p_model->SetBirthTime(mBirthTime);
153  p_model->SetDimension(mDimension);
154  p_model->SetMinimumGapDuration(mMinimumGapDuration);
155  p_model->SetStemCellG1Duration(mStemCellG1Duration);
156  p_model->SetTransitCellG1Duration(mTransitCellG1Duration);
157  p_model->SetSDuration(mSDuration);
158  p_model->SetG2Duration(mG2Duration);
159  p_model->SetMDuration(mMDuration);
160  p_model->SetLastTime(mLastTime);
167 
168  /*
169  * Create the new cell-cycle model's ODE system and use the current values
170  * of the state variables in mpOdeSystem as an initial condition.
171  */
172  assert(mpOdeSystem);
173  // note should the second argument here not be a flag ...
174  p_model->SetOdeSystem(new Owen2011OxygenBasedCellCycleOdeSystem(mpCell->GetCellData()->GetItem("oxygen")*mReferenceConcentrationScale,
175  mpCell->GetMutationState()));
176  p_model->SetStateVariables(mpOdeSystem->rGetStateVariables());
177 
178  return p_model;
179 }
180 
182 {
183  return 0.0;
184 }
185 
187 {
188  return 0.0;
189 }
190 
192 {
193  return 0.0;
194 }
195 
197 {
198  assert(mpOdeSystem != NULL);
199  double phi = mpOdeSystem->rGetStateVariables()[0];
200  return phi;
201 }
202 
204 {
205  assert(mpOdeSystem != NULL);
206  double VEGF = mpOdeSystem->rGetStateVariables()[2];
207  return VEGF;
208 }
209 
211 {
212  assert(mpOdeSystem != NULL);
213  double p53 = mpOdeSystem->rGetStateVariables()[1];
214  return p53;
215 }
216 
218 {
220 }
221 
223 {
225 }
226 
228 {
230 }
231 
233 {
235 }
236 
238 {
240 }
241 
243 {
244  assert(mpOdeSystem == NULL);
245  assert(mpCell != NULL);
246 
247  mpOdeSystem = new Owen2011OxygenBasedCellCycleOdeSystem(mpCell->GetCellData()->GetItem("oxygen")*mReferenceConcentrationScale,
248  mpCell->GetMutationState());
249 
250  mpCell->SetBirthTime(SimulationTime::Instance()->GetTime());
251  std::vector<double> init_conds = mpOdeSystem->GetInitialConditions();
252  init_conds[0] = mMaxRandInitialPhase*RandomNumberGenerator::Instance()->ranf(); // phi is random initially
253  init_conds[3] = mpCell->GetCellData()->GetItem("oxygen");
254 
255  mpOdeSystem->SetStateVariables(init_conds);
256 }
257 
259 {
260  mpOdeSystem->rGetStateVariables()[0] = mpOdeSystem->GetInitialConditions()[0];
261  mCurrentCellCyclePhase = G_ONE_PHASE;
262 }
263 
265 {
266  *rParamsFile << "\t\t\t<EnterQuiescenceOxygenConcentration>" << mEnterQuiescenceOxygenConcentration << "</EnterQuiescenceOxygenConcentration>\n";
267  *rParamsFile << "\t\t\t<LeaveQuiescenceOxygenConcentration>" << mLeaveQuiescenceOxygenConcentration << "</LeaveQuiescenceOxygenConcentration>\n";
268  *rParamsFile << "\t\t\t<CriticalQuiescentDuration>" << mCriticalQuiescentDuration << "</CriticalQuiescentDuration>\n";
269 
270  // Call method on direct parent class
271  AbstractOdeBasedPhaseBasedCellCycleModel::OutputCellCycleModelParameters(rParamsFile);
272 }
273 
275 {
276  assert(mpOdeSystem != NULL);
277  assert(mFinishedRunningOdes);
278  assert(mReadyToDivide);
279  mReadyToDivide = false;
280  mFinishedRunningOdes = false;
281 
282  // Keep the oxygen concentration the same but reset everything else
283  mpOdeSystem->rGetStateVariables()[0] = mpOdeSystem->GetInitialConditions()[0];
284  mpOdeSystem->rGetStateVariables()[1] = mpOdeSystem->GetInitialConditions()[1];
285  mpOdeSystem->rGetStateVariables()[2] = mpOdeSystem->GetInitialConditions()[2];
286 
287  assert(!mpCell->GetMutationState()->IsType<QuiescentCancerCellMutationState>());
288  mpCell->SetMutationState(mpCell->GetMutationState());
289  mCurrentCellCyclePhase = G_ONE_PHASE;
290 }
291 
293 {
294  if (mpCell->GetMutationState()->IsType<TipCellMutationState>() || mpCell->GetMutationState()->IsType<StalkCellMutationState>())
295  {
296  mReadyToDivide = false;
297  }
298  else
299  {
300  if(!mpCell->HasApoptosisBegun() && !mpCell->IsDead())
301  {
303  if(mFinishedRunningOdes)
304  {
305  mReadyToDivide = true;
306  }
307  else
308  {
309  mReadyToDivide = false;
310  }
311  }
312  else
313  {
314  mReadyToDivide = false;
315  }
316  }
317  return mReadyToDivide;
318 }
319 
320 void Owen2011OxygenBasedCellCycleModel::SetSOnset(units::quantity<unit::dimensionless> value)
321 {
322  sOnset = value;
323 }
324 
325 void Owen2011OxygenBasedCellCycleModel::SetG2Onset(units::quantity<unit::dimensionless> value)
326 {
327  g2Onset = value;
328 }
329 
330 void Owen2011OxygenBasedCellCycleModel::SetMOnset(units::quantity<unit::dimensionless> value)
331 {
332  mOnset = value;
333 }
334 
335 void Owen2011OxygenBasedCellCycleModel::SetOdeSolverTimeStep(units::quantity<unit::time> timeStep)
336 {
337  mOdeIntegrationTimeStep = timeStep;
339 }
340 
341 void Owen2011OxygenBasedCellCycleModel::SetReferenceTimeScale(units::quantity<unit::time> referenceTimeScale)
342 {
343  mReferenceTimeScale = referenceTimeScale;
344 }
345 
346 void Owen2011OxygenBasedCellCycleModel::SetReferenceConcentrationScale(units::quantity<unit::concentration> referenceConcentrationScale)
347 {
348  mReferenceConcentrationScale = referenceConcentrationScale;
349 }
350 
351 void Owen2011OxygenBasedCellCycleModel::SetMaxRandInitialPhase(units::quantity<unit::dimensionless> rand_max_phase)
352 {
353  assert(rand_max_phase >= 0.0);
354  mMaxRandInitialPhase = rand_max_phase;
355 }
356 
357 void Owen2011OxygenBasedCellCycleModel::SetEnterQuiescenceOxygenConcentration(units::quantity<unit::pressure> enterQuiescenceOxygenConcentration)
358 {
359  assert(enterQuiescenceOxygenConcentration>=0.0*unit::pascals);
360  mEnterQuiescenceOxygenConcentration = enterQuiescenceOxygenConcentration;
361 }
362 
363 void Owen2011OxygenBasedCellCycleModel::SetLeaveQuiescenceOxygenConcentration(units::quantity<unit::pressure> leaveQuiescenceOxygenConcentration)
364 {
365  assert(leaveQuiescenceOxygenConcentration >= 0.0*unit::pascals);
366  mLeaveQuiescenceOxygenConcentration = leaveQuiescenceOxygenConcentration;
367 }
368 
369 void Owen2011OxygenBasedCellCycleModel::SetCriticalQuiescentDuration(units::quantity<unit::time> criticalQuiescentDuration)
370 {
371  assert(criticalQuiescentDuration >= 0.0*unit::seconds);
372  mCriticalQuiescentDuration = criticalQuiescentDuration;
373 }
374 
375 void Owen2011OxygenBasedCellCycleModel::SetCurrentQuiescenceOnsetTime(units::quantity<unit::time> currentQuiescenceOnsetTime)
376 {
377  assert(currentQuiescenceOnsetTime >= 0.0*unit::seconds);
378  mCurrentQuiescenceOnsetTime = currentQuiescenceOnsetTime;
379 }
380 
382 {
384 }
385 
387 {
388  assert(!mpCell->HasApoptosisBegun());
389  assert(!mpCell->IsDead());
390 
391  // if cell is still marked for division then the cell has failed to divide and we need to reset the cell here
392  // most notably this happens in on-lattice simulations where there is no space available for a cell to divide
393  if(mReadyToDivide)
394  {
396  }
397 
398  if(mpCell->GetMutationState()->IsType<CancerCellMutationState>() || mpCell->GetMutationState()->IsType<WildTypeCellMutationState>())
399  {
401  }
402 
403  if(mpCell->GetMutationState()->IsType<QuiescentCancerCellMutationState>())
404  {
406  }
407 
408  // must do this because we are using CVode and by
409  // default stopping events are not found
410  mpOdeSolver->CheckForStoppingEvents();
411 
412  assert(mpOdeSystem != NULL);
413  double current_time = SimulationTime::Instance()->GetTime();
414 
415  // adjust ode parameters is called in here ... updates mutation state and oxygen concentration
416  mFinishedRunningOdes = SolveOdeToTime(current_time);
417 
418  // Check no concentrations have gone negative
419  for (unsigned i=0; i<mpOdeSystem->GetNumberOfStateVariables(); i++)
420  {
421  if (mpOdeSystem->rGetStateVariables()[i] < -DBL_EPSILON)
422  {
423  EXCEPTION("A protein concentration " << i << " has gone negative (" << mpOdeSystem->rGetStateVariables()[i] << ")\n"
424  << "A CellCycleModel numerical method is probably unstable.");
425  }
426  }
427 
428  if(mCurrentCellCyclePhase != G_ZERO_PHASE)
429  {
430  if(mpOdeSystem->rGetStateVariables()[0]<sOnset)
431  {
432  mCurrentCellCyclePhase = G_ONE_PHASE;
433  }
434  else if(mpOdeSystem->rGetStateVariables()[0]<g2Onset)
435  {
436  mCurrentCellCyclePhase = S_PHASE;
437  }
438  else if(mpOdeSystem->rGetStateVariables()[0]<mOnset)
439  {
440  mCurrentCellCyclePhase = G_TWO_PHASE;
441  }
442  else
443  {
444  mCurrentCellCyclePhase = M_PHASE;
445  }
446  }
447 }
448 
450 {
451  assert(mpCell->GetMutationState()->IsType<QuiescentCancerCellMutationState>());
452  assert(!(mpCell->HasCellProperty<ApoptoticCellProperty>()));
453  assert(!mpCell->HasApoptosisBegun());
454 
455  // Get cell's oxygen concentration
456  units::quantity<unit::concentration> oxygen_concentration = mpCell->GetCellData()->GetItem("oxygen")*mReferenceConcentrationScale;
457  if (oxygen_concentration/mReferenceSolubility <= mLeaveQuiescenceOxygenConcentration)
458  {
459  // Update the duration of the current period of hypoxia
460  mCurrentQuiescentDuration = SimulationTime::Instance()->GetTime()*mReferenceTimeScale - mCurrentQuiescenceOnsetTime;
462  {
463  mpCell->AddCellProperty(CellPropertyRegistry::Instance()->Get<ApoptoticCellProperty>());
464  }
465  }
466  else
467  {
468  // Reset the cell's quiescent duration.
469  mCurrentQuiescentDuration = 0.0 * unit::seconds;
470  mCurrentQuiescenceOnsetTime = 0.0 * unit::seconds;
471  mCurrentCellCyclePhase = G_ONE_PHASE;
472  mpCell->SetMutationState(CellPropertyRegistry::Instance()->Get<CancerCellMutationState>());
473  }
474 }
475 
476 // Serialization for Boost >= 1.36
477 #include "SerializationExportWrapperForCpp.hpp"
478 CHASTE_CLASS_EXPORT(Owen2011OxygenBasedCellCycleModel)
479 #include "CellCycleModelOdeSolverExportWrapper.hpp"
480 EXPORT_CELL_CYCLE_MODEL_ODE_SOLVER(Owen2011OxygenBasedCellCycleModel)
void SetReferenceConcentrationScale(units::quantity< unit::concentration > referenceConcentrationScale)
units::quantity< unit::time > GetCurrentQuiescenceOnsetTime()
units::quantity< unit::solubility > mReferenceSolubility
void SetLeaveQuiescenceOxygenConcentration(units::quantity< unit::pressure > leaveQuiescenceOxygenConcentration)
void SetOdeSolverTimeStep(units::quantity< unit::time > timeStep)
units::quantity< unit::dimensionless > sOnset
units::quantity< unit::concentration > mReferenceConcentrationScale
units::quantity< unit::time > mCurrentQuiescenceOnsetTime
void SetMOnset(units::quantity< unit::dimensionless > value)
units::quantity< unit::time > GetCurrentQuiescentDuration()
units::quantity< unit::dimensionless > mp53ThresholdForApoptosisOfNormalCellsInTumourMicroenvironment
void SetCriticalQuiescentDuration(units::quantity< unit::time > criticalQuiescentDuration)
virtual void OutputCellCycleModelParameters(out_stream &rParamsFile)
void SetEnterQuiescenceOxygenConcentration(units::quantity< unit::pressure > enterQuiescenceOxygenConcentration)
units::quantity< unit::pressure > GetEnterQuiescenceOxygenConcentration()
units::quantity< unit::dimensionless > g2Onset
units::quantity< unit::pressure > GetLeaveQuiescenceOxygenConcentration()
units::quantity< unit::dimensionless > mMaxRandInitialPhase
Owen2011OxygenBasedCellCycleModel(boost::shared_ptr< AbstractCellCycleModelOdeSolver > pOdeSolver=boost::shared_ptr< AbstractCellCycleModelOdeSolver >())
void SetSOnset(units::quantity< unit::dimensionless > value)
units::quantity< unit::dimensionless > mthresholdFractionOfNormalCellNeighbours
units::quantity< unit::time > GetCriticalQuiescentDuration()
static const boost::shared_ptr< ParameterInstance< unit::volumetric_solubility > > mpOxygenVolumetricSolubility
void SetReferenceTimeScale(units::quantity< unit::time > referenceTimeScale)
void SetG2Onset(units::quantity< unit::dimensionless > value)
units::quantity< unit::dimensionless > mp53ThresholdForApoptosisOfNormalCellsInHealthyMicroenvironment
void SetCurrentQuiescenceOnsetTime(units::quantity< unit::time > currentQuiescenceOnsetTime)
units::quantity< unit::pressure > mEnterQuiescenceOxygenConcentration
units::quantity< unit::dimensionless > mOnset
units::quantity< unit::pressure > mLeaveQuiescenceOxygenConcentration
void SetMaxRandInitialPhase(units::quantity< unit::dimensionless > rand_max_phase)
units::quantity< unit::time > mCriticalQuiescentDuration
static const boost::shared_ptr< ParameterInstance< unit::concentration > > mpGasConcentrationAtStp