Chaste Release::3.1
AbstractCellPopulation.cpp
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>;