CryptSimulation2d.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 "CryptSimulation2d.hpp"
00030 #include "WntConcentration.hpp"
00031 #include "VanLeeuwen2009WntSwatCellCycleModelHypothesisOne.hpp"
00032 #include "VanLeeuwen2009WntSwatCellCycleModelHypothesisTwo.hpp"
00033 
00034 CryptSimulation2d::CryptSimulation2d(AbstractCellPopulation<2>& rCellPopulation,
00035                                      bool deleteCellPopulationAndForceCollection,
00036                                      bool initialiseCells)
00037     : CellBasedSimulation<2>(rCellPopulation,
00038                              deleteCellPopulationAndForceCollection,
00039                              initialiseCells),
00040       mUseJiggledBottomCells(false),
00041       mWriteBetaCatenin(false)
00042 {
00043     mpStaticCastCellPopulation = static_cast<MeshBasedCellPopulationWithGhostNodes<2>*>(&mrCellPopulation);
00044 
00045     /*
00046      * To check if beta-catenin results will be written to file, we test if the first
00047      * cell has a cell-cycle model that is a subclass of AbstractVanLeeuwen2009WntSwatCellCycleModel.
00048      * In doing so, we assume that all cells in the simulation have the same cell cycle
00049      * model.
00050      */
00051     if (dynamic_cast<AbstractVanLeeuwen2009WntSwatCellCycleModel*>(mrCellPopulation.Begin()->GetCellCycleModel()))
00052     {
00053         mWriteBetaCatenin = true;
00054     }
00055 }
00056 
00057 c_vector<double, 2> CryptSimulation2d::CalculateCellDivisionVector(CellPtr pParentCell)
00058 {
00059     // Location of parent and daughter cells
00060     c_vector<double, 2> parent_coords = mrCellPopulation.GetLocationOfCellCentre(pParentCell);
00061     c_vector<double, 2> daughter_coords;
00062 
00063     // Get separation parameter
00064     double separation = mpStaticCastCellPopulation->GetMeinekeDivisionSeparation();
00065 
00066     // Make a random direction vector of the required length
00067     c_vector<double, 2> random_vector;
00068 
00069     /*
00070      * Pick a random direction and move the parent cell backwards by 0.5*separation
00071      * in that direction and return the position of the daughter cell 0.5*separation
00072      * forwards in that direction.
00073      */
00074 
00075     double random_angle = RandomNumberGenerator::Instance()->ranf();
00076     random_angle *= 2.0*M_PI;
00077 
00078     random_vector(0) = 0.5*separation*cos(random_angle);
00079     random_vector(1) = 0.5*separation*sin(random_angle);
00080 
00081     c_vector<double, 2> proposed_new_parent_coords = parent_coords - random_vector;
00082     c_vector<double, 2> proposed_new_daughter_coords = parent_coords + random_vector;
00083 
00084     if ((proposed_new_parent_coords(1) >= 0.0) && (proposed_new_daughter_coords(1) >= 0.0))
00085     {
00086         // We are not too close to the bottom of the cell population, so move parent
00087         parent_coords = proposed_new_parent_coords;
00088         daughter_coords = proposed_new_daughter_coords;
00089     }
00090     else
00091     {
00092         proposed_new_daughter_coords = parent_coords + 2.0*random_vector;
00093         while (proposed_new_daughter_coords(1) < 0.0)
00094         {
00095             random_angle = RandomNumberGenerator::Instance()->ranf();
00096             random_angle *= 2.0*M_PI;
00097 
00098             random_vector(0) = separation*cos(random_angle);
00099             random_vector(1) = separation*sin(random_angle);
00100             proposed_new_daughter_coords = parent_coords + random_vector;
00101         }
00102         daughter_coords = proposed_new_daughter_coords;
00103     }
00104 
00105     assert(daughter_coords(1) >= 0.0); // to make sure dividing cells stay in the cell population
00106     assert(parent_coords(1) >= 0.0);   // to make sure dividing cells stay in the cell population
00107 
00108     // Set the parent to use this location
00109     ChastePoint<2> parent_coords_point(parent_coords);
00110 
00111     unsigned node_index = mrCellPopulation.GetLocationIndexUsingCell(pParentCell);
00112     mrCellPopulation.SetNode(node_index, parent_coords_point);
00113 
00114     return daughter_coords;
00115 }
00116 
00117 void CryptSimulation2d::WriteVisualizerSetupFile()
00118 {
00119     *mpVizSetupFile << "MeshWidth\t" << mrCellPopulation.GetWidth(0) << "\n";
00120 }
00121 
00122 void CryptSimulation2d::SetupWriteBetaCatenin()
00123 {
00124     OutputFileHandler output_file_handler(this->mSimulationOutputDirectory + "/", false);
00125     mVizBetaCateninResultsFile = output_file_handler.OpenOutputFile("results.vizbetacatenin");
00126     *mpVizSetupFile << "BetaCatenin\n";
00127 }
00128 
00129 void CryptSimulation2d::WriteBetaCatenin(double time)
00130 {
00131     *mVizBetaCateninResultsFile <<  time << "\t";
00132 
00133     unsigned global_index;
00134     double x;
00135     double y;
00136     double b_cat_membrane;
00137     double b_cat_cytoplasm;
00138     double b_cat_nuclear;
00139 
00140     for (AbstractCellPopulation<2>::Iterator cell_iter = mrCellPopulation.Begin();
00141          cell_iter != mrCellPopulation.End();
00142          ++cell_iter)
00143     {
00144         global_index = mrCellPopulation.GetLocationIndexUsingCell(*cell_iter);
00145         x = mrCellPopulation.GetLocationOfCellCentre(*cell_iter)[0];
00146         y = mrCellPopulation.GetLocationOfCellCentre(*cell_iter)[1];
00147 
00148         // We should only be calling this code block if mWriteBetaCatenin has been set to true in the constructor
00149         assert(mWriteBetaCatenin);
00150 
00151         AbstractVanLeeuwen2009WntSwatCellCycleModel* p_model = dynamic_cast<AbstractVanLeeuwen2009WntSwatCellCycleModel*>(cell_iter->GetCellCycleModel());
00152         b_cat_membrane = p_model->GetMembraneBoundBetaCateninLevel();
00153         b_cat_cytoplasm = p_model->GetCytoplasmicBetaCateninLevel();
00154         b_cat_nuclear = p_model->GetNuclearBetaCateninLevel();
00155 
00156         *mVizBetaCateninResultsFile << global_index << " " << x << " " << y << " " << b_cat_membrane << " " << b_cat_cytoplasm << " " << b_cat_nuclear << " ";
00157     }
00158 
00159     *mVizBetaCateninResultsFile << "\n";
00160 }
00161 
00162 void CryptSimulation2d::SetupSolve()
00163 {
00164     /*
00165      * If there are any cells in the simulation, and mWriteBetaCatenin has been set
00166      * to true in the constructor, then set up the beta-catenin results file and
00167      * write the initial conditions to file.
00168      */
00169     bool any_cells_present = (mrCellPopulation.Begin() != mrCellPopulation.End());
00170     if (any_cells_present && mWriteBetaCatenin)
00171     {
00172         SetupWriteBetaCatenin();
00173         double current_time = SimulationTime::Instance()->GetTime();
00174         WriteBetaCatenin(current_time);
00175     }
00176 }
00177 
00178 void CryptSimulation2d::PostSolve()
00179 {
00180     SimulationTime* p_time = SimulationTime::Instance();
00181 
00182     if ((p_time->GetTimeStepsElapsed()+1)%mSamplingTimestepMultiple == 0)
00183     {
00184         /*
00185          * If there are any cells in the simulation, and mWriteBetaCatenin has been set
00186          * to true in the constructor, then set up the beta-catenin results file and
00187          * write the initial conditions to file.
00188          */
00189         bool any_cells_present = (mrCellPopulation.Begin() != mrCellPopulation.End());
00190         if (any_cells_present && mWriteBetaCatenin)
00191         {
00192             double time_next_step = p_time->GetTime() + p_time->GetTimeStep();
00193             WriteBetaCatenin(time_next_step);
00194         }
00195     }
00196 }
00197 
00198 void CryptSimulation2d::AfterSolve()
00199 {
00200     /*
00201      * If there are any cells in the simulation, and mWriteBetaCatenin has been set
00202      * to true in the constructor, then close the beta-catenin results file.
00203      */
00204     bool any_cells_present = (mrCellPopulation.Begin() != mrCellPopulation.End());
00205     if (any_cells_present && mWriteBetaCatenin)
00206     {
00207         mVizBetaCateninResultsFile->close();
00208     }
00209 }
00210 
00211 void CryptSimulation2d::UseJiggledBottomCells()
00212 {
00213     mUseJiggledBottomCells = true;
00214 }
00215 
00216 void CryptSimulation2d::ApplyCellPopulationBoundaryConditions(const std::vector< c_vector<double, 2> >& rOldLocations)
00217 {
00218     bool is_wnt_included = WntConcentration<2>::Instance()->IsWntSetUp();
00219     if (!is_wnt_included)
00220     {
00221         WntConcentration<2>::Destroy();
00222     }
00223 
00224     // Iterate over all nodes associated with real cells to update their positions
00225     // according to any cell population boundary conditions
00226     for (AbstractCellPopulation<2>::Iterator cell_iter = mrCellPopulation.Begin();
00227          cell_iter != mrCellPopulation.End();
00228          ++cell_iter)
00229     {
00230         // Get index of node associated with cell
00231         unsigned node_index = mrCellPopulation.GetLocationIndexUsingCell(*cell_iter);
00232 
00233         // Get pointer to this node
00234         Node<2>* p_node = mrCellPopulation.GetNode(node_index);
00235 
00236         if (!is_wnt_included)
00237         {
00242             if (cell_iter->GetCellCycleModel()->GetCellProliferativeType()==STEM)
00243             {
00244                 // Get old node location
00245                 c_vector<double, 2> old_node_location = rOldLocations[node_index];
00246 
00247                 // Return node to old location
00248                 p_node->rGetModifiableLocation()[0] = old_node_location[0];
00249                 p_node->rGetModifiableLocation()[1] = old_node_location[1];
00250             }
00251         }
00252 
00253         // Any cell that has moved below the bottom of the crypt must be moved back up
00254         if (p_node->rGetLocation()[1] < 0.0)
00255         {
00256             p_node->rGetModifiableLocation()[1] = 0.0;
00257             if (mUseJiggledBottomCells)
00258             {
00259                /*
00260                 * Here we give the cell a push upwards so that it doesn't
00261                 * get stuck on the bottom of the crypt (as per #422).
00262                 *
00263                 * Note that all stem cells may get moved to the same height, so
00264                 * we use a random perturbation to help ensure we are not simply
00265                 * faced with the same problem at a different height!
00266                 */
00267                 p_node->rGetModifiableLocation()[1] = 0.05*mpRandomGenerator->ranf();
00268             }
00269         }
00270         assert(p_node->rGetLocation()[1] >= 0.0);
00271     }
00272 }
00273 
00274 void CryptSimulation2d::SetBottomCellAncestors()
00275 {
00276     unsigned index = 0;
00277     for (AbstractCellPopulation<2>::Iterator cell_iter = mrCellPopulation.Begin();
00278          cell_iter != mrCellPopulation.End();
00279          ++cell_iter)
00280     {
00281         if (mrCellPopulation.GetLocationOfCellCentre(*cell_iter)[1] < 0.5)
00282         {
00283             cell_iter->SetAncestor(index++);
00284         }
00285     }
00286 }
00287 
00288 void CryptSimulation2d::OutputSimulationParameters(out_stream& rParamsFile)
00289 {
00290     *rParamsFile << "\t\t<CryptCircumference>" << mrCellPopulation.GetWidth(0) << "</CryptCircumference>\n";
00291     *rParamsFile << "\t\t<UseJiggledBottomCells>" << mUseJiggledBottomCells << "</UseJiggledBottomCells>\n";
00292 
00293     // Call method on direct parent class
00294     CellBasedSimulation<2>::OutputSimulationParameters(rParamsFile);
00295 }
00296 
00297 // Serialization for Boost >= 1.36
00298 #include "SerializationExportWrapperForCpp.hpp"
00299 CHASTE_CLASS_EXPORT(CryptSimulation2d)

Generated on Tue May 31 14:31:41 2011 for Chaste by  doxygen 1.5.5