AbstractCellPopulation.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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 <boost/bind.hpp>
00037 #include <boost/mem_fn.hpp>
00038 
00039 #include <algorithm>
00040 #include <functional>
00041 
00042 #include "AbstractCellPopulation.hpp"
00043 #include "AbstractOdeBasedCellCycleModel.hpp"
00044 #include "Exception.hpp"
00045 #include "PetscTools.hpp"
00046 #include "SmartPointers.hpp"
00047 
00048 // Cell writers
00049 #include "BoundaryNodeWriter.hpp"
00050 #include "CellProliferativeTypesWriter.hpp"
00051 
00052 // Cell population writers
00053 #include "CellMutationStatesCountWriter.hpp"
00054 #include "CellProliferativePhasesCountWriter.hpp"
00055 #include "CellProliferativeTypesCountWriter.hpp"
00056 #include "NodeLocationWriter.hpp"
00057 
00058 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00059 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AbstractCellPopulation( AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00060                                     std::vector<CellPtr>& rCells,
00061                                     const std::vector<unsigned> locationIndices)
00062     : mrMesh(rMesh),
00063       mCells(rCells.begin(), rCells.end()),
00064       mCentroid(zero_vector<double>(SPACE_DIM)),
00065       mpCellPropertyRegistry(CellPropertyRegistry::Instance()->TakeOwnership()),
00066       mOutputResultsForChasteVisualizer(true)
00067 {
00068     /*
00069      * To avoid double-counting problems, clear the passed-in cells vector.
00070      * We force a reallocation of memory so that subsequent usage of the
00071      * vector is more likely to give an error.
00072      */
00073     std::vector<CellPtr>().swap(rCells);
00074 
00075     // There must be a one-one correspondence between cells and location indices
00076     if (!locationIndices.empty())
00077     {
00078         if (mCells.size() != locationIndices.size())
00079         {
00080             EXCEPTION("There is not a one-one correspondence between cells and location indices");
00081         }
00082     }
00083 
00084     // Set up the map between location indices and cells
00085     mLocationCellMap.clear();
00086     mCellLocationMap.clear();
00087 
00088     std::list<CellPtr>::iterator it = mCells.begin();
00089     for (unsigned i=0; it != mCells.end(); ++it, ++i)
00090     {
00091         // Give each cell a pointer to the property registry (we have taken ownership in this constructor)
00092         (*it)->rGetCellPropertyCollection().SetCellPropertyRegistry(mpCellPropertyRegistry.get());
00093     }
00094 }
00095 
00096 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00097 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AbstractCellPopulation(AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh)
00098     : mrMesh(rMesh)
00099 {
00100 }
00101 
00102 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00103 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::~AbstractCellPopulation()
00104 {
00105 }
00106 
00107 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00108 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::InitialiseCells()
00109 {
00110     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
00111          cell_iter!=this->End();
00112          ++cell_iter)
00113     {
00114         cell_iter->InitialiseCellCycleModel();
00115     }
00116 }
00117 
00118 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00119 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetDataOnAllCells(const std::string& dataName, double dataValue)
00120 {
00121     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
00122          cell_iter!=this->End();
00123          ++cell_iter)
00124     {
00125         cell_iter->GetCellData()->SetItem(dataName, dataValue);
00126     }
00127 }
00128 
00129 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00130 AbstractMesh<ELEMENT_DIM, SPACE_DIM>& AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::rGetMesh()
00131 {
00132     return mrMesh;
00133 }
00134 
00135 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00136 std::list<CellPtr>& AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::rGetCells()
00137 {
00138     return mCells;
00139 }
00140 
00141 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00142 unsigned AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetNumRealCells()
00143 {
00144     unsigned counter = 0;
00145     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
00146          cell_iter!=this->End();
00147          ++cell_iter)
00148     {
00149         counter++;
00150     }
00151     return counter;
00152 }
00153 
00154 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00155 unsigned AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetNumAllCells()
00156 {
00157     return mCells.size();
00158 }
00159 
00160 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00161 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetCellAncestorsToLocationIndices()
00162 {
00163     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00164     {
00165         MAKE_PTR_ARGS(CellAncestor, p_cell_ancestor, (mCellLocationMap[(*cell_iter).get()]));
00166         cell_iter->SetAncestor(p_cell_ancestor);
00167     }
00168 }
00169 
00170 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00171 std::set<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellAncestors()
00172 {
00173     std::set<unsigned> remaining_ancestors;
00174     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00175     {
00176         remaining_ancestors.insert(cell_iter->GetAncestor());
00177     }
00178     return remaining_ancestors;
00179 }
00180 
00181 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00182 std::vector<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellMutationStateCount()
00183 {
00184     std::vector<unsigned> mutation_state_count;
00185     const std::vector<boost::shared_ptr<AbstractCellProperty> >& r_cell_properties
00186         = mpCellPropertyRegistry->rGetAllCellProperties();
00187 
00188     // Calculate mutation states count
00189     for (unsigned i=0; i<r_cell_properties.size(); i++)
00190     {
00191         if (r_cell_properties[i]->IsSubType<AbstractCellMutationState>())
00192         {
00193             mutation_state_count.push_back(r_cell_properties[i]->GetCellCount());
00194         }
00195     }
00196 
00197     // Reduce results onto all processes
00198     if (PetscTools::IsParallel())
00199     {
00200         // Make sure the vector on each process has the same size
00201         unsigned local_size = mutation_state_count.size();
00202         unsigned global_size;
00203         MPI_Allreduce(&local_size, &global_size, 1, MPI_UNSIGNED, MPI_MAX, PetscTools::GetWorld());
00204         assert(local_size == global_size);
00205 
00206         std::vector<unsigned> mutation_counts(global_size);
00207         MPI_Allreduce(&mutation_state_count[0], &mutation_counts[0], mutation_counts.size(), MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
00208 
00209         mutation_state_count = mutation_counts;
00210     }
00211 
00212     return mutation_state_count;
00213 }
00214 
00215 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00216 std::vector<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellProliferativeTypeCount()
00217 {
00218     std::vector<unsigned> proliferative_type_count;
00219     const std::vector<boost::shared_ptr<AbstractCellProperty> >& r_cell_properties
00220         = mpCellPropertyRegistry->rGetAllCellProperties();
00221 
00222     // Calculate proliferative types count
00223     for (unsigned i=0; i<r_cell_properties.size(); i++)
00224     {
00225         if (r_cell_properties[i]->IsSubType<AbstractCellProliferativeType>())
00226         {
00227             proliferative_type_count.push_back(r_cell_properties[i]->GetCellCount());
00228         }
00229     }
00230 
00231     // Reduce results onto all processes
00232     if (PetscTools::IsParallel())
00233     {
00234         // Make sure the vector on each process has the same size
00235         unsigned local_size = proliferative_type_count.size();
00236         unsigned global_size;
00237 
00238         MPI_Allreduce(&local_size, &global_size, 1, MPI_UNSIGNED, MPI_MAX, PetscTools::GetWorld());
00239         assert(local_size == global_size);
00240 
00241         std::vector<unsigned> total_types_counts(global_size);
00242         MPI_Allreduce(&proliferative_type_count[0], &total_types_counts[0], total_types_counts.size(), MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
00243 
00244         proliferative_type_count = total_types_counts;
00245     }
00246 
00247     return proliferative_type_count;
00248 }
00249 
00250 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00251 std::vector<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellCyclePhaseCount()
00252 {
00253     std::vector<unsigned> cell_cycle_phase_count(5);
00254     for (unsigned i=0; i<5; i++)
00255     {
00256         cell_cycle_phase_count[i] = 0;
00257     }
00258 
00259     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00260          cell_iter != this->End();
00261          ++cell_iter)
00262     {
00263         switch ((*cell_iter)->GetCellCycleModel()->GetCurrentCellCyclePhase())
00264         {
00265             case G_ZERO_PHASE:
00266                 cell_cycle_phase_count[0]++;
00267                 break;
00268             case G_ONE_PHASE:
00269                 cell_cycle_phase_count[1]++;
00270                 break;
00271             case S_PHASE:
00272                 cell_cycle_phase_count[2]++;
00273                 break;
00274             case G_TWO_PHASE:
00275                 cell_cycle_phase_count[3]++;
00276                 break;
00277             case M_PHASE:
00278                 cell_cycle_phase_count[4]++;
00279                 break;
00280             default:
00281                 NEVER_REACHED;
00282         }
00283     }
00284 
00285     // Reduce results onto all processes
00286     if (PetscTools::IsParallel())
00287     {
00288         std::vector<unsigned> phase_counts(cell_cycle_phase_count.size(), 0u);
00289         MPI_Allreduce(&cell_cycle_phase_count[0], &phase_counts[0], phase_counts.size(), MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
00290 
00291         cell_cycle_phase_count = phase_counts;
00292     }
00293 
00294     return cell_cycle_phase_count;
00295 }
00296 
00297 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00298 CellPtr AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellUsingLocationIndex(unsigned index)
00299 {
00300     // Get the set of pointers to cells corresponding to this location index
00301     std::set<CellPtr> cells = mLocationCellMap[index];
00302 
00303     // If there is only one cell attached return the cell. Note currently only one cell per index.
00304     if (cells.size() == 1)
00305     {
00306         return *(cells.begin());
00307     }
00308     if (cells.empty())
00309     {
00310         EXCEPTION("Location index input argument does not correspond to a Cell");
00311     }
00312     else
00313     {
00314         EXCEPTION("Multiple cells are attached to a single location index.");
00315     }
00316 }
00317 
00318 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00319 std::set<CellPtr> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellsUsingLocationIndex(unsigned index)
00320 {
00321     // Return the set of pointers to cells corresponding to this location index, note the set may be empty.
00322     return mLocationCellMap[index];
00323 }
00324 
00325 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00326 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsCellAttachedToLocationIndex(unsigned index)
00327 {
00328     // Get the set of pointers to cells corresponding to this location index
00329     std::set<CellPtr> cells = mLocationCellMap[index];
00330 
00331     // Return whether there is a cell attached to the location index
00332     return !(cells.empty());
00333 }
00334 
00335 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00336 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetCellUsingLocationIndex(unsigned index, CellPtr pCell)
00337 {
00338     // Clear the maps
00339     mLocationCellMap[index].clear();
00340     mCellLocationMap.erase(pCell.get());
00341 
00342     // Replace with new cell
00343     mLocationCellMap[index].insert(pCell);
00344 
00345     // Do other half of the map
00346     mCellLocationMap[pCell.get()] = index;
00347 }
00348 
00349 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00350 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
00351 {
00352     mLocationCellMap[index].insert(pCell);
00353     mCellLocationMap[pCell.get()] = index;
00354 }
00355 
00356 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00357 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::RemoveCellUsingLocationIndex(unsigned index, CellPtr pCell)
00358 {
00359     std::set<CellPtr>::iterator cell_iter = mLocationCellMap[index].find(pCell);
00360 
00361     if (cell_iter == mLocationCellMap[index].end())
00362     {
00363         EXCEPTION("Tried to remove a cell which is not attached to the given location index");
00364     }
00365     else
00366     {
00367         mLocationCellMap[index].erase(cell_iter);
00368         mCellLocationMap.erase(pCell.get());
00369     }
00370 }
00371 
00372 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00373 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::MoveCellInLocationMap(CellPtr pCell, unsigned old_index, unsigned new_index)
00374 {
00375     // Remove the cell from its current location
00376     RemoveCellUsingLocationIndex(old_index, pCell);
00377 
00378     // Add it to the new location
00379     AddCellUsingLocationIndex(new_index, pCell);
00380 }
00381 
00382 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00383 unsigned AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetLocationIndexUsingCell(CellPtr pCell)
00384 {
00385     // Check the cell is in the map
00386     assert(this->mCellLocationMap.find(pCell.get()) != this->mCellLocationMap.end());
00387 
00388     return mCellLocationMap[pCell.get()];
00389 }
00390 
00391 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00392 boost::shared_ptr<CellPropertyRegistry> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellPropertyRegistry()
00393 {
00394     return mpCellPropertyRegistry;
00395 }
00396 
00397 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00398 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetDefaultCellMutationStateAndProliferativeTypeOrdering()
00399 {
00400     boost::shared_ptr<CellPropertyRegistry> p_registry = GetCellPropertyRegistry();
00401     if (!p_registry->HasOrderingBeenSpecified())
00402     {
00403         std::vector<boost::shared_ptr<AbstractCellProperty> > mutations_and_proliferative_types;
00404         mutations_and_proliferative_types.push_back(p_registry->Get<WildTypeCellMutationState>());
00405         mutations_and_proliferative_types.push_back(p_registry->Get<ApcOneHitCellMutationState>());
00406         mutations_and_proliferative_types.push_back(p_registry->Get<ApcTwoHitCellMutationState>());
00407         mutations_and_proliferative_types.push_back(p_registry->Get<BetaCateninOneHitCellMutationState>());
00408         mutations_and_proliferative_types.push_back(p_registry->Get<StemCellProliferativeType>());
00409         mutations_and_proliferative_types.push_back(p_registry->Get<TransitCellProliferativeType>());
00410         mutations_and_proliferative_types.push_back(p_registry->Get<DifferentiatedCellProliferativeType>());
00411         // Parallel process with no cells won't have the default property, so add it in
00412         mutations_and_proliferative_types.push_back(p_registry->Get<DefaultCellProliferativeType>());
00413         p_registry->SpecifyOrdering(mutations_and_proliferative_types);
00414     }
00415 }
00416 
00417 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00418 c_vector<double, SPACE_DIM> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCentroidOfCellPopulation()
00419 {
00420     mCentroid = zero_vector<double>(SPACE_DIM);
00421     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00422          cell_iter != this->End();
00423          ++cell_iter)
00424     {
00425         mCentroid += GetLocationOfCellCentre(*cell_iter);
00426     }
00427     mCentroid /= this->GetNumRealCells();
00428 
00429     return mCentroid;
00430 }
00431 
00432 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00433 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::UpdateCellProcessLocation()
00434 {
00435 }
00436 
00437 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00438 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::CloseRoundRobinWritersFiles()
00439 {
00440     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00441     BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00442     {
00443         p_cell_writer->CloseFile();
00444     }
00445 
00446     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00447     BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00448     {
00449         p_pop_writer->CloseFile();
00450     }
00451 }
00452 
00453 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00454 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::CloseWritersFiles()
00455 {
00456     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00457     BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00458     {
00459         p_cell_writer->CloseFile();
00460     }
00461 
00462     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00463     BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00464     {
00465         p_pop_writer->CloseFile();
00466     }
00467 
00468 #ifdef CHASTE_VTK
00469     *mpVtkMetaFile << "    </Collection>\n";
00470     *mpVtkMetaFile << "</VTKFile>\n";
00471     mpVtkMetaFile->close();
00472 #endif //CHASTE_VTK
00473 }
00474 
00475 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00476 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OpenWritersFiles(OutputFileHandler& rOutputFileHandler)
00477 {
00478 #ifdef CHASTE_VTK
00479     mpVtkMetaFile = rOutputFileHandler.OpenOutputFile("results.pvd");
00480     *mpVtkMetaFile << "<?xml version=\"1.0\"?>\n";
00481     *mpVtkMetaFile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n";
00482     *mpVtkMetaFile << "    <Collection>\n";
00483 #endif //CHASTE_VTK
00484 
00485     if (mOutputResultsForChasteVisualizer)
00486     {
00487         if (!HasWriter<NodeLocationWriter>())
00488         {
00489             AddPopulationWriter<NodeLocationWriter>();
00490         }
00491         if (!HasWriter<BoundaryNodeWriter>())
00492         {
00493             AddPopulationWriter<BoundaryNodeWriter>();
00494         }
00495         if (!HasWriter<CellProliferativeTypesWriter>())
00496         {
00497             AddCellWriter<CellProliferativeTypesWriter>();
00498         }
00499     }
00500 
00501     // Open output files for any cell writers
00502     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00503     BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00504     {
00505         p_cell_writer->OpenOutputFile(rOutputFileHandler);
00506     }
00507 
00508     // Open output files and write headers for any population writers
00509     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00510     BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00511     {
00512         p_pop_writer->OpenOutputFile(rOutputFileHandler);
00513         p_pop_writer->WriteHeader(this);
00514     }
00515 
00516     // Open output files and write headers for any population count writers
00517     typedef AbstractCellPopulationCountWriter<ELEMENT_DIM, SPACE_DIM> count_writer_t;
00518     BOOST_FOREACH(boost::shared_ptr<count_writer_t> p_count_writer, mCellPopulationCountWriters)
00519     {
00520         p_count_writer->OpenOutputFile(rOutputFileHandler);
00521         p_count_writer->WriteHeader(this);
00522     }
00523 }
00524 
00525 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00526 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OpenRoundRobinWritersFilesForAppend(OutputFileHandler& rOutputFileHandler)
00527 {
00528     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00529     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00530     BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00531     {
00532         p_cell_writer->OpenOutputFileForAppend(rOutputFileHandler);
00533     }
00534     BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00535     {
00536         p_pop_writer->OpenOutputFileForAppend(rOutputFileHandler);
00537     }
00538 }
00539 
00540 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00541 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::WriteResultsToFiles(const std::string& rDirectory)
00542 {
00543     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00544     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00545     OutputFileHandler output_file_handler(rDirectory, false);
00546 
00547     if (!(mCellWriters.empty() && mCellPopulationWriters.empty() && mCellPopulationCountWriters.empty()))
00548     {
00549         // An ordering must be specified for cell mutation states and cell proliferative types
00550         SetDefaultCellMutationStateAndProliferativeTypeOrdering();
00551 
00552         PetscTools::BeginRoundRobin();
00553         {
00554             OpenRoundRobinWritersFilesForAppend(output_file_handler);
00555 
00556             // The master process writes time stamps
00557             if (PetscTools::AmMaster())
00558             {
00559                 BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00560                 {
00561                     p_cell_writer->WriteTimeStamp();
00562                 }
00563                 BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00564                 {
00565                     p_pop_writer->WriteTimeStamp();
00566                 }
00567             }
00568 
00569             for (typename std::vector<boost::shared_ptr<AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator pop_writer_iter = mCellPopulationWriters.begin();
00570                  pop_writer_iter != mCellPopulationWriters.end();
00571                  ++pop_writer_iter)
00572             {
00573                 AcceptPopulationWriter(*pop_writer_iter);
00574             }
00575 
00576             for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00577                  cell_iter != this->End();
00578                  ++cell_iter)
00579             {
00580                 for (typename std::vector<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = mCellWriters.begin();
00581                      cell_writer_iter != mCellWriters.end();
00582                      ++cell_writer_iter)
00583                 {
00584                     AcceptCellWriter(*cell_writer_iter, *cell_iter);
00585                 }
00586             }
00587 
00588             // The top-most process adds a newline
00589             if (PetscTools::AmTopMost())
00590             {
00591                 BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00592                 {
00593                     p_cell_writer->WriteNewline();
00594                 }
00595                 BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00596                 {
00597                     p_pop_writer->WriteNewline();
00598                 }
00599             }
00600             CloseRoundRobinWritersFiles();
00601         }
00602         PetscTools::EndRoundRobin();
00603 
00604         // Outside the round robin, deal with population count writers
00605         typedef AbstractCellPopulationCountWriter<ELEMENT_DIM, SPACE_DIM> count_writer_t;
00606 
00607         if (PetscTools::AmMaster())
00608         {
00609             // Open mCellPopulationCountWriters in append mode for writing, and write time stamps
00610             BOOST_FOREACH(boost::shared_ptr<count_writer_t> p_count_writer, mCellPopulationCountWriters)
00611             {
00612                 p_count_writer->OpenOutputFileForAppend(output_file_handler);
00613                 p_count_writer->WriteTimeStamp();
00614             }
00615         }
00616         for (typename std::vector<boost::shared_ptr<AbstractCellPopulationCountWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator count_writer_iter = mCellPopulationCountWriters.begin();
00617              count_writer_iter != mCellPopulationCountWriters.end();
00618              ++count_writer_iter)
00619         {
00620             AcceptPopulationCountWriter(*count_writer_iter);
00621         }
00622 
00623         if (PetscTools::AmMaster())
00624         {
00625             // Add a newline and close any output files
00626             BOOST_FOREACH(boost::shared_ptr<count_writer_t> p_count_writer, mCellPopulationCountWriters)
00627             {
00628                 p_count_writer->WriteNewline();
00629                 p_count_writer->CloseFile();
00630             }
00631         }
00632     }
00633 
00634     // VTK can only be written in 2 or 3 dimensions
00635     if (SPACE_DIM > 1)
00636     {
00637        WriteVtkResultsToFile(rDirectory);
00638     }
00639 }
00640 
00641 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00642 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OutputCellPopulationInfo(out_stream& rParamsFile)
00643 {
00644     std::string cell_population_type = GetIdentifier();
00645 
00646     *rParamsFile << "\t<" << cell_population_type << ">\n";
00647     OutputCellPopulationParameters(rParamsFile);
00648     *rParamsFile << "\t</" << cell_population_type << ">\n";
00649     *rParamsFile << "\n";
00650     *rParamsFile << "\t<CellCycleModels>\n";
00651 
00658     std::set<std::string> unique_cell_cycle_models;
00659     std::vector<CellPtr> first_cell_with_unique_CCM;
00660     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00661          cell_iter != this->End();
00662          ++cell_iter)
00663     {
00664         std::string identifier = cell_iter->GetCellCycleModel()->GetIdentifier();
00665         if (unique_cell_cycle_models.count(identifier) == 0)
00666         {
00667             unique_cell_cycle_models.insert(identifier);
00668             first_cell_with_unique_CCM.push_back((*cell_iter));
00669         }
00670     }
00671 
00672     // Loop over unique cell-cycle models
00673     for (unsigned i=0; i<first_cell_with_unique_CCM.size(); i++)
00674     {
00675         // Output cell-cycle model details
00676         first_cell_with_unique_CCM[i]->GetCellCycleModel()->OutputCellCycleModelInfo(rParamsFile);
00677     }
00678 
00679     *rParamsFile << "\t</CellCycleModels>\n";
00680 }
00681 
00682 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00683 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
00684 {
00685     *rParamsFile << "\t\t<OutputResultsForChasteVisualizer>" << mOutputResultsForChasteVisualizer << "</OutputResultsForChasteVisualizer>\n";
00686 }
00687 
00688 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00689 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputResultsForChasteVisualizer()
00690 {
00691     return mOutputResultsForChasteVisualizer;
00692 }
00693 
00694 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00695 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputResultsForChasteVisualizer(bool outputResultsForChasteVisualizer)
00696 {
00697     mOutputResultsForChasteVisualizer = outputResultsForChasteVisualizer;
00698 }
00699 
00700 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00701 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsRoomToDivide(CellPtr pCell)
00702 {
00703     return true;
00704 }
00705 
00706 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00707 c_vector<double,SPACE_DIM> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetSizeOfCellPopulation()
00708 {
00709     // Compute the centre of mass of the cell population
00710     c_vector<double,SPACE_DIM> centre = GetCentroidOfCellPopulation();
00711 
00712     // Loop over cells and find the maximum distance from the centre of mass in each dimension
00713     c_vector<double,SPACE_DIM> max_distance_from_centre = zero_vector<double>(SPACE_DIM);
00714     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00715          cell_iter != this->End();
00716          ++cell_iter)
00717     {
00718         c_vector<double,SPACE_DIM> cell_location = GetLocationOfCellCentre(*cell_iter);
00719 
00720         // Note that we define this vector before setting it as otherwise the profiling build will break (see #2367)
00721         c_vector<double,SPACE_DIM> displacement;
00722         displacement = centre - cell_location;
00723 
00724         for (unsigned i=0; i<SPACE_DIM; i++)
00725         {
00726             if (displacement[i] > max_distance_from_centre[i])
00727             {
00728                 max_distance_from_centre[i] = displacement[i];
00729             }
00730         }
00731     }
00732 
00733     return max_distance_from_centre;
00734 }
00735 
00736 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00737 std::pair<unsigned,unsigned> AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::CreateOrderedPair(unsigned index1, unsigned index2)
00738 {
00739     assert(index1 != index2);
00740 
00741     std::pair<unsigned, unsigned> ordered_pair;
00742     if (index1 < index2)
00743     {
00744         ordered_pair.first = index1;
00745         ordered_pair.second = index2;
00746     }
00747     else
00748     {
00749         ordered_pair.first = index2;
00750         ordered_pair.second = index1;
00751     }
00752     return ordered_pair;
00753 }
00754 
00755 // Explicit instantiation
00756 template class AbstractCellPopulation<1,1>;
00757 template class AbstractCellPopulation<1,2>;
00758 template class AbstractCellPopulation<2,2>;
00759 template class AbstractCellPopulation<1,3>;
00760 template class AbstractCellPopulation<2,3>;
00761 template class AbstractCellPopulation<3,3>;

Generated by  doxygen 1.6.2