Chemotaxis on a cell-by-cell basis

Just like the secretion is typically defined for cell types the same applies to chemotaxis. And similarly as in the case of the secretion there is an easy way to implement chemotaxis on a cell-by-cell basis. You can find relevant example in Demos/PluginDemos/chemotaxis_by_cell_id. Let us look at the code:

from cc3d.core.PySteppables import *


class ChemotaxisSteering(SteppableBasePy):
    def __init__(self, frequency=100):
        SteppableBasePy.__init__(self, frequency)

    def start(self):

        for cell in self.cell_list:
            if cell.type == self.MACROPHAGE:
                cd = self.chemotaxisPlugin.addChemotaxisData(cell, "ATTR")
                cd.setLambda(30.0)
                cd.assignChemotactTowardsVectorTypes([self.MEDIUM, self.BACTERIUM])
                break

    def step(self, mcs):
        if mcs > 100 and not mcs % 100:
            for cell in self.cell_list:
                if cell.type == self.MACROPHAGE:

                    cd = self.chemotaxisPlugin.getChemotaxisData(cell, "ATTR")
                    if cd:
                        lm = cd.getLambda() - 3
                        cd.setLambda(lm)
                    break

Before we start analyzing this code let’s look at CC3DML declaration of the chemotaxis plugin:

<Plugin Name="Chemotaxis">
   <ChemicalField Name="ATTR">
<!--     <ChemotaxisByType Type="Macrophage" Lambda="20"/>           -->
   </ChemicalField>
 </Plugin>

As you can see we have commented out ChemotaxisByType but leaving information about fields so that chemotaxis plugin can fetch pointers to the fields. Clearly, leaving such definition of chemotaxis in the CC3DML would have no effect on the simulation. However, as you can see in the Python steppable code we define chemotaxis on a cell-by-cell basis.We loop over all cells and when we encounter cell of type Macrophage we assign to it object called ChemotaxisData (we use self.chemotaxisPlugin.addChemotaxisData function to do that). ChemotaxisData object allows definition of all chemotaxis properties available via CC3DML but here we apply them to single cells. In our example code we set lambda describing chemotaxis strength and cells types that don’t inhibit chemotaxis by touching our cell (in other words, cell experiences chemotaxis when it touches cell types listed in assignChemotactTowardsVectorTypes function).

Notice break instruction at the end of the loop. It ensures that the for loop that iterates over all cells stops after it encounters first cell of type Macrophage.

In the step function iterate through all cells and search for first occurrence of Macrophage cell (break instruction at the end of this function will ensure it). This time however, instead of adding chemotaxis data we fetch ChemotaxisData object associated with a cell. We extract lambda and decrease it by 3 units. The net result of several operations like that is that lambda chemotaxis will go from positive number to negative number and cell that initially chemotaxed up the concentration gradient, now will start moving away from the source of the chemical.

When you want to implement chemotaxis using alternative calculations with saturation terms all you need to do is to add cd.setSaturationCoef function call to enable type of chemotaxis that corresponds in the CC3DML to the following call:

<ChemotaxisByType ChemotactTowards="CELL_TYPES" Lambda="1.0" SaturationCoef="100.0" Type="CHEMOTAXING_TYPE"/>

The Python code would look like:

for cell in self.cell_list:
    if cell.type == self.MACROPHAGE:
        cd = self.chemotaxisPlugin.addChemotaxisData(cell, "ATTR")
        cd.setLambda(30.0)
        cd.setSaturationCoef(100)
        cd.assignChemotactTowardsVectorTypes([self.MEDIUM, self.BACTERIUM])

If we want to replicate the following CC3DML version of chemotaxis for a single cell:

<ChemotaxisByType ChemotactTowards="CELL_TYPES" Lambda="1.0" SaturationLinearCoef="10.1" Type="CHEMOTAXING_TYPE"/>

we would use the following Python snippet:

for cell in self.cell_list:
    if cell.type == self.MACROPHAGE:
        cd = self.chemotaxisPlugin.addChemotaxisData(cell, "ATTR")
        cd.setLambda(30.0)
        cd.setSaturationLinearCoef(100)
        cd.assignChemotactTowardsVectorTypes([self.MEDIUM, self.BACTERIUM])