CryptSimulation2d.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
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 
00035 CryptSimulation2d::CryptSimulation2d(AbstractTissue<2>& rTissue,
00036                   std::vector<AbstractForce<2>*> forceCollection,
00037                   bool deleteTissueAndForceCollection,
00038                   bool initialiseCells)
00039     : TissueSimulation<2>(rTissue,
00040                           forceCollection,
00041                           deleteTissueAndForceCollection,
00042                           initialiseCells),
00043       mUseJiggledBottomCells(false)
00044 {
00045     mpStaticCastTissue = static_cast<MeshBasedTissueWithGhostNodes<2>*>(&mrTissue);
00046 }
00047 
00048 
00049 c_vector<double, 2> CryptSimulation2d::CalculateCellDivisionVector(TissueCell& rParentCell)
00050 {
00051     // Location of parent and daughter cells
00052     c_vector<double, 2> parent_coords = mpStaticCastTissue->GetLocationOfCellCentre(rParentCell);
00053     c_vector<double, 2> daughter_coords;
00054 
00055     // Get separation parameter
00056     double separation = TissueConfig::Instance()->GetDivisionSeparation();
00057 
00058     // Make a random direction vector of the required length
00059     c_vector<double, 2> random_vector;
00060 
00061     /*
00062      * Pick a random direction and move the parent cell backwards by 0.5*separation
00063      * in that direction and return the position of the daughter cell 0.5*separation
00064      * forwards in that direction.
00065      */
00066 
00067     double random_angle = RandomNumberGenerator::Instance()->ranf();
00068     random_angle *= 2.0*M_PI;
00069 
00070     random_vector(0) = 0.5*separation*cos(random_angle);
00071     random_vector(1) = 0.5*separation*sin(random_angle);
00072 
00073     c_vector<double, 2> proposed_new_parent_coords = parent_coords - random_vector;
00074     c_vector<double, 2> proposed_new_daughter_coords = parent_coords + random_vector;
00075 
00076     if (   (proposed_new_parent_coords(1) >= 0.0)
00077         && (proposed_new_daughter_coords(1) >= 0.0))
00078     {
00079         // We are not too close to the bottom of the tissue, so move parent
00080         parent_coords = proposed_new_parent_coords;
00081         daughter_coords = proposed_new_daughter_coords;
00082     }
00083     else
00084     {
00085         proposed_new_daughter_coords = parent_coords + 2.0*random_vector;
00086         while (proposed_new_daughter_coords(1) < 0.0)
00087         {
00088             random_angle = RandomNumberGenerator::Instance()->ranf();
00089             random_angle *= 2.0*M_PI;
00090 
00091             random_vector(0) = separation*cos(random_angle);
00092             random_vector(1) = separation*sin(random_angle);
00093             proposed_new_daughter_coords = parent_coords + random_vector;
00094         }
00095         daughter_coords = proposed_new_daughter_coords;
00096     }
00097 
00098     assert(daughter_coords(1) >= 0.0); // to make sure dividing cells stay in the tissue
00099     assert(parent_coords(1) >= 0.0);   // to make sure dividing cells stay in the tissue
00100 
00101     // Set the parent to use this location
00102     ChastePoint<2> parent_coords_point(parent_coords);
00103 
00104     unsigned node_index = mpStaticCastTissue->GetLocationIndexUsingCell(rParentCell);
00105     mrTissue.SetNode(node_index, parent_coords_point);
00106 
00107     return daughter_coords;
00108 }
00109 
00110 
00111 void CryptSimulation2d::WriteVisualizerSetupFile()
00112 {
00113     *mpSetupFile << "MeshWidth\t" << mpStaticCastTissue->rGetMesh().GetWidth(0u) << "\n";// get furthest distance between nodes in the x-direction
00114 }
00115 
00116 
00117 void CryptSimulation2d::SetupWriteBetaCatenin()
00118 {
00119     OutputFileHandler output_file_handler(this->mSimulationOutputDirectory + "/", false);
00120     mBetaCatResultsFile = output_file_handler.OpenOutputFile("results.vizbetacatenin");
00121     *mpSetupFile << "BetaCatenin\n";
00122 }
00123 
00124 
00125 void CryptSimulation2d::WriteBetaCatenin(double time)
00126 {
00127     *mBetaCatResultsFile <<  time << "\t";
00128 
00129     unsigned global_index;
00130     double x;
00131     double y;
00132     double b_cat_membrane;
00133     double b_cat_cytoplasm;
00134     double b_cat_nuclear;
00135 
00136     for (AbstractTissue<2>::Iterator cell_iter = mrTissue.Begin();
00137          cell_iter != mrTissue.End();
00138          ++cell_iter)
00139     {
00140         global_index = mpStaticCastTissue->GetLocationIndexUsingCell(*cell_iter);
00141         x = mpStaticCastTissue->GetLocationOfCellCentre(*cell_iter)[0];
00142         y = mpStaticCastTissue->GetLocationOfCellCentre(*cell_iter)[1];
00143 
00144         // If writing beta-catenin, the model has to be an VanLeeuwen2009WntSwatCellCycleModel
00145         AbstractVanLeeuwen2009WntSwatCellCycleModel* p_model = dynamic_cast<AbstractVanLeeuwen2009WntSwatCellCycleModel*>(cell_iter->GetCellCycleModel());
00146         assert(p_model); // if this fails, it wasn't a VanLeeuwen2009WntSwatCellCycleModel!!
00147 
00148         b_cat_membrane = p_model->GetMembraneBoundBetaCateninLevel();
00149         b_cat_cytoplasm = p_model->GetCytoplasmicBetaCateninLevel();
00150         b_cat_nuclear = p_model->GetNuclearBetaCateninLevel();
00151 
00152         *mBetaCatResultsFile << global_index << " " << x << " " << y << " " << b_cat_membrane << " " << b_cat_cytoplasm << " " << b_cat_nuclear << " ";
00153     }
00154 
00155     *mBetaCatResultsFile << "\n";
00156 }
00157 
00158 
00159 void CryptSimulation2d::SetupSolve()
00160 {
00161     if (   (mrTissue.Begin() != mrTissue.End()) // there are any cells
00162         && (dynamic_cast<AbstractVanLeeuwen2009WntSwatCellCycleModel*>(mrTissue.Begin()->GetCellCycleModel())) ) // assume all the cells are the same
00163     {
00164         SetupWriteBetaCatenin();
00165         double current_time = SimulationTime::Instance()->GetTime();
00166         WriteBetaCatenin(current_time);
00167     }
00168 
00169     OutputParameters();
00170 }
00171 
00172 void CryptSimulation2d::OutputParameters()
00173 {
00174     // Create Output file
00175     OutputFileHandler output_file_handler(this->mSimulationOutputDirectory + "/", false);
00176 
00177     out_stream ParameterFile = output_file_handler.OpenOutputFile("results.parameters");
00178 
00179     TissueConfig* p_inst = TissueConfig::Instance();
00180 
00181     *ParameterFile << "SG2MDuration \t" << p_inst->GetSG2MDuration() << " \n";
00182     *ParameterFile << "SDuration \t" << p_inst->GetSDuration() << " \n";
00183     *ParameterFile << "G2Duration \t" << p_inst->GetG2Duration() << " \n";
00184     *ParameterFile << "MDuration \t" << p_inst->GetMDuration() << " \n";
00185     *ParameterFile << "StemCellG1Duration \t" << p_inst->GetStemCellG1Duration() << " \n";
00186     *ParameterFile << "TransitCellG1Duration \t" << p_inst->GetTransitCellG1Duration() << " \n";
00187     *ParameterFile << "HepaOneCellG1Duration \t" << p_inst->GetHepaOneCellG1Duration() << " \n";
00188     *ParameterFile << "MinimumGapDuration \t" << p_inst->GetMinimumGapDuration() << " \n";
00189     *ParameterFile << "MaxTransitGenerations \t" << p_inst->GetMaxTransitGenerations() << " \n";
00190     *ParameterFile << "CryptLength \t" << p_inst->GetCryptLength() << " \n";
00191     *ParameterFile << "CryptWidth \t" << p_inst->GetCryptWidth() << " \n";
00192     *ParameterFile << "SpringStiffness \t" << p_inst->GetSpringStiffness() << " \n";
00193     *ParameterFile << "MechanicsCutOffLength \t" << p_inst->GetMechanicsCutOffLength() << " \n";
00194     *ParameterFile << "DampingConstantNormal \t" << p_inst->GetDampingConstantNormal() << " \n";
00195     *ParameterFile << "DampingConstantMutant \t" << p_inst->GetDampingConstantMutant() << " \n";
00196     *ParameterFile << "BetaCatSpringScaler \t" << p_inst->GetBetaCatSpringScaler() << " \n";
00197     *ParameterFile << "ApoptosisTime \t" << p_inst->GetApoptosisTime() << " \n";
00198     *ParameterFile << "HepaOneCellHypoxicConcentration \t" << p_inst->GetHepaOneCellHypoxicConcentration() << " \n";
00199     *ParameterFile << "HepaOneCellQuiescentConcentration \t" << p_inst->GetHepaOneCellQuiescentConcentration() << " \n";
00200     *ParameterFile << "WntStemThreshold \t" << p_inst->GetWntStemThreshold() << " \n";
00201     *ParameterFile << "WntTransitThreshold \t" << p_inst->GetWntTransitThreshold() << " \n";
00202     *ParameterFile << "WntLabelledThreshold \t" << p_inst->GetWntLabelledThreshold() << " \n";
00203     *ParameterFile << "WntConcentrationParameter \t" << p_inst->GetWntConcentrationParameter() << " \n";
00204     *ParameterFile << "CriticalHypoxicDuration \t" << p_inst->GetCriticalHypoxicDuration() << " \n";
00205     *ParameterFile << "CryptProjectionParameterA \t" << p_inst->GetCryptProjectionParameterA() << " \n";
00206     *ParameterFile << "CryptProjectionParameterB \t" << p_inst->GetCryptProjectionParameterB() << " \n";
00207     *ParameterFile << "ApoptoticSpringTensionStiffness \t" << p_inst->GetApoptoticSpringTensionStiffness() << " \n";
00208     *ParameterFile << "ApoptoticSpringCompressionStiffness \t" << p_inst->GetApoptoticSpringCompressionStiffness() << " \n";
00209     *ParameterFile << "WntChemotaxisStrength \t" << p_inst->GetWntChemotaxisStrength() << " \n";
00210     *ParameterFile << "SymmetricDivisionProbability \t" << p_inst->GetSymmetricDivisionProbability() << " \n";
00211     *ParameterFile << "AreaBasedDampingConstantParameter \t" << p_inst->GetAreaBasedDampingConstantParameter() << " \n";
00212     *ParameterFile << "DeformationEnergyParameter \t" << p_inst->GetDeformationEnergyParameter() << " \n";
00213     *ParameterFile << "MembraneSurfaceEnergyParameter \t" << p_inst->GetMembraneSurfaceEnergyParameter() << " \n";
00214     *ParameterFile << "CellCellAdhesionEnergyParameter \t" << p_inst->GetCellCellAdhesionEnergyParameter() << " \n";
00215     *ParameterFile << "CellBoundaryAdhesionEnergyParameter \t" << p_inst->GetCellBoundaryAdhesionEnergyParameter() << " \n";
00216     *ParameterFile << "WelikyOsterAreaParameter \t" << p_inst->GetWelikyOsterAreaParameter() << " \n";
00217     *ParameterFile << "WelikyOsterPerimeterParameter \t" << p_inst->GetWelikyOsterPerimeterParameter() << " \n";
00218     *ParameterFile << "OutputCellIdData \t" << p_inst->GetOutputCellIdData() << " \n";
00219     *ParameterFile << "OutputCellMutationStates \t" << p_inst->GetOutputCellMutationStates() << " \n";
00220     *ParameterFile << "OutputCellAncestors \t" << p_inst->GetOutputCellAncestors() << " \n";
00221     *ParameterFile << "OutputCellProliferativeTypes \t" << p_inst->GetOutputCellProliferativeTypes() << " \n";
00222     *ParameterFile << "OutputCellVariables \t" << p_inst->GetOutputCellVariables() << " \n";
00223     *ParameterFile << "OutputCellCyclePhases \t" << p_inst->GetOutputCellCyclePhases() << " \n";
00224     *ParameterFile << "OutputCellAges \t" << p_inst->GetOutputCellAges() << " \n";
00225     *ParameterFile << "OutputCellAreas \t" << p_inst->GetOutputCellAreas() << " \n";
00226     *ParameterFile << "OutputVoronoiData \t" << p_inst->GetOutputVoronoiData() << " \n";
00227     *ParameterFile << "OutputTissueAreas \t" << p_inst->GetOutputTissueAreas() << " \n";
00228     *ParameterFile << "OutputNodeVelocities \t" << p_inst->GetOutputNodeVelocities() << " \n";
00229 
00230     ParameterFile->close();
00231 }
00232 
00233 
00234 void CryptSimulation2d::PostSolve()
00235 {
00236     SimulationTime* p_time = SimulationTime::Instance();
00237 
00238     if ((p_time->GetTimeStepsElapsed()+1)%mSamplingTimestepMultiple==0)
00239     {
00240         if (   (mrTissue.Begin() != mrTissue.End()) // there are any cells
00241             && (dynamic_cast<AbstractVanLeeuwen2009WntSwatCellCycleModel*>(mrTissue.Begin()->GetCellCycleModel())) ) // assume all the cells are the same
00242         {
00243             double time_next_step = p_time->GetTime() + p_time->GetTimeStep();
00244             WriteBetaCatenin(time_next_step);
00245         }
00246     }
00247 }
00248 
00249 
00250 void CryptSimulation2d::AfterSolve()
00251 {
00252     if (   (mrTissue.Begin() != mrTissue.End()) // there are any cells
00253         && (dynamic_cast<AbstractVanLeeuwen2009WntSwatCellCycleModel*>(mrTissue.Begin()->GetCellCycleModel())) ) // assume all the cells are the same
00254     {
00255         mBetaCatResultsFile->close();
00256     }
00257 }
00258 
00259 
00260 void CryptSimulation2d::UseJiggledBottomCells()
00261 {
00262     mUseJiggledBottomCells = true;
00263 }
00264 
00265 
00266 void CryptSimulation2d::ApplyTissueBoundaryConditions(const std::vector< c_vector<double, 2> >& rOldLocations)
00267 {
00268     bool is_wnt_included = WntConcentration<2>::Instance()->IsWntSetUp();
00269     if (!is_wnt_included)
00270     {
00271         WntConcentration<2>::Destroy();
00272     }
00273 
00274     // Iterate over all nodes associated with real cells to update their positions
00275     // according to any tissue boundary conditions
00276     for (AbstractTissue<2>::Iterator cell_iter = mrTissue.Begin();
00277          cell_iter != mrTissue.End();
00278          ++cell_iter)
00279     {
00280         // Get index of node associated with cell
00281         unsigned node_index = mpStaticCastTissue->GetLocationIndexUsingCell(*cell_iter);
00282 
00283         // Get pointer to this node
00284         Node<2>* p_node = mpStaticCastTissue->GetNodeCorrespondingToCell(*cell_iter);
00285 
00286         if (!is_wnt_included)
00287         {
00292             if (cell_iter->GetCellProliferativeType()==STEM)
00293             {
00294                 // Get old node location
00295                 c_vector<double, 2> old_node_location = rOldLocations[node_index];
00296 
00297                 // Return node to old location
00298                 p_node->rGetModifiableLocation()[0] = old_node_location[0];
00299                 p_node->rGetModifiableLocation()[1] = old_node_location[1];
00300             }
00301         }
00302 
00303         // Any cell that has moved below the bottom of the crypt must be moved back up
00304         if (p_node->rGetLocation()[1] < 0.0)
00305         {
00306             p_node->rGetModifiableLocation()[1] = 0.0;
00307             if (mUseJiggledBottomCells)
00308             {
00309                /*
00310                 * Here we give the cell a push upwards so that it doesn't
00311                 * get stuck on the bottom of the crypt (as per #422).
00312                 *
00313                 * Note that all stem cells may get moved to the same height, so
00314                 * we use a random perturbation to help ensure we are not simply
00315                 * faced with the same problem at a different height!
00316                 */
00317                 p_node->rGetModifiableLocation()[1] = 0.05*mpRandomGenerator->ranf();
00318             }
00319         }
00320         assert(p_node->rGetLocation()[1] >= 0.0);
00321     }
00322 }
00323 
00324 
00325 void CryptSimulation2d::SetBottomCellAncestors()
00326 {
00327     unsigned index = 0;
00328     for (AbstractTissue<2>::Iterator cell_iter = mpStaticCastTissue->Begin();
00329          cell_iter != mpStaticCastTissue->End();
00330          ++cell_iter)
00331     {
00332         if (mpStaticCastTissue->GetLocationOfCellCentre(*cell_iter)[1] < 0.5)
00333         {
00334             cell_iter->SetAncestor(index++);
00335         }
00336     }
00337 }
00338 
00339 
00340 // Serialization for Boost >= 1.36
00341 #include "SerializationExportWrapperForCpp.hpp"
00342 CHASTE_CLASS_EXPORT(CryptSimulation2d)

Generated by  doxygen 1.6.2