CryptCellsGenerator.hpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #ifndef CRYPTCELLSGENERATOR_HPP_
00037 #define CRYPTCELLSGENERATOR_HPP_
00038 
00039 #include <boost/mpl/integral_c.hpp>
00040 #include <boost/type_traits/is_same.hpp>
00041 #include <boost/mpl/if.hpp>
00042 
00043 #include "CellsGenerator.hpp"
00044 
00045 #include "CellPropertyRegistry.hpp"
00046 #include "TetrahedralMesh.hpp"
00047 #include "VertexMesh.hpp"
00048 #include "PottsMesh.hpp"
00049 
00050 #include "StochasticDurationGenerationBasedCellCycleModel.hpp"
00051 #include "FixedDurationGenerationBasedCellCycleModel.hpp"
00052 #include "TysonNovakCellCycleModel.hpp"
00053 #include "WntCellCycleModel.hpp"
00054 #include "SimpleWntCellCycleModel.hpp"
00055 #include "StochasticWntCellCycleModel.hpp"
00056 #include "VanLeeuwen2009WntSwatCellCycleModelHypothesisOne.hpp"
00057 #include "VanLeeuwen2009WntSwatCellCycleModelHypothesisTwo.hpp"
00058 #include "Exception.hpp"
00059 #include "StemCellProliferativeType.hpp"
00060 #include "TransitCellProliferativeType.hpp"
00061 #include "DifferentiatedCellProliferativeType.hpp"
00062 
00063 
00068 template<class T1, class T2>
00069 bool ClassesAreSame()
00070 {
00071     using namespace boost::mpl;
00072     using namespace boost;
00073     typedef typename if_< is_same<T1, T2>, integral_c<unsigned, 1>, integral_c<unsigned, 0> >::type selector_t;
00074     return  (selector_t()==1);
00075 }
00076 
00082 template<class CELL_CYCLE_MODEL>
00083 class CryptCellsGenerator : public CellsGenerator<CELL_CYCLE_MODEL,2>
00084 {
00085 public:
00086 
00104     void Generate(std::vector<CellPtr>& rCells,
00105                   AbstractMesh<2,2>* pMesh,
00106                   const std::vector<unsigned> locationIndices,
00107                   bool randomBirthTimes,
00108                   double y0 = 0.3,
00109                   double y1 = 2.0,
00110                   double y2 = 3.0,
00111                   double y3 = 4.0,
00112                   bool initialiseCells = false);
00113 };
00114 
00115 template<class CELL_CYCLE_MODEL>
00116 void CryptCellsGenerator<CELL_CYCLE_MODEL>::Generate(
00117                                       std::vector<CellPtr>& rCells,
00118                                       AbstractMesh<2,2>* pMesh,
00119                                       const std::vector<unsigned> locationIndices,
00120                                       bool randomBirthTimes,
00121                                       double y0,
00122                                       double y1,
00123                                       double y2,
00124                                       double y3,
00125                                       bool initialiseCells)
00126 {
00127     rCells.clear();
00128 
00129     RandomNumberGenerator* p_random_num_gen = RandomNumberGenerator::Instance();
00130 
00131     unsigned mesh_size;
00132     if (dynamic_cast<TetrahedralMesh<2,2>*>(pMesh))
00133     {
00134         mesh_size = pMesh->GetNumNodes();
00135         unsigned num_cells = locationIndices.empty() ? pMesh->GetNumNodes() : locationIndices.size();
00136         rCells.reserve(num_cells);
00137     }
00138     else if (dynamic_cast<PottsMesh<2>*>(pMesh))
00139     {
00140         mesh_size = static_cast<PottsMesh<2>*>(pMesh)->GetNumElements();
00141         rCells.reserve(mesh_size);
00142     }
00143     else
00144     {
00145         // Note the double brackets, to stop the macro thinking is has two arguments.
00146         assert((dynamic_cast<VertexMesh<2,2>*>(pMesh)));
00147         mesh_size = static_cast<VertexMesh<2,2>*>(pMesh)->GetNumElements();
00148         rCells.reserve(mesh_size);
00149     }
00150 
00151     boost::shared_ptr<AbstractCellProperty> p_state(CellPropertyRegistry::Instance()->Get<WildTypeCellMutationState>());
00152 
00153     // Loop over the mesh and populate rCells
00154     for (unsigned i=0; i<mesh_size; i++)
00155     {
00156         // Find the location of this cell
00157         double y = 0.0;
00158         if (dynamic_cast<TetrahedralMesh<2,2>*>(pMesh))
00159         {
00160             if (locationIndices.empty())
00161             {
00162                 y = pMesh->GetNode(i)->GetPoint().rGetLocation()[1];
00163 
00164             }
00165             else if (std::find(locationIndices.begin(), locationIndices.end(), i) != locationIndices.end())
00166             {
00167                 y = pMesh->GetNode(i)->GetPoint().rGetLocation()[1];
00168             }
00169         }
00170         else if (dynamic_cast<PottsMesh<2>*>(pMesh))
00171         {
00172             y = static_cast<PottsMesh<2>*>(pMesh)->GetCentroidOfElement(i)[1];
00173         }
00174         else
00175         {
00176             // Note the double brackets, to stop the macro thinking is has two arguments.
00177             assert((dynamic_cast<VertexMesh<2,2>*>(pMesh)));
00178             y = static_cast<VertexMesh<2,2>*>(pMesh)->GetCentroidOfElement(i)[1];
00179         }
00180 
00181         // Create a cell-cycle model and set the spatial dimension
00182         CELL_CYCLE_MODEL* p_cell_cycle_model = new CELL_CYCLE_MODEL;
00183         p_cell_cycle_model->SetDimension(2);
00184 
00185         double typical_transit_cycle_time = p_cell_cycle_model->GetAverageTransitCellCycleTime();
00186         double typical_stem_cycle_time = p_cell_cycle_model->GetAverageStemCellCycleTime();
00187 
00188         double birth_time = 0.0;
00189         if (randomBirthTimes)
00190         {
00191             birth_time = -p_random_num_gen->ranf();
00192         }
00193 
00194         // Set the cell-cycle model's generation if required
00195         unsigned generation = 4;
00196         if (y <= y0)
00197         {
00198             generation = 0;
00199         }
00200         else if (y < y1)
00201         {
00202             generation = 1;
00203         }
00204         else if (y < y2)
00205         {
00206             generation = 2;
00207         }
00208         else if (y < y3)
00209         {
00210             generation = 3;
00211         }
00212         if (dynamic_cast<AbstractSimpleGenerationBasedCellCycleModel*>(p_cell_cycle_model))
00213         {
00214             dynamic_cast<AbstractSimpleGenerationBasedCellCycleModel*>(p_cell_cycle_model)->SetGeneration(generation);
00215         }
00216 
00217         // Create a cell
00218         CellPtr p_cell(new Cell(p_state, p_cell_cycle_model));
00219 
00220         // Set the cell's proliferative type, dependent on its height up the crypt and whether it can terminally differentiate
00221         if (y <= y0)
00222         {
00223             p_cell->SetCellProliferativeType(CellPropertyRegistry::Instance()->Get<StemCellProliferativeType>());
00224         }
00225         else
00226         {
00227             p_cell->SetCellProliferativeType(CellPropertyRegistry::Instance()->Get<TransitCellProliferativeType>());
00228             if (y >= y3 && p_cell_cycle_model->CanCellTerminallyDifferentiate())
00229             {
00230                 p_cell->SetCellProliferativeType(CellPropertyRegistry::Instance()->Get<DifferentiatedCellProliferativeType>());
00231             }
00232         }
00233 
00234         // Initialise the cell-cycle model if this is required
00235         if (initialiseCells)
00236         {
00237             p_cell->InitialiseCellCycleModel();
00238         }
00239 
00240         // Set the cell's birth time
00241         if (y <= y0)
00242         {
00243             birth_time *= typical_stem_cycle_time; // hours
00244         }
00245         else
00246         {
00247             birth_time *= typical_transit_cycle_time; // hours
00248         }
00249         p_cell->SetBirthTime(birth_time);
00250 
00251         if (locationIndices.empty())
00252         {
00253             rCells.push_back(p_cell);
00254         }
00255         else if (std::find(locationIndices.begin(), locationIndices.end(), i) != locationIndices.end())
00256         {
00257             rCells.push_back(p_cell);
00258         }
00259     }
00260 }
00261 
00262 #endif /* CRYPTCELLSGENERATOR_HPP_ */

Generated by  doxygen 1.6.2