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