Chaste  Release::3.4
Cell.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 "Cell.hpp"
37 
38 // Included here rather than the .hpp to avoid a circular include.
39 #include "NullSrnModel.hpp"
40 
54 {
56  void operator()(void const *) const
57  {
58  }
59 };
60 
61 Cell::Cell(boost::shared_ptr<AbstractCellProperty> pMutationState,
62  AbstractCellCycleModel* pCellCycleModel,
63  AbstractSrnModel* pSrnModel,
64  bool archiving,
65  CellPropertyCollection cellPropertyCollection)
66  : mCanDivide(false),
67  mCellPropertyCollection(cellPropertyCollection),
68  mpCellCycleModel(pCellCycleModel),
69  mpSrnModel(pSrnModel),
70  mDeathTime(DBL_MAX), // This has to be initialised for archiving
71  mStartOfApoptosisTime(DBL_MAX),
72  mApoptosisTime(0.25), // cell takes 15 min to fully undergo apoptosis
73  mUndergoingApoptosis(false),
74  mIsDead(false),
75  mIsLogged(false)
76 {
77  if (SimulationTime::Instance()->IsStartTimeSetUp()==false)
78  {
79  EXCEPTION("Cell is setting up a cell-cycle model but SimulationTime has not been set up");
80  }
81 
82  if (pCellCycleModel == NULL)
83  {
84  EXCEPTION("Cell-cycle model is null");
85  }
86 
87  mpCellCycleModel->SetCell(CellPtr(this, null_deleter()));
88 
89  // Create a null srn model if none given
90  if (pSrnModel == NULL)
91  {
92  pSrnModel = new NullSrnModel;
93  mpSrnModel = pSrnModel;
94  }
95 
96  mpSrnModel->SetCell(CellPtr(this, null_deleter()));
97 
99  {
100  // Set cell identifier this will be called all the time unless the constructor is called through archiving
101  MAKE_PTR(CellId, p_cell_id);
102  p_cell_id->AssignCellId();
104  }
105 
106  if (!pMutationState->IsSubType<AbstractCellMutationState>())
107  {
108  EXCEPTION("Attempting to create cell with a cell mutation state that is not a subtype of AbstractCellMutationState");
109  }
110 
111  if (!mCellPropertyCollection.HasProperty(pMutationState))
112  {
113  mCellPropertyCollection.AddProperty(pMutationState);
114  }
115 
117  {
118  // Add empty cell data
119  MAKE_PTR(CellData, p_cell_data);
121  }
122 
123  /*
124  * If a cell proliferative type was not passed in via the input
125  * argument cellPropertyCollection (for example as in the case
126  * of a daughter cell being created following division) then add
127  * add a 'default' cell proliferative type to the cell property
128  * collection. This ensures that the method GetCellProliferativeType()
129  * always returns a valid proliferative type.
130  */
132  {
133  mCellPropertyCollection.AddProperty(CellPropertyRegistry::Instance()->Get<DefaultCellProliferativeType>());
134  }
135 
136  if (!archiving)
137  {
138  // Increment cell count for each cell property in mCellPropertyCollection
140  property_iter != mCellPropertyCollection.End();
141  ++property_iter)
142  {
143  (*property_iter)->IncrementCellCount();
144  }
145  }
146 }
147 
149 {
150  if (!mIsDead)
151  {
152  Kill();
153  }
154  delete mpCellCycleModel;
155  delete mpSrnModel;
156 }
157 
158 void Cell::SetCellProliferativeType(boost::shared_ptr<AbstractCellProperty> pProliferativeType)
159 {
160  if (!pProliferativeType->IsSubType<AbstractCellProliferativeType>())
161  {
162  EXCEPTION("Attempting to give cell a cell proliferative type that is not a subtype of AbstractCellProliferativeType");
163  }
164 
165  boost::shared_ptr<AbstractCellProliferativeType> p_old_proliferative_type = GetCellProliferativeType();
166 
167  p_old_proliferative_type->DecrementCellCount();
168  mCellPropertyCollection.RemoveProperty(p_old_proliferative_type);
169 
170  AddCellProperty(pProliferativeType);
171 }
172 
173 boost::shared_ptr<AbstractCellProliferativeType> Cell::GetCellProliferativeType() const
174 {
176 
177  /*
178  * Note: In its current form the code requires each cell to have exactly
179  * one proliferative type. This is reflected in the assertion below. If a user
180  * wishes to include cells with multiple proliferative types, each possible
181  * combination must be created as a separate proliferative type class.
182  */
183  assert(proliferative_type_collection.GetSize() == 1);
184 
185  return boost::static_pointer_cast<AbstractCellProliferativeType>(proliferative_type_collection.GetProperty());
186 }
187 
189 {
190  if (mpCellCycleModel != pCellCycleModel)
191  {
192  delete mpCellCycleModel;
193  }
194  mpCellCycleModel = pCellCycleModel;
195  mpCellCycleModel->SetCell(CellPtr(this, null_deleter()));
196 }
197 
199 {
200  return mpCellCycleModel;
201 }
202 
204 {
206 }
207 
209 {
210  if (mpSrnModel != pSrnModel)
211  {
212  delete mpSrnModel;
213  }
214  mpSrnModel = pSrnModel;
215  mpSrnModel->SetCell(CellPtr(this, null_deleter()));
216 }
217 
219 {
220  return mpSrnModel;
221 }
222 
224 {
226 }
227 
228 double Cell::GetAge() const
229 {
230  return mpCellCycleModel->GetAge();
231 }
232 
233 double Cell::GetBirthTime() const
234 {
235  return mpCellCycleModel->GetBirthTime();
236 }
237 
238 void Cell::SetBirthTime(double birthTime)
239 {
240  mpCellCycleModel->SetBirthTime(birthTime);
241 }
242 
243 void Cell::SetMutationState(boost::shared_ptr<AbstractCellProperty> pMutationState)
244 {
245  if (!pMutationState->IsSubType<AbstractCellMutationState>())
246  {
247  EXCEPTION("Attempting to give cell a cell mutation state that is not a subtype of AbstractCellMutationState");
248  }
249 
250  boost::shared_ptr<AbstractCellMutationState> p_old_mutation_state = GetMutationState();
251  p_old_mutation_state->DecrementCellCount();
252  mCellPropertyCollection.RemoveProperty(p_old_mutation_state);
253 
254  AddCellProperty(pMutationState);
255 }
256 
257 boost::shared_ptr<AbstractCellMutationState> Cell::GetMutationState() const
258 {
260 
261  /*
262  * Note: In its current form the code requires each cell to have exactly
263  * one mutation state. This is reflected in the assertion below. If a user
264  * wishes to include cells with multiple mutation states, each possible
265  * combination must be created as a separate mutation state class.
266  */
267  assert(mutation_state_collection.GetSize() == 1);
268 
269  return boost::static_pointer_cast<AbstractCellMutationState>(mutation_state_collection.GetProperty());
270 }
271 
272 boost::shared_ptr<CellData> Cell::GetCellData() const
273 {
275 
276  /*
277  * Note: In its current form the code requires each cell to have exactly
278  * one CellData object. This is reflected in the assertion below.
279  */
280  assert(cell_data_collection.GetSize() <= 1);
281 
282  return boost::static_pointer_cast<CellData>(cell_data_collection.GetProperty());
283 }
284 
286 {
288 }
289 
290 boost::shared_ptr<CellVecData> Cell::GetCellVecData() const
291 {
292  assert(HasCellVecData());
293 
295 
296  /*
297  * Note: In its current form the code requires each cell to have exactly
298  * one CellVecData object. This is reflected in the assertion below.
299  */
300  assert(cell_data_collection.GetSize() <= 1);
301 
302  return boost::static_pointer_cast<CellVecData>(cell_data_collection.GetProperty());
303 }
304 
306 {
308 }
309 
311 {
313 }
314 
315 void Cell::AddCellProperty(const boost::shared_ptr<AbstractCellProperty>& rProperty)
316 {
317  // Note: if the cell already has the specified property, no action is taken
318  if (!mCellPropertyCollection.HasProperty(rProperty))
319  {
321  rProperty->IncrementCellCount();
322  }
323 }
324 
326 {
327  mIsLogged = true;
328 }
329 
331 {
332  return mIsLogged;
333 }
334 
335 void Cell::StartApoptosis(bool setDeathTime)
336 {
337  assert(!IsDead());
338 
340  {
341  EXCEPTION("StartApoptosis() called when already undergoing apoptosis");
342  }
343  mUndergoingApoptosis = true;
345  if (setDeathTime)
346  {
348  }
349  else
350  {
351  mDeathTime = DBL_MAX;
352  }
354 }
355 
357 {
358  return mUndergoingApoptosis;
359 }
360 
362 {
363  return mStartOfApoptosisTime;
364 }
365 
367 {
368  return mApoptosisTime;
369 }
370 
371 void Cell::SetApoptosisTime(double apoptosisTime)
372 {
373  assert(apoptosisTime > 0.0);
374  mApoptosisTime = apoptosisTime;
375 }
376 
378 {
379  if (!mUndergoingApoptosis || mDeathTime==DBL_MAX)
380  {
381  EXCEPTION("Shouldn't be checking time until apoptosis as it isn't set");
382  }
383 
385 }
386 
388 {
390  {
391  double sloppy_death_time = mDeathTime - DBL_EPSILON * mApoptosisTime;
392  if (SimulationTime::Instance()->GetTime() >= sloppy_death_time )
393  {
394  this->Kill();
395  }
396  }
397  return mIsDead;
398 }
399 
401 {
402  // Decrement cell count for each cell property in mCellPropertyCollection
404  property_iter != mCellPropertyCollection.End();
405  ++property_iter)
406  {
407  (*property_iter)->DecrementCellCount();
408  }
409  mIsDead = true;
410 }
411 
412 void Cell::SetAncestor(boost::shared_ptr<AbstractCellProperty> pCellAncestor)
413 {
414  if (!pCellAncestor->IsSubType<CellAncestor>())
415  {
416  EXCEPTION("Attempting to give cell a cell ancestor which is not a CellAncestor");
417  }
418 
419  // You can only set ancestors once
421  if (ancestor_collection.GetSize() == 0)
422  {
423  AddCellProperty(pCellAncestor);
424  }
425  else
426  {
427  // Overwrite the CellAncestor
428  RemoveCellProperty<CellAncestor>();
429  AddCellProperty(pCellAncestor);
430  }
431 }
432 
433 unsigned Cell::GetAncestor() const
434 {
436 
437  assert(ancestor_collection.GetSize() <= 1);
438  if (ancestor_collection.GetSize() == 0)
439  {
440  return UNSIGNED_UNSET;
441  }
442 
443  boost::shared_ptr<CellAncestor> p_ancestor = boost::static_pointer_cast<CellAncestor>(ancestor_collection.GetProperty());
444 
445  return p_ancestor->GetAncestor();
446 }
447 
448 unsigned Cell::GetCellId() const
449 {
451 
452  assert(cell_id_collection.GetSize() == 1);
453 
454  boost::shared_ptr<CellId> p_cell_id = boost::static_pointer_cast<CellId>(cell_id_collection.GetProperty());
455 
456  return p_cell_id->GetCellId();
457 }
458 
460 {
461  assert(!IsDead());
462  if (mUndergoingApoptosis || HasCellProperty<ApoptoticCellProperty>())
463  {
464  return false;
465  }
466 
467  // NOTE - we run the SRN model here first before the CCM
469  // This in turn runs any simulations within the CCM thru UpdateCellCyclePhases()
471 
472  return mCanDivide;
473 }
474 
475 CellPtr Cell::Divide()
476 {
477  // Check we're allowed to divide
478  assert(!IsDead());
479  assert(mCanDivide);
480  mCanDivide = false;
481 
482  // Reset properties of parent cell
485 
486  // Create copy of cell property collection to modify for daughter cell
487  CellPropertyCollection daughter_property_collection = mCellPropertyCollection;
488 
489  // Remove the CellId from the daughter cell, as a new one will be assigned in the constructor
490  daughter_property_collection.RemoveProperty<CellId>();
491 
492  // Copy all cell data (note we create a new object not just copying the pointer)
493  assert(daughter_property_collection.HasPropertyType<CellData>());
494 
495  // Get the existing copy of the cell data and remove it from the daughter cell
496  boost::shared_ptr<CellData> p_cell_data = GetCellData();
497  daughter_property_collection.RemoveProperty(p_cell_data);
498 
499  // Create a new cell data object using the copy constructor and add this to the daughter cell
500  MAKE_PTR_ARGS(CellData, p_daughter_cell_data, (*p_cell_data));
501  daughter_property_collection.AddProperty(p_daughter_cell_data);
502 
503  // Copy all cell Vec data (note we create a new object not just copying the pointer)
504  if (daughter_property_collection.HasPropertyType<CellVecData>())
505  {
506  // Get the existing copy of the cell data and remove it from the daughter cell
507  boost::shared_ptr<CellVecData> p_cell_vec_data = GetCellVecData();
508  daughter_property_collection.RemoveProperty(p_cell_vec_data);
509 
510  // Create a new cell data object using the copy constructor and add this to the daughter cell
511  MAKE_PTR_ARGS(CellVecData, p_daughter_cell_vec_data, (*p_cell_vec_data));
512  daughter_property_collection.AddProperty(p_daughter_cell_vec_data);
513  }
514 
515  // Create daughter cell with modified cell property collection
516  CellPtr p_new_cell(new Cell(GetMutationState(), mpCellCycleModel->CreateCellCycleModel(), mpSrnModel->CreateSrnModel(), false, daughter_property_collection));
517 
518  // Initialise properties of daughter cell
519  p_new_cell->GetCellCycleModel()->InitialiseDaughterCell();
520  p_new_cell->GetSrnModel()->InitialiseDaughterCell();
521 
522  // Set the daughter cell to inherit the apoptosis time of the parent cell
523  p_new_cell->SetApoptosisTime(mApoptosisTime);
524 
525  return p_new_cell;
526 }
void InitialiseSrnModel()
Definition: Cell.cpp:223
AbstractCellCycleModel * GetCellCycleModel() const
Definition: Cell.cpp:198
bool ReadyToDivide()
Definition: Cell.cpp:459
double GetAge() const
Definition: Cell.cpp:228
virtual void SetBirthTime(double birthTime)
double GetBirthTime() const
Definition: Cell.cpp:233
double GetTimeUntilDeath() const
Definition: Cell.cpp:377
void SetLogged()
Definition: Cell.cpp:325
void Kill()
Definition: Cell.cpp:400
void InitialiseCellCycleModel()
Definition: Cell.cpp:203
bool mCanDivide
Definition: Cell.hpp:82
void SetCellCycleModel(AbstractCellCycleModel *pCellCycleModel)
Definition: Cell.cpp:188
CollectionType::iterator Iterator
boost::shared_ptr< AbstractCellProperty > GetProperty() const
#define EXCEPTION(message)
Definition: Exception.hpp:143
static SimulationTime * Instance()
AbstractSrnModel * mpSrnModel
Definition: Cell.hpp:116
double mDeathTime
Definition: Cell.hpp:119
double mApoptosisTime
Definition: Cell.hpp:125
double GetStartOfApoptosisTime() const
Definition: Cell.cpp:361
CellPropertyCollection GetPropertiesType() const
unsigned GetAncestor() const
Definition: Cell.cpp:433
boost::shared_ptr< AbstractCellProliferativeType > GetCellProliferativeType() const
Definition: Cell.cpp:173
void operator()(void const *) const
Definition: Cell.cpp:56
void AddCellProperty(const boost::shared_ptr< AbstractCellProperty > &rProperty)
Definition: Cell.cpp:315
void SetCell(CellPtr pCell)
void SetApoptosisTime(double apoptosisTime)
Definition: Cell.cpp:371
static CellPropertyRegistry * Instance()
virtual void SimulateToCurrentTime()=0
unsigned GetCellId() const
Definition: CellId.cpp:57
#define MAKE_PTR(TYPE, NAME)
boost::shared_ptr< CellVecData > GetCellVecData() const
Definition: Cell.cpp:290
virtual void ResetForDivision()
bool mIsLogged
Definition: Cell.hpp:137
virtual AbstractSrnModel * CreateSrnModel()=0
bool mUndergoingApoptosis
Definition: Cell.hpp:128
virtual void Initialise()
double GetApoptosisTime() const
Definition: Cell.cpp:366
bool IsDead()
Definition: Cell.cpp:387
CellPropertyCollection & rGetCellPropertyCollection()
Definition: Cell.cpp:305
void SetCellProliferativeType(boost::shared_ptr< AbstractCellProperty > pProliferativeType)
Definition: Cell.cpp:158
bool HasApoptosisBegun() const
Definition: Cell.cpp:356
AbstractCellCycleModel * mpCellCycleModel
Definition: Cell.hpp:113
~Cell()
Definition: Cell.cpp:148
boost::shared_ptr< AbstractCellProperty > Get()
const unsigned UNSIGNED_UNSET
Definition: Exception.hpp:52
AbstractSrnModel * GetSrnModel() const
Definition: Cell.cpp:218
void StartApoptosis(bool setDeathTime=true)
Definition: Cell.cpp:335
bool HasProperty(const boost::shared_ptr< AbstractCellProperty > &rProp) const
void AddProperty(const boost::shared_ptr< AbstractCellProperty > &rProp)
CellPtr Divide()
Definition: Cell.cpp:475
bool mIsDead
Definition: Cell.hpp:134
bool HasCellVecData() const
Definition: Cell.cpp:285
CellPropertyRegistry * GetCellPropertyRegistry()
double GetTime() const
unsigned GetCellId() const
Definition: Cell.cpp:448
CellPropertyCollection mCellPropertyCollection
Definition: Cell.hpp:110
boost::shared_ptr< CellData > GetCellData() const
Definition: Cell.cpp:272
void SetMutationState(boost::shared_ptr< AbstractCellProperty > pMutationState)
Definition: Cell.cpp:243
unsigned GetAncestor() const
void SetBirthTime(double birthTime)
Definition: Cell.cpp:238
bool IsLogged()
Definition: Cell.cpp:330
void SetAncestor(boost::shared_ptr< AbstractCellProperty > pCellAncestor)
Definition: Cell.cpp:412
void SetSrnModel(AbstractSrnModel *pSrnModel)
Definition: Cell.cpp:208
double mStartOfApoptosisTime
Definition: Cell.hpp:122
virtual AbstractCellCycleModel * CreateCellCycleModel()=0
#define MAKE_PTR_ARGS(TYPE, NAME, ARGS)
Cell(boost::shared_ptr< AbstractCellProperty > pMutationState, AbstractCellCycleModel *pCellCycleModel, AbstractSrnModel *pSrnModel=NULL, bool archiving=false, CellPropertyCollection cellPropertyCollection=CellPropertyCollection())
Definition: Cell.cpp:61
boost::shared_ptr< AbstractCellMutationState > GetMutationState() const
Definition: Cell.cpp:257