Passing information between steppables¶
When you work with more than one steppable (and it is a good idea to
work with several steppables each of which has a well defined purpose) you
may sometimes need to access or change member variable of one steppable
inside the code of another steppable. The most straightforward method to implement exchange of
information between steppables is to utilize the python dictionary shared_steppable_vars
,
which is a shared dictionary that every steppable can access as an attribute.
Say we have two steppables, where one steppable updates a shared variable x_shared
, and the
other steppable prints the current value of x_shared
. Let’s call our steppables
UpdaterSteppable
and PrinterSteppable
for our tasks of updating and printing x_shared
,
respectively:
class UpdaterSteppable(SteppableBasePy):
def __init__(self, frequency=1):
SteppableBasePy.__init__(self, frequency)
def start(self):
self.shared_steppable_vars['x_shared'] = 0
def step(self, mcs):
self.shared_steppable_vars['x_shared'] += 1
class PrinterSteppable(SteppableBasePy):
def __init__(self, frequency=1):
SteppableBasePy.__init__(self, frequency)
def step(self, mcs):
print('x_shared=', self.shared_steppable_vars['x_shared'])
We see that UpdaterSteppable
initializes a key x_shared
with a value of 0
in the
shared dictionary and updates it every step. Meanwhile PrinterSteppable
accesses and prints
the value of the same key in the shared dictionary.
The same can be done with simulation objects. Say we have two steppables, where one steppable
tests whether or not each cell undergoes mitosis, and the other steppable implements mitosis.
For this case, we’ll call our steppable that checks for mitosis CheckMitosisSteppable
, and
we’ll use the mitosis steppable base class to implement mitosis with a steppable called
MitosisSteppable
. When checking for the occurrence of mitosis, we’ll say that all cells
with a volume greater than 75 undergo mitosis:
class CheckMitosisSteppable(SteppableBasePy):
def __init__(self, frequency=1):
SteppableBasePy.__init__(self, frequency)
def step(self, mcs):
for cell in self.cell_list:
if cell.volume > 75:
self.shared_steppable_vars['cells_to_divide'].append(cell)
class MitosisSteppable(MitosisSteppableBase):
def __init__(self, frequency=1):
MitosisSteppableBase.__init__(self, frequency)
self.set_parent_child_position_flag(0)
def start(self):
self.shared_steppable_vars['cells_to_divide'] = []
def step(self, mcs):
for cell in self.shared_steppable_vars['cells_to_divide']:
self.divide_cell_random_orientation(cell)
self.shared_steppable_vars['cells_to_divide'] = []
def update_attributes(self):
self.clone_parent_2_child()
We see that MitosisSteppable
initializes the key cells_to_divide
with an empty list in
the shared dictionary. CheckMitosisSteppable
populates that same list every step with
cell objects according to results of our imaginary function check_for_mitosis
, each of
which MitosisSteppable
then passes to the built-in method divide_cell_random_orientation
for randomly-oriented mitosis. After processing all mitosis results, MitosisSteppable
then returns the shared list to an empty list, so that each positive result of
check_for_mitosis
corresponds to one division of a mitotic cell (otherwise a cell in
shared_steppable_vars['cells_to_divide']
would divide every step!).