Steering – changing CC3DML parameters on-the-fly.

CC3D 4.0.0 greatly simplifies modification of CC3DML parameters from Python script as the simulation runs. we call it programmatic steering.

Imagine that we would like to increase cell membrane fluctuation amplitude (in CC3D terminology Temperature) every 100 MCS by 1 unit. The Temperature is declared in the CC3DML so, unlike variables declared in Python script, we dont have a direct access to it.

Let’s look at CC3DML code first:

<Potts>
   <Dimensions x="100" y="100" z="1"/>
   <Steps>10000</Steps>
   <Temperature>10</Temperature>
   <NeighborOrder>2</NeighborOrder>
</Potts>

The way CC3D 4.x solves this problem is very much inspired by Javascript/HTML approach. First you tag element that you wish to change using id tag as shown below:

<Potts>
   <Dimensions x="100" y="100" z="1"/>
   <Steps>10000</Steps>
   <Temperature id="temp_elem">10</Temperature>
   <NeighborOrder>2</NeighborOrder>
</Potts>

Here we add id="temp_elem". If you have multiple id tags for in your XML script we require that they are unique.

After we tagged the CC3DML elements we can easily access and modify them on-the-fly as shown below

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

    def step(self, mcs):
        temp_elem = self.get_xml_element('temp_elem')
        temp_elem.cdata = float(temp_elem.cdata) + 1

In the step function we first access the tagged element:

temp_elem = self.get_xml_element('temp_elem')

and then we modify its cdata portion using

temp_elem.cdata = float(temp_elem.cdata) + 1

After this last modification CC3D will take a notice that the change has been made and will update appropriate internal variables.

XML Element Structure

Each XML (CC3DML is also a valid XML) has the following structure

<MyMLElement attr_1="attr_1_value"  attr_2="attr_2_value">cdata</MyMLElement>

For example in the following element

<Energy Type1="Medium" Type2="Condensing">10</Energy>

the element name is Energy. It has two attributes Type1 with value Medium and Type2 with value Condensing. And the value of cdata component is 10

Similarly, the element ChemotaxisByType

<ChemotaxisByType Type="Macrophage" Lambda="20"/>

has two attributes Type and Lambda with values Macrophage and 20 respectively.

Modifying CC3DML attributes

If we want to modify attributes of the XML element we use similar approach to the one outlined above. We tag element we want modify and then update attributes. Here is an example

<Plugin Name="Chemotaxis">
    <ChemicalField Name="ATTR">
        <ChemotaxisByType id="macro_chem" Type="Macrophage" Lambda="20"/>
    </ChemicalField>
</Plugin>

and the Python code that modifies Lambda attribute of ChemotaxisByType

from cc3d.core.PySteppables import *


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

    def step(self, mcs):
        if mcs > 100 and not mcs % 100:
            macro_chem_elem = self.get_xml_element('macro_chem')
            macro_chem_elem.Lambda = float(macro_chem_elem.Lambda) - 3

As you can see the syntax is quite straightforward. We first fetch the reference to the XML element (we tagged it using id="macro_chem"):

macro_chem_elem = self.get_xml_element('macro_chem')

and modify its Lambda attribute

macro_chem_elem = self.get_xml_element('macro_chem')
macro_chem_elem.Lambda = float(macro_chem_elem.Lambda) - 3

Two things are worth mentioning here.

1. when we access attribute we use the name of the attribute and “dot” it with reference to the XML element we fetched:

macro_chem_elem.Lambda

2. cdata and attributes are returned as strings so before doing any arithmetic operation we need to convert strings to appropriate Python types. Here we convert string returned by macro_chem_elem.Lambda (first call will return string 20) to floating point number float(macro_chem_elem.Lambda) and subtract 3 . When we assign it back to the attribute we do not need to convert to string - CC3D will handle this conversion automatically

Full example of steering can be found in Demos/Models/bacterium_macrophage_2D_steering