00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <cmath>
00029 #include <ctime>
00030 #include <iostream>
00031 #include <fstream>
00032 #include <set>
00033
00034 #include "TissueSimulation.hpp"
00035 #include "AbstractCellCentreBasedTissue.hpp"
00036 #include "CancerEventHandler.hpp"
00037 #include "LogFile.hpp"
00038
00039
00040 template<unsigned DIM>
00041 TissueSimulation<DIM>::TissueSimulation(AbstractTissue<DIM>& rTissue,
00042 std::vector<AbstractForce<DIM>*> forceCollection,
00043 bool deleteTissueAndForceCollection,
00044 bool initialiseCells)
00045 : mrTissue(rTissue)
00046 {
00047 #define COVERAGE_IGNORE
00048 assert(DIM==2 || DIM==3);
00049 #undef COVERAGE_IGNORE
00050
00051 mDeleteTissue = deleteTissueAndForceCollection;
00052
00053 mInitialiseCells = initialiseCells;
00054
00055 mpParams = CancerParameters::Instance();
00056
00057
00058 mpRandomGenerator = RandomNumberGenerator::Instance();
00059
00060 mDt = 1.0/120.0;
00061 mEndTime = 0.0;
00062
00063
00064 mOutputDirectory = "";
00065 mSimulationOutputDirectory = mOutputDirectory;
00066
00067 if (mrTissue.HasMesh())
00068 {
00069 mUpdateTissue = true;
00070 }
00071 else
00072 {
00073 mUpdateTissue = false;
00074 }
00075
00076 mOutputCellMutationStates = false;
00077 mOutputCellAncestors = false;
00078 mOutputCellTypes = false;
00079 mOutputCellVariables = false;
00080 mOutputCellCyclePhases = false;
00081 mNoBirth = false;
00082 mNumBirths = 0;
00083 mNumDeaths = 0;
00084 mSamplingTimestepMultiple = 1;
00085
00086 mAllocatedMemoryForForceCollection = deleteTissueAndForceCollection;
00087
00088 mForceCollection = forceCollection;
00089 if (mInitialiseCells)
00090 {
00091 mrTissue.InitialiseCells();
00092 }
00093 }
00094
00095
00096 template<unsigned DIM>
00097 TissueSimulation<DIM>::~TissueSimulation()
00098 {
00099 if (mAllocatedMemoryForForceCollection)
00100 {
00101 for (typename std::vector<AbstractForce<DIM>*>::iterator force_iter = mForceCollection.begin();
00102 force_iter != mForceCollection.end();
00103 ++force_iter)
00104 {
00105 delete *force_iter;
00106 }
00107 }
00108
00109 if (mDeleteTissue)
00110 {
00111 for (typename std::vector<AbstractCellKiller<DIM>*>::iterator it=mCellKillers.begin();
00112 it != mCellKillers.end();
00113 ++it)
00114 {
00115 delete *it;
00116 }
00117 delete &mrTissue;
00118 }
00119 }
00120
00121
00122 template<unsigned DIM>
00123 unsigned TissueSimulation<DIM>::DoCellBirth()
00124 {
00125 if (mNoBirth)
00126 {
00127 return 0;
00128 }
00129
00130 unsigned num_births_this_step = 0;
00131
00132
00133 for (typename AbstractTissue<DIM>::Iterator cell_iter = mrTissue.Begin();
00134 cell_iter != mrTissue.End();
00135 ++cell_iter)
00136 {
00137
00138 if (cell_iter->GetAge() > 0.0)
00139 {
00140 if (cell_iter->ReadyToDivide())
00141 {
00142
00143 TissueCell new_cell = cell_iter->Divide();
00144
00145 c_vector<double, DIM> new_location = zero_vector<double>(DIM);
00146 if (dynamic_cast<AbstractCellCentreBasedTissue<DIM>*>(&mrTissue))
00147 {
00148 new_location = CalculateDividingCellCentreLocations(&(*cell_iter));
00149 }
00150
00151
00152 mrTissue.AddCell(new_cell, new_location, &(*cell_iter));
00153
00154
00155 num_births_this_step++;
00156 }
00157 }
00158 }
00159 return num_births_this_step;
00160 }
00161
00162
00163 template<unsigned DIM>
00164 unsigned TissueSimulation<DIM>::DoCellRemoval()
00165 {
00166 unsigned num_deaths_this_step = 0;
00167
00168
00169
00170 for (typename std::vector<AbstractCellKiller<DIM>*>::iterator killer_iter = mCellKillers.begin();
00171 killer_iter != mCellKillers.end();
00172 ++killer_iter)
00173 {
00174 (*killer_iter)->TestAndLabelCellsForApoptosisOrDeath();
00175 }
00176
00177 num_deaths_this_step += mrTissue.RemoveDeadCells();
00178
00179 return num_deaths_this_step;
00180 }
00181
00182
00183 template<unsigned DIM>
00184 const std::vector<AbstractForce<DIM>*> TissueSimulation<DIM>::rGetForceCollection() const
00185 {
00186 return mForceCollection;
00187 }
00188
00189
00190 template<unsigned DIM>
00191 c_vector<double, DIM> TissueSimulation<DIM>::CalculateDividingCellCentreLocations(TissueCell* pParentCell)
00192 {
00193 double separation = CancerParameters::Instance()->GetDivisionSeparation();
00194 c_vector<double, DIM> parent_coords = mrTissue.GetLocationOfCellCentre(pParentCell);
00195 c_vector<double, DIM> daughter_coords;
00196
00197
00198
00199
00200
00201
00202 c_vector<double, DIM> random_vector;
00203
00204 if (DIM==2)
00205 {
00206 double random_angle = RandomNumberGenerator::Instance()->ranf();
00207 random_angle *= 2.0*M_PI;
00208
00209 random_vector(0) = 0.5*separation*cos(random_angle);
00210 random_vector(1) = 0.5*separation*sin(random_angle);
00211
00212 parent_coords = parent_coords - random_vector;
00213 daughter_coords = parent_coords + random_vector;
00214 }
00215 else if (DIM==3)
00216 {
00217 double random_zenith_angle = RandomNumberGenerator::Instance()->ranf();
00218 random_zenith_angle *= M_PI;
00219 double random_azimuth_angle = RandomNumberGenerator::Instance()->ranf();
00220 random_azimuth_angle *= 2*M_PI;
00221
00222 random_vector(0) = 0.5*separation*cos(random_azimuth_angle)*sin(random_zenith_angle);
00223 random_vector(1) = 0.5*separation*sin(random_azimuth_angle)*sin(random_zenith_angle);
00224 random_vector(2) = 0.5*separation*cos(random_zenith_angle);
00225
00226 daughter_coords = parent_coords + random_vector;
00227 parent_coords = parent_coords - random_vector;
00228 }
00229
00230
00231 ChastePoint<DIM> parent_coords_point(parent_coords);
00232 unsigned node_index = mrTissue.GetLocationIndexUsingCell(pParentCell);
00233 mrTissue.SetNode(node_index, parent_coords_point);
00234
00235 return daughter_coords;
00236 }
00237
00238
00239 template<unsigned DIM>
00240 void TissueSimulation<DIM>::UpdateNodePositions(const std::vector< c_vector<double, DIM> >& rNodeForces)
00241 {
00242
00243
00244
00245 std::vector<c_vector<double, DIM> > old_node_locations;
00246 old_node_locations.reserve(mrTissue.GetNumNodes());
00247 for (unsigned node_index=0; node_index<mrTissue.GetNumNodes(); node_index++)
00248 {
00249 old_node_locations[node_index] = mrTissue.GetNode(node_index)->rGetLocation();
00250 }
00251
00252
00253 mrTissue.UpdateNodeLocations(rNodeForces, mDt);
00254
00255
00256 ApplyTissueBoundaryConditions(old_node_locations);
00257 }
00258
00259
00260 template<unsigned DIM>
00261 void TissueSimulation<DIM>::SetDt(double dt)
00262 {
00263 assert(dt > 0);
00264 mDt = dt;
00265 }
00266
00267
00268 template<unsigned DIM>
00269 double TissueSimulation<DIM>::GetDt()
00270 {
00271 return mDt;
00272 }
00273
00274
00275 template<unsigned DIM>
00276 unsigned TissueSimulation<DIM>::GetNumBirths()
00277 {
00278 return mNumBirths;
00279 }
00280
00281
00282 template<unsigned DIM>
00283 unsigned TissueSimulation<DIM>::GetNumDeaths()
00284 {
00285 return mNumDeaths;
00286 }
00287
00288
00289 template<unsigned DIM>
00290 void TissueSimulation<DIM>::SetEndTime(double endTime)
00291 {
00292 assert(endTime > 0);
00293 mEndTime = endTime;
00294 }
00295
00296
00297 template<unsigned DIM>
00298 void TissueSimulation<DIM>::SetOutputDirectory(std::string outputDirectory)
00299 {
00300 mOutputDirectory = outputDirectory;
00301 mSimulationOutputDirectory = mOutputDirectory;
00302 }
00303
00304
00305 template<unsigned DIM>
00306 std::string TissueSimulation<DIM>::GetOutputDirectory()
00307 {
00308 return mOutputDirectory;
00309 }
00310
00311
00312 template<unsigned DIM>
00313 void TissueSimulation<DIM>::SetSamplingTimestepMultiple(unsigned samplingTimestepMultiple)
00314 {
00315 assert(samplingTimestepMultiple > 0);
00316 mSamplingTimestepMultiple = samplingTimestepMultiple;
00317 }
00318
00319
00320 template<unsigned DIM>
00321 AbstractTissue<DIM>& TissueSimulation<DIM>::rGetTissue()
00322 {
00323 return mrTissue;
00324 }
00325
00326
00327 template<unsigned DIM>
00328 const AbstractTissue<DIM>& TissueSimulation<DIM>::rGetTissue() const
00329 {
00330 return mrTissue;
00331 }
00332
00333
00334 template<unsigned DIM>
00335 void TissueSimulation<DIM>::SetUpdateTissueRule(bool updateTissue)
00336 {
00337 mUpdateTissue = updateTissue;
00338 }
00339
00340
00341 template<unsigned DIM>
00342 void TissueSimulation<DIM>::SetNoBirth(bool noBirth)
00343 {
00344 mNoBirth = noBirth;
00345 }
00346
00347
00348 template<unsigned DIM>
00349 void TissueSimulation<DIM>::SetOutputCellMutationStates(bool outputCellMutationStates)
00350 {
00351 mOutputCellMutationStates = outputCellMutationStates;
00352 }
00353
00354
00355 template<unsigned DIM>
00356 void TissueSimulation<DIM>::SetOutputCellTypes(bool outputCellTypes)
00357 {
00358 mOutputCellTypes = outputCellTypes;
00359 }
00360
00361
00362 template<unsigned DIM>
00363 void TissueSimulation<DIM>::SetOutputCellAncestors(bool outputCellAncestors)
00364 {
00365 mOutputCellAncestors = outputCellAncestors;
00366 }
00367
00368
00369 template<unsigned DIM>
00370 void TissueSimulation<DIM>::SetOutputCellVariables(bool outputCellVariables)
00371 {
00372 mOutputCellVariables = outputCellVariables;
00373 }
00374
00375
00376 template<unsigned DIM>
00377 void TissueSimulation<DIM>::SetOutputCellCyclePhases(bool outputCellCyclePhases)
00378 {
00379 mOutputCellCyclePhases = outputCellCyclePhases;
00380 }
00381
00382
00383 template<unsigned DIM>
00384 void TissueSimulation<DIM>::AddCellKiller(AbstractCellKiller<DIM>* pCellKiller)
00385 {
00386 mCellKillers.push_back(pCellKiller);
00387 }
00388
00389
00390 template<unsigned DIM>
00391 std::vector<double> TissueSimulation<DIM>::GetNodeLocation(const unsigned& rNodeIndex)
00392 {
00393 std::vector<double> location;
00394 for (unsigned i=0; i<DIM; i++)
00395 {
00396 location.push_back( mrTissue.GetNode(rNodeIndex)->rGetLocation()[i] );
00397 }
00398 return location;
00399 }
00400
00401
00402 template<unsigned DIM>
00403 void TissueSimulation<DIM>::Solve()
00404 {
00405 CancerEventHandler::BeginEvent(CancerEventHandler::EVERYTHING);
00406 CancerEventHandler::BeginEvent(CancerEventHandler::SETUP);
00407
00408
00409 SimulationTime* p_simulation_time = SimulationTime::Instance();
00410 double current_time = p_simulation_time->GetTime();
00411
00412 unsigned num_time_steps = (unsigned) ((mEndTime-current_time)/mDt+0.5);
00413
00414 if (current_time > 0)
00415 {
00416 p_simulation_time->ResetEndTimeAndNumberOfTimeSteps(mEndTime, num_time_steps);
00417 }
00418 else
00419 {
00420 p_simulation_time->SetEndTimeAndNumberOfTimeSteps(mEndTime, num_time_steps);
00421 }
00422
00423 if (mOutputDirectory=="")
00424 {
00425 EXCEPTION("OutputDirectory not set");
00426 }
00427
00428 double time_now = p_simulation_time->GetTime();
00429 std::ostringstream time_string;
00430 time_string << time_now;
00431
00432 std::string results_directory = mOutputDirectory +"/results_from_time_" + time_string.str();
00433 mSimulationOutputDirectory = results_directory;
00434
00436
00438
00439
00440 OutputFileHandler output_file_handler(results_directory+"/", true);
00441
00442 mrTissue.CreateOutputFiles(results_directory+"/",
00443 false,
00444 mOutputCellMutationStates,
00445 mOutputCellTypes,
00446 mOutputCellVariables,
00447 mOutputCellCyclePhases,
00448 mOutputCellAncestors);
00449
00450 mpSetupFile = output_file_handler.OpenOutputFile("results.vizsetup");
00451
00452 SetupSolve();
00453
00454
00455
00456 LOG(1, "Setting up cells...");
00457 for (typename AbstractTissue<DIM>::Iterator cell_iter = mrTissue.Begin();
00458 cell_iter != mrTissue.End();
00459 ++cell_iter)
00460 {
00461
00462
00463 cell_iter->ReadyToDivide();
00464 }
00465 LOG(1, "\tdone\n");
00466
00467
00468 if (DIM==2)
00469 {
00470 WriteVisualizerSetupFile();
00471 }
00472 *mpSetupFile << std::flush;
00473
00474 mrTissue.WriteResultsToFiles(mOutputCellMutationStates,
00475 mOutputCellTypes,
00476 mOutputCellVariables,
00477 mOutputCellCyclePhases,
00478 mOutputCellAncestors);
00479
00480 CancerEventHandler::EndEvent(CancerEventHandler::SETUP);
00481
00482
00483 std::vector<c_vector<double, DIM> > forces(mrTissue.GetNumNodes(),zero_vector<double>(DIM));
00484
00486
00488
00489 while ((p_simulation_time->GetTimeStepsElapsed() < num_time_steps) && !(StoppingEventHasOccurred()) )
00490 {
00491 LOG(1, "--TIME = " << p_simulation_time->GetTime() << "\n");
00492
00494
00496 CancerEventHandler::BeginEvent(CancerEventHandler::DEATH);
00497 unsigned deaths_this_step = DoCellRemoval();
00498 mNumDeaths += deaths_this_step;
00499 LOG(1, "\tNum deaths = " << mNumDeaths << "\n");
00500 CancerEventHandler::EndEvent(CancerEventHandler::DEATH);
00501
00503
00505 CancerEventHandler::BeginEvent(CancerEventHandler::BIRTH);
00506 unsigned births_this_step = DoCellBirth();
00507 mNumBirths += births_this_step;
00508 LOG(1, "\tNum births = " << mNumBirths << "\n");
00509 CancerEventHandler::EndEvent(CancerEventHandler::BIRTH);
00510
00512
00514
00520 if (mrTissue.HasMesh())
00521 {
00522
00523
00524
00525
00526 }
00527 else
00528 {
00529 mUpdateTissue = false;
00530 if ( (births_this_step>0) || (deaths_this_step>0) )
00531 {
00532 mUpdateTissue = true;
00533 }
00534 }
00535
00536
00537 CancerEventHandler::BeginEvent(CancerEventHandler::UPDATE);
00538 if (mUpdateTissue)
00539 {
00540 LOG(1, "\tUpdating tissue...");
00541 mrTissue.Update();
00542 LOG(1, "\tdone.\n");
00543 }
00544 CancerEventHandler::EndEvent(CancerEventHandler::UPDATE);
00545
00547
00549 CancerEventHandler::BeginEvent(CancerEventHandler::FORCE);
00550
00551
00552 for (unsigned i=0; i<forces.size(); i++)
00553 {
00554 forces[i].clear();
00555 }
00556
00557
00558
00559 if (mrTissue.GetNumNodes()!=forces.size())
00560 {
00561 forces.resize(mrTissue.GetNumNodes(), zero_vector<double>(DIM));
00562 }
00563
00564
00565 for (typename std::vector<AbstractForce<DIM>*>::iterator iter = mForceCollection.begin();
00566 iter !=mForceCollection.end();
00567 iter++)
00568 {
00569 (*iter)->AddForceContribution(forces, mrTissue);
00570 }
00571 CancerEventHandler::EndEvent(CancerEventHandler::FORCE);
00572
00574
00576 CancerEventHandler::BeginEvent(CancerEventHandler::POSITION);
00577 UpdateNodePositions(forces);
00578 CancerEventHandler::EndEvent(CancerEventHandler::POSITION);
00579
00581
00582
00584 PostSolve();
00585
00586
00587 p_simulation_time->IncrementTimeOneStep();
00588
00589
00591
00593 CancerEventHandler::BeginEvent(CancerEventHandler::OUTPUT);
00594
00595
00596 if (p_simulation_time->GetTimeStepsElapsed()%mSamplingTimestepMultiple==0)
00597 {
00598 mrTissue.WriteResultsToFiles(mOutputCellMutationStates,
00599 mOutputCellTypes,
00600 mOutputCellVariables,
00601 mOutputCellCyclePhases,
00602 mOutputCellAncestors);
00603 }
00604
00605 CancerEventHandler::EndEvent(CancerEventHandler::OUTPUT);
00606
00607 }
00608
00609 AfterSolve();
00610
00611 CancerEventHandler::BeginEvent(CancerEventHandler::OUTPUT);
00612 mrTissue.CloseOutputFiles(mOutputCellMutationStates,
00613 mOutputCellTypes,
00614 mOutputCellVariables,
00615 mOutputCellCyclePhases,
00616 mOutputCellAncestors);
00617
00618 *mpSetupFile << "Complete\n";
00619 mpSetupFile->close();
00620
00621 CancerEventHandler::EndEvent(CancerEventHandler::OUTPUT);
00622
00623 CancerEventHandler::EndEvent(CancerEventHandler::EVERYTHING);
00624 }
00625
00626
00627 template<unsigned DIM>
00628 void TissueSimulation<DIM>::AfterSolve()
00629 {
00630 LOG(1, "--TIME = " << SimulationTime::Instance()->GetTime() << "\n");
00631
00632
00633 CancerEventHandler::BeginEvent(CancerEventHandler::DEATH);
00634 mNumDeaths += DoCellRemoval();
00635 LOG(1, "\tNum deaths = " << mNumDeaths << "\n");
00636 CancerEventHandler::EndEvent(CancerEventHandler::DEATH);
00637
00638 CancerEventHandler::BeginEvent(CancerEventHandler::BIRTH);
00639 mNumBirths += DoCellBirth();
00640 LOG(1, "\tNum births = " << mNumBirths << "\n");
00641 CancerEventHandler::EndEvent(CancerEventHandler::BIRTH);
00642
00643
00644 if (mrTissue.HasMesh())
00645 {
00646
00647
00648
00649
00650 }
00651 else
00652 {
00653 mUpdateTissue = false;
00654 if ( (mNumBirths>0) || (mNumDeaths>0) )
00655 {
00656 mUpdateTissue = true;
00657 }
00658 }
00659
00660 if (mUpdateTissue)
00661 {
00662 LOG(1, "\tUpdating tissue...");
00663 mrTissue.Update();
00664 LOG(1, "\tdone.\n");
00665 }
00666 }
00667
00668
00669 template<unsigned DIM>
00670 bool TissueSimulation<DIM>::StoppingEventHasOccurred()
00671 {
00672 return false;
00673 }
00674
00675
00676 template<unsigned DIM>
00677 c_vector<unsigned, NUM_CELL_MUTATION_STATES> TissueSimulation<DIM>::GetCellMutationStateCount()
00678 {
00679 if (!mOutputCellMutationStates)
00680 {
00681 EXCEPTION("Call simulator.SetOutputCellMutationStates before using this function");
00682 }
00683 return mrTissue.GetCellMutationStateCount();
00684 }
00685
00686
00687 template<unsigned DIM>
00688 c_vector<unsigned, NUM_CELL_TYPES> TissueSimulation<DIM>::GetCellTypeCount()
00689 {
00690 if (!mOutputCellTypes)
00691 {
00692 EXCEPTION("Call simulator.SetOutputCellTypes() before using this function");
00693 }
00694 return mrTissue.GetCellTypeCount();
00695 }
00696
00697
00698 template<unsigned DIM>
00699 c_vector<unsigned, 5> TissueSimulation<DIM>::GetCellCyclePhaseCount()
00700 {
00701 if (!mOutputCellCyclePhases)
00702 {
00703 EXCEPTION("Call simulator.SetOutputCellCyclePhases() before using this function");
00704 }
00705 return mrTissue.GetCellCyclePhaseCount();
00706 }
00707
00708
00710
00712
00713
00714 template class TissueSimulation<1>;
00715 template class TissueSimulation<2>;
00716 template class TissueSimulation<3>;