Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, 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 #include "AbstractCellPopulation.hpp" 00037 #include "AbstractOdeBasedCellCycleModel.hpp" 00038 #include "Exception.hpp" 00039 #include "SmartPointers.hpp" 00040 00041 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00042 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AbstractCellPopulation( AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh, 00043 std::vector<CellPtr>& rCells, 00044 const std::vector<unsigned> locationIndices) 00045 : mrMesh(rMesh), 00046 mCells(rCells.begin(), rCells.end()), 00047 mCentroid(zero_vector<double>(SPACE_DIM)), 00048 mpCellPropertyRegistry(CellPropertyRegistry::Instance()->TakeOwnership()), 00049 mOutputCellIdData(false), 00050 mOutputCellMutationStates(false), 00051 mOutputCellAncestors(false), 00052 mOutputCellProliferativeTypes(false), 00053 mOutputCellVariables(false), 00054 mOutputCellCyclePhases(false), 00055 mOutputCellAges(false), 00056 mOutputCellVolumes(false) 00057 { 00058 // There must be at least one cell 00059 assert(!mCells.empty()); 00060 00061 // To avoid double-counting problems, clear the passed-in cells vector 00062 rCells.clear(); 00063 00064 if (!locationIndices.empty()) 00065 { 00066 // There must be a one-one correspondence between cells and location indices 00067 if (mCells.size() != locationIndices.size()) 00068 { 00069 EXCEPTION("There is not a one-one correspondence between cells and location indices"); 00070 } 00071 } 00072 00073 // Set up the map between location indices and cells 00074 mLocationCellMap.clear(); 00075 mCellLocationMap.clear(); 00076 00077 std::list<CellPtr>::iterator it = mCells.begin(); 00078 for (unsigned i=0; it != mCells.end(); ++it, ++i) 00079 { 00080 unsigned index = locationIndices.empty() ? i : locationIndices[i]; // assume that the ordering matches 00081 AddCellUsingLocationIndex(index,*it); 00082 00083 // Give each cell a pointer to the property registry (we have taken ownership in this constructor). 00084 (*it)->rGetCellPropertyCollection().SetCellPropertyRegistry(mpCellPropertyRegistry.get()); 00085 } 00086 00087 /* 00088 * Initialise cell counts to zero. 00089 * 00090 * Note: In its current form the code requires each cell-cycle model 00091 * to comprise four phases (G1, S, G2, M) and requires a cell to have 00092 * one of three possible proliferative types (STEM, TRANSIT and 00093 * DIFFERENTIATED). This is reflected in the explicit use of the 00094 * variables NUM_CELL_PROLIFERATIVE_TYPES and NUM_CELL_CYCLE_PHASES 00095 * below. 00096 */ 00097 mCellProliferativeTypeCount = std::vector<unsigned>(NUM_CELL_PROLIFERATIVE_TYPES); 00098 for (unsigned i=0; i<mCellProliferativeTypeCount.size(); i++) 00099 { 00100 mCellProliferativeTypeCount[i] = 0; 00101 } 00102 00103 mCellCyclePhaseCount = std::vector<unsigned>(NUM_CELL_CYCLE_PHASES); 00104 for (unsigned i=0; i<mCellCyclePhaseCount.size(); i++) 00105 { 00106 mCellCyclePhaseCount[i] = 0; 00107 } 00108 } 00109 00110 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00111 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AbstractCellPopulation(AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh) 00112 : mrMesh(rMesh) 00113 { 00114 } 00115 00116 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00117 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::~AbstractCellPopulation() 00118 { 00119 } 00120 00121 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00122 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::InitialiseCells() 00123 { 00124 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter) 00125 { 00126 cell_iter->InitialiseCellCycleModel(); 00127 } 00128 } 00129 00130 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00131 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetDataOnAllCells(const std::string& dataName, double dataValue) 00132 { 00133 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter) 00134 { 00135 cell_iter->GetCellData()->SetItem(dataName, dataValue); 00136 } 00137 } 00138 00139 00140 00141 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00142 AbstractMesh<ELEMENT_DIM, SPACE_DIM>& AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::rGetMesh() 00143 { 00144 return mrMesh; 00145 } 00146 00147 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00148 std::list<CellPtr>& AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::rGetCells() 00149 { 00150 return mCells; 00151 } 00152 00153 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00154 unsigned AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetNumRealCells() 00155 { 00156 unsigned counter = 0; 00157 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter) 00158 { 00159 counter++; 00160 } 00161 return counter; 00162 } 00163 00164 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00165 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetCellAncestorsToLocationIndices() 00166 { 00167 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter) 00168 { 00169 MAKE_PTR_ARGS(CellAncestor, p_cell_ancestor, (mCellLocationMap[(*cell_iter).get()])); 00170 cell_iter->SetAncestor(p_cell_ancestor); 00171 } 00172 } 00173 00174 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00175 std::set<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellAncestors() 00176 { 00177 std::set<unsigned> remaining_ancestors; 00178 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter) 00179 { 00180 remaining_ancestors.insert(cell_iter->GetAncestor()); 00181 } 00182 return remaining_ancestors; 00183 } 00184 00185 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00186 std::vector<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellMutationStateCount() 00187 { 00188 if (!mOutputCellMutationStates) 00189 { 00190 EXCEPTION("Call SetOutputCellMutationStates(true) before using this function"); 00191 } 00192 00193 // An ordering must have been specified for cell mutation states 00194 SetDefaultMutationStateOrdering(); 00195 00196 const std::vector<boost::shared_ptr<AbstractCellProperty> >& r_cell_properties = 00197 mpCellPropertyRegistry->rGetAllCellProperties(); 00198 00199 std::vector<unsigned> cell_mutation_state_count; 00200 for (unsigned i=0; i<r_cell_properties.size(); i++) 00201 { 00202 if (r_cell_properties[i]->IsSubType<AbstractCellMutationState>()) 00203 { 00204 cell_mutation_state_count.push_back(r_cell_properties[i]->GetCellCount()); 00205 } 00206 } 00207 00208 return cell_mutation_state_count; 00209 } 00210 00211 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00212 const std::vector<unsigned>& AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::rGetCellProliferativeTypeCount() const 00213 { 00214 if (!mOutputCellProliferativeTypes) 00215 { 00216 EXCEPTION("Call SetOutputCellProliferativeTypes(true) before using this function"); 00217 } 00218 return mCellProliferativeTypeCount; 00219 } 00220 00221 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00222 const std::vector<unsigned>& AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::rGetCellCyclePhaseCount() const 00223 { 00224 if (!mOutputCellCyclePhases) 00225 { 00226 EXCEPTION("Call SetOutputCellCyclePhases(true) before using this function"); 00227 } 00228 return mCellCyclePhaseCount; 00229 } 00230 00231 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00232 CellPtr AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellUsingLocationIndex(unsigned index) 00233 { 00234 // Get the set of pointers to cells corresponding to this location index 00235 std::set<CellPtr> cells = mLocationCellMap[index]; 00236 00237 // If there is only one cell attached return the cell. Note currently only one cell per index. 00238 if (cells.size()==1) 00239 { 00240 return *(cells.begin()); 00241 } 00242 if (cells.size()==0) 00243 { 00244 EXCEPTION("Location index input argument does not correspond to a Cell"); 00245 } 00246 else 00247 { 00248 EXCEPTION("Multiple cells are attached to a single location index."); 00249 } 00250 } 00251 00252 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00253 std::set<CellPtr> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellsUsingLocationIndex(unsigned index) 00254 { 00255 // Return the set of pointers to cells corresponding to this location index, note the set may be empty. 00256 return mLocationCellMap[index]; 00257 } 00258 00259 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00260 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsCellAttachedToLocationIndex(unsigned index) 00261 { 00262 // Get the set of pointers to cells corresponding to this location index 00263 std::set<CellPtr> cells = mLocationCellMap[index]; 00264 00265 // check if there is a cell attached to the location index. 00266 if (cells.size()==0) 00267 { 00268 return false; 00269 } 00270 else 00271 { 00272 return true; 00273 } 00274 } 00275 00276 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00277 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetCellUsingLocationIndex(unsigned index, CellPtr pCell) 00278 { 00279 // Clear the maps 00280 mLocationCellMap[index].clear(); 00281 mCellLocationMap.erase(pCell.get()); 00282 00283 // Replace with new cell 00284 mLocationCellMap[index].insert(pCell); 00285 00286 // Do other half of the map 00287 mCellLocationMap[pCell.get()] = index; 00288 } 00289 00290 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00291 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AddCellUsingLocationIndex(unsigned index, CellPtr pCell) 00292 { 00293 mLocationCellMap[index].insert(pCell); 00294 mCellLocationMap[pCell.get()] = index; 00295 } 00296 00297 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00298 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::RemoveCellUsingLocationIndex(unsigned index, CellPtr pCell) 00299 { 00300 std::set<CellPtr>::iterator cell_iter = mLocationCellMap[index].find(pCell); 00301 00302 if (cell_iter == mLocationCellMap[index].end()) 00303 { 00304 EXCEPTION("Tried to remove a cell which is not attached to the given location index"); 00305 } 00306 else 00307 { 00308 mLocationCellMap[index].erase(cell_iter); 00309 mCellLocationMap.erase(pCell.get()); 00310 } 00311 } 00312 00313 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00314 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::MoveCellInLocationMap(CellPtr pCell, unsigned old_index, unsigned new_index) 00315 { 00316 // Remove the cell from its current location 00317 RemoveCellUsingLocationIndex(old_index, pCell); 00318 00319 // Add it to the new location 00320 AddCellUsingLocationIndex(new_index, pCell); 00321 } 00322 00323 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00324 unsigned AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetLocationIndexUsingCell(CellPtr pCell) 00325 { 00326 // Check the cell is in the map. 00327 assert(this->mCellLocationMap.find(pCell.get()) != this->mCellLocationMap.end()); 00328 00329 return mCellLocationMap[pCell.get()]; 00330 } 00331 00332 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00333 boost::shared_ptr<CellPropertyRegistry> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellPropertyRegistry() 00334 { 00335 return mpCellPropertyRegistry; 00336 } 00337 00338 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00339 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetDefaultMutationStateOrdering() 00340 { 00341 boost::shared_ptr<CellPropertyRegistry> p_registry = GetCellPropertyRegistry(); 00342 if (!p_registry->HasOrderingBeenSpecified()) 00343 { 00344 std::vector<boost::shared_ptr<AbstractCellProperty> > mutations; 00345 mutations.push_back(p_registry->Get<WildTypeCellMutationState>()); 00346 mutations.push_back(p_registry->Get<ApcOneHitCellMutationState>()); 00347 mutations.push_back(p_registry->Get<ApcTwoHitCellMutationState>()); 00348 mutations.push_back(p_registry->Get<BetaCateninOneHitCellMutationState>()); 00349 p_registry->SpecifyOrdering(mutations); 00350 } 00351 } 00352 00353 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00354 c_vector<double, SPACE_DIM> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCentroidOfCellPopulation() 00355 { 00356 mCentroid = zero_vector<double>(SPACE_DIM); 00357 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin(); 00358 cell_iter != this->End(); 00359 ++cell_iter) 00360 { 00361 mCentroid += GetLocationOfCellCentre(*cell_iter); 00362 } 00363 mCentroid /= this->GetNumRealCells(); 00364 00365 return mCentroid; 00366 } 00367 00369 // Output methods // 00371 00372 00373 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00374 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::CreateOutputFiles(const std::string& rDirectory, bool cleanOutputDirectory) 00375 { 00376 OutputFileHandler output_file_handler(rDirectory, cleanOutputDirectory); 00377 00378 if(PetscTools::AmMaster()) 00379 { 00380 mpVizNodesFile = output_file_handler.OpenOutputFile("results.viznodes"); 00381 mpVizBoundaryNodesFile = output_file_handler.OpenOutputFile("results.vizboundarynodes"); 00382 mpVizCellProliferativeTypesFile = output_file_handler.OpenOutputFile("results.vizcelltypes"); 00383 00384 if (mOutputCellAncestors) 00385 { 00386 mpVizCellAncestorsFile = output_file_handler.OpenOutputFile("results.vizancestors"); 00387 } 00388 if (mOutputCellMutationStates) 00389 { 00390 // An ordering must be specified for cell mutation states 00391 SetDefaultMutationStateOrdering(); 00392 00393 mpCellMutationStatesFile = output_file_handler.OpenOutputFile("cellmutationstates.dat"); 00394 00395 *mpCellMutationStatesFile << "Time\t "; 00396 00397 const std::vector<boost::shared_ptr<AbstractCellProperty> >& r_cell_properties = 00398 mpCellPropertyRegistry->rGetAllCellProperties(); 00399 00400 std::vector<unsigned> cell_mutation_state_count; 00401 for (unsigned i=0; i<r_cell_properties.size(); i++) 00402 { 00403 if (r_cell_properties[i]->IsSubType<AbstractCellMutationState>()) 00404 { 00405 *mpCellMutationStatesFile << r_cell_properties[i]->GetIdentifier() << "\t "; 00406 } 00407 } 00408 *mpCellMutationStatesFile << "\n"; 00409 } 00410 if (mOutputCellProliferativeTypes) 00411 { 00412 mpCellProliferativeTypesFile = output_file_handler.OpenOutputFile("celltypes.dat"); 00413 } 00414 if (mOutputCellVariables) 00415 { 00416 mpCellVariablesFile = output_file_handler.OpenOutputFile("cellvariables.dat"); 00417 } 00418 if (mOutputCellCyclePhases) 00419 { 00420 mpCellCyclePhasesFile = output_file_handler.OpenOutputFile("cellcyclephases.dat"); 00421 mpVizCellProliferativePhasesFile = output_file_handler.OpenOutputFile("results.vizcellphases"); 00422 } 00423 if (mOutputCellAges) 00424 { 00425 mpCellAgesFile = output_file_handler.OpenOutputFile("cellages.dat"); 00426 } 00427 if (mOutputCellIdData) 00428 { 00429 mpCellIdFile = output_file_handler.OpenOutputFile("loggedcell.dat"); 00430 } 00431 if (this->mOutputCellVolumes) 00432 { 00433 mpCellVolumesFile = output_file_handler.OpenOutputFile("cellareas.dat"); 00434 } 00435 } 00436 00437 mDirPath = rDirectory; 00438 #ifdef CHASTE_VTK 00439 mpVtkMetaFile = output_file_handler.OpenOutputFile("results.pvd"); 00440 *mpVtkMetaFile << "<?xml version=\"1.0\"?>\n"; 00441 *mpVtkMetaFile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n"; 00442 *mpVtkMetaFile << " <Collection>\n"; 00443 #endif //CHASTE_VTK 00444 } 00445 00446 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00447 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::CloseOutputFiles() 00448 { 00449 // In parallel all files are closed after writing 00450 if(PetscTools::IsSequential()) 00451 { 00452 mpVizNodesFile->close(); 00453 mpVizBoundaryNodesFile->close(); 00454 mpVizCellProliferativeTypesFile->close(); 00455 00456 00457 if (mOutputCellMutationStates) 00458 { 00459 mpCellMutationStatesFile->close(); 00460 } 00461 if (mOutputCellProliferativeTypes) 00462 { 00463 mpCellProliferativeTypesFile->close(); 00464 } 00465 if (mOutputCellVariables) 00466 { 00467 mpCellVariablesFile->close(); 00468 } 00469 if (mOutputCellCyclePhases) 00470 { 00471 mpCellCyclePhasesFile->close(); 00472 mpVizCellProliferativePhasesFile->close(); 00473 } 00474 if (mOutputCellAncestors) 00475 { 00476 mpVizCellAncestorsFile->close(); 00477 } 00478 if (mOutputCellAges) 00479 { 00480 mpCellAgesFile->close(); 00481 } 00482 if (mOutputCellIdData) 00483 { 00484 mpCellIdFile->close(); 00485 } 00486 if (this->mOutputCellVolumes) 00487 { 00488 mpCellVolumesFile->close(); 00489 } 00490 } 00491 #ifdef CHASTE_VTK 00492 *mpVtkMetaFile << " </Collection>\n"; 00493 *mpVtkMetaFile << "</VTKFile>\n"; 00494 mpVtkMetaFile->close(); 00495 #endif //CHASTE_VTK 00496 } 00497 00498 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00499 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GenerateCellResults(CellPtr pCell, 00500 std::vector<unsigned>& rCellProliferativeTypeCounter, 00501 std::vector<unsigned>& rCellCyclePhaseCounter) 00502 { 00503 unsigned location_index = this->GetLocationIndexUsingCell(pCell); 00504 00505 unsigned colour = STEM_COLOUR; 00506 00507 if (mOutputCellCyclePhases) 00508 { 00509 // Update rCellCyclePhaseCounter 00510 switch (pCell->GetCellCycleModel()->GetCurrentCellCyclePhase()) 00511 { 00512 case G_ZERO_PHASE: 00513 rCellCyclePhaseCounter[0]++; 00514 break; 00515 case G_ONE_PHASE: 00516 rCellCyclePhaseCounter[1]++; 00517 break; 00518 case S_PHASE: 00519 rCellCyclePhaseCounter[2]++; 00520 break; 00521 case G_TWO_PHASE: 00522 rCellCyclePhaseCounter[3]++; 00523 break; 00524 case M_PHASE: 00525 rCellCyclePhaseCounter[4]++; 00526 break; 00527 default: 00528 NEVER_REACHED; 00529 } 00530 *mpVizCellProliferativePhasesFile << pCell->GetCellCycleModel()->GetCurrentCellCyclePhase() << " "; 00531 } 00532 00533 if (mOutputCellAncestors) 00534 { 00535 // Set colour dependent on cell ancestor and write to file 00536 colour = pCell->GetAncestor(); 00537 if (colour == UNSIGNED_UNSET) 00538 { 00539 // Set the file to -1 to mark this case. 00540 colour = 1; 00541 *mpVizCellAncestorsFile << "-"; 00542 } 00543 *mpVizCellAncestorsFile << colour << " "; 00544 } 00545 00546 // Set colour dependent on cell type 00547 switch (pCell->GetCellProliferativeType()) 00548 { 00549 case STEM: 00550 colour = STEM_COLOUR; 00551 if (mOutputCellProliferativeTypes) 00552 { 00553 rCellProliferativeTypeCounter[0]++; 00554 } 00555 break; 00556 case TRANSIT: 00557 colour = TRANSIT_COLOUR; 00558 if (mOutputCellProliferativeTypes) 00559 { 00560 rCellProliferativeTypeCounter[1]++; 00561 } 00562 break; 00563 case DIFFERENTIATED: 00564 colour = DIFFERENTIATED_COLOUR; 00565 if (mOutputCellProliferativeTypes) 00566 { 00567 rCellProliferativeTypeCounter[2]++; 00568 } 00569 break; 00570 default: 00571 NEVER_REACHED; 00572 } 00573 00574 if (mOutputCellMutationStates) 00575 { 00576 // Set colour dependent on cell mutation state 00577 if (!pCell->GetMutationState()->IsType<WildTypeCellMutationState>()) 00578 { 00579 colour = pCell->GetMutationState()->GetColour(); 00580 } 00581 if (pCell->HasCellProperty<CellLabel>()) 00582 { 00583 CellPropertyCollection collection = pCell->rGetCellPropertyCollection().GetProperties<CellLabel>(); 00584 boost::shared_ptr<CellLabel> p_label = boost::static_pointer_cast<CellLabel>(collection.GetProperty()); 00585 colour = p_label->GetColour(); 00586 } 00587 } 00588 00589 if (pCell->HasCellProperty<ApoptoticCellProperty>() || pCell->HasApoptosisBegun()) 00590 { 00591 // For any type of cell set the colour to this if it is undergoing apoptosis 00592 colour = APOPTOSIS_COLOUR; 00593 } 00594 00595 // Write cell variable data to file if required 00596 if (mOutputCellVariables && dynamic_cast<AbstractOdeBasedCellCycleModel*>(pCell->GetCellCycleModel()) ) 00597 { 00598 // Write location index corresponding to cell 00599 *mpCellVariablesFile << location_index << " "; 00600 00601 // Write cell variables 00602 std::vector<double> proteins = (static_cast<AbstractOdeBasedCellCycleModel*>(pCell->GetCellCycleModel()))->GetProteinConcentrations(); 00603 for (unsigned i=0; i<proteins.size(); i++) 00604 { 00605 *mpCellVariablesFile << proteins[i] << " "; 00606 } 00607 } 00608 00609 // Write cell age data to file if required 00610 if (mOutputCellAges) 00611 { 00612 // Write location index corresponding to cell 00613 *mpCellAgesFile << location_index << " "; 00614 00615 // Write cell location 00616 c_vector<double, SPACE_DIM> cell_location = GetLocationOfCellCentre(pCell); 00617 00618 for (unsigned i=0; i<SPACE_DIM; i++) 00619 { 00620 *mpCellAgesFile << cell_location[i] << " "; 00621 } 00622 00623 // Write cell age 00624 *mpCellAgesFile << pCell->GetAge() << " "; 00625 } 00626 00627 *mpVizCellProliferativeTypesFile << colour << " "; 00628 00629 } 00630 00631 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00632 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::WriteCellResultsToFiles(std::vector<unsigned>& rCellProliferativeTypeCounter, 00633 std::vector<unsigned>& rCellCyclePhaseCounter) 00634 { 00635 *mpVizCellProliferativeTypesFile << "\n"; 00636 00637 if (mOutputCellAncestors) 00638 { 00639 *mpVizCellAncestorsFile << "\n"; 00640 } 00641 00642 // Write cell mutation state data to file if required 00643 if (mOutputCellMutationStates) 00644 { 00645 std::vector<unsigned> mutation_state_count = GetCellMutationStateCount(); 00646 00647 for (unsigned i=0; i<mutation_state_count.size(); i++) 00648 { 00649 *mpCellMutationStatesFile << mutation_state_count[i] << "\t"; 00650 } 00651 *mpCellMutationStatesFile << "\n"; 00652 } 00653 00654 // Write cell type data to file if required 00655 if (mOutputCellProliferativeTypes) 00656 { 00657 for (unsigned i=0; i<mCellProliferativeTypeCount.size(); i++) 00658 { 00659 mCellProliferativeTypeCount[i] = rCellProliferativeTypeCounter[i]; 00660 *mpCellProliferativeTypesFile << rCellProliferativeTypeCounter[i] << "\t"; 00661 } 00662 *mpCellProliferativeTypesFile << "\n"; 00663 } 00664 00665 if (mOutputCellVariables) 00666 { 00667 *mpCellVariablesFile << "\n"; 00668 } 00669 00670 // Write cell cycle phase data to file if required 00671 if (mOutputCellCyclePhases) 00672 { 00673 for (unsigned i=0; i<mCellCyclePhaseCount.size(); i++) 00674 { 00675 mCellCyclePhaseCount[i] = rCellCyclePhaseCounter[i]; 00676 *mpCellCyclePhasesFile << rCellCyclePhaseCounter[i] << "\t"; 00677 } 00678 *mpCellCyclePhasesFile << "\n"; 00679 00680 // The data for this is output in GenerateCellResults() 00681 *mpVizCellProliferativePhasesFile << "\n"; 00682 } 00683 00684 // Write cell age data to file if required 00685 if (mOutputCellAges) 00686 { 00687 *mpCellAgesFile << "\n"; 00688 } 00689 } 00690 00691 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00692 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::WriteTimeAndNodeResultsToFiles() 00693 { 00694 OutputFileHandler output_file_handler(mDirPath, false); 00695 00696 PetscTools::BeginRoundRobin(); 00697 { 00698 if(!PetscTools::AmMaster() || SimulationTime::Instance()->IsEndTimeAndNumberOfTimeStepsSetUp()) 00699 { 00700 mpVizNodesFile = output_file_handler.OpenOutputFile("results.viznodes", std::ios::app); 00701 mpVizBoundaryNodesFile = output_file_handler.OpenOutputFile("results.vizboundarynodes", std::ios::app); 00702 } 00703 if(PetscTools::AmMaster()) 00704 { 00705 double time = SimulationTime::Instance()->GetTime(); 00706 00707 *mpVizNodesFile << time << "\t"; 00708 *mpVizBoundaryNodesFile << time << "\t"; 00709 } 00710 // Write node data to file 00711 for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = mrMesh.GetNodeIteratorBegin(); 00712 node_iter != mrMesh.GetNodeIteratorEnd(); 00713 ++node_iter) 00714 { 00715 if (!node_iter->IsDeleted()) 00716 { 00717 const c_vector<double,SPACE_DIM>& position = node_iter->rGetLocation(); 00718 00719 for (unsigned i=0; i<SPACE_DIM; i++) 00720 { 00721 *mpVizNodesFile << position[i] << " "; 00722 } 00723 *mpVizBoundaryNodesFile << node_iter->IsBoundaryNode() << " "; 00724 } 00725 } 00726 if(PetscTools::AmTopMost()) 00727 { 00728 *mpVizNodesFile << "\n"; 00729 *mpVizBoundaryNodesFile << "\n"; 00730 } 00731 00732 mpVizNodesFile->close(); 00733 mpVizBoundaryNodesFile->close(); 00734 } 00735 } 00736 00737 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00738 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::WriteResultsToFiles() 00739 { 00740 WriteTimeAndNodeResultsToFiles(); 00741 double time = SimulationTime::Instance()->GetTime(); 00742 00743 *mpVizCellProliferativeTypesFile << time << "\t"; 00744 00745 if (mOutputCellAncestors) 00746 { 00747 *mpVizCellAncestorsFile << time << "\t"; 00748 } 00749 if (mOutputCellMutationStates) 00750 { 00751 *mpCellMutationStatesFile << time << "\t"; 00752 } 00753 if (mOutputCellProliferativeTypes) 00754 { 00755 *mpCellProliferativeTypesFile << time << "\t"; 00756 } 00757 if (mOutputCellVariables) 00758 { 00759 *mpCellVariablesFile << time << "\t"; 00760 } 00761 if (mOutputCellCyclePhases) 00762 { 00763 *mpCellCyclePhasesFile << time << "\t"; 00764 *mpVizCellProliferativePhasesFile << time << "\t"; 00765 } 00766 if (mOutputCellAges) 00767 { 00768 *mpCellAgesFile << time << "\t"; 00769 } 00770 if (this->mOutputCellVolumes) 00771 { 00772 WriteCellVolumeResultsToFile(); 00773 } 00774 00775 GenerateCellResultsAndWriteToFiles(); 00776 00777 // Write logged cell data if required 00778 if (mOutputCellIdData) 00779 { 00780 WriteCellIdDataToFile(); 00781 } 00782 00783 // VTK can only be written in 2 or 3 dimensions 00784 if (SPACE_DIM > 1) 00785 { 00786 WriteVtkResultsToFile(); 00787 } 00788 } 00789 00790 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00791 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::WriteCellIdDataToFile() 00792 { 00793 // Write time to file 00794 *mpCellIdFile << SimulationTime::Instance()->GetTime(); 00795 00796 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = Begin(); 00797 cell_iter != End(); 00798 ++cell_iter) 00799 { 00800 unsigned cell_id = cell_iter->GetCellId(); 00801 unsigned location_index = mCellLocationMap[(*cell_iter).get()]; 00802 *mpCellIdFile << " " << cell_id << " " << location_index; 00803 00804 c_vector<double, SPACE_DIM> coords = GetLocationOfCellCentre(*cell_iter); 00805 for (unsigned i=0; i<SPACE_DIM; i++) 00806 { 00807 *mpCellIdFile << " " << coords[i]; 00808 } 00809 } 00810 *mpCellIdFile << "\n"; 00811 } 00812 00813 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00814 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OutputCellPopulationInfo(out_stream& rParamsFile) 00815 { 00816 std::string cell_population_type = GetIdentifier(); 00817 00818 *rParamsFile << "\t<" << cell_population_type << ">\n"; 00819 OutputCellPopulationParameters(rParamsFile); 00820 *rParamsFile << "\t</" << cell_population_type << ">\n"; 00821 *rParamsFile << "\n"; 00822 *rParamsFile << "\t<CellCycleModels>\n"; 00823 00824 /* 00825 * Loop over cells and generate a set of cell-cycle model classes 00826 * that are present in the population. 00827 * 00828 * \todo this currently ignores different parameter regimes (#1453) 00829 */ 00830 std::set<std::string> unique_cell_cycle_models; 00831 std::vector<CellPtr> first_cell_with_unique_CCM; 00832 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin(); 00833 cell_iter != this->End(); 00834 ++cell_iter) 00835 { 00836 std::string identifier = cell_iter->GetCellCycleModel()->GetIdentifier(); 00837 if (unique_cell_cycle_models.count(identifier) == 0) 00838 { 00839 unique_cell_cycle_models.insert(identifier); 00840 first_cell_with_unique_CCM.push_back((*cell_iter)); 00841 } 00842 } 00843 00844 // Loop over unique cell-cycle models 00845 for (unsigned i=0; i<first_cell_with_unique_CCM.size(); i++) 00846 { 00847 // Output cell-cycle model details 00848 first_cell_with_unique_CCM[i]->GetCellCycleModel()->OutputCellCycleModelInfo(rParamsFile); 00849 } 00850 00851 *rParamsFile << "\t</CellCycleModels>\n"; 00852 } 00853 00854 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00855 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OutputCellPopulationParameters(out_stream& rParamsFile) 00856 { 00857 *rParamsFile << "\t\t<OutputCellIdData>" << mOutputCellIdData << "</OutputCellIdData>\n"; 00858 *rParamsFile << "\t\t<OutputCellMutationStates>" << mOutputCellMutationStates << "</OutputCellMutationStates>\n"; 00859 *rParamsFile << "\t\t<OutputCellAncestors>" << mOutputCellAncestors << "</OutputCellAncestors>\n"; 00860 *rParamsFile << "\t\t<OutputCellProliferativeTypes>" << mOutputCellProliferativeTypes << "</OutputCellProliferativeTypes>\n"; 00861 *rParamsFile << "\t\t<OutputCellVariables>" << mOutputCellVariables << "</OutputCellVariables>\n"; 00862 *rParamsFile << "\t\t<OutputCellCyclePhases>" << mOutputCellCyclePhases << "</OutputCellCyclePhases>\n"; 00863 *rParamsFile << "\t\t<OutputCellAges>" << mOutputCellAges << "</OutputCellAges>\n"; 00864 *rParamsFile << "\t\t<OutputCellVolumes>" << mOutputCellVolumes << "</OutputCellVolumes>\n"; 00865 } 00866 00868 // Getter methods 00870 00871 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00872 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputCellIdData() 00873 { 00874 return mOutputCellIdData; 00875 } 00876 00877 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00878 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputCellMutationStates() 00879 { 00880 return mOutputCellMutationStates; 00881 } 00882 00883 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00884 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputCellAncestors() 00885 { 00886 return mOutputCellAncestors; 00887 } 00888 00889 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00890 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputCellProliferativeTypes() 00891 { 00892 return mOutputCellProliferativeTypes; 00893 } 00894 00895 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00896 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputCellVariables() 00897 { 00898 return mOutputCellVariables; 00899 } 00900 00901 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00902 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputCellCyclePhases() 00903 { 00904 return mOutputCellCyclePhases; 00905 } 00906 00907 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00908 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputCellAges() 00909 { 00910 return mOutputCellAges; 00911 } 00912 00913 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00914 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputCellVolumes() 00915 { 00916 return mOutputCellVolumes; 00917 } 00918 00920 // Setter methods 00922 00923 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00924 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputCellIdData(bool writeCellIdData) 00925 { 00926 mOutputCellIdData = writeCellIdData; 00927 } 00928 00929 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00930 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputCellMutationStates(bool outputCellMutationStates) 00931 { 00932 mOutputCellMutationStates = outputCellMutationStates; 00933 } 00934 00935 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00936 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputCellAncestors(bool outputCellAncestors) 00937 { 00938 mOutputCellAncestors = outputCellAncestors; 00939 } 00940 00941 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00942 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputCellProliferativeTypes(bool outputCellProliferativeTypes) 00943 { 00944 mOutputCellProliferativeTypes = outputCellProliferativeTypes; 00945 } 00946 00947 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00948 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputCellVariables(bool outputCellVariables) 00949 { 00950 mOutputCellVariables = outputCellVariables; 00951 } 00952 00953 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00954 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputCellCyclePhases(bool outputCellCyclePhases) 00955 { 00956 mOutputCellCyclePhases = outputCellCyclePhases; 00957 } 00958 00959 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00960 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputCellAges(bool outputCellAges) 00961 { 00962 mOutputCellAges = outputCellAges; 00963 } 00964 00965 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00966 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputCellVolumes(bool outputCellVolumes) 00967 { 00968 mOutputCellVolumes = outputCellVolumes; 00969 } 00970 00971 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00972 c_vector<double,SPACE_DIM> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetSizeOfCellPopulation() 00973 { 00974 // Compute the centre of mass of the cell population 00975 c_vector<double,SPACE_DIM> centre = GetCentroidOfCellPopulation(); 00976 00977 // Loop over cells and find the maximum distance from the centre of mass in each dimension 00978 c_vector<double,SPACE_DIM> max_distance_from_centre = zero_vector<double>(SPACE_DIM); 00979 for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin(); 00980 cell_iter != this->End(); 00981 ++cell_iter) 00982 { 00983 c_vector<double,SPACE_DIM> cell_location = GetLocationOfCellCentre(*cell_iter); 00984 c_vector<double,SPACE_DIM> displacement = centre - cell_location; 00985 00986 for (unsigned i=0; i<SPACE_DIM; i++) 00987 { 00988 if (displacement[i] > max_distance_from_centre[i]) 00989 { 00990 max_distance_from_centre[i] = displacement[i]; 00991 } 00992 } 00993 } 00994 00995 return max_distance_from_centre; 00996 } 00997 00999 // Explicit instantiation 01001 01002 template class AbstractCellPopulation<1,1>; 01003 template class AbstractCellPopulation<1,2>; 01004 template class AbstractCellPopulation<2,2>; 01005 template class AbstractCellPopulation<1,3>; 01006 template class AbstractCellPopulation<2,3>; 01007 template class AbstractCellPopulation<3,3>;