Пример #1
0
CellPtr Cell::Divide()
{
    // Check we're allowed to divide
    assert(!IsDead());
    assert(mCanDivide);
    mCanDivide = false;

    // Reset properties of parent cell
    mpCellCycleModel->ResetForDivision();
    mpSrnModel->ResetForDivision();

    // Create copy of cell property collection to modify for daughter cell
    CellPropertyCollection daughter_property_collection = mCellPropertyCollection;

    // Remove the CellId from the daughter cell, as a new one will be assigned in the constructor
    daughter_property_collection.RemoveProperty<CellId>();

    // Copy all cell data (note we create a new object not just copying the pointer)
    assert(daughter_property_collection.HasPropertyType<CellData>());

    // Get the existing copy of the cell data and remove it from the daughter cell
    boost::shared_ptr<CellData> p_cell_data = GetCellData();
    daughter_property_collection.RemoveProperty(p_cell_data);

    // Create a new cell data object using the copy constructor and add this to the daughter cell
    MAKE_PTR_ARGS(CellData, p_daughter_cell_data, (*p_cell_data));
    daughter_property_collection.AddProperty(p_daughter_cell_data);

    // Copy all cell Vec data (note we create a new object not just copying the pointer)
    if (daughter_property_collection.HasPropertyType<CellVecData>())
    {
        // Get the existing copy of the cell data and remove it from the daughter cell
        boost::shared_ptr<CellVecData> p_cell_vec_data = GetCellVecData();
        daughter_property_collection.RemoveProperty(p_cell_vec_data);

        // Create a new cell data object using the copy constructor and add this to the daughter cell
        MAKE_PTR_ARGS(CellVecData, p_daughter_cell_vec_data, (*p_cell_vec_data));
        daughter_property_collection.AddProperty(p_daughter_cell_vec_data);
    }

    // Create daughter cell with modified cell property collection
    CellPtr p_new_cell(new Cell(GetMutationState(), mpCellCycleModel->CreateCellCycleModel(), mpSrnModel->CreateSrnModel(), false, daughter_property_collection));

    // Initialise properties of daughter cell
    p_new_cell->GetCellCycleModel()->InitialiseDaughterCell();
    p_new_cell->GetSrnModel()->InitialiseDaughterCell();

    // Set the daughter cell to inherit the apoptosis time of the parent cell
    p_new_cell->SetApoptosisTime(mApoptosisTime);

    return p_new_cell;
}
Пример #2
0
    void TestAddCellWithShovingBasedDivisionRuleAndShovingRequired()
    {

        /**
         * In this test of ShovingCaBasedDivisionRule we check the case where there is
         * no room to divide without the cells being shoved to the edge of the mesh.
         */

        // Create a simple Potts mesh
        PottsMeshGenerator<2> generator(5, 0, 0, 5, 0, 0);
        PottsMesh<2>* p_mesh = generator.GetMesh();

        // Create 25 cells, one for each node
        std::vector<unsigned> location_indices;
        for (unsigned index=0; index<25; index++)
        {
            location_indices.push_back(index);
        }

        std::vector<CellPtr> cells;
        CellsGenerator<FixedG1GenerationalCellCycleModel, 1> cells_generator;
        cells_generator.GenerateBasic(cells, location_indices.size());

        // Create cell population
        CaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices);

        // Make a new cell to add
        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(StemCellProliferativeType, p_stem_type);

        FixedG1GenerationalCellCycleModel* p_model = new FixedG1GenerationalCellCycleModel();
        CellPtr p_new_cell(new Cell(p_state, p_model));
        p_new_cell->SetCellProliferativeType(p_stem_type);
        p_new_cell->SetBirthTime(-1);

        // Set the division rule for our population to be the shoving division rule
        boost::shared_ptr<AbstractCaBasedDivisionRule<2> > p_division_rule_to_set(new ShovingCaBasedDivisionRule<2>());
        cell_population.SetCaBasedDivisionRule(p_division_rule_to_set);

        // Get the division rule back from the population and try to add new cell by dividing cell at site 0;
        boost::shared_ptr<AbstractCaBasedDivisionRule<2> > p_division_rule = cell_population.GetCaBasedDivisionRule();

        // Select central cell
        CellPtr p_cell_12 = cell_population.GetCellUsingLocationIndex(12);

        // Try to divide but cant as hit boundary
        TS_ASSERT_THROWS_THIS(p_division_rule->CalculateDaughterNodeIndex(p_new_cell, p_cell_12, cell_population),
            "Cells reaching the boundary of the domain. Make the Potts mesh larger.");
    }
    void TestAddCell() throw(Exception)
    {
        // Create a simple 2D PottsMesh with one cell
        PottsMeshGenerator<2> generator(2, 1, 2, 2, 1, 2);
        PottsMesh<2>* p_mesh = generator.GetMesh();

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, p_mesh->GetNumElements());

        // Create cell population
        PottsBasedCellPopulation<2> cell_population(*p_mesh, cells);

        // Test we have the correct number of cells and elements
        TS_ASSERT_EQUALS(cell_population.GetNumElements(), 1u);
        TS_ASSERT_EQUALS(cell_population.rGetCells().size(), 1u);

        // Create a new cell
        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(StemCellProliferativeType, p_stem_type);
        FixedDurationGenerationBasedCellCycleModel* p_model = new FixedDurationGenerationBasedCellCycleModel();
        CellPtr p_new_cell(new Cell(p_state, p_model));
        p_new_cell->SetCellProliferativeType(p_stem_type);

        // Add new cell to the cell population by dividing the cell
        AbstractCellPopulation<2>::Iterator cell_iter_1 = cell_population.Begin();
        cell_population.AddCell(p_new_cell, zero_vector<double>(2), *cell_iter_1);

        TS_ASSERT_EQUALS(cell_population.GetLocationIndexUsingCell(p_new_cell), 1u);

        TS_ASSERT_EQUALS(cell_population.rGetCells().size(), 2u);
        TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 2u);

        // Check locations of parent and daughter cell
        AbstractCellPopulation<2>::Iterator cell_iter_2 = cell_population.Begin();
        TS_ASSERT_EQUALS(cell_population.GetLocationIndexUsingCell(*cell_iter_2), 0u);
        ++cell_iter_2;
        TS_ASSERT_EQUALS(cell_population.GetLocationIndexUsingCell(*cell_iter_2), 1u);

        // Check Elements are as expected
        TS_ASSERT_EQUALS(cell_population.rGetMesh().GetElement(0)->GetNodeGlobalIndex(0), 0u);
        TS_ASSERT_EQUALS(cell_population.rGetMesh().GetElement(0)->GetNodeGlobalIndex(1), 1u);
        TS_ASSERT_EQUALS(cell_population.rGetMesh().GetElement(1)->GetNodeGlobalIndex(0), 2u);
        TS_ASSERT_EQUALS(cell_population.rGetMesh().GetElement(1)->GetNodeGlobalIndex(1), 3u);
    }
Пример #4
0
    void TestAddCellWithShovingBasedDivisionRule()
    {
        /**
         * In this test we create a new ShovingCaBasedDivisionRule, divide a cell with it
         * and check that the new cells are in the correct locations. First, we test where
         * there is space around the cells. This is the default setup.
         */

        // Create a simple Potts mesh
        PottsMeshGenerator<2> generator(5, 0, 0, 5, 0, 0);
        PottsMesh<2>* p_mesh = generator.GetMesh();

        // Create 9 cells in the central nodes
        std::vector<unsigned> location_indices;
        for (unsigned row=1; row<4; row++)
        {
            location_indices.push_back(1+row*5);
            location_indices.push_back(2+row*5);
            location_indices.push_back(3+row*5);
        }

        std::vector<CellPtr> cells;
        CellsGenerator<FixedG1GenerationalCellCycleModel, 1> cells_generator;
        cells_generator.GenerateBasic(cells, location_indices.size());

        // Create cell population
        CaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices);

        // Check the cell locations
        unsigned cell_locations[9] = {6, 7, 8, 11, 12, 13, 16, 17, 18};
        unsigned index = 0;
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            TS_ASSERT_EQUALS(cell_population.GetLocationIndexUsingCell(*cell_iter),cell_locations[index])
            ++index;
        }

        // Make a new cell to add
        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(StemCellProliferativeType, p_stem_type);

        FixedG1GenerationalCellCycleModel* p_model = new FixedG1GenerationalCellCycleModel();
        CellPtr p_new_cell(new Cell(p_state, p_model));
        p_new_cell->SetCellProliferativeType(p_stem_type);
        p_new_cell->SetBirthTime(-1);

        // Set the division rule for our population to be the shoving division rule
        boost::shared_ptr<AbstractCaBasedDivisionRule<2> > p_division_rule_to_set(new ShovingCaBasedDivisionRule<2>());
        cell_population.SetCaBasedDivisionRule(p_division_rule_to_set);

        // Get the division rule back from the population and try to add new cell by dividing cell at site 0
        boost::shared_ptr<AbstractCaBasedDivisionRule<2> > p_division_rule = cell_population.GetCaBasedDivisionRule();

        // Select central cell
        CellPtr p_cell_12 = cell_population.GetCellUsingLocationIndex(12);

        // The ShovingCaBasedDivisionRule method IsRoomToDivide() always returns true
        TS_ASSERT_EQUALS((p_division_rule->IsRoomToDivide(p_cell_12, cell_population)), true);

        /*
         * Test adding the new cell to the population; this calls CalculateDaughterNodeIndex().
         * The new cell moves into node 13.
         */
        cell_population.AddCell(p_new_cell, p_cell_12);

        // Now check the cells are in the correct place
        TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 10u);

        // Note the cell originally on node 13 has been shoved to node 14 and the new cell is on node 13
        unsigned new_cell_locations[10] = {6, 7, 8, 11, 12, 14, 16, 17, 18, 13};
        index = 0;
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            TS_ASSERT_EQUALS(cell_population.GetLocationIndexUsingCell(*cell_iter), new_cell_locations[index])
            ++index;
        }
    }
void MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>::DivideLongSprings(double springDivisionThreshold)
{
    // Only implemented for 2D elements
    assert(ELEMENT_DIM==2);

    std::vector<c_vector<unsigned, 5> > new_nodes;
    new_nodes = rGetMesh().SplitLongEdges(springDivisionThreshold);

    // Add new cells onto new nodes
    for (unsigned index=0; index<new_nodes.size(); index++)
    {
        // Copy the cell attached to one of the neighbouring nodes onto the new node
        unsigned new_node_index = new_nodes[index][0];
        unsigned node_a_index = new_nodes[index][1];
        unsigned node_b_index = new_nodes[index][2];

         CellPtr p_neighbour_cell = this->GetCellUsingLocationIndex(node_a_index);

        // Create copy of cell property collection to modify for daughter cell
        CellPropertyCollection daughter_property_collection = p_neighbour_cell->rGetCellPropertyCollection();

        // Remove the CellId from the daughter cell a new one will be assigned in the constructor
        daughter_property_collection.RemoveProperty<CellId>();

        CellPtr p_new_cell(new Cell(p_neighbour_cell->GetMutationState(),
                                    p_neighbour_cell->GetCellCycleModel()->CreateCellCycleModel(),
                                    p_neighbour_cell->GetSrnModel()->CreateSrnModel(),
                                    false,
                                    daughter_property_collection));

        // Add new cell to cell population
        this->mCells.push_back(p_new_cell);
        this->AddCellUsingLocationIndex(new_node_index,p_new_cell);

        // Update rest lengths

        // Remove old node pair // note node_a_index < node_b_index
        std::pair<unsigned,unsigned> node_pair = this->CreateOrderedPair(node_a_index, node_b_index);
        double old_rest_length  = mSpringRestLengths[node_pair];

        std::map<std::pair<unsigned,unsigned>, double>::iterator  iter = mSpringRestLengths.find(node_pair);
        mSpringRestLengths.erase(iter);

        // Add new pairs
        node_pair = this->CreateOrderedPair(node_a_index, new_node_index);
        mSpringRestLengths[node_pair] = 0.5*old_rest_length;

        node_pair = this->CreateOrderedPair(node_b_index, new_node_index);
        mSpringRestLengths[node_pair] = 0.5*old_rest_length;

        // If necessary add other new spring rest lengths
        for (unsigned pair_index=3; pair_index<5; pair_index++)
        {
            unsigned other_node_index = new_nodes[index][pair_index];

            if (other_node_index != UNSIGNED_UNSET)
            {
                node_pair = this->CreateOrderedPair(other_node_index, new_node_index);
                double new_rest_length = rGetMesh().GetDistanceBetweenNodes(new_node_index, other_node_index);
                mSpringRestLengths[node_pair] = new_rest_length;
            }
        }
    }
}
    void TestAddAndRemoveAndAddWithOutUpdate()
    {
        EXIT_IF_PARALLEL;    // This test doesn't work in parallel.

        SimulationTime* p_simulation_time = SimulationTime::Instance();
        p_simulation_time->SetEndTimeAndNumberOfTimeSteps(10.0, 1);

        // Create a simple mesh
        TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/square_128_elements");
        TetrahedralMesh<2,2> generating_mesh;
        generating_mesh.ConstructFromMeshReader(mesh_reader);

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(generating_mesh, 1.2);

        // Create vector of cell location indices
        std::vector<unsigned> cell_location_indices;
        for (unsigned i=10; i<mesh.GetNumNodes(); i++)
        {
            if (i != 80)
            {
                cell_location_indices.push_back(i);
            }
        }

        // Set up cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, cell_location_indices.size());
        cells[27]->StartApoptosis();

        // Create a cell population, with some random particles
        NodeBasedCellPopulationWithParticles<2> cell_population(mesh, cells, cell_location_indices);

        TS_ASSERT_EQUALS(mesh.GetNumNodes(), 81u);
        TS_ASSERT_EQUALS(cell_population.rGetCells().size(), 70u);

        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(StemCellProliferativeType, p_stem_type);

        FixedDurationGenerationBasedCellCycleModel* p_model = new FixedDurationGenerationBasedCellCycleModel();
        CellPtr p_new_cell(new Cell(p_state, p_model));
        p_new_cell->SetCellProliferativeType(p_stem_type);
        p_new_cell->SetBirthTime(0);

        c_vector<double,2> new_location = zero_vector<double>(2);
        new_location[0] = 0.3433453454443;
        new_location[0] = 0.3435346344234;
        cell_population.AddCell(p_new_cell, new_location, cell_population.rGetCells().front() /*random choice of parent*/);

        TS_ASSERT_EQUALS(mesh.GetNumNodes(), 82u);
        TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 71u);

        p_simulation_time->IncrementTimeOneStep();

        unsigned num_removed = cell_population.RemoveDeadCells();
        TS_ASSERT_EQUALS(num_removed, 1u);

        TS_ASSERT_EQUALS(mesh.GetNumNodes(), 81u);
        TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 70u);

        FixedDurationGenerationBasedCellCycleModel* p_model2 = new FixedDurationGenerationBasedCellCycleModel();
        CellPtr p_new_cell2(new Cell(p_state, p_model2));
        p_new_cell2->SetCellProliferativeType(p_stem_type);
        p_new_cell2->SetBirthTime(0);

        c_vector<double,2> new_location2 = zero_vector<double>(2);
        new_location2[0] = 0.6433453454443;
        new_location2[0] = 0.6435346344234;
        cell_population.AddCell(p_new_cell2, new_location2, cell_population.rGetCells().front() /*random choice of parent*/);

        TS_ASSERT_EQUALS(mesh.GetNumNodes(), 82u);
        TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 71u);
    }