Chaste  Release::3.4
CryptCellsGenerator.hpp
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 #ifndef CRYPTCELLSGENERATOR_HPP_
37 #define CRYPTCELLSGENERATOR_HPP_
38 
39 #include <boost/mpl/integral_c.hpp>
40 #include <boost/type_traits/is_same.hpp>
41 #include <boost/mpl/if.hpp>
42 
43 #include "CellsGenerator.hpp"
44 
45 #include "CellPropertyRegistry.hpp"
46 #include "TetrahedralMesh.hpp"
47 #include "VertexMesh.hpp"
48 #include "PottsMesh.hpp"
49 
50 #include "StochasticDurationGenerationBasedCellCycleModel.hpp"
51 #include "FixedDurationGenerationBasedCellCycleModel.hpp"
52 #include "TysonNovakCellCycleModel.hpp"
53 #include "WntCellCycleModel.hpp"
54 #include "SimpleWntCellCycleModel.hpp"
55 #include "StochasticWntCellCycleModel.hpp"
56 #include "VanLeeuwen2009WntSwatCellCycleModelHypothesisOne.hpp"
57 #include "VanLeeuwen2009WntSwatCellCycleModelHypothesisTwo.hpp"
58 #include "Exception.hpp"
59 #include "StemCellProliferativeType.hpp"
60 #include "TransitCellProliferativeType.hpp"
61 #include "DifferentiatedCellProliferativeType.hpp"
62 
63 
68 template<class T1, class T2>
69 bool ClassesAreSame()
70 {
71  using namespace boost::mpl;
72  using namespace boost;
73  typedef typename if_< is_same<T1, T2>, integral_c<unsigned, 1>, integral_c<unsigned, 0> >::type selector_t;
74  return (selector_t()==1);
75 }
76 
82 template<class CELL_CYCLE_MODEL>
83 class CryptCellsGenerator : public CellsGenerator<CELL_CYCLE_MODEL,2>
84 {
85 public:
86 
104  void Generate(std::vector<CellPtr>& rCells,
105  AbstractMesh<2,2>* pMesh,
106  const std::vector<unsigned> locationIndices,
107  bool randomBirthTimes,
108  double y0 = 0.3,
109  double y1 = 2.0,
110  double y2 = 3.0,
111  double y3 = 4.0,
112  bool initialiseCells = false);
113 };
114 
115 template<class CELL_CYCLE_MODEL>
117  std::vector<CellPtr>& rCells,
118  AbstractMesh<2,2>* pMesh,
119  const std::vector<unsigned> locationIndices,
120  bool randomBirthTimes,
121  double y0,
122  double y1,
123  double y2,
124  double y3,
125  bool initialiseCells)
126 {
127  rCells.clear();
128 
130 
131  unsigned mesh_size;
132  if (dynamic_cast<TetrahedralMesh<2,2>*>(pMesh))
133  {
134  mesh_size = pMesh->GetNumNodes();
135  unsigned num_cells = locationIndices.empty() ? pMesh->GetNumNodes() : locationIndices.size();
136  rCells.reserve(num_cells);
137  }
138  else if (dynamic_cast<PottsMesh<2>*>(pMesh))
139  {
140  mesh_size = static_cast<PottsMesh<2>*>(pMesh)->GetNumElements();
141  rCells.reserve(mesh_size);
142  }
143  else
144  {
145  // Note the double brackets, to stop the macro thinking is has two arguments.
146  assert((dynamic_cast<VertexMesh<2,2>*>(pMesh)));
147  mesh_size = static_cast<VertexMesh<2,2>*>(pMesh)->GetNumElements();
148  rCells.reserve(mesh_size);
149  }
150 
151  boost::shared_ptr<AbstractCellProperty> p_state(CellPropertyRegistry::Instance()->Get<WildTypeCellMutationState>());
152 
153  // Loop over the mesh and populate rCells
154  for (unsigned i=0; i<mesh_size; i++)
155  {
156  // Find the location of this cell
157  double y = 0.0;
158  if (dynamic_cast<TetrahedralMesh<2,2>*>(pMesh))
159  {
160  if (locationIndices.empty())
161  {
162  y = pMesh->GetNode(i)->GetPoint().rGetLocation()[1];
163 
164  }
165  else if (std::find(locationIndices.begin(), locationIndices.end(), i) != locationIndices.end())
166  {
167  y = pMesh->GetNode(i)->GetPoint().rGetLocation()[1];
168  }
169  }
170  else if (dynamic_cast<PottsMesh<2>*>(pMesh))
171  {
172  y = static_cast<PottsMesh<2>*>(pMesh)->GetCentroidOfElement(i)[1];
173  }
174  else
175  {
176  // Note the double brackets, to stop the macro thinking is has two arguments.
177  assert((dynamic_cast<VertexMesh<2,2>*>(pMesh)));
178  y = static_cast<VertexMesh<2,2>*>(pMesh)->GetCentroidOfElement(i)[1];
179  }
180 
181  // Create a cell-cycle model and set the spatial dimension
182  CELL_CYCLE_MODEL* p_cell_cycle_model = new CELL_CYCLE_MODEL;
183  p_cell_cycle_model->SetDimension(2);
184 
185  double typical_transit_cycle_time = p_cell_cycle_model->GetAverageTransitCellCycleTime();
186  double typical_stem_cycle_time = p_cell_cycle_model->GetAverageStemCellCycleTime();
187 
188  double birth_time = 0.0;
189  if (randomBirthTimes)
190  {
191  birth_time = -p_random_num_gen->ranf();
192  }
193 
194  // Set the cell-cycle model's generation if required
195  unsigned generation = 4;
196  if (y <= y0)
197  {
198  generation = 0;
199  }
200  else if (y < y1)
201  {
202  generation = 1;
203  }
204  else if (y < y2)
205  {
206  generation = 2;
207  }
208  else if (y < y3)
209  {
210  generation = 3;
211  }
212  if (dynamic_cast<AbstractSimpleGenerationBasedCellCycleModel*>(p_cell_cycle_model))
213  {
214  dynamic_cast<AbstractSimpleGenerationBasedCellCycleModel*>(p_cell_cycle_model)->SetGeneration(generation);
215  }
216 
217  // Create a cell
218  CellPtr p_cell(new Cell(p_state, p_cell_cycle_model));
219 
220  // Set the cell's proliferative type, dependent on its height up the crypt and whether it can terminally differentiate
221  if (y <= y0)
222  {
223  p_cell->SetCellProliferativeType(CellPropertyRegistry::Instance()->Get<StemCellProliferativeType>());
224  }
225  else
226  {
227  p_cell->SetCellProliferativeType(CellPropertyRegistry::Instance()->Get<TransitCellProliferativeType>());
228  if (y >= y3 && p_cell_cycle_model->CanCellTerminallyDifferentiate())
229  {
230  p_cell->SetCellProliferativeType(CellPropertyRegistry::Instance()->Get<DifferentiatedCellProliferativeType>());
231  }
232  }
233 
234  // Initialise the cell-cycle model if this is required
235  if (initialiseCells)
236  {
237  p_cell->InitialiseCellCycleModel();
238  }
239 
240  // Set the cell's birth time
241  if (y <= y0)
242  {
243  birth_time *= typical_stem_cycle_time; // hours
244  }
245  else
246  {
247  birth_time *= typical_transit_cycle_time; // hours
248  }
249  p_cell->SetBirthTime(birth_time);
250 
251  if (locationIndices.empty())
252  {
253  rCells.push_back(p_cell);
254  }
255  else if (std::find(locationIndices.begin(), locationIndices.end(), i) != locationIndices.end())
256  {
257  rCells.push_back(p_cell);
258  }
259  }
260 }
261 
262 #endif /* CRYPTCELLSGENERATOR_HPP_ */
void Generate(std::vector< CellPtr > &rCells, AbstractMesh< 2, 2 > *pMesh, const std::vector< unsigned > locationIndices, bool randomBirthTimes, double y0=0.3, double y1=2.0, double y2=3.0, double y3=4.0, bool initialiseCells=false)
Definition: Cell.hpp:77
Node< SPACE_DIM > * GetNode(unsigned index) const
virtual unsigned GetNumNodes() const
static CellPropertyRegistry * Instance()
static RandomNumberGenerator * Instance()