AbstractCentreBasedCellPopulation.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "AbstractCentreBasedCellPopulation.hpp"
00030 
00031 template<unsigned DIM>
00032 AbstractCentreBasedCellPopulation<DIM>::AbstractCentreBasedCellPopulation(std::vector<CellPtr>& rCells,
00033                                                                   const std::vector<unsigned> locationIndices)
00034     : AbstractOffLatticeCellPopulation<DIM>(rCells, locationIndices),
00035       mMeinekeDivisionSeparation(0.3) // educated guess
00036 {
00037 }
00038 
00039 template<unsigned DIM>
00040 AbstractCentreBasedCellPopulation<DIM>::AbstractCentreBasedCellPopulation()
00041     : AbstractOffLatticeCellPopulation<DIM>(),
00042       mMeinekeDivisionSeparation(0.3) // educated guess
00043 {
00044 }
00045 
00046 template<unsigned DIM>
00047 c_vector<double, DIM> AbstractCentreBasedCellPopulation<DIM>::GetLocationOfCellCentre(CellPtr pCell)
00048 {
00049     return GetNodeCorrespondingToCell(pCell)->rGetLocation();
00050 }
00051 
00052 template<unsigned DIM>
00053 Node<DIM>* AbstractCentreBasedCellPopulation<DIM>::GetNodeCorrespondingToCell(CellPtr pCell)
00054 {
00055     assert(this->mCellLocationMap.find(pCell.get()) != this->mCellLocationMap.end());
00056 
00057     return this->GetNode(this->mCellLocationMap[pCell.get()]);
00058 }
00059 
00060 template<unsigned DIM>
00061 CellPtr AbstractCentreBasedCellPopulation<DIM>::AddCell(CellPtr pNewCell, const c_vector<double,DIM>& rCellDivisionVector, CellPtr pParentCell)
00062 {
00063     // Create a new node
00064     Node<DIM>* p_new_node = new Node<DIM>(this->GetNumNodes(), rCellDivisionVector, false);   // never on boundary
00065     unsigned new_node_index = AddNode(p_new_node); // use copy constructor so it doesn't matter that new_node goes out of scope
00066 
00067     // Update cells vector
00068     this->mCells.push_back(pNewCell);
00069 
00070     // Update mappings between cells and location indices
00071     this->mLocationCellMap[new_node_index] = pNewCell;
00072     this->mCellLocationMap[pNewCell.get()] = new_node_index;
00073 
00074     return pNewCell;
00075 }
00076 
00077 template<unsigned DIM>
00078 bool AbstractCentreBasedCellPopulation<DIM>::IsCellAssociatedWithADeletedLocation(CellPtr pCell)
00079 {
00080     return GetNodeCorrespondingToCell(pCell)->IsDeleted();
00081 }
00082 
00083 template<unsigned DIM>
00084 void AbstractCentreBasedCellPopulation<DIM>::UpdateNodeLocations(const std::vector< c_vector<double, DIM> >& rNodeForces, double dt)
00085 {
00086     // Iterate over all nodes associated with real cells to update their positions
00087     for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00088          cell_iter != this->End();
00089          ++cell_iter)
00090     {
00091         // Get index of node associated with cell
00092         unsigned node_index = this->mCellLocationMap[(*cell_iter).get()];
00093 
00094         // Get damping constant for node
00095         double damping_const = this->GetDampingConstant(node_index);
00096 
00097         // Get new node location
00098         c_vector<double, DIM> new_node_location = this->GetNode(node_index)->rGetLocation() + dt*rNodeForces[node_index]/damping_const;
00099 
00100         // Create ChastePoint for new node location
00101         ChastePoint<DIM> new_point(new_node_location);
00102 
00103         // Move the node
00104         this->SetNode(node_index, new_point);
00105     }
00106 }
00107 
00108 template<unsigned DIM>
00109 double AbstractCentreBasedCellPopulation<DIM>::GetDampingConstant(unsigned nodeIndex)
00110 {
00111     CellPtr p_cell = this->GetCellUsingLocationIndex(nodeIndex);
00112     if (p_cell->GetMutationState()->IsType<WildTypeCellMutationState>() && !p_cell->HasCellProperty<CellLabel>())
00113     {
00114         return this->GetDampingConstantNormal();
00115     }
00116     else
00117     {
00118         return this->GetDampingConstantMutant();
00119     }
00120 }
00121 
00122 template<unsigned DIM>
00123 bool AbstractCentreBasedCellPopulation<DIM>::IsGhostNode(unsigned index)
00124 {
00125     return false;
00126 }
00127 
00128 template<unsigned DIM>
00129 void AbstractCentreBasedCellPopulation<DIM>::GenerateCellResults(unsigned locationIndex,
00130                                                              std::vector<unsigned>& rCellProliferativeTypeCounter,
00131                                                              std::vector<unsigned>& rCellCyclePhaseCounter)
00132 {
00133     if (IsGhostNode(locationIndex) == true)
00134     {
00135         *(this->mpVizCellProliferativeTypesFile) << INVISIBLE_COLOUR << " ";
00136     }
00137     else
00138     {
00139         AbstractOffLatticeCellPopulation<DIM>::GenerateCellResults(locationIndex,
00140                                                  rCellProliferativeTypeCounter,
00141                                                  rCellCyclePhaseCounter);
00142     }
00143 }
00144 
00145 template<unsigned DIM>
00146 void AbstractCentreBasedCellPopulation<DIM>::GenerateCellResultsAndWriteToFiles()
00147 {
00148     // Set up cell type counter
00149     unsigned num_cell_types = this->mCellProliferativeTypeCount.size();
00150     std::vector<unsigned> cell_type_counter(num_cell_types);
00151     for (unsigned i=0; i<num_cell_types; i++)
00152     {
00153         cell_type_counter[i] = 0;
00154     }
00155 
00156     // Set up cell cycle phase counter
00157     unsigned num_cell_cycle_phases = this->mCellCyclePhaseCount.size();
00158     std::vector<unsigned> cell_cycle_phase_counter(num_cell_cycle_phases);
00159     for (unsigned i=0; i<num_cell_cycle_phases; i++)
00160     {
00161         cell_cycle_phase_counter[i] = 0;
00162     }
00163 
00164     // Write cell data to file
00165     for (unsigned node_index=0; node_index<this->GetNumNodes(); node_index++)
00166     {
00167         // Hack that covers the case where the node is associated with a cell that has just been killed (#1129)
00168         bool node_corresponds_to_dead_cell = false;
00169         if (this->mLocationCellMap[node_index])
00170         {
00171             node_corresponds_to_dead_cell = this->mLocationCellMap[node_index]->IsDead();
00172         }
00173 
00174         // Write cell data to file
00175         if (!(this->GetNode(node_index)->IsDeleted()) && !node_corresponds_to_dead_cell)
00176         {
00177             this->GenerateCellResults(node_index, cell_type_counter, cell_cycle_phase_counter);
00178         }
00179     }
00180 
00181     this->WriteCellResultsToFiles(cell_type_counter, cell_cycle_phase_counter);
00182 }
00183 
00184 template<unsigned DIM>
00185 void AbstractCentreBasedCellPopulation<DIM>::WriteTimeAndNodeResultsToFiles()
00186 {
00187     double time = SimulationTime::Instance()->GetTime();
00188 
00189     *this->mpVizNodesFile << time << "\t";
00190     *this->mpVizBoundaryNodesFile << time << "\t";
00191 
00192     // Write node data to file
00193     for (unsigned node_index=0; node_index<this->GetNumNodes(); node_index++)
00194     {
00195         // Hack that covers the case where the node in an AbstractCentreBasedCellPopulation is associated with a cell that has just been killed (#1129) This breaks the vertex visualiser when apoptotic cells are involved.
00196         bool node_corresponds_to_dead_cell = false;
00197         if (this->mLocationCellMap[node_index])
00198         {
00199             node_corresponds_to_dead_cell = this->mLocationCellMap[node_index]->IsDead();
00200         }
00201 
00202         // Write node data to file
00203         if (!(this->GetNode(node_index)->IsDeleted()) && !node_corresponds_to_dead_cell)
00204         {
00205             const c_vector<double,DIM>& position = this->GetNode(node_index)->rGetLocation();
00206 
00207             for (unsigned i=0; i<DIM; i++)
00208             {
00209                 *this->mpVizNodesFile << position[i] << " ";
00210             }
00211             *this->mpVizBoundaryNodesFile << this->GetNode(node_index)->IsBoundaryNode() << " ";
00212         }
00213     }
00214     *this->mpVizNodesFile << "\n";
00215     *this->mpVizBoundaryNodesFile << "\n";
00216 }
00217 
00218 template<unsigned DIM>
00219 double AbstractCentreBasedCellPopulation<DIM>::GetMeinekeDivisionSeparation()
00220 {
00221     return mMeinekeDivisionSeparation;
00222 }
00223 
00224 template<unsigned DIM>
00225 void AbstractCentreBasedCellPopulation<DIM>::SetMeinekeDivisionSeparation(double divisionSeparation)
00226 {
00227     assert(divisionSeparation <= 1.0);
00228     assert(divisionSeparation >= 0.0);
00229     mMeinekeDivisionSeparation = divisionSeparation;
00230 }
00231 
00232 template<unsigned DIM>
00233 void AbstractCentreBasedCellPopulation<DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
00234 {
00235     *rParamsFile << "\t\t<MeinekeDivisionSeparation>" << mMeinekeDivisionSeparation << "</MeinekeDivisionSeparation>\n";
00236 
00237     // Call method on direct parent class
00238     AbstractOffLatticeCellPopulation<DIM>::OutputCellPopulationParameters(rParamsFile);
00239 }
00240 
00242 // Explicit instantiation
00244 
00245 template class AbstractCentreBasedCellPopulation<1>;
00246 template class AbstractCentreBasedCellPopulation<2>;
00247 template class AbstractCentreBasedCellPopulation<3>;
Generated on Thu Dec 22 13:00:04 2011 for Chaste by  doxygen 1.6.3