示例#1
0
 CellPropertyCollection GetPropertiesType() const
 {
     CellPropertyCollection result;
     for (ConstIteratorType it = mProperties.begin(); it != mProperties.end(); ++it)
     {
         if ((*it)->IsSubType<BASECLASS>())
         {
             result.AddProperty(*it);
         }
     }
     return result;
 }
示例#2
0
    /*
     * We are checking that the CellPtrs work with the Wnt
     * cell-cycle models here. This just tests the set-up and checks that
     * the functions can all be called (not what they return).
     *
     * For more in depth tests see TestNightlyCellPtr.hpp
     * (these test that the cell cycle times are correct for the
     * various mutant cells)
     */
    void TestWntMutantVariantsAndLabelling() throw(Exception)
    {
        SimulationTime* p_simulation_time = SimulationTime::Instance();

        unsigned num_steps = 10;
        p_simulation_time->SetEndTimeAndNumberOfTimeSteps(1.0, num_steps+1);

        double wnt_stimulus = 1.0;
        WntConcentration<2>::Instance()->SetConstantWntValueForTesting(wnt_stimulus);

        boost::shared_ptr<AbstractCellProperty> p_wt_state(CellPropertyRegistry::Instance()->Get<WildTypeCellMutationState>());
        boost::shared_ptr<AbstractCellProperty> p_apc_one_hit_state(CellPropertyRegistry::Instance()->Get<ApcOneHitCellMutationState>());
        boost::shared_ptr<AbstractCellProperty> p_apc_two_hit_state(CellPropertyRegistry::Instance()->Get<ApcTwoHitCellMutationState>());
        boost::shared_ptr<AbstractCellProperty> p_bcat_one_hit_state(CellPropertyRegistry::Instance()->Get<BetaCateninOneHitCellMutationState>());
        boost::shared_ptr<AbstractCellProperty> p_label(CellPropertyRegistry::Instance()->Get<CellLabel>());
        boost::shared_ptr<AbstractCellProperty> p_transit_type(CellPropertyRegistry::Instance()->Get<TransitCellProliferativeType>());

        WntCellCycleModel* p_cell_cycle_model1 = new WntCellCycleModel();
        p_cell_cycle_model1->SetDimension(2);
        CellPtr p_wnt_cell(new Cell(p_apc_one_hit_state, p_cell_cycle_model1));
        p_wnt_cell->SetCellProliferativeType(p_transit_type);
        p_wnt_cell->InitialiseCellCycleModel();

        WntCellCycleModel* p_cell_cycle_model2 = new WntCellCycleModel();
        p_cell_cycle_model2->SetDimension(2);
        CellPtr p_wnt_cell2(new Cell(p_bcat_one_hit_state, p_cell_cycle_model2));
        p_wnt_cell2->SetCellProliferativeType(p_transit_type);
        p_wnt_cell2->InitialiseCellCycleModel();

        WntCellCycleModel* p_cell_cycle_model3 = new WntCellCycleModel();
        p_cell_cycle_model3->SetDimension(2);
        CellPtr p_wnt_cell3(new Cell(p_apc_two_hit_state, p_cell_cycle_model3));
        p_wnt_cell3->SetCellProliferativeType(p_transit_type);
        p_wnt_cell3->InitialiseCellCycleModel();

        WntCellCycleModel* p_cell_cycle_model4 = new WntCellCycleModel();
        p_cell_cycle_model4->SetDimension(2);
        CellPropertyCollection collection;
        collection.AddProperty(p_label);
        CellPtr p_wnt_cell4(new Cell(p_wt_state, p_cell_cycle_model4, false, collection));
        p_wnt_cell4->SetCellProliferativeType(p_transit_type);
        p_wnt_cell4->InitialiseCellCycleModel();

        TS_ASSERT_EQUALS(p_wnt_cell->ReadyToDivide(), false);
        TS_ASSERT_EQUALS(p_wnt_cell2->ReadyToDivide(), false);
        TS_ASSERT_EQUALS(p_wnt_cell3->ReadyToDivide(), false);
        TS_ASSERT_EQUALS(p_wnt_cell4->ReadyToDivide(), false);

        //Tidy up
        WntConcentration<2>::Destroy();
    }
    void TestArchiveCellPropertyCollection() throw (Exception)
    {
        OutputFileHandler handler("archive", false);
        std::string archive_filename = handler.GetOutputDirectoryFullPath() + "properties.arch";

        // Archive a cell property collection
        {
            // Create a cell property collection
            CellPropertyCollection collection;

            NEW_PROP(BetaCateninOneHitCellMutationState, p_bcat1_mutation);
            collection.AddProperty(p_bcat1_mutation);
            NEW_PROP(ApcOneHitCellMutationState, p_apc1_mutation);
            collection.AddProperty(p_apc1_mutation);

            // Create an output archive
            std::ofstream ofs(archive_filename.c_str());
            boost::archive::text_oarchive output_arch(ofs);

            // Write the cell to the archive
            output_arch << static_cast<const CellPropertyCollection>(collection);
        }

        // Restore cell property collection
        {
            CellPropertyCollection collection;

            // Restore the cell property collection
            std::ifstream ifs(archive_filename.c_str());
            boost::archive::text_iarchive input_arch(ifs);

            input_arch >> collection;

            // Test that the collection was archived correctly
            TS_ASSERT_EQUALS(collection.GetSize(), 2u);

            TS_ASSERT_EQUALS(collection.HasProperty<BetaCateninOneHitCellMutationState>(), true);
            TS_ASSERT_EQUALS(collection.HasProperty<ApcOneHitCellMutationState>(), true);
            TS_ASSERT_EQUALS(collection.HasProperty<ApcTwoHitCellMutationState>(), false);

            NEW_PROP(ApcOneHitCellMutationState, p_apc1_mutation_2);
            TS_ASSERT_EQUALS(collection.HasProperty(p_apc1_mutation_2), false);

            TS_ASSERT_EQUALS(collection.HasPropertyType<AbstractCellProperty>(), true);
            TS_ASSERT_EQUALS(collection.HasPropertyType<AbstractCellMutationState>(), true);

            for (CellPropertyCollection::Iterator it = collection.Begin(); it != collection.End(); ++it)
            {
                TS_ASSERT_EQUALS(collection.HasProperty(*it), true);
                TS_ASSERT((*it)->IsType<BetaCateninOneHitCellMutationState>() || (*it)->IsType<ApcOneHitCellMutationState>());
                TS_ASSERT_EQUALS((*it)->IsSubType<AbstractCellMutationState>(), true);
            }
        }
    }
    /*
     * === Using the cell property in a cell-based simulation ===
     *
     * We conclude with a brief test demonstrating how {{{MotileCellProperty}}} can be used
     * in a cell-based simulation.
     */
    void TestOffLatticeSimulationWithMotileCellProperty() throw(Exception)
    {
        /* Note that HoneycombMeshGenerator, used in this test, is not
         *  yet implemented in parallel. */

        /* We use the {{{HoneycombMeshGenerator}}} to create a honeycomb mesh covering a
         * circular domain of given radius, and use this to generate a {{{NodesOnlyMesh}}}
         * as follows. */
        HoneycombMeshGenerator generator(10, 10);
        MutableMesh<2,2>* p_generating_mesh = generator.GetCircularMesh(5);

        NodesOnlyMesh<2> mesh;
        /* We construct the mesh using the generating mesh and a cut-off 1.5 which defines the
         * connectivity in the mesh.
         */
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        /* We now create a shared pointer to our new property, as follows. */
        MAKE_PTR(MotileCellProperty, p_motile);
        /*
         * Also create a shared pointer to a cell label so we can visualize the
         * different cell types. Note that this is also a {{{CellProperty}}}.
         */
        MAKE_PTR(CellLabel, p_label);

        /* Next, we create some cells. We don't use a Generator as we want to give some cells the new cell property, therefore
         * we create the cells in a loop, as follows.*/
        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type);
        std::vector<CellPtr> cells;
        for (unsigned i=0; i<mesh.GetNumNodes(); i++)
        {
            /* For each node we create a cell with our cell-cycle model and the wild-type cell mutation state.
             * We then add the property {{{MotileCellProperty}}} to a random selection of the cells, as follows. */
            FixedDurationGenerationBasedCellCycleModel* p_model = new FixedDurationGenerationBasedCellCycleModel();

            CellPropertyCollection collection;
            if (RandomNumberGenerator::Instance()->ranf() < 0.2)
            {
                collection.AddProperty(p_motile);
                collection.AddProperty(p_label);
            }

            CellPtr p_cell(new Cell(p_state, p_model, false, collection));
            p_cell->SetCellProliferativeType(p_diff_type);

            /* Now, we define a random birth time, chosen from [-T,0], where
             * T = t,,1,, + t,,2,,, where t,,1,, is a parameter representing the G,,1,, duration
             * of a stem cell, and t,,2,, is the basic S+G,,2,,+M phases duration.
             */
            double birth_time = - RandomNumberGenerator::Instance()->ranf() *
                                    (p_model->GetStemCellG1Duration()
                                        + p_model->GetSG2MDuration());

            /* Finally, we set the birth time and push the cell back into the vector of cells. */
            p_cell->SetBirthTime(birth_time);
            cells.push_back(p_cell);
        }

        /* Now that we have defined the mesh and cells, we can define the cell population. The constructor
         * takes in the mesh and the cells vector. */
        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        /* In order to visualize labelled cells we need to use the following command.*/
        cell_population.AddCellPopulationCountWriter<CellMutationStatesCountWriter>();

        /* We then pass in the cell population into an {{{OffLatticeSimulation}}},
         * and set the output directory, output multiple, and end time. */
        OffLatticeSimulation<2> simulator(cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithMotileCellProperty");
        simulator.SetSamplingTimestepMultiple(12);
        simulator.SetEndTime(10.0);

        /* We create a force law and pass it to the {{{OffLatticeSimulation}}}. */
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        /* Now create a {{{MotlieForce}}} and pass it to the {{{OffLatticeSimulation}}}. */
        MAKE_PTR(MyMotiveForce, p_motive_force);
        simulator.AddForce(p_motive_force);

        /* To run the simulation, we call {{{Solve()}}}. */
        simulator.Solve();
    }
    void TestPropertyCollection() throw (Exception)
    {
        CellPropertyCollection collection;
        TS_ASSERT_EQUALS(collection.GetSize(), 0u);

        // Test that the CellPropertyRegistry assigned to the CellPropertyCollection defaults to CellPropertyRegistry::Instance().
        TS_ASSERT_EQUALS(collection.GetCellPropertyRegistry(),CellPropertyRegistry::Instance());

        // Add some properties
        NEW_PROP(WildTypeCellMutationState, p_wt_mutation);

        TS_ASSERT_EQUALS(p_wt_mutation->GetIdentifier(), "WildTypeCellMutationState");

        collection.AddProperty(p_wt_mutation);
        NEW_PROP(ApcOneHitCellMutationState, p_apc1_mutation);
        collection.AddProperty(p_apc1_mutation);

        // Test we can't add the same *object* twice
        TS_ASSERT_THROWS_THIS(collection.AddProperty(p_wt_mutation),
                              "That property object is already in the collection.");
        NEW_PROP(WildTypeCellMutationState, p_wt_mutation_2);
        collection.AddProperty(p_wt_mutation_2);
        collection.RemoveProperty(p_wt_mutation_2);

        // Check the contents
        TS_ASSERT_EQUALS(collection.GetSize(), 2u);
        // ...by object
        TS_ASSERT_EQUALS(collection.HasProperty(p_wt_mutation), true);
        TS_ASSERT_EQUALS(collection.HasProperty(p_apc1_mutation), true);
        NEW_PROP(ApcOneHitCellMutationState, p_apc1_mutation_2);
        TS_ASSERT_EQUALS(collection.HasProperty(p_apc1_mutation_2), false);
        // ...by type
        TS_ASSERT_EQUALS(collection.HasProperty<WildTypeCellMutationState>(), true);
        TS_ASSERT_EQUALS(collection.HasProperty<ApcOneHitCellMutationState>(), true);
        TS_ASSERT_EQUALS(collection.HasProperty<ApcTwoHitCellMutationState>(), false);
        // ..by subclass
        TS_ASSERT_EQUALS(collection.HasPropertyType<AbstractCellProperty>(), true);
        TS_ASSERT_EQUALS(collection.HasPropertyType<AbstractCellMutationState>(), true);
        //TS_ASSERT_EQUALS(!collection.HasProperty<AbstractCellMutationState>(), false); <-- This won't compile (yet)
        // ..by iteration
        for (CellPropertyCollection::Iterator it = collection.Begin(); it != collection.End(); ++it)
        {
            TS_ASSERT_EQUALS(collection.HasProperty(*it), true);
            TS_ASSERT((*it)->IsType<WildTypeCellMutationState>() || (*it)->IsType<ApcOneHitCellMutationState>());
            TS_ASSERT_EQUALS((*it)->IsSubType<AbstractCellMutationState>(), true);
        }

        // Remove property
        collection.RemoveProperty<WildTypeCellMutationState>();
        TS_ASSERT_EQUALS(collection.HasProperty<WildTypeCellMutationState>(), false);
        collection.RemoveProperty(p_apc1_mutation);
        TS_ASSERT_EQUALS(collection.HasProperty<ApcOneHitCellMutationState>(), false);
        TS_ASSERT_THROWS_THIS(collection.RemoveProperty<WildTypeCellMutationState>(),
                              "Collection does not contain the given property type.");
        TS_ASSERT_THROWS_THIS(collection.RemoveProperty(p_apc1_mutation),
                              "Collection does not contain the given property.");

        TS_ASSERT_EQUALS(collection.GetSize(), 0u);

        // Get matching properties
        collection.AddProperty(p_wt_mutation);
        collection.AddProperty(p_apc1_mutation);
        CellPropertyCollection mutations = collection.GetPropertiesType<AbstractCellMutationState>();
        TS_ASSERT_EQUALS(mutations.GetSize(), 2u);
        CellPropertyCollection::Iterator it = mutations.Begin();
        TS_ASSERT_EQUALS(collection.HasProperty(*it), true);
        TS_ASSERT_EQUALS((*it)->IsSubType<AbstractCellMutationState>(), true);
        TS_ASSERT( (*it)->IsType<WildTypeCellMutationState>() || (*(++it))->IsType<WildTypeCellMutationState>() );

        CellPropertyCollection wild_types = collection.GetProperties<WildTypeCellMutationState>();
        TS_ASSERT_EQUALS(wild_types.GetSize(), 1u);
        it = wild_types.Begin();
        TS_ASSERT_EQUALS((*it)->IsType<WildTypeCellMutationState>(), true);
        TS_ASSERT( *it == wild_types.GetProperty() );
        TS_ASSERT_THROWS_THIS(collection.GetProperty(),
                              "Can only call GetProperty on a collection of size 1.");
    }
    void TestOffLatticeSimulationWithMotileCellPropertyAndWriters() throw(Exception)
    {
        /*
         * We begin by creating a {{{NodeBasedCellPopulation}}}, just as in [wiki:UserTutorials/CreatingAndUsingANewCellProperty].
         * We add the {{{MotileCellProperty}}} to a random selection of cells.
         * We also add the {{{CellLabel}}} to these cells so that we can easily visualize the different cell types.
         */
        EXIT_IF_PARALLEL;

        HoneycombMeshGenerator generator(10, 10);
        MutableMesh<2,2>* p_generating_mesh = generator.GetCircularMesh(5);

        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        MAKE_PTR(MotileCellProperty, p_motile);
        MAKE_PTR(CellLabel, p_label);
        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type);

        std::vector<CellPtr> cells;
        for (unsigned i=0; i<mesh.GetNumNodes(); i++)
        {
            FixedDurationGenerationBasedCellCycleModel* p_model = new FixedDurationGenerationBasedCellCycleModel();

            CellPropertyCollection collection;
            if (RandomNumberGenerator::Instance()->ranf() < 0.2)
            {
                collection.AddProperty(p_motile);
                collection.AddProperty(p_label);
            }

            CellPtr p_cell(new Cell(p_state, p_model, false, collection));
            p_cell->SetCellProliferativeType(p_diff_type);

            double birth_time = - RandomNumberGenerator::Instance()->ranf() *
                                    (p_model->GetStemCellG1Duration() + p_model->GetSG2MDuration());

            p_cell->SetBirthTime(birth_time);
            cells.push_back(p_cell);
        }

        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        /* In order to write cell motility data using our writer, we must add it to the list of writers
         * used by the population. This is achieved using the {{{AddCellWriter()}}} method,
         * which is templated. */
        cell_population.AddCellWriter<CellMotilityWriter>();

        /* We then pass in the cell population into an {{{OffLatticeSimulation}}},
         * and set the output directory, output multiple, and end time. */
        OffLatticeSimulation<2> simulator(cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithMotileCellPropertyAndWriters");
        simulator.SetSamplingTimestepMultiple(12);
        simulator.SetEndTime(10.0);

        /* Next we create a force law and pass it to the {{{OffLatticeSimulation}}}, and call {{{Solve()}}} to run the simulation. */
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        simulator.Solve();
    }
    void TestArchivingOfCell() throw(Exception)
    {
        OutputFileHandler handler("archive", false);
        handler.SetArchiveDirectory();
        std::string archive_filename = handler.GetOutputDirectoryFullPath() + "cell.arch";

        // Archive a cell
        {
            SimulationTime* p_simulation_time = SimulationTime::Instance();
            p_simulation_time->SetEndTimeAndNumberOfTimeSteps(2.0, 4);

            // Create mutation state
            boost::shared_ptr<AbstractCellProperty> p_healthy_state(CellPropertyRegistry::Instance()->Get<WildTypeCellMutationState>());
            boost::shared_ptr<AbstractCellProperty> p_type(CellPropertyRegistry::Instance()->Get<StemCellProliferativeType>());

            // Create cell-cycle model
            FixedDurationGenerationBasedCellCycleModel* p_cell_model = new FixedDurationGenerationBasedCellCycleModel();

            // Create SRN
            Goldbeter1991SrnModel* p_srn_model = new Goldbeter1991SrnModel();

            // Create cell property collection
            CellPropertyCollection collection;
            MAKE_PTR(CellLabel, p_label);
            collection.AddProperty(p_label);

            // Create cell
            CellPtr p_cell(new Cell(p_healthy_state, p_cell_model, p_srn_model,  false, collection));
            p_cell->SetCellProliferativeType(p_type);
            p_cell->InitialiseCellCycleModel();
            p_cell->InitialiseSrnModel();
            p_simulation_time->IncrementTimeOneStep();

            TS_ASSERT_EQUALS(p_cell->GetAge(), 0.5);
            TS_ASSERT_EQUALS(p_cell->GetAncestor(), UNSIGNED_UNSET);

            // Set ancestor
            MAKE_PTR_ARGS(CellAncestor, p_cell_ancestor, (2u));
            p_cell->SetAncestor(p_cell_ancestor);
            TS_ASSERT_EQUALS(p_cell->GetAncestor(), 2u);

            // Set CellVecData with some actual content
            boost::shared_ptr<AbstractCellProperty> p_vec_data(CellPropertyRegistry::Instance()->Get<CellVecData>());
            p_cell->AddCellProperty(p_vec_data);
            Vec item_1 = PetscTools::CreateAndSetVec(2, -17.3); // <-17.3, -17.3>
            p_cell->GetCellVecData()->SetItem("item 1", item_1);

            // Check properties set correctly
            CellPropertyCollection& final_collection = p_cell->rGetCellPropertyCollection();
            TS_ASSERT_EQUALS(final_collection.GetSize(), 7u);
            TS_ASSERT_EQUALS(final_collection.HasProperty<WildTypeCellMutationState>(), true);
            TS_ASSERT_EQUALS(final_collection.HasProperty<ApcOneHitCellMutationState>(), false);
            TS_ASSERT_EQUALS(final_collection.HasProperty<ApcTwoHitCellMutationState>(), false);
            TS_ASSERT_EQUALS(final_collection.HasProperty<CellLabel>(), true);
            TS_ASSERT_EQUALS(final_collection.HasPropertyType<AbstractCellProperty>(), true);
            TS_ASSERT_EQUALS(final_collection.HasPropertyType<AbstractCellMutationState>(), true);
            TS_ASSERT_EQUALS(final_collection.HasPropertyType<CellAncestor>(), true);
            TS_ASSERT_EQUALS(final_collection.HasPropertyType<CellId>(), true);
            TS_ASSERT_EQUALS(p_cell->GetAncestor(), 2u);

            for (CellPropertyCollection::Iterator it = final_collection.Begin(); it != final_collection.End(); ++it)
            {
                TS_ASSERT_EQUALS(final_collection.HasProperty(*it), true);

                bool is_wildtype = (*it)->IsType<WildTypeCellMutationState>();
                bool is_label = (*it)->IsType<CellLabel>();
                bool is_ancestor = (*it)->IsType<CellAncestor>();
                bool is_cellid = (*it)->IsType<CellId>();
                bool is_data = (*it)->IsType<CellData>();
                bool is_vec_data = (*it)->IsType<CellVecData>();
                bool is_stem = (*it)->IsType<StemCellProliferativeType>();

                bool is_any_of_above = is_wildtype || is_label || is_ancestor || is_cellid || is_data || is_vec_data || is_stem;
                TS_ASSERT_EQUALS(is_any_of_above, true);
            }

            // Create another cell
            boost::shared_ptr<AbstractCellProperty> p_another_healthy_state(CellPropertyRegistry::Instance()->Get<WildTypeCellMutationState>());
            FixedDurationGenerationBasedCellCycleModel* p_another_cell_model = new FixedDurationGenerationBasedCellCycleModel();
            Goldbeter1991SrnModel* p_another_srn_model = new Goldbeter1991SrnModel();
            CellPtr p_another_cell(new Cell(p_another_healthy_state, p_another_cell_model, p_another_srn_model, false, collection));
            boost::shared_ptr<AbstractCellProperty> p_another_vec_data(new CellVecData);
            p_another_cell->AddCellProperty(p_another_vec_data);
            TS_ASSERT_EQUALS(p_cell->GetCellVecData()->GetNumItems(), 1u);
            TS_ASSERT_EQUALS(p_another_cell->GetCellVecData()->GetNumItems(), 0u);
            Vec another_item_1 = PetscTools::CreateAndSetVec(2, 42.0); // <42, 42>

            p_another_cell->GetCellVecData()->SetItem("item 1", another_item_1);

            // Create an output archive
            std::ofstream ofs(archive_filename.c_str());
            boost::archive::text_oarchive output_arch(ofs);

            CellPtr const p_const_cell = p_cell;

            // Write the cell to the archive
            output_arch << static_cast<const SimulationTime&> (*p_simulation_time);
            output_arch << p_const_cell;
            // Write the second cell also
            CellPtr const p_another_const_cell = p_another_cell;
            output_arch << p_another_const_cell;

            // Tidy up
            SimulationTime::Destroy();
            PetscTools::Destroy(item_1);
            PetscTools::Destroy(another_item_1);
        }

        // Restore CellPtr
        {
            // Need to set up time to initialize a cell
            SimulationTime* p_simulation_time = SimulationTime::Instance();
            p_simulation_time->SetStartTime(1.0);
            p_simulation_time->SetEndTimeAndNumberOfTimeSteps(2.0, 1); // will be restored

            // Initialize a cell

            CellPtr p_cell;

            // Restore the cell
            std::ifstream ifs(archive_filename.c_str(), std::ios::binary);
            boost::archive::text_iarchive input_arch(ifs);

            input_arch >> *p_simulation_time;
            input_arch >> p_cell;

            // Check the simulation time has been restored (through the cell)
            TS_ASSERT_EQUALS(p_simulation_time->GetTime(), 0.5);
            TS_ASSERT_EQUALS(p_simulation_time->GetTimeStep(), 0.5);

            TS_ASSERT_EQUALS(p_cell->GetAge(), 0.5);
            TS_ASSERT_EQUALS(static_cast<FixedDurationGenerationBasedCellCycleModel*>(p_cell->GetCellCycleModel())->GetGeneration(), 0u);
            TS_ASSERT(dynamic_cast<Goldbeter1991SrnModel*>(p_cell->GetSrnModel()));
            TS_ASSERT_EQUALS(p_cell->GetCellProliferativeType()->IsType<StemCellProliferativeType>(), true);

            AbstractCellCycleModel* p_cc_model = p_cell->GetCellCycleModel();
            TS_ASSERT_EQUALS(p_cc_model->GetCell(), p_cell);

            AbstractSrnModel* p_srn_model = p_cell->GetSrnModel();
            TS_ASSERT_EQUALS(p_srn_model->GetCell(), p_cell);

            CellPropertyCollection& collection = p_cell->rGetCellPropertyCollection();
            TS_ASSERT_EQUALS(collection.GetSize(), 7u);
            TS_ASSERT_EQUALS(collection.HasProperty<WildTypeCellMutationState>(), true);
            TS_ASSERT_EQUALS(collection.HasProperty<ApcOneHitCellMutationState>(), false);
            TS_ASSERT_EQUALS(collection.HasProperty<ApcTwoHitCellMutationState>(), false);
            TS_ASSERT_EQUALS(collection.HasProperty<CellLabel>(), true);
            TS_ASSERT_EQUALS(collection.HasPropertyType<AbstractCellProperty>(), true);
            TS_ASSERT_EQUALS(collection.HasPropertyType<AbstractCellMutationState>(), true);
            TS_ASSERT_EQUALS(collection.HasPropertyType<CellAncestor>(), true);
            TS_ASSERT_EQUALS(collection.HasPropertyType<CellId>(), true);
            TS_ASSERT_EQUALS(p_cell->GetAncestor(), 2u);

            // Check explicitly for CellVecData as it is not available by default as CellData
            TS_ASSERT_EQUALS(collection.HasPropertyType<CellVecData>(), true);

            // Check that the Vec stored in CellVecData was unarchived correctly
            boost::shared_ptr<CellVecData> p_cell_vec_data = boost::static_pointer_cast<CellVecData>(collection.GetPropertiesType<CellVecData>().GetProperty());
            PetscInt vec_size;
            VecGetSize(p_cell_vec_data->GetItem("item 1"), &vec_size);
            TS_ASSERT_EQUALS(vec_size, 2);
            ReplicatableVector rep_item_1(p_cell_vec_data->GetItem("item 1"));
            TS_ASSERT_DELTA(rep_item_1[0], -17.3, 2e-14);

            for (CellPropertyCollection::Iterator it = collection.Begin(); it != collection.End(); ++it)
            {
                TS_ASSERT_EQUALS(collection.HasProperty(*it), true);

                bool is_wildtype = (*it)->IsType<WildTypeCellMutationState>();
                bool is_label = (*it)->IsType<CellLabel>();
                bool is_ancestor = (*it)->IsType<CellAncestor>();
                bool is_cellid = (*it)->IsType<CellId>();
                bool is_data = (*it)->IsType<CellData>();
                bool is_vec_data = (*it)->IsType<CellVecData>();
                bool is_stem = (*it)->IsType<StemCellProliferativeType>();

                bool is_any_of_above = is_wildtype || is_label || is_ancestor || is_cellid || is_data || is_vec_data || is_stem;
                TS_ASSERT_EQUALS(is_any_of_above, true);
            }

            // Try another cell
            CellPtr p_another_cell;
            input_arch >> p_another_cell;
            ReplicatableVector rep_another_item_1(p_another_cell->GetCellVecData()->GetItem("item 1"));
            TS_ASSERT_DELTA(rep_another_item_1[0], 42.0, 2e-14);
        }
    }