Cell.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "Cell.hpp"
00030 #include "ApoptoticCellProperty.hpp"
00031 
00032 unsigned Cell::mMaxCellId = 0;
00033 
00046 struct null_deleter
00047 {
00049     void operator()(void const *) const
00050     {
00051     }
00052 };
00053 
00054 Cell::Cell(boost::shared_ptr<AbstractCellProperty> pMutationState,
00055            AbstractCellCycleModel* pCellCycleModel,
00056            bool archiving,
00057            CellPropertyCollection cellPropertyCollection)
00058     : mCanDivide(false),
00059       mCellPropertyCollection(cellPropertyCollection),
00060       mpCellCycleModel(pCellCycleModel),
00061       mAncestor(UNSIGNED_UNSET), // Has to be set by a SetAncestor() call (usually from CellPopulation)
00062       mDeathTime(DBL_MAX), // This has to be initialised for archiving
00063       mStartOfApoptosisTime(DBL_MAX),
00064       mApoptosisTime(0.25), // cell takes 15 min to fully undergo apoptosis
00065       mUndergoingApoptosis(false),
00066       mIsDead(false),
00067       mIsLogged(false)
00068 {
00069     if (SimulationTime::Instance()->IsStartTimeSetUp()==false)
00070     {
00071         EXCEPTION("Cell is setting up a cell-cycle model but SimulationTime has not been set up");
00072     }
00073 
00074     if (pCellCycleModel == NULL)
00075     {
00076         EXCEPTION("Cell-cycle model is null");
00077     }
00078 
00079     mpCellCycleModel->SetCell(CellPtr(this, null_deleter()));
00080 
00081     // Set cell identifier
00082     mCellId = ++ mMaxCellId -1;
00083 
00084     if (!pMutationState->IsSubType<AbstractCellMutationState>())
00085     {
00086         EXCEPTION("Attempting to create cell with a cell mutation state is not a subtype of AbstractCellMutationState");
00087     }
00088 
00089     if (!mCellPropertyCollection.HasProperty(pMutationState))
00090     {
00091         mCellPropertyCollection.AddProperty(pMutationState);
00092     }
00093 
00094     if (!archiving)
00095     {
00096         // Increment cell count for each cell property in mCellPropertyCollection
00097         for (CellPropertyCollection::Iterator property_iter = mCellPropertyCollection.Begin();
00098              property_iter != mCellPropertyCollection.End();
00099              ++property_iter)
00100         {
00101             (*property_iter)->IncrementCellCount();
00102         }
00103     }
00104 }
00105 
00106 Cell::~Cell()
00107 {
00108     if (!mIsDead)
00109     {
00110         Kill();
00111     }
00112     delete mpCellCycleModel;
00113 }
00114 
00115 void Cell::SetCellCycleModel(AbstractCellCycleModel* pCellCycleModel)
00116 {
00117     if (mpCellCycleModel != pCellCycleModel)
00118     {
00119         delete mpCellCycleModel;
00120     }
00121     mpCellCycleModel = pCellCycleModel;
00122     mpCellCycleModel->SetCell(CellPtr(this, null_deleter()));
00123 }
00124 
00125 AbstractCellCycleModel* Cell::GetCellCycleModel() const
00126 {
00127     return mpCellCycleModel;
00128 }
00129 
00130 void Cell::InitialiseCellCycleModel()
00131 {
00132     mpCellCycleModel->Initialise();
00133 }
00134 
00135 double Cell::GetAge() const
00136 {
00137     return mpCellCycleModel->GetAge();
00138 }
00139 
00140 double Cell::GetBirthTime() const
00141 {
00142     return mpCellCycleModel->GetBirthTime();
00143 }
00144 
00145 void Cell::SetBirthTime(double birthTime)
00146 {
00147     mpCellCycleModel->SetBirthTime(birthTime);
00148 }
00149 
00150 void Cell::SetMutationState(boost::shared_ptr<AbstractCellProperty> pMutationState)
00151 {
00152     if (!pMutationState->IsSubType<AbstractCellMutationState>())
00153     {
00154         EXCEPTION("Attempting to give cell a cell mutation state is not a subtype of AbstractCellMutationState");
00155     }
00156 
00157     boost::shared_ptr<AbstractCellMutationState> p_old_mutation_state = GetMutationState();
00158     p_old_mutation_state->DecrementCellCount();
00159     mCellPropertyCollection.RemoveProperty(p_old_mutation_state);
00160 
00161     AddCellProperty(pMutationState);
00162 }
00163 
00164 boost::shared_ptr<AbstractCellMutationState> Cell::GetMutationState() const
00165 {
00166     CellPropertyCollection mutation_state_collection = mCellPropertyCollection.GetPropertiesType<AbstractCellMutationState>();
00167 
00168     /*
00169      * Note: In its current form the code requires each cell to have exactly
00170      * one mutation state. This is reflected in the assertion below. If a user
00171      * wishes to include cells with multiple mutation states, each possible
00172      * combination must be created as a separate mutation state class.
00173      */
00174     assert(mutation_state_collection.GetSize() == 1);
00175 
00176     return boost::static_pointer_cast<AbstractCellMutationState>(mutation_state_collection.GetProperty());
00177 }
00178 
00179 CellPropertyCollection& Cell::rGetCellPropertyCollection()
00180 {
00181     return mCellPropertyCollection;
00182 }
00183 
00184 const CellPropertyCollection& Cell::rGetCellPropertyCollection() const
00185 {
00186     return mCellPropertyCollection;
00187 }
00188 
00189 void Cell::AddCellProperty(const boost::shared_ptr<AbstractCellProperty>& rProperty)
00190 {
00191     // Note: if the cell already has the specified property, no action is taken
00192     if (!mCellPropertyCollection.HasProperty(rProperty))
00193     {
00194         mCellPropertyCollection.AddProperty(rProperty);
00195         rProperty->IncrementCellCount();
00196     }
00197 }
00198 
00199 void Cell::SetLogged()
00200 {
00201     mIsLogged = true;
00202 }
00203 
00204 bool Cell::IsLogged()
00205 {
00206     return mIsLogged;
00207 }
00208 
00209 void Cell::StartApoptosis(bool setDeathTime)
00210 {
00211     assert(!IsDead());
00212 
00213     if (mUndergoingApoptosis)
00214     {
00215         EXCEPTION("StartApoptosis() called when already undergoing apoptosis");
00216     }
00217     mUndergoingApoptosis = true;
00218     mStartOfApoptosisTime = SimulationTime::Instance()->GetTime();
00219     if (setDeathTime)
00220     {
00221         mDeathTime = mStartOfApoptosisTime + mApoptosisTime;
00222     }
00223     else
00224     {
00225         mDeathTime = DBL_MAX;
00226     }
00227     AddCellProperty(mCellPropertyCollection.GetCellPropertyRegistry()->Get<ApoptoticCellProperty>());
00228 }
00229 
00230 bool Cell::HasApoptosisBegun() const
00231 {
00232     return mUndergoingApoptosis;
00233 }
00234 
00235 double Cell::GetStartOfApoptosisTime() const
00236 {
00237     return mStartOfApoptosisTime;
00238 }
00239 
00240 double Cell::GetApoptosisTime() const
00241 {
00242     return mApoptosisTime;
00243 }
00244 
00245 void Cell::SetApoptosisTime(double apoptosisTime)
00246 {
00247     assert(apoptosisTime > 0.0);
00248     mApoptosisTime = apoptosisTime;
00249 }
00250 
00251 double Cell::GetTimeUntilDeath() const
00252 {
00253     if (!mUndergoingApoptosis || mDeathTime==DBL_MAX)
00254     {
00255         EXCEPTION("Shouldn't be checking time until apoptosis as it isn't set");
00256     }
00257 
00258     return mDeathTime - SimulationTime::Instance()->GetTime();
00259 }
00260 
00261 bool Cell::IsDead()
00262 {
00263     if (mUndergoingApoptosis && !mIsDead)
00264     {
00265         double sloppy_death_time = mDeathTime - DBL_EPSILON * mApoptosisTime;
00266         if (SimulationTime::Instance()->GetTime() >= sloppy_death_time )
00267         {
00268             this->Kill();
00269         }
00270     }
00271     return mIsDead;
00272 }
00273 
00274 void Cell::Kill()
00275 {
00276     // Decrement cell count for each cell property in mCellPropertyCollection
00277     for (CellPropertyCollection::Iterator property_iter = mCellPropertyCollection.Begin();
00278          property_iter != mCellPropertyCollection.End();
00279          ++property_iter)
00280     {
00281         (*property_iter)->DecrementCellCount();
00282     }
00283     mIsDead = true;
00284 }
00285 
00286 void Cell::SetAncestor(unsigned ancestorIndex)
00287 {
00288     mAncestor = ancestorIndex;
00289 }
00290 
00291 unsigned Cell::GetAncestor() const
00292 {
00293     return mAncestor;
00294 }
00295 
00296 unsigned Cell::GetCellId() const
00297 {
00298     return mCellId;
00299 }
00300 
00301 void Cell::ResetMaxCellId()
00302 {
00303     mMaxCellId = 0;
00304 }
00305 
00306 bool Cell::ReadyToDivide()
00307 {
00308     assert(!IsDead());
00309     if (mUndergoingApoptosis || HasCellProperty<ApoptoticCellProperty>())
00310     {
00311         return false;
00312     }
00313 
00314     mCanDivide = mpCellCycleModel->ReadyToDivide();
00315 
00316     return mCanDivide;
00317 }
00318 
00319 CellPtr Cell::Divide()
00320 {
00321     // Check we're allowed to divide
00322     assert(!IsDead());
00323     assert(mCanDivide);
00324     mCanDivide = false;
00325 
00326     // Reset properties of parent cell
00327     mpCellCycleModel->ResetForDivision();
00328 
00329     // Create daughter cell
00330     CellPtr p_new_cell(new Cell(GetMutationState(), mpCellCycleModel->CreateCellCycleModel(), false, mCellPropertyCollection));
00331 
00332     // Initialise properties of daughter cell
00333     p_new_cell->GetCellCycleModel()->InitialiseDaughterCell();
00334     p_new_cell->SetAncestor(GetAncestor());
00335 
00336     return p_new_cell;
00337 }
Generated on Thu Dec 22 13:00:04 2011 for Chaste by  doxygen 1.6.3