Chaste Commit::f841a6fa79bd6f7a205054452b95ddf6d10aae23
Cell.cpp
1/*
2
3Copyright (c) 2005-2026, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF 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 "DefaultCellProliferativeType.hpp"
42#include "NullSrnModel.hpp"
43#include "SmartPointers.hpp"
44
45Cell::Cell(boost::shared_ptr<AbstractCellProperty> pMutationState,
46 AbstractCellCycleModel* pCellCycleModel,
47 AbstractSrnModel* pSrnModel,
48 bool archiving,
49 CellPropertyCollection cellPropertyCollection)
50 : mCanDivide(false),
51 mCellPropertyCollection(cellPropertyCollection),
52 mpCellCycleModel(pCellCycleModel),
53 mpSrnModel(pSrnModel),
54 mDeathTime(DBL_MAX), // This has to be initialised for archiving
55 mStartOfApoptosisTime(DBL_MAX),
56 mApoptosisTime(0.25), // cell takes 15 min to fully undergo apoptosis
57 mUndergoingApoptosis(false),
58 mIsDead(false),
59 mIsLogged(false),
60 mHasSrnModel(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 else
81 {
82 mHasSrnModel = true;
83 }
84
85 mpSrnModel->SetCell(CellPtr(this, null_deleter()));
86
88 {
89 // Set cell identifier this will be called all the time unless the constructor is called through archiving
90 MAKE_PTR(CellId, p_cell_id);
91 p_cell_id->AssignCellId();
93 }
94
95 if (!pMutationState->IsSubType<AbstractCellMutationState>())
96 {
97 EXCEPTION("Attempting to create cell with a cell mutation state that is not a subtype of AbstractCellMutationState");
98 }
99
100 if (!mCellPropertyCollection.HasProperty(pMutationState))
101 {
102 mCellPropertyCollection.AddProperty(pMutationState);
103 }
104
106 {
107 // Add empty cell data
108 MAKE_PTR(CellData, p_cell_data);
110 }
111
113 {
114 // Add empty cell edge data
115 MAKE_PTR(CellEdgeData, p_cell_edge_data);
116 mCellPropertyCollection.AddProperty(p_cell_edge_data);
117 }
118
119 /*
120 * If a cell proliferative type was not passed in via the input
121 * argument cellPropertyCollection (for example as in the case
122 * of a daughter cell being created following division) then add
123 * add a 'default' cell proliferative type to the cell property
124 * collection. This ensures that the method GetCellProliferativeType()
125 * always returns a valid proliferative type.
126 */
128 {
129 mCellPropertyCollection.AddProperty(CellPropertyRegistry::Instance()->Get<DefaultCellProliferativeType>());
130 }
131
132 if (!archiving)
133 {
134 // Increment cell count for each cell property in mCellPropertyCollection
136 property_iter != mCellPropertyCollection.End();
137 ++property_iter)
138 {
139 (*property_iter)->IncrementCellCount();
140 }
141 }
142}
143
145{
146 if (!mIsDead)
147 {
148 Kill();
149 }
150 delete mpCellCycleModel;
151 delete mpSrnModel;
152}
153
154void Cell::SetCellProliferativeType(boost::shared_ptr<AbstractCellProperty> pProliferativeType)
155{
156 if (!pProliferativeType->IsSubType<AbstractCellProliferativeType>())
157 {
158 EXCEPTION("Attempting to give cell a cell proliferative type that is not a subtype of AbstractCellProliferativeType");
159 }
160
161 boost::shared_ptr<AbstractCellProliferativeType> p_old_proliferative_type = GetCellProliferativeType();
162
163 p_old_proliferative_type->DecrementCellCount();
164 mCellPropertyCollection.RemoveProperty(p_old_proliferative_type);
165
166 AddCellProperty(pProliferativeType);
167}
168
169boost::shared_ptr<AbstractCellProliferativeType> Cell::GetCellProliferativeType() const
170{
172
173 /*
174 * Note: In its current form the code requires each cell to have exactly
175 * one proliferative type. This is reflected in the assertion below. If a user
176 * wishes to include cells with multiple proliferative types, each possible
177 * combination must be created as a separate proliferative type class.
178 */
179 assert(proliferative_type_collection.GetSize() == 1);
180
181 return boost::static_pointer_cast<AbstractCellProliferativeType>(proliferative_type_collection.GetProperty());
182}
183
185{
186 if (mpCellCycleModel != pCellCycleModel)
187 {
188 delete mpCellCycleModel;
189 }
190 mpCellCycleModel = pCellCycleModel;
191 mpCellCycleModel->SetCell(CellPtr(this, null_deleter()));
192}
193
198
203
205{
206 if (mpSrnModel != pSrnModel)
207 {
208 delete mpSrnModel;
209 }
210 mpSrnModel = pSrnModel;
211 mpSrnModel->SetCell(CellPtr(this, null_deleter()));
212 mHasSrnModel = true;
213}
214
216{
217 return mpSrnModel;
218}
219
224
225double Cell::GetAge() const
226{
227 return mpCellCycleModel->GetAge();
228}
229
230double Cell::GetBirthTime() const
231{
233}
234
235void Cell::SetBirthTime(double birthTime)
236{
237 mpCellCycleModel->SetBirthTime(birthTime);
238}
239
240void Cell::SetMutationState(boost::shared_ptr<AbstractCellProperty> pMutationState)
241{
242 if (!pMutationState->IsSubType<AbstractCellMutationState>())
243 {
244 EXCEPTION("Attempting to give cell a cell mutation state that is not a subtype of AbstractCellMutationState");
245 }
246
247 boost::shared_ptr<AbstractCellMutationState> p_old_mutation_state = GetMutationState();
248 p_old_mutation_state->DecrementCellCount();
249 mCellPropertyCollection.RemoveProperty(p_old_mutation_state);
250
251 AddCellProperty(pMutationState);
252}
253
254boost::shared_ptr<AbstractCellMutationState> Cell::GetMutationState() const
255{
257
258 /*
259 * Note: In its current form the code requires each cell to have exactly
260 * one mutation state. This is reflected in the assertion below. If a user
261 * wishes to include cells with multiple mutation states, each possible
262 * combination must be created as a separate mutation state class.
263 */
264 assert(mutation_state_collection.GetSize() == 1);
265
266 return boost::static_pointer_cast<AbstractCellMutationState>(mutation_state_collection.GetProperty());
267}
268
269boost::shared_ptr<CellData> Cell::GetCellData() const
270{
272
273 /*
274 * Note: In its current form the code requires each cell to have exactly
275 * one CellData object. This is reflected in the assertion below.
276 */
277 assert(cell_data_collection.GetSize() <= 1);
278
279 return boost::static_pointer_cast<CellData>(cell_data_collection.GetProperty());
280}
281
282boost::shared_ptr<CellEdgeData> Cell::GetCellEdgeData() const
283{
285
286 /*
287 * Note: In its current form the code requires each cell to have exactly
288 * one CellEdgeData object. This is reflected in the assertion below.
289 */
290 assert(collection.GetSize() <= 1);
291
292 return boost::static_pointer_cast<CellEdgeData>(collection.GetProperty());
293}
294
299
300boost::shared_ptr<CellVecData> Cell::GetCellVecData() const
301{
302 assert(HasCellVecData());
303
305
306 /*
307 * Note: In its current form the code requires each cell to have exactly
308 * one CellVecData object. This is reflected in the assertion below.
309 */
310 assert(cell_data_collection.GetSize() <= 1);
311
312 return boost::static_pointer_cast<CellVecData>(cell_data_collection.GetProperty());
313}
314
319
324
325void Cell::AddCellProperty(const boost::shared_ptr<AbstractCellProperty>& rProperty)
326{
327 // Note: if the cell already has the specified property, no action is taken
328 if (!mCellPropertyCollection.HasProperty(rProperty))
329 {
331 rProperty->IncrementCellCount();
332 }
333}
334
336{
337 mIsLogged = true;
338}
339
341{
342 return mIsLogged;
343}
344
345void Cell::StartApoptosis(bool setDeathTime)
346{
347 assert(!IsDead());
348
350 {
351 EXCEPTION("StartApoptosis() called when already undergoing apoptosis");
352 }
355 if (setDeathTime)
356 {
358 }
359 else
360 {
361 mDeathTime = DBL_MAX;
362 }
364}
365
367{
369}
370
372{
374}
375
377{
378 return mApoptosisTime;
379}
380
381void Cell::SetApoptosisTime(double apoptosisTime)
382{
383 assert(apoptosisTime > 0.0);
384 mApoptosisTime = apoptosisTime;
385}
386
388{
389 if (!mUndergoingApoptosis || mDeathTime==DBL_MAX)
390 {
391 EXCEPTION("Shouldn't be checking time until apoptosis as it isn't set");
392 }
393
395}
396
398{
400 {
401 double sloppy_death_time = mDeathTime - DBL_EPSILON * mApoptosisTime;
402 if (SimulationTime::Instance()->GetTime() >= sloppy_death_time )
403 {
404 this->Kill();
405 }
406 }
407 return mIsDead;
408}
409
411{
412 // Decrement cell count for each cell property in mCellPropertyCollection
414 property_iter != mCellPropertyCollection.End();
415 ++property_iter)
416 {
417 (*property_iter)->DecrementCellCount();
418 }
419 mIsDead = true;
420}
421
422void Cell::SetAncestor(boost::shared_ptr<AbstractCellProperty> pCellAncestor)
423{
424 if (!pCellAncestor->IsSubType<CellAncestor>())
425 {
426 EXCEPTION("Attempting to give cell a cell ancestor which is not a CellAncestor");
427 }
428
429 // You can only set ancestors once
431 if (ancestor_collection.GetSize() == 0)
432 {
433 AddCellProperty(pCellAncestor);
434 }
435 else
436 {
437 // Overwrite the CellAncestor
438 RemoveCellProperty<CellAncestor>();
439 AddCellProperty(pCellAncestor);
440 }
441}
442
443unsigned Cell::GetAncestor() const
444{
446
447 assert(ancestor_collection.GetSize() <= 1);
448 if (ancestor_collection.GetSize() == 0)
449 {
450 return UNSIGNED_UNSET;
451 }
452
453 boost::shared_ptr<CellAncestor> p_ancestor = boost::static_pointer_cast<CellAncestor>(ancestor_collection.GetProperty());
454
455 return p_ancestor->GetAncestor();
456}
457
458unsigned Cell::GetCellId() const
459{
461
462 assert(cell_id_collection.GetSize() == 1);
463
464 boost::shared_ptr<CellId> p_cell_id = boost::static_pointer_cast<CellId>(cell_id_collection.GetProperty());
465
466 return p_cell_id->GetCellId();
467}
468
470{
471 assert(!IsDead());
472 if (mUndergoingApoptosis || HasCellProperty<ApoptoticCellProperty>())
473 {
474 return false;
475 }
476
477 // NOTE - we run the SRN model here first before the CCM
479
480 // This in turn runs any simulations within the CCM through ReadyToDivide();
482
483 return mCanDivide;
484}
485
487{
488 // Check we're allowed to divide
489 assert(!IsDead());
490 assert(mCanDivide);
491 mCanDivide = false;
492
493 // Reset properties of parent cell
496
497 // Create copy of cell property collection to modify for daughter cell
498 CellPropertyCollection daughter_property_collection = mCellPropertyCollection;
499
500 // Remove the CellId from the daughter cell, as a new one will be assigned in the constructor
501 daughter_property_collection.RemoveProperty<CellId>();
502
503 // Copy all cell data (note we create a new object not just copying the pointer)
504 assert(daughter_property_collection.HasPropertyType<CellData>());
505
506 // Get the existing copy of the cell data and remove it from the daughter cell
507 boost::shared_ptr<CellData> p_cell_data = GetCellData();
508 daughter_property_collection.RemoveProperty(p_cell_data);
509
510 // Create a new cell data object using the copy constructor and add this to the daughter cell
511 MAKE_PTR_ARGS(CellData, p_daughter_cell_data, (*p_cell_data));
512 daughter_property_collection.AddProperty(p_daughter_cell_data);
513
514 // Get the existing copy of the cell edge data and remove it from the daughter cell
515 boost::shared_ptr<CellEdgeData> p_cell_edge_data = GetCellEdgeData();
516 daughter_property_collection.RemoveProperty(p_cell_edge_data);
517
518 // Create a new cell edge data object using the copy constructor and add this to the daughter cell
519 MAKE_PTR_ARGS(CellEdgeData, p_daughter_cell_edge_data, (*p_cell_edge_data));
520 daughter_property_collection.AddProperty(p_daughter_cell_edge_data);
521
522 // Copy all cell Vec data (note we create a new object not just copying the pointer)
523 if (daughter_property_collection.HasPropertyType<CellVecData>())
524 {
525 // Get the existing copy of the cell data and remove it from the daughter cell
526 boost::shared_ptr<CellVecData> p_cell_vec_data = GetCellVecData();
527 daughter_property_collection.RemoveProperty(p_cell_vec_data);
528
529 // Create a new cell data object using the copy constructor and add this to the daughter cell
530 MAKE_PTR_ARGS(CellVecData, p_daughter_cell_vec_data, (*p_cell_vec_data));
531 daughter_property_collection.AddProperty(p_daughter_cell_vec_data);
532 }
533
534 // Create daughter cell with modified cell property collection
535 CellPtr p_new_cell(new Cell(GetMutationState(), mpCellCycleModel->CreateCellCycleModel(), mpSrnModel->CreateSrnModel(), false, daughter_property_collection));
536
537 // Initialise properties of daughter cell
538 p_new_cell->GetCellCycleModel()->InitialiseDaughterCell();
539 p_new_cell->GetSrnModel()->InitialiseDaughterCell();
540
541 // Set the daughter cell to inherit the apoptosis time of the parent cell
542 p_new_cell->SetApoptosisTime(mApoptosisTime);
543
544 return p_new_cell;
545}
546
548{
549 return mHasSrnModel;
550}
#define EXCEPTION(message)
const unsigned UNSIGNED_UNSET
Definition Exception.hpp:53
#define MAKE_PTR_ARGS(TYPE, NAME, ARGS)
#define MAKE_PTR(TYPE, NAME)
virtual void SetBirthTime(double birthTime)
virtual AbstractCellCycleModel * CreateCellCycleModel()=0
virtual bool ReadyToDivide()=0
virtual void SimulateToCurrentTime()=0
virtual AbstractSrnModel * CreateSrnModel()=0
virtual void SetCell(CellPtr pCell)
virtual void ResetForDivision()
virtual void Initialise()
bool HasProperty(const boost::shared_ptr< AbstractCellProperty > &rProp) const
boost::shared_ptr< AbstractCellProperty > GetProperty() const
CollectionType::iterator Iterator
CellPropertyCollection GetPropertiesType() const
void AddProperty(const boost::shared_ptr< AbstractCellProperty > &rProp)
CellPropertyRegistry * GetCellPropertyRegistry()
static CellPropertyRegistry * Instance()
boost::shared_ptr< AbstractCellProperty > Get()
Definition Cell.hpp:92
double mDeathTime
Definition Cell.hpp:134
double GetAge() const
Definition Cell.cpp:225
void Kill()
Definition Cell.cpp:410
bool mIsLogged
Definition Cell.hpp:152
void SetLogged()
Definition Cell.cpp:335
bool mHasSrnModel
Definition Cell.hpp:155
bool HasSrnModel() const
Definition Cell.cpp:547
unsigned GetCellId() const
Definition Cell.cpp:458
AbstractSrnModel * GetSrnModel() const
Definition Cell.cpp:215
AbstractCellCycleModel * GetCellCycleModel() const
Definition Cell.cpp:194
void InitialiseSrnModel()
Definition Cell.cpp:220
AbstractSrnModel * mpSrnModel
Definition Cell.hpp:131
AbstractCellCycleModel * mpCellCycleModel
Definition Cell.hpp:128
bool HasCellVecData() const
Definition Cell.cpp:295
void SetSrnModel(AbstractSrnModel *pSrnModel)
Definition Cell.cpp:204
Cell(boost::shared_ptr< AbstractCellProperty > pMutationState, AbstractCellCycleModel *pCellCycleModel, AbstractSrnModel *pSrnModel=nullptr, bool archiving=false, CellPropertyCollection cellPropertyCollection=CellPropertyCollection())
Definition Cell.cpp:45
double mStartOfApoptosisTime
Definition Cell.hpp:137
double GetBirthTime() const
Definition Cell.cpp:230
bool IsDead()
Definition Cell.cpp:397
double GetStartOfApoptosisTime() const
Definition Cell.cpp:371
void AddCellProperty(const boost::shared_ptr< AbstractCellProperty > &rProperty)
Definition Cell.cpp:325
void SetBirthTime(double birthTime)
Definition Cell.cpp:235
boost::shared_ptr< AbstractCellProliferativeType > GetCellProliferativeType() const
Definition Cell.cpp:169
CellPropertyCollection mCellPropertyCollection
Definition Cell.hpp:125
bool mUndergoingApoptosis
Definition Cell.hpp:143
bool mCanDivide
Definition Cell.hpp:122
void SetCellCycleModel(AbstractCellCycleModel *pCellCycleModel)
Definition Cell.cpp:184
boost::shared_ptr< CellData > GetCellData() const
Definition Cell.cpp:269
bool mIsDead
Definition Cell.hpp:149
bool HasApoptosisBegun() const
Definition Cell.cpp:366
unsigned GetAncestor() const
Definition Cell.cpp:443
boost::shared_ptr< CellVecData > GetCellVecData() const
Definition Cell.cpp:300
virtual ~Cell()
Definition Cell.cpp:144
bool ReadyToDivide()
Definition Cell.cpp:469
void SetApoptosisTime(double apoptosisTime)
Definition Cell.cpp:381
double GetApoptosisTime() const
Definition Cell.cpp:376
CellPropertyCollection & rGetCellPropertyCollection()
Definition Cell.cpp:315
boost::shared_ptr< CellEdgeData > GetCellEdgeData() const
Definition Cell.cpp:282
void SetMutationState(boost::shared_ptr< AbstractCellProperty > pMutationState)
Definition Cell.cpp:240
void SetCellProliferativeType(boost::shared_ptr< AbstractCellProperty > pProliferativeType)
Definition Cell.cpp:154
double mApoptosisTime
Definition Cell.hpp:140
void SetAncestor(boost::shared_ptr< AbstractCellProperty > pCellAncestor)
Definition Cell.cpp:422
void StartApoptosis(bool setDeathTime=true)
Definition Cell.cpp:345
double GetTimeUntilDeath() const
Definition Cell.cpp:387
void InitialiseCellCycleModel()
Definition Cell.cpp:199
virtual CellPtr Divide()
Definition Cell.cpp:486
boost::shared_ptr< AbstractCellMutationState > GetMutationState() const
Definition Cell.cpp:254
bool IsLogged()
Definition Cell.cpp:340
double GetTime() const
static SimulationTime * Instance()