Skip to content
antonkan edited this page Jun 30, 2015 · 50 revisions

In this tutorial we will go through the basic structure of a CellModeller model, how set cell properties, create rules for division, and work with the biophysics module.

Tutorial 1a: basics

Firstly, we will go through what each part of the model does, and how to set up your simulation. Let’s look at Examples/Tutorial_1/Tutorial_1a.py, so please open it in your favourite text editor.

Alongside, let's run this model by running $ cmgui Examples/Tutorial_1/Tutorial_1a.py in the Terminal (whilst in the CellModeller directory). After pressing Run for a few seconds, you should see something like this: Tutorial_1a

Here we see the most basic layout of a model that contain the minimal information required to run a simulation – there are 4 functions:

  1. Setup def setup(sim)

Here the component modules of the model are initialised and set up with the appropriate parameters. In this case, only the biophysics and the regulation modules are initialised: biophys = CLBacterium(sim, jitter_z=False) This sets up the biophysics module CLBacterium, which controls the physical properties and interactions of the bacterial cells. This module is connected to the simulator object, and is initialized with the default parameters – with the exception of jitter_z, which is set to False, this keeps the simulation constrained to 2 dimensions by preventing movement in the z-axis. We will discuss other parameters that can be set later, for now let’s just keep the default settings.

regul = ModuleRegulator(sim, sim.moduleName) This initalizes the Regulator module and connects it with the simulator. This module connects this model file to the simulator object.

sim.init(biophys, regul, None, None) Here we initialise the Simulator object with the biophysics and regulation modules. Note that these are the minimal module requirements for a simulation.

Now that we have initialized the simulator, we can add cells to our simulation: sim.addCell(cellType=0, pos=(0,0,0), dir=(1,0,0)) Here, we see that a cell is added to position (0,0,0) and oriented along the x-axis. The cellType is an inheritable cell parameter that can be used to distinguish cells, allowing for rules or behaviours specific to particular cell types.

The renderer for the cells is then initilized, allowing the simulation to draw the cells to create visual outputs. Finally, pickleSteps – this sets how often the simulation saves its state to a '.pickle' file in the relevant folder within the data directory. In this case it is set to 20, meaning that the simulation with output a pickle file every 20 simulation steps. Keep in mind that data can be quite large, so regular output can fill up your hard-drive quickly.

  1. Init init(cell)

The init(cell) function sets the state of the cell when it is created – either at the beginning of the simulation as an initial condition or when a cell is born through division. Here we define the size at which the bacterial cells will divide – cell.targetVol. We will see how this plays out in the update function. Cell growth rates and color, in (red, green, blue) values, are also set here.

  1. Update update(cells)

The update function determines how the properties of cells evolve in time. Here the simulation loops over cells once per simulation step, and updates the cell states to the next time step. In this simple case, the division rules are implemented here –

if cell.volume > cell.targetVol:
cell.divideFlag = True

So when any cell reaches its target volume, it is flagged for division, which is then handled by the simulator and any relevant modules.

  1. Divide divide(parent, d1, d2)

This optional function determines how daughter cells inherit their state from their parents, and gets called once per cell division. The arguments are:
• p, the parent CellState
• d1, daughter1 CellState
• d2, daughter2 CellState
You can set any of the properties of daughter cells here based on the parent state. The parent will no longer exist after this function is called. The default behaviour for most properties is that daughter cells inherit the same state as their parents. Notable exceptions are of course position, orientation etc. which reflect the positions of the new cells.

Now that we know and understand the structure of a model file, let's look at how to change the parameters and rules in a simulation to generate interesting behaviours. Let's look at Tutorial_1b, where we have added a few more interesting things.

Running this tutorial model for a longer time yields a large circular 2D colony, with 10,000 cells. By initializing the biophysics module with more cells eg:

biophys = CLBacterium(sim, jitter_z=False, max_cells=100000)

we can grow colonies to much larger sizes in order to study the arrangements of cells.

Tutorial 1b: parameters and rules

Now let's look at Examples/Tutorial_1/Tutorial_1b.py and run $ cmgui Examples/Tutorial_1/Tutorial_1b.py in the Terminal. In this tutorial, we set cellTypes with different properties as well as a custom growth rule.

First of all, notice that we have 3 python dictionaries at the top of the model:

cell_cols = {0:[0,1.0,0], 1:[1.0,0,0], 2:[0,0,1.0]}
cell_lens = {0:1.0, 1:2.0, 2:3.5}
cell_growr = {0:2.0, 1:1.1, 2:0.8}

These are here to simply and efficiently connect cell types to their properties. We see that in setup we have added 3 cells, with cellTypes 0,1 and 2. In the init function, these dictionaries are used to set the growth rate, color and lengths of each cell of a given type via the appropriate dictionary:

cell.targetVol = cell_lens[cell.cellType] + random.uniform(0.0,0.5)
cell.growthRate = cell_growr[cell.cellType]
cell.color = cell_cols[cell.cellType]

This gives us 3 types of cells:
cellType = 0: short, green, fast growing cells
cellType = 1: medium length, red, medium growth rate cells
cellType = 2: long, blue, slow growing cells
Tutorial_1b

Since bacterial cells grow exponentially (the change in length is proportional to the length itself), this leads to quite a balanced gain in biomass for each cell type.

We can also set growth rules in the update function, making the growth rates depend on variables. In this case, the growth rate depends on the y-coordinate, with a growth zone 5 units wide on the top most edge of the colony growing:

maxy = max_y_coord(cells)
for (id, cell) in cells.iteritems():
    dist = maxy - cell.pos[1]
    growthZone = 5.0
    if dist < growthZone:
        cell.growthRate = cell_growr[cell.cellType]
    else:
        cell.color = numpy.divide(cell_cols[cell.cellType],2)
        cell.growthRate = 0.0

So, this first code finds the maximal y-coordinate of all cells in the colony with the max_y_coord function. Any cells with y-coordinates in the growthZone keep their original growth rates, whereas cells that slip out of the zone have their growth rate drop to 0 and their colour dimmed.
Note: physical variables can be found with cellState.pos[n] for position, cellState.dir[n] for a unit direction vector and cellState.len for the cells length, for n=0,1 or 2 representing the x,y and z coordinates respectively.

Leaving this model to run for a bit yields:

Tutorial_1b

This model explores how cells with different shapes and growth rates compete for space when they are closely packed. In the screenshot above, the green cells are winning, although due to stochastic effects this does not happen every time. Competition is not strictly driven by growth rates, and physical effects can also play a role. You can explore what happens different cell parameters and a different growth zone, and how it affects competition between cells.

Tutorial 1c: biophysical properties and constraints

In this Tutorial, we will look at altering the biophysical properties of the simulation, which affects the physical interactions of all the cells in the simulation. Also, we introduce constraints - these allow us to create containers and obstacles for our bacteria.

There is one biophysical parameter in CellModeller - which we call gamma. Cells in CellModeller grow by an impulse adding length at each timestep, which is the only way energy is added to the system. The gamma parameter is the frictional drag on this growth. The CLBacterium default is gamma = 10.
A further consequence of this parameter is how quickly cells stop growing due to physical forces. In CellModeller, cells can be seen as expending a particular amount of energy on growth each timestep, but, this may need to go into pushing other cells out of the way. If there are enough cells blocking it, the cell will not be able to push them out of the way to grow. At low gamma values, cells are stopped from growing at very low physical forces, and as gamma goes to infinity, cells get increasingly insensitive to physical forces and grow at the same rate in all situations. [Note - the simulation becomes unphysical at very large gamma values unless the timestep is altered to compensate].

In most cases, gamma does not have to be altered unless precise biophysical properties of bacterial colonies are being studied, in which case it has to be matched to the situation of interest as it may depend on species, media and various other experimental conditions.

In Examples/Tutorial_1/Tutorial_1c.py the biophysical module is initiated like so:

biophys = CLBacterium(sim, jitter_z=True, gamma = 20, max_planes=5)

These initialization conditions have set jitter_z true, meaning we no longer constrain the simulation to 2 dimensions, gamma to 20, and a parameter max_planes to 5 which allows us to set up to 5 plane constraints.

Plane constraints are planes which prevent cell movement past them, and are initiated in the following code in setup:

biophys.addPlane((0,0,0),(0,0,1),1.0)
biophys.addPlane((10,0,0),(-1,0,0),1.0)
biophys.addPlane((-10,0,0),(1,0,0),1.0)
biophys.addPlane((0,10,0),(0,-1,0),1.0)
biophys.addPlane((0,-10,0),(0,1,0),1.0)

The addPlane command takes 3 arguments: ((a tuple specifying the position of the plane), (a tuple specifying the plane normal) and a float specifying the stiffness - at values lower than 1.0, the plane can be penetrated a little. In this case we have made 5 planes constraining the cells to a open topped 20x20 box. Note that because we have a plane at (0,0,0), the initial cell has to be placed above it at (0,0,0.5) in sim.addCell(cellType=0, pos=(0,0,0.5)) so that the cell is not violating the constraint in the beginning of the simulation. Note that the GUI will show a little red square near the centre of the plane.

Running this model for a while yields a clump of cells trapped in a box: Tutorial_1c

Now we have covered the features of the biophysical model, let's move on to Tutorial 2.