In the Creating And Using A New Cell Mutation State
tutorial we showed how to create a new cell mutation state class,
and how this can be used in a cell-based simulation. As well as
mutation states, cells may be given much more general properties, using the cell
property class hierarchy. In this tutorial, we show how to create a new cell property
class, and how this can be used in a cell-based simulation. We will also use a simple
new force to illustrate what you can do with cell properties (and also mutations).
As in previous cell-based Chaste tutorials, we begin by including the necessary
header file and archiving headers.
The next header defines a base class for cell properties. Our new
cell property will inherit from this abstract class.
The remaining header files define classes that will be used in the cell-based
simulation test. We have encountered each of these header files in previous cell-based
Chaste tutorials.
As an example, let us consider a cell property class that is used to label
those cells that are “motile”. This cell property could then be used when
implementing some form of chemotaxis down an imposed chemoattractant gradient,
as occurs for example when macrophages migrate within a tumour towards high
concentrations of the vascular endothelial growth factor VEGF; for further
details, see for example
Owen et al., J. Theor. Biol. 226: 377-391 (2004).
Note that usually this code would be separated out into a separate declaration
in a .hpp file and definition in a .cpp file.
We define a member variable mColour, which can be used by visualization tools
to paint cells with this mutation state a distinct colour if required.
The next block of code allows us to archive (save or load) the cell property object
in a cell-based simulation. The code consists of a serialize() method, in which we first
archive the cell property using the serialization code defined in the base class
AbstractCellProperty, then archive the member variable mColour.
The default constructor allows us to specify a value for the member variable mColour,
or leave it with a default value.
We then define a destructor and a get method for the member variable mColour.
This completes the code for MotileCellProperty. Note that usually this code would
be separated out into a separate declaration in a .hpp file and definition in a .cpp file.
In order to illustrate the use of cell properties we make a simple force law which
causes all cells with the MotileCellProperty to move towards the origin. To do this we
create a new force class, MyMotiveForce, which inherits from
AbstractForce and overrides the methods AddForceContribution() and
OutputForceParameters().
Note that usually this code would be separated out into a separate declaration
in a .hpp file and definition in a .cpp file.
This force class includes a member variable, mStrength, which
defines the strength of the force. This member variable will be set
in the constructor.
We only need to include the next block of code if we wish to be able
to archive (save or load) the force model object in a cell-based simulation.
The code consists of a serialize method, in which we first archive the force
using the serialization code defined in the base class AbstractForce,
then archive the member variable.
The first public method is a default constructor, which calls the base
constructor. There is a single input argument, which defines the strength
of the force. We provide a default value of 2.0 for this argument. Inside
the method, we add an assertion to make sure that the strength is strictly
positive.
The second public method overrides AddForceContribution().
This method takes in one argument, a reference to the cell population itself.
Inside the method, we loop over cells, and add a vector to
each node associated with cells with the MotileCellProperty, which is proportional (with constant mStrength) to the negative of the position. Causing
cells to move inwards towards the origin. Note that this will currently only work with subclasses of AbstractCentreBasedCellPopulations as
we associate cells with nodes in the force calculation. However, this could easily be modified to make it work for VertexBasedCellPopulations.
Just as we encountered in Creating And Using A New Cell Killer, here we must override
a method that outputs any member variables to a specified results file rParamsFile.
In our case, we output the member variable mStrength, then call the method on the base class.
As mentioned in previous cell-based Chaste tutorials, we need to include the next block
of code to be able to archive the cell property and force objects in a cell-based simulation,
and to obtain a unique identifier for our new classes for when writing results to file.
Identifiers for both classes are defined together here, since we can only have each #include once
in this source file. Normally the first include and export would go in the class’ header, and the second
include and export in the .cpp file for each respective class.
This completes the code for MyMotiveForce. Note that usually this code
would be separated out into a separate declaration in a .hpp file and definition
in a .cpp file.
We begin by testing that our new cell property is implemented correctly.
We begin by testing that some of the base class methods work correctly.
We typically use shared pointers to create and access a cell property
like MotileCellProperty, for which it makes sense for all cells
that have the same mutation to share a pointer to the same cell property
object (although strictly speaking, they are not required to). Observe that
in this case we have provided a value for the member variable mColour
in the MotileCellProperty constructor.
Each cell property has a member variable, mCellCount, which
stores the number of cells with this cell property. We can test whether
mCellCount is being updated correctly by our cell property, as follows.
We can also test whether our cell property is of a given type, as follows.
We can also test that archiving is implemented correctly for our cell
property, as follows (further details on how to implement and
test archiving can be found at Boost Serialization Guide).
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.
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.
We construct the mesh using the generating mesh and a cut-off 1.5 which defines the
connectivity in the mesh.
We now create a shared pointer to our new property, as follows.
Also create a shared pointer to a cell label so we can visualize the
different cell types. Note that this is also a CellProperty.
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.
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.
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=S+G_2+M$ phases duration.
Finally, we set the birth time and push the cell back into the vector of cells.
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.
In order to visualize labelled cells we need to use the following command.
We then pass in the cell population into an OffLatticeSimulation,
and set the output directory, output multiple, and end time.
We create a force law and pass it to the OffLatticeSimulation.
Now create a MotlieForce and pass it to the OffLatticeSimulation.