void TestAddCellwithDiagonalVertexBasedDivisionRule() { /** * In this test we basically test that the AbstractVertexBasedDivisionRule is implemented and joined with the population * correctly. We make a new DiagonalVertexBasedDivisionRule, divide a cell with it and check that the new vertices * are in the correct position. */ // Make some nodes std::vector<Node<2>*> nodes; nodes.push_back(new Node<2>(0, true, 2.0, 0.0)); nodes.push_back(new Node<2>(1, true, 0.0, 2.0)); nodes.push_back(new Node<2>(2, true, -2.0, 0.0)); nodes.push_back(new Node<2>(3, true, 0.0, -2.0)); // Make a rectangular element out of nodes 0,1,2,3 std::vector<Node<2>*> nodes_elem_1; nodes_elem_1.push_back(nodes[0]); nodes_elem_1.push_back(nodes[1]); nodes_elem_1.push_back(nodes[2]); nodes_elem_1.push_back(nodes[3]); std::vector<VertexElement<2,2>*> vertex_elements; vertex_elements.push_back(new VertexElement<2,2>(0, nodes_elem_1)); // Make a vertex mesh MutableVertexMesh<2,2> vertex_mesh(nodes, vertex_elements); TS_ASSERT_EQUALS(vertex_mesh.GetNumElements(), 1u); TS_ASSERT_EQUALS(vertex_mesh.GetNumNodes(), 4u); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 1> cells_generator; cells_generator.GenerateBasic(cells, vertex_mesh.GetNumElements()); // Create cell population VertexBasedCellPopulation<2> cell_population(vertex_mesh, cells); unsigned old_num_nodes = vertex_mesh.GetNumNodes(); CellPtr p_cell0 = cell_population.GetCellUsingLocationIndex(0); MAKE_PTR(WildTypeCellMutationState, p_state); MAKE_PTR(StemCellProliferativeType, p_stem_type); FixedDurationGenerationBasedCellCycleModel* p_model = new FixedDurationGenerationBasedCellCycleModel(); CellPtr p_temp_cell(new Cell(p_state, p_model)); p_temp_cell->SetCellProliferativeType(p_stem_type); p_temp_cell->SetBirthTime(-1); // Set the division rule for our population to be the diagonal division rule boost::shared_ptr<AbstractVertexBasedDivisionRule<2> > p_division_rule_to_set(new DiagonalVertexBasedDivisionRule<2>()); cell_population.SetVertexBasedDivisionRule(p_division_rule_to_set); // Get the division rule back from the population and add new cell by dividing element 0 along diagonal axis boost::shared_ptr<AbstractVertexBasedDivisionRule<2> > p_division_rule = cell_population.GetVertexBasedDivisionRule(); c_vector<double, 2> diagonal_axis = p_division_rule->CalculateCellDivisionVector(p_cell0, cell_population); // Check that the axis is pointing in direction (1,1) TS_ASSERT_DELTA(diagonal_axis[0], 1.0, 1e-9); TS_ASSERT_DELTA(diagonal_axis[1], 1.0, 1e-9); cell_population.AddCell(p_temp_cell, diagonal_axis, p_cell0); // Check the location of the new nodes TS_ASSERT_DELTA(cell_population.GetNode(old_num_nodes)->rGetLocation()[0], 1.0, 1e-12); TS_ASSERT_DELTA(cell_population.GetNode(old_num_nodes)->rGetLocation()[1], 1.0, 1e-12); TS_ASSERT_DELTA(cell_population.GetNode(old_num_nodes+1)->rGetLocation()[0], -1.0, 1e-12); TS_ASSERT_DELTA(cell_population.GetNode(old_num_nodes+1)->rGetLocation()[1], -1.0, 1e-12); }
/** * Test that post-#878, WntConcentration copes with a VertexBasedCellPopulation. * \todo When vertex-based cell population code is added to cell_based folder, move this * test to TestWntConcentration.hpp */ void TestWntConcentrationWithVertexBasedCellPopulation() throw(Exception) { // Make some nodes std::vector<Node<2>*> nodes; nodes.push_back(new Node<2>(0, true, 2.0, -1.0)); nodes.push_back(new Node<2>(1, true, 2.0, 1.0)); nodes.push_back(new Node<2>(2, true, -2.0, 1.0)); nodes.push_back(new Node<2>(3, true, -2.0, -1.0)); nodes.push_back(new Node<2>(4, true, 0.0, 2.0)); // Make a rectangular element out of nodes 0,1,2,3 std::vector<Node<2>*> nodes_elem_1; nodes_elem_1.push_back(nodes[0]); nodes_elem_1.push_back(nodes[1]); nodes_elem_1.push_back(nodes[2]); nodes_elem_1.push_back(nodes[3]); // Make a triangular element out of nodes 1,4,2 std::vector<Node<2>*> nodes_elem_2; nodes_elem_2.push_back(nodes[1]); nodes_elem_2.push_back(nodes[4]); nodes_elem_2.push_back(nodes[2]); std::vector<VertexElement<2,2>*> vertex_elements; vertex_elements.push_back(new VertexElement<2,2>(0, nodes_elem_1)); vertex_elements.push_back(new VertexElement<2,2>(1, nodes_elem_2)); // Make a vertex mesh MutableVertexMesh<2,2> vertex_mesh(nodes, vertex_elements); // Create cells std::vector<CellPtr> cells; MAKE_PTR(WildTypeCellMutationState, p_state); MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type); for (unsigned i=0; i<vertex_mesh.GetNumElements(); i++) { WntCellCycleModel* p_cell_cycle_model = new WntCellCycleModel; p_cell_cycle_model->SetDimension(2); CellPtr p_cell(new Cell(p_state, p_cell_cycle_model)); p_cell->SetCellProliferativeType(p_diff_type); double birth_time = 0.0 - i; p_cell->SetBirthTime(birth_time); cells.push_back(p_cell); } // Create cell population VertexBasedCellPopulation<2> cell_population(vertex_mesh, cells); // Set the top of this cell_population, for the purposes of computing the WntConcentration double crypt_length = 4.0; // Set up an instance of the WntConcentration singleton object WntConcentration<2>* p_wnt = WntConcentration<2>::Instance(); TS_ASSERT_EQUALS(p_wnt->IsWntSetUp(), false); // Check that the singleton can be set up p_wnt->SetType(LINEAR); p_wnt->SetCellPopulation(cell_population); p_wnt->SetCryptLength(crypt_length); TS_ASSERT_EQUALS(p_wnt->IsWntSetUp(), true); // Check that the singleton can be destroyed then recreated WntConcentration<2>::Destroy(); WntConcentration<2>::Instance()->SetType(NONE); WntConcentration<2>::Instance()->SetCellPopulation(cell_population); WntConcentration<2>::Instance()->SetCryptLength(crypt_length); TS_ASSERT_EQUALS(WntConcentration<2>::Instance()->IsWntSetUp(), false); // not fully set up now it is a NONE type WntConcentration<2>::Destroy(); WntConcentration<2>::Instance()->SetType(LINEAR); WntConcentration<2>::Instance()->SetCellPopulation(cell_population); WntConcentration<2>::Instance()->SetCryptLength(crypt_length); p_wnt = WntConcentration<2>::Instance(); TS_ASSERT_EQUALS(p_wnt->IsWntSetUp(), true); // set up again double wnt_at_cell0 = p_wnt->GetWntLevel(cell_population.GetCellUsingLocationIndex(0)); double wnt_at_cell1 = p_wnt->GetWntLevel(cell_population.GetCellUsingLocationIndex(1)); // We have set the top of the cell population to be 4, so the WntConcentration should decrease linearly // up the cell_population, from one at height 0 to zero at height 4. // Cell 0 has centre of mass (0,0) TS_ASSERT_DELTA(wnt_at_cell0, 1.0, 1e-4); // Cell 1 has centre of mass (0, 4/3) TS_ASSERT_DELTA(wnt_at_cell1, 2.0/3.0, 1e-4); }
void TestRandomDirectionVertexBasedDivisionRule() { /** * This tests the RandomDirectionVertexBasedDivisionRule. We first create a vertex based cell population and check whether we can * give the division rule to the population and get it back. Then we create 10000 division vectors and check that they point * uniformly in random directions. */ // Make some nodes std::vector<Node<2>*> nodes; nodes.push_back(new Node<2>(0, true, 2.0, 0.0)); nodes.push_back(new Node<2>(1, true, 0.0, 2.0)); nodes.push_back(new Node<2>(2, true, -2.0, 0.0)); nodes.push_back(new Node<2>(3, true, 0.0, -2.0)); // Make a rectangular element out of nodes 0,1,2,3 std::vector<Node<2>*> nodes_elem_1; nodes_elem_1.push_back(nodes[0]); nodes_elem_1.push_back(nodes[1]); nodes_elem_1.push_back(nodes[2]); nodes_elem_1.push_back(nodes[3]); std::vector<VertexElement<2,2>*> vertex_elements; vertex_elements.push_back(new VertexElement<2,2>(0, nodes_elem_1)); // Make a vertex mesh MutableVertexMesh<2,2> vertex_mesh(nodes, vertex_elements); TS_ASSERT_EQUALS(vertex_mesh.GetNumElements(), 1u); TS_ASSERT_EQUALS(vertex_mesh.GetNumNodes(), 4u); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 1> cells_generator; cells_generator.GenerateBasic(cells, vertex_mesh.GetNumElements()); // Create a cell population VertexBasedCellPopulation<2> cell_population(vertex_mesh, cells); CellPtr p_cell0 = cell_population.GetCellUsingLocationIndex(0); // Set the division rule for our population to be the random direction division rule boost::shared_ptr<AbstractVertexBasedDivisionRule<2> > p_division_rule_to_set(new RandomDirectionVertexBasedDivisionRule<2>()); cell_population.SetVertexBasedDivisionRule(p_division_rule_to_set); // Get the division rule back from the population boost::shared_ptr<AbstractVertexBasedDivisionRule<2> > p_division_rule = cell_population.GetVertexBasedDivisionRule(); // Get 10000 division vectors, check each length, their mean and their variance. c_vector<double, 2> average_axis = zero_vector<double>(2); c_vector<double, 2> axis_variance = zero_vector<double>(2); double average_angle = 0.0; double angle_variance = 0.0; for (unsigned iteration = 0; iteration < 10000; iteration++) { c_vector<double, 2> random_axis = p_division_rule->CalculateCellDivisionVector(p_cell0, cell_population); TS_ASSERT_DELTA(norm_2(random_axis), 1.0,1e-6); average_axis(0) += random_axis(0); axis_variance(0) += random_axis(0)*random_axis(0); average_axis(1) += random_axis(1); axis_variance(1) += random_axis(1)*random_axis(1); average_angle += asin(random_axis(0)); angle_variance += asin(random_axis(0))*asin(random_axis(0)); } average_axis(0) /= 10000.0; average_axis(1) /= 10000.0; axis_variance(0) /= 10000.0; axis_variance(1) /= 10000.0; average_angle /= 10000.0; angle_variance /= 10000.0; TS_ASSERT_DELTA(average_axis(0), 0.0, 1e-2); TS_ASSERT_DELTA(average_axis(1), 0.0, 1e-2); TS_ASSERT_DELTA(axis_variance(0), 0.5, 1e-2); TS_ASSERT_DELTA(axis_variance(1), 0.5, 1e-2); TS_ASSERT_DELTA(average_angle, 0.0, 1e-2); TS_ASSERT_DELTA(angle_variance, M_PI*M_PI/12.0, 1e-2); }