Title: scripting inside CompuCell3D
1scripting inside CompuCell3D
- XML gives you the ability to change simulation
parameters using human-readable syntax but does
not allow users to implement more complex cell
behaviors, sophisticated cell type transition
rules, inter-cell signaling or connecting to
intracellular models - Python scripting capabilities in CompuCell3D
allow users to accomplish abovementioned tasks
(and much more) and are the reasons why
CompuCell3D is called simulation environment, not
simulation application. - Python scripting capabilities allow users to use
rich set of Python modules and third party
libraries and provide level flexibility
comparable with packages such as Matlab or
Mathematica
2Python Scripting Prerequisites
- To make full use of Python scripting users should
be familiar with Python programming language.
They do not need to be experts though. - CompuCell3D comes with template and example codes
that make Python scripting inside CompuCell3D
quite easy even for beginners. - Python scripting in CompuCell3D typically
requires users to develop a class that implements
required logic. If you are unfamiliar with
concept of class , think of it as a type that has
several data members (such as floats, integers,
other classes) and set of functions that operate
on those internal members but can also take
external arguments. Class is a generalization of
C structure or Pascal record. - Fortunately CompuCell3D comes with plenty of
examples that users can adapt to serve their
needs. This does not require thorough programming
knowledge. If you are unfamiliar with Python
scripting, reading (and doing) CompuCell3D
Python Scripting Tutorials should quickly get
you up-to-speed.
3Typical example when Python proves to be very
useful
Start with a small cell that grows
It reaches doubling volume
and divides into two cells
After mitosis you want to specify types of parent
and daughter cells. You may want to change target
surface and target volume of daughter. And
target volume is a function of a FGF
concentration at the center of mass of the
daughter cell. How would you do it from just
XML? Python seems to be the best solution for
problems like this one
4Where Do You Begin?
- Early version of Python scripting in CompuCell3D
required users to provide CC3DML configuration
file. This is no longer true. You can describe
entire simulation from Python level. However, you
may still use XML and Python if you want. The
choice is up to you. - You will need to write Python script that
implements main CompuCell3D logic i.e. reads
CC3DML file (if you are using CC3DML file),
initializes modules and executes calls in a loop
Metropolis algorithm. This file will also call
set up and initialize your modules written in
Python. CompuCell3D comes with many examples of
such files so in fact preparing one is reduced to
minor modification of existing one. - Once you have Python script (and optionally
CC3DML file) ready, you open them up in the
Player and start running simulations .
5What Can You Do in Python?
- You may implement any CompuCell3D module using
Python energy functions, lattice monitors,
steppers, steppables, fixed steppers. - You need to remember that Python is an
interpreted language and thus executes orders of
magnitudes slower than, for example, C. This
means that although you can easily develop energy
functions (remember, they are the most frequently
called modules in CompuCell3D) in Python, you
will probably want to avoid using them with your
production runs. In this it makes sense to
implement those functions in C , which is not
too difficult and we provide comprehensive
Developers documentation. - Since lattice monitors are called less frequently
than energy functions, the performance
degradation due to lattice monitor being
implemented in Python is much smaller. That same
is true for steppers, fixed steppers and
steppables. - Notice that CompuCell3D kernel that is called
from Python, as well as other core CompuCell3D
modules called from Python run at native speeds,
as they are implemented in C with only their
API exposed to Python. Therefore if you run
CompuCell3D through Python script but decide not
to implement new Python modules, your speed of
run will be essentially identical as if you ran
CompuCell3D using just CC3DML file.
6What are the advantages of using Python inside
CompuCell3D
- Rapid development no compilation is necessary.
Write or modify your script and run - Portability script developed by you on one
machine (e.g. Mac) is ready to use under linux - Model integration - you can quite easily
implement hooks to subcellular models. We have
been able to set up CompuCell3D simulation that
was using SBW network intracell simulators within
few minutes. T - Rich set of external libraries you may tap into
rich Python library repositories that exist for
essentially any task - Agile development developing and refining your
model is an iterative process. Working at the
compiled language stage will force you to spend
significant portion of your time waiting for the
program to compile. With Python you eliminate
this step thus increase productivity. Users
should first prototype their models in Python and
once they are ready to be used for production
runs, rewrite the ones causing significant
slowdown in C.
7Your first CompuCell3D Python script. Make sure
you have your copy of Python Scripting Tutorials
Begin with template code (the file will be called
cellsort_2D.py) import useful modules import
sys from os import environ from os import
getcwd import string setup search
patths sys.path.append(environ"PYTHON_MODULE_PATH
") sys.path.append(getcwd()"/examples_PythonTuto
rial") add search path import
CompuCellSetup sim,simthread
CompuCellSetup.getCoreSimulationObjects() Create
extra player fields here or add
attributes CompuCellSetup.initializeSimulationObj
ects(sim,simthread) Add Python steppables
here steppableRegistryCompuCellSetup.getSteppable
Registry() CompuCellSetup.mainLoop(sim,simthread,
steppableRegistry)
8Opening a Simulation With Accompanying Python
Script in the Player
Go to File-gtOpen Simulation Choose xml file if
required . Click Python script Browse button
to select python script. Do not forget to check
Run Python script check-box!
9Using Python to describe entire simulations
- Starting with 3.2.0 versions you may get rid of
XML file and use Python to describe entire
simulation. - The advantage of doing so is that you have one
less file to worry about but also you may more
easily manipulate simulation parameters. For
example if you want contact energy between two
cell types be twice as big as between two other
cell types you could easily implement it in
Python. Doing the same exercise with CC3dML is a
bit harder (but not impossible). - Python syntax used to describe simulation closely
mimics CC3DML syntax. There are however certain
differences and inconsistencies caused by the
fact that we are using different languages to
accomplish same task. Currently there is no
documentation explaining in detail Python syntax
that replaces CC3DML. It will be developed soon - The most important reason for defining entire
simulation in Python is the possibility of
simulation steering i.e. the ability to
dynamically change simulation parameters while
simulation is running (available in 3.2.1) - While there are certain disadvantages of this
approach (mainly lack of good documentation) you
get many benefits by using Python only to
describe the simulation
10Cell -sorting simulation. Main script requires
minimal modification
import sys from os import environ import
string sys.path.append(environ"PYTHON_MODULE_PATH
") import CompuCellSetup sim,simthread
CompuCellSetup.getCoreSimulationObjects() configu
reSimulation(sim) CompuCellSetup.initializeSimula
tionObjects(sim,simthread) from PySteppables
import SteppableRegistry steppableRegistrySteppab
leRegistry() CompuCellSetup.mainLoop(sim,simthre
ad,steppableRegistry)
11But you need to implement configureSimulation
function
XML
Python
ltPottsgt ltDimensions x"100" y"100"
z"1"/gt ltAnnealgt10lt/Annealgt
ltStepsgt10000lt/Stepsgt ltTemperaturegt10lt/Temperatu
regt ltFlip2DimRatiogt1lt/Flip2DimRatiogt
ltNeighborOrdergt2lt/NeighborOrdergt
lt/Pottsgt ltPlugin Name"CellType"gt ltCellType
TypeName"Medium" TypeId"0"/gt ltCellType
TypeName"Condensing" TypeId"1"/gt ltCellType
TypeName"NonCondensing" TypeId"2"/gt lt/Plugingt
ltPlugin Name"Contact"gt ltEnergy Type1"Medium"
Type2"Medium"gt0lt/Energygt ltEnergy
Type1"NonCondensing" Type2"NonCondensing"gt16lt/En
ergygt ltEnergy Type1"Condensing"
Type2"Condensing"gt2lt/Energygt ltEnergy
Type1"NonCondensing" Type2"Condensing"gt11lt/Energ
ygt ltEnergy Type1"NonCondensing"
Type2"Medium"gt16lt/Energygt ltEnergy
Type1"Condensing" Type2"Medium"gt16lt/Energygt
ltNeighborOrdergt2lt/NeighborOrdergt lt/Plugingt
def configureSimulation(sim) import
CompuCell import CompuCellSetup
ppdCompuCell.PottsParseData()
ppd.DebugOutputFrequency(40) ppd.Steps(20000)
ppd.Anneal(10) ppd.Temperature(5)
ppd.Flip2DimRatio(1.0) ppd.NeighborOrder(2)
ppd.Dimensions(CompuCell.Dim3D(100,100,1))
ctpdCompuCell.CellTypeParseData()
ctpd.CellType("Medium",0) ctpd.CellType("Conden
sing",1) ctpd.CellType("NonCondensing",2)
cpdCompuCell.ContactParseData()
cpd.Energy("Medium","Medium",0)
cpd.Energy("NonCondensing","NonCondensing",16)
cpd.Energy("Condensing","Condensing",2)
cpd.Energy("NonCondensing","Condensing",11)
cpd.Energy("NonCondensing","Medium",16)
cpd.Energy("Condensing","Medium",16)
12Continued
Python
XML
ltPlugin Name"Volume"gt ltTargetVolumegt25lt/Targe
tVolumegt ltLambdaVolumegt2.0lt/LambdaVolumegt
lt/Plugingt ltSteppable Type"BlobInitializer"gt
ltRegiongt ltGapgt0lt/Gapgt ltWidthgt5lt/Widthgt
ltRadiusgt40lt/Radiusgt ltCenter x50"
y50" z"0"/gt ltTypesgtCondensing,NonCondensin
glt/Typesgt lt/Regiongt lt/Steppablegt
vpdCompuCell.VolumeParseData()
vpd.LambdaVolume(1.0) vpd.TargetVolume(25.0)
bipdCompuCell.BlobInitializerParseData()
regionbipd.Region() region.Center(CompuCel
l.Point3D(50,50,0)) region.Radius(40)
region.Types("Condensing") region.Types("NonCon
densing") region.Width(5) remember to
register ParseData CompuCellSetup.registerPot
ts(sim,ppd) CompuCellSetup.registerPlugin(s
im,ctpd) CompuCellSetup.registerPlugin(sim,cpd)
CompuCellSetup.registerPlugin(sim,vpd)
CompuCellSetup.registerSteppable(sim,bipd)
13You need to remember this Python distinguishes
blocks of codes by their indentation.
Therefore for a in xrange(0,5) print v
ariable a,a print " Final value of variable a
is , a would result in an error because the
line print " Final value of variable a",a has
different indentation than other print statement
and thus does belong to the for loop. Python
will attempt executing this line once after the
for loop is finished and will return an error
that global object a was not found. It was
found because a name is valid only inside the
for loop body. Since the last line was not in
the body, you get an error. We are using 3
spaces to indent block of codes, you may choose
differently, but need to be consistent.
14Opening a Python-based simulation in the Player
no XML
Go to File-gtOpen Simulation Click Python script
Browse button to select python script. Do not
forget to check Run Python script check-box!
15The trick to use Python to describe simulations
is to learn the syntax Sometimes this is
intuitive cpdCompuCell.ContactParseData()
cpd.Energy("Medium","Medium",0)
cpd.Energy("NonCondensing","NonCondensing",16) So
metimes it is less intuitive
bipdCompuCell.BlobInitializerParseData()
regionbipd.Region() region.Center(CompuCell.Po
int3D(50,50,0)) region.Radius(30)
region.Types("Condensing") region.Types("NonCon
densing") region.Width(5) Sometimes you need
to know what particular function arguments mean
ctpdCompuCell.CellTypeParseData()
ctpd.CellType("Medium",0) ctpd.CellType("Conden
sing",1,True) here we freeze Condensing cells
16- Few basic rules to remember
- Plugin MyPlugin is initialized by creating
ParseData type object - mppdCompuCell.MyPluginParseData()
- Example
- vpdCompuCell.VolumeParseData()
- Initialize ParseData object
- Example
- vpd.LambdaVolume(1.0)
- vpd.TargetVolume(25.0)
- Register ParseData Object using either
registerPotts, registerPlugin or
registerSteppable functions. - Example
- CompuCellSetup.registerPlugin(sim,vpd)
- See also the following examples in CompuCell3D
package -new-syntax.py
17Bacterium and macrophage simulation
ppdCompuCell.PottsParseData()
ppd.Steps(20000) ppd.Temperature(15)
ppd.Flip2DimRatio(1.0) ppd.Dimensions(CompuCell
.Dim3D(100,100,1)) ctpdCompuCell.CellT
ypeParseData() ctpd.CellType("Medium",0)
ctpd.CellType("Bacterium",1)
ctpd.CellType("Macrophage",2)
ctpd.CellType("Wall",3,True)
cpdCompuCell.ContactParseData()
cpd.Energy("Medium","Medium",0)
cpd.Energy("Macrophage","Macrophage",15)
cpd.Energy("Macrophage","Medium",8)
cpd.Energy("Bacterium","Bacterium",15)
cpd.Energy("Bacterium","Macrophage",15)
cpd.Energy("Bacterium","Medium",8)
cpd.Energy("Wall","Wall",0) cpd.Energy("Wall","
Medium",0) cpd.Energy("Wall","Bacterium",50)
cpd.Energy("Wall","Macrophage",50)
cpd.NeighborOrder(2) vpdCompuCell.VolumeParse
Data() vpd.LambdaVolume(15.0)
vpd.TargetVolume(25.0)
ltPottsgt ltDimensions x"100" y"100" z"1"/gt
ltStepsgt20000lt/Stepsgt ltTemperaturegt15lt/Temperatu
regt ltFlip2DimRatiogt1.0lt/Flip2DimRatiogt lt/Pottsgt
ltPlugin Name"CellType"gt ltCellType
TypeName"Medium" TypeId"0"/gt ltCellType
TypeName"Bacterium" TypeId"1" /gt ltCellType
TypeName"Macrophage" TypeId"2"/gt
ltCellType TypeName"Wall" TypeId"3" Freeze""/gt
lt/Plugingt ltPlugin Name"Contact"gt
ltEnergy Type1"Medium" Type2"Medium"gt0lt/Energygt
ltEnergy Type1"Macrophage" Type2"Macrophage"gt15
lt/Energygt ltEnergy Type1"Macrophage"
Type2"Medium"gt8lt/Energygt ltEnergy
Type1"Bacterium" Type2"Bacterium"gt15lt/Energygt
ltEnergy Type1"Bacterium" Type2"Macrophage"gt15lt/
Energygt ltEnergy Type1"Bacterium"
Type2"Medium"gt8lt/Energygt ltEnergy Type1"Wall"
Type2"Wall"gt0lt/Energygt ltEnergy Type1"Wall"
Type2"Medium"gt0lt/Energygt ltEnergy Type1"Wall"
Type2"Bacterium"gt50lt/Energygt ltEnergy
Type1"Wall" Type2"Macrophage"gt50lt/Energygt
ltNeighborOrdergt2lt/NeighborOrdergt lt/Plugingt
ltPlugin Name"Volume"gt ltTargetVolumegt25lt/Target
Volumegt ltLambdaVolumegt15.0lt/LambdaVolumegt
lt/Plugingt
Freeze
18 ltPlugin Name"Surface"gt ltTargetSurfacegt20lt/Tar
getSurfacegt ltLambdaSurfacegt4.0lt/LambdaSurfacegt
lt/Plugingt ltPlugin Name"Chemotaxis"gt
ltChemicalField Source"FlexibleDiffusionSolverFE"
Name"ATTR" gt ltChemotaxisByType
Type"Macrophage" Lambda"200"/gt
lt/ChemicalFieldgt lt/Plugingt ltSteppable
Type"FlexibleDiffusionSolverFE"gt
ltDiffusionFieldgt ltDiffusionDatagt
ltFieldNamegtATTRlt/FieldNamegt
ltDiffusionConstantgt0.10lt/DiffusionConstantgt
ltDecayConstantgt0.000lt/DecayConstantgt
ltDoNotDiffuseTogtWalllt/DoNotDiffuseTogt
lt/DiffusionDatagt ltSecretionDatagt
ltSecretion Type"Bacterium"gt200lt/Secretiongt
lt/SecretionDatagt lt/DiffusionFieldgt
lt/Steppablegt ltSteppable Type"PIFInitializer"gt
ltPIFNamegtbacterium_macrophage_2D_wall.piflt/PIFN
amegt lt/Steppablegt
spdCompuCell.SurfaceParseData()
spd.LambdaSurface(4.0) spd.TargetSurface(20.0)
chpdCompuCell.ChemotaxisParseData()
chfieldchpd.ChemicalField()
chfield.Source("FastDiffusionSolver2DFE")
chfield.Name("ATTR") chbtchfield.ChemotaxisByT
ype() chbt.Type("Macrophage")
chbt.Lambda(2.0) fdspdCompuCell.FastDiffusio
nSolver2DFEParseData() dffdspd.DiffusionField(
) diffDatadf.DiffusionData()
secrDatadf.SecretionData() diffData.DiffusionC
onstant(0.1) diffData.FieldName("ATTR")
diffData.DoNotDiffuseTo("Wall")
secrData.Secretion("Bacterium",200)
pifpdCompuCell.PIFInitializerParseData()
pifpd.PIFName("bacterium_macrophage_2D_wall.pif")
19 CompuCellSetup.registerPotts(sim,ppd)
CompuCellSetup.registerPlugin(sim,ctpd)
CompuCellSetup.registerPlugin(sim,vpd)
CompuCellSetup.registerPlugin(sim,spd)
CompuCellSetup.registerPlugin(sim,chpd)
CompuCellSetup.registerSteppable(sim,pifpd)
CompuCellSetup.registerSteppable(sim,fdspd)
Notice that the amount of Python coding in
configureSimulation function is comparable to
amount of the cc3DML code. Once you know CC3DML
you should be able to pick up Python syntax
easily. You get a lot more in terms of
flexibility when you use Python instead of CC3DML
20Example Scaling contact energies advantage of
using Python to configure entire
simulation energyScale10 def
configureSimulation(sim) . . .
cpdCompuCell.ContactParseData()
cpd.Energy("Medium","Medium",0energyScale)
cpd.Energy("Macrophage","Macrophage",1.5energySca
le) cpd.Energy("Macrophage","Medium",0.8energy
Scale) cpd.Energy("Bacterium","Bacterium",1.5e
nergyScale) cpd.Energy("Bacterium","Macrophage"
,1.5energyScale) cpd.Energy("Bacterium","Mediu
m",0.8energyScale) cpd.Energy("Wall","Wall",0
energyScale) cpd.Energy("Wall","Medium",0energ
yScale) cpd.Energy("Wall","Bacterium",5.0energ
yScale) cpd.Energy("Wall","Macrophage",5.0ener
gyScale) It would be a bit awkward (but not
impossible) to have same functionality in CC3DML
21- Figuring out ParseData members and functions
without documentation (VolumePlugin) - Go to source code directory CompuCell3D/plugins/Vo
lume - Open up VolumeParseData.h file
- Check class members and class functions and try
to associate them with appropriate XML tags - class DECLSPECIFIER VolumeParseData public
ParseData - public
- VolumeParseData()
- ParseData("Volume"),
- targetVolume(0.),
- lambdaVolume(0.)
-
-
- double targetVolume
- double lambdaVolume
- void LambdaVolume(double
_lambdaVolume)lambdaVolume_lambdaVolume - void TargetVolume(double
_targetVolume)targetVolume_targetVolume -
22PlasticityTrackerPlugin class DECLSPECIFIER
PlasticityTrackerParseDatapublic ParseData
public PlasticityTrackerParseData()
ParseData("PlasticityTracker")
stdsetltstdstringgt plasticityTypesNames
void IncludeType(stdstring _typeName)plastici
tyTypesNames.insert(_typeName)
PlasticityPlugin class DECLSPECIFIER
PlasticityParseDatapublic ParseData
public PlasticityParseData()ParseData("Pla
sticity"), localCalcFlag (false),
targetLengthPlasticity (0.),
lambdaPlasticity(0.) void Local(bool
_localCalcFlag)localCalcFlag_localCalcFlag
void TargetLengthPlasticity(double
_targetLengthPlasticity)targetLengthPlasticity_t
argetLengthPlasticity void
LambdaPlasticity(double _lambdaPlasticity)lambdaP
lasticity_lambdaPlasticity bool
localCalcFlag double targetLengthPlasticity
double lambdaPlasticity
23Beyond XML - Developing Python Steppables
Examples presented above showed how to run Python
based simulations and how to replace XML with
Python. However, the true power of Python is
demonstrated in the case when you develop your
own modules. We will first teach you how to
develop a steppable because steppables are most
likely to be developed in Python anyway.
Lets take a look at the module that prints cell
id, cell type and cell volume for every cell in
the simulation. Iterating over all cells is
probably most frequently used task in steppables
class InfoPrinterSteppable(SteppablePy) def __
init__(self,_simulator,_frequency10) Stepp
ablePy.__init__(self,_frequency) self.simula
tor_simulator self.inventoryself.simulator
.getPotts().getCellInventory()
self.cellListCellList(self.inventory) def star
t(self) print "This function is called once
before simulation" def step(self,mcs)
print "This function is called every 10 MCS
for cell in self.cellList print "
CELL ID",cell.id, " CELL TYPE",cell.type," volum
e",cell.volume
24Python Steppable
Each Python Steppable should have three
functions start() step(mcs) finish() It is OK to
leave the implementation of any of above
functions empty. An empty function will be then
called. In addition to this, because Python
steppables are implemented as classes they need
to define __init__ function that act as a
constructor. Steppable Template class
YourPythonSteppable(SteppablePy) def
__init__(self,_simulator,_frequency10)
your code here def start(self)
your code here def step(self,mcs)
your code here def finish(self) your
code here
25If you are non-programmer it may looks a bit
strange, but imagine how much more would be
required to write do the same in C/C. Much
more. Lets explain the code
class InfoPrinterSteppable(SteppablePy) def __
init__(self,_simulator,_frequency10) Stepp
ablePy.__init__(self,_frequency) self.simula
tor_simulator self.inventoryself.simulator
.getPotts().getCellInventory()
self.cellListCellList(self.inventory) First line
defines our steppable class. Each class has to
have __init__method that is called when object of
this class is created. You can pass any arguments
to this method, but the first argument must be
self. This is required by Python
language. First line in __init__ method
initializes Base class SteppablePy. Do not worry
if you do not understand it. Treat it as a boiler
plate code. Line self.simulator_simulator
stores a pointer or reference to simulator object
as a member variable. This way, later on whenever
we decide to reference simulator we would use
self.simmulator instead of getting simulator some
other , more complicated way. Notice, that
whenever you access member variable you prepend
their name with keyword self Subsequently we
get reference to cell inventoryt (C object) and
use it to create iterable cellList
(self.cellListCellList(self.inventory)) Notice,
self shows up again.
26 def step(self,mcs) print "This function i
s called every 10 MCS for cell in
self.cellList print "CELL ID",cell.id,
" CELL TYPE",cell.type," volume",cell.volume Abo
ve function implements core functionality of our
steppable. It informs that it is called every 10
MCS see how we set frequency parameter in the
__init__ function. The last two lines do actual
iteration over each cell in the cell
inventory Notice that it is really easy to do the
iteration for cell in self.cellList Now you can
see how storing CellType object as self.cellList
comes handy. All we need to do is to pass
iterable cell list (self.cellList) to the for
loop. Actual printing is done in line
print "CELL ID",cell.id, " CELL TYPE",cell.type
," volume",cell.volume For each cell in
inventory cell variable of the for loop will be
initialized with different cell from inventory.
All you need to do is to print cell.id,
cell.type, and cell.volume. It is pretty simple.
27Now save the file with the steppable as ,
cellsort_2D_steppables.py . All you need to do is
to provide hooks to your steppable in the main
Python script steppableRegistryCompuCellSetup
.getSteppableRegistry()
Steppable Registration from
cellsort_2D_steppables import InfoPrinterSteppable
infoPrinter InfoPrinterSteppable(sim)
steppableRegistry.registerSteppable(infoPrinter)
End of Steppable Registration
steppableRegistry.init(sim) Notic
e that registering steppable requires importing
your steppable from the file from
cellsort_2D_stepables import InfoPrinterSteppable
creating steppable object infoPrinter
InfoPrinterSteppable(sim) registering it with
steppable registry steppableRegistry.registerSte
ppable(infoPrinter)
28Full Main Script import sys from os import
environ from os import getcwd import
string sys.path.append(environ"PYTHON_MODULE_PAT
H") sys.path.append(getcwd()"/examples_PythonTut
orial") import CompuCellSetup sim,simthread
CompuCellSetup.getCoreSimulationObjects() Crea
te extra player fields here or add
attributes CompuCellSetup.initializeSimulationObj
ects(sim,simthread) Add Python steppables
here steppableRegistryCompuCellSetup.getSteppable
Registry() from cellsort_2D_steppables import
InfoPrinterSteppable infoPrinterSteppableInfoPrin
terSteppable(_simulatorsim,_frequency10) steppab
leRegistry.registerSteppable(infoPrinterSteppable)
CompuCellSetup.mainLoop(sim,simthread,steppableR
egistry)
29import useful modules import sys from os import
environ from os import getcwd import
string setup search patths sys.path.append(enviro
n"PYTHON_MODULE_PATH") sys.path.append(getcwd()
"/examples_PythonTutorial") add search path
import CompuCellSetup sim,simthread
CompuCellSetup.getCoreSimulationObjects() Create
extra player fields here or add
attributes CompuCellSetup.initializeSimulationObje
cts(sim,simthread) Add Python steppables
here steppableRegistryCompuCellSetup.getSteppable
Registry() from cellsort_2D_steppables import
InfoPrinterSteppable infoPrinterSteppableInfoPrin
terSteppable(_simulatorsim,_frequency10) steppab
leRegistry.registerSteppable(infoPrinterSteppable)
CompuCellSetup.mainLoop(sim,simthread,steppableR
egistry)
30Useful shortcut simplifying steppable
definition
class InfoPrinterSteppable(SteppableBasePy) de
f __init__(self,_simulator,_frequency10) S
teppableBasePy.__init__(self,_frequency) def st
art(self) print "This function is called on
ce before simulation" def step(self,mcs)
print "This function is called every 10 MC
S for cell in self.cellList print
"CELL ID",cell.id, " CELL TYPE",cell.type," vol
ume",cell.volume
Notice that we have used as a base class
SteppableBasePy instead of SteppablePy.
SteppableBasePy already contains members and
initializations for self.cellList self.simulator
self.potts self.cellField self.dim self.inventory
31SteppableBasePy class SteppableBasePy(SteppableP
y) def __init__(self,_simulator,_frequency1)
SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.potts_simulator.getPotts()
self.cellFieldself.potts.getCellFieldG()
self.dimself.cellField.getDim()
self.inventoryself.simulator.getPotts().getCellIn
ventory() self.cellListCellList(self.invent
ory)
32Now, all you need to do is to open in the Player
previous xml file (cellsort_2D.xml) together with
newly created cellsort_2D.py and check Run Python
check box. Notice that you are not loading
directly cellsort_2D_steppables.py file. The
module you stored to this file will be called
from cellsort_2D.py. Try running the simulation
and see if you got any performance degradation.
Probably not, but by using Python you have saved
yourself a lot of tedious C coding, not to
mention that you do not need to care about
dependencies, compilation, etc.. Writing your
next Python steppable will require much less
effort as well, as you will quickly discover that
you will be using same basic code template all
over again. Instead of thinking how the code you
are writing fits in the overall framework you
will just concentrate on its core functionality
and leave the rest to CompuCell3D. In case you
wonder how this is all possible , it is due to
Object Oriented programming. Hopefully this short
tutorial will encourage you to learn more of
object oriented programming. It is really worth
the effort.
33Info Printer results
34- Python Scripting Checklist
- Write main Python script (modify or reuse
existing one) - Write Python modules in a separate file. You will
import these modules from main Python script - Provide CC3DML configuration file or describe
entire simulation in Python skipping CC3DML
entirely
Note when using Python scripting your simulation
may consists of many files. Make sure you keep
track of them
35More Complicated Simulations Adding Extra
Attribute To a Cell
In CompuCell3D simulations each cell by default
will have several attributes such as volume,
surface, centroids , target volume, cell id etc.
One can write a plugin that attaches additional
attributes to a cell during run time. Doing so
avoids recompilation of entire CompuCell3D but
requires to write and compile the C plugin. It
is by far the easiest to attach additional cell
attribute in Python. Not only there is no need to
recompile anything, but the actual task takes one
line of code pyAttributeAdder,listAdderCompuCel
lSetup.attachListToCells(sim) Above we told
CompuCell3D to attach a Python list to each cell
that will be produced by the CompuCell3D
kernel. We can access this list very easily from
Python level. Python list is dynamic data
structure that can grow or shrink and can hold
arbitrary Python objects. Therefore by attaching
a list to each cell we effectively came up with a
way to attach any cell attribute. We may also
attach dictionary instead of the
list pyAttributeAdder,dictAdderCompuCellSetup.at
tachDictionaryToCells(sim) And everything takes
place during run time
36Full listing of simulation where each cell gets
extra attribute a list
import sys from os import environ from os import
getcwd import string sys.path.append(environ"PYT
HON_MODULE_PATH") sys.path.append(getcwd()"/exam
ples_PythonTutorial") import
CompuCellSetup sim,simthread
CompuCellSetup.getCoreSimulationObjects() Create
extra player fields here or add
attributes pyAttributeAdder,listAdderCompuCellSet
up.attachListToCells(sim) CompuCellSetup.initiali
zeSimulationObjects(sim,simthread) Add Python
steppables here steppableRegistryCompuCellSetup.g
etSteppableRegistry() here we will add
ExtraAttributeCellsort steppable from
cellsort_2D_steppables import ExtraAttributeCellso
rt extraAttributeCellsortExtraAttributeCellsort(_
simulatorsim,_frequency10) steppableRegistry.reg
isterSteppable(extraAttributeCellsort) from
cellsort_2D_steppables import TypeSwitcherSteppabl
e typeSwitcherSteppableTypeSwitcherSteppable(sim,
100) steppableRegistry.registerSteppable(typeSwitc
herSteppable) CompuCellSetup.mainLoop(sim,simthre
ad,steppableRegistry)
37ExtraAttributeCellsort
class ExtraAttributeCellsort(SteppablePy) def
__init__(self,_simulator,_frequency10)
SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.inventoryself.simulator.getPotts().getCellIn
ventory() self.cellListCellList(self.invent
ory) def step(self,mcs) for cell
in self.cellList pyAttribCompuCell.getP
yAttrib(cell) pyAttrib02cell.idmcs
, cell.id(mcs-1) print "CELL ID
modified",pyAttrib0," ", pyAttrib1
Initializing first two elements of the list
Notice, you may also attach a dictionary to a
cell instead of a list. See Python Scripting
Tutorials for more information. Dictionaries are
actually more useful then lists in the
CompuCell3D context so make sure you understand
them and know how to attach them to cells.
38ExtraAttrib results
39TypeSwitcherSteppable
class TypeSwitcherSteppable(SteppablePy) def
__init__(self,_simulator,_frequency100)
SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.inventoryself.simulator.getPotts().getCellIn
ventory() self.cellListCellList(self.invent
ory) def step(self,mcs) for cell
in self.cellList if cell.type1
cell.type2 elif (cell.type2)
cell.type1 else
print "Unknown type. In cellsort simulation there
should only be two types ,\ 1 and
2"
Line continuation in Python
40Accessing NeighborTracker from Python As you
remember from lectures on CC3DML configuration
files, CompuCell3D can track cell neighbors. You
can access information about cell neighbors
directly from Python class NeighborTrackerPrinte
rSteppable(SteppablePy) def
__init__(self,_simulator,_frequency100)
SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.nTrackerPluginCompuCell.getNeighborTrackerPl
ugin() self.inventoryself.simulator.
getPotts().getCellInventory()
self.cellListCellList(self.inventory) def
start(self)pass def
step(self,mcs) self.cellListCellList(self.
inventory) for cell in self.cellList
cellNeighborListCellNeighborListAuto(self.nTra
ckerPlugin,cell) create local neighbor list
print "NEIGHBORS OF CELL WITH ID
",cell.id," " for
neighborSurfaceData in cellNeighborList
iterate over local neighbor list if
neighborSurfaceData.neighborAddress check if
neighbor is non-Medium print
"neighbor.id",neighborSurfaceData.neighborAddress.
id," commonSurfaceArea",\
neighborSurfaceData.commonSurfaceArea access
common surface area and id else
print "Medium commonSurfaceArea",neighb
orSurfaceData.commonSurfaceArea
41Understanding iteration over cell neighbors
def step(self,mcs) self.cellListCellList(s
elf.inventory) for cell in self.cellList
cellNeighborListCellNeighborListAuto(self.
nTrackerPlugin,cell) print
"NEIGHBORS OF CELL WITH ID ",cell.id,"
" for
neighborSurfaceData in cellNeighborList
if neighborSurfaceData.neighborAddress
print "neighbor.id",neighborSurfaceData.ne
ighborAddress.id," commonSurfaceArea",\
neighborSurfaceData.commonSurfaceArea
else print "Medium
commonSurfaceArea",neighborSurfaceData.commonSurf
aceArea
Iterating over all cells in the simulation
This function constructs list of cell neighbors
neighborSurfaceData object has neighborAddress
and commonSurfaceArea members. The first one
stores a pointer to a neighbor cell, the second
stores sommon surface area between neighbors
42import sys from os import environ from os import
getcwd import string sys.path.append(environ"PYT
HON_MODULE_PATH") sys.path.append(getcwd()"/exam
ples_PythonTutorial") import
CompuCellSetup sim,simthread CompuCellSetup.getC
oreSimulationObjects() Create extra player
fields here or add attributes pyAttributeAdder,lis
tAdderCompuCellSetup.attachListToCells(sim) Comp
uCellSetup.initializeSimulationObjects(sim,simthre
ad) Add Python steppables here steppableRegistry
CompuCellSetup.getSteppableRegistry() from
cellsort_2D_steppables import NeighborTrackerPrint
erSteppable neighborTrackerPrinterSteppableNeighb
orTrackerPrinterSteppable(sim,100) steppableRegist
ry.registerSteppable(neighborTrackerPrinterSteppab
le) CompuCellSetup.mainLoop(sim,simthread,steppab
leRegistry)
43NeighborTracker printouts
44Printing values of the concentration to a file
import sys from os import environ from os import
getcwd import string sys.path.append(environ"PYT
HON_MODULE_PATH") sys.path.append(getcwd()"/exam
ples_PythonTutorial") import
CompuCellSetup sim,simthread CompuCellSetup.getC
oreSimulationObjects() Create extra player
fields here or add attributes CompuCellSetup.initi
alizeSimulationObjects(sim,simthread) Add
Python steppables here from PySteppablesExamples
import SteppableRegistry steppableRegistrySteppab
leRegistry() from cellsort_2D_steppables import
ConcentrationFieldDumperSteppable concentrationFie
ldDumperSteppableConcentrationFieldDumperSteppabl
e(sim,_frequency100) concentrationFieldDumperStep
pable.setFieldName("FGF") steppableRegistry.regist
erSteppable(concentrationFieldDumperSteppable) Co
mpuCellSetup.mainLoop(sim,simthread,steppableRegis
try)
45class ConcentrationFieldDumperSteppable(SteppableP
y) def __init__(self,_simulator,_frequency1)
SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.dimself.simulator.getPotts().getCellFieldG()
.getDim() def setFieldName(self,_fieldName)
self.fieldName_fieldName def
step(self,mcs) fileNameself.fieldName"_"
str(mcs)".dat" self.outputField(self.fieldN
ame,fileName) def outputField(self,_fiel
dName,_fileName) fieldCompuCell.getConcent
rationField(self.simulator,_fieldName)
ptCompuCell.Point3D() if field
try fileHandleopen(_fileName,"w")
except IOError print "Could
not open file ", _fileName," for writing. Check
if you have necessary permissions"
print "dim.x",self.dim.x for i in
xrange(self.dim.x) for j in
xrange(self.dim.y) for k in
xrange(self.dim.z) pt.xi
pt.yj pt.zk
fileHandle.write("d\td\td\tf\n"(
pt.x,pt.y,pt.z,field.get(pt))) write to a file
46- Creating, initializing and manipulating a
concentration field directly from Python - Although in most cases concentration fields are
created and manipulated by PDE solvers it is
possible to accomplish all those tasks directly
from Python. - This can be very useful if you want to develop
custom visualization that is not directly
supported by the Player. For example you may want
to color cells according to how many neighbors
they have. Player does not offer such an option
but you can implement it very easily in Python in
less then 5 minutes. This is not a joke. I am
sure that by combining two examples from this
tutorial you will accomplish this task very fast. - The task of adding extra field to the Player and
managing it consist of two steps - Creating extra field and registering it with the
Player and CompuCell3D kernel - Writing steppable that manipulates values stored
in the field - First lets look at the full listing
47import sys from os import environ from os import
getcwd import string sys.path.append(environ"PYT
HON_MODULE_PATH") sys.path.append(getcwd()"/exam
ples_PythonTutorial") import SystemUtils SystemUti
ls.initializeSystemResources() import
CompuCellSetup sim,simthread CompuCellSetup.getC
oreSimulationObjects() import CompuCell notice
importing CompuCell to main script has to be done
after call to getCoreSimulationObjects() Create
extra player fields here or add
attributes CompuCellSetup.initializeSimulationObje
cts(sim,simthread) Need to call
initializeSimulationObjects before trying to
access lattice dimension dimsim.getPotts().getCel
lFieldG().getDim() extraPlayerFieldsimthread.crea
teFloatFieldPy(dim,"ExtraField") initializing
extra Field - this location in the Add Python
steppables here from PySteppablesExamples import
SteppableRegistry steppableRegistrySteppableRegis
try() from cellsort_2D_steppables import
ExtraFieldVisualizationSteppable extraFieldVisuali
zationSteppableExtraFieldVisualizationSteppable(_
simulatorsim,_frequency10) extraFieldVisualizati
onSteppable.setScalarField(extraPlayerField) stepp
ableRegistry.registerSteppable(extraFieldVisualiza
tionSteppable) CompuCellSetup.mainLoop(sim,simthr
ead,steppableRegistry)
Creating extra field is is really easy. The
location of the function call that creates the
field is , however important. See the comment
48from PlayerPython import necessary to
manipulate Player fields from math import
getting access to special functions from math
module class ExtraFieldVisualizationSteppable(Ste
ppablePy) def __init__(self,_simulator,_freque
ncy10) SteppablePy.__init__(self,_frequenc
y) self.simulator_simulator
self.cellFieldGself.simulator.getPotts().getCellF
ieldG() self.dimself.cellFieldG.getDim()
def setScalarField(self,_field)
getting access to newly created field
self.scalarField_field def
start(self)pass def step(self,mcs)
for x in xrange(self.dim.x) iteration over each
pixel for y in xrange(self.dim.y)
for z in xrange(self.dim.z)
ptCompuCell.Point3D(x,y,z) if
(not mcs20) filling the values of the
concentration valuexy
sometimes it is xy
fillScalarValue(self.scalarField,x,y,z,value)
else valuesin(xy)
sometimes sin(xy)
fillScalarValue(self.scalarField,x,y,z,value)
49Managing concentration field from Python - results
c(x,y)xy
c(x,y)sin(xy)
50Mitosis in CompuCell3D simulations Supporting
cell division (mitosis) in CompuCell3D
simulations is a prerequisite for building
faithful biomedical simulations. You can use
mitosis module (Mitosis Plugin) directly from XML
however, its use will be very limited because of
the following fact After cell division you end
up with two cells. What parameters should those
two cells have (type, target volume etc.)? How do
you modify the parameters? The best solution is
to manage mitosis from Python and the example
below will explain you how to do it.
51import sys from os import environ from os import
getcwd import string sys.path.append(environ"PYT
HON_MODULE_PATH") import CompuCellSetup sim,simt
hread CompuCellSetup.getCoreSimulationObjects()
add additional attributes pyAttributeAdder,listA
dderCompuCellSetup.attachListToCells(sim) CompuC
ellSetup.initializeSimulationObjects(sim,simthread
) import CompuCell notice importing CompuCell
to main script has to be done after call to
getCoreSimulationObjects() changeWatcherRegistryC
ompuCellSetup.getChangeWatcherRegistry(sim) steppe
rRegistryCompuCellSetup.getStepperRegistry(sim)
from cellsort_2D_field_modules import
CellsortMitosis cellsortMitosisCellsortMitosis(si
m,changeWatcherRegistry,stepperRegistry) cellsortM
itosis.setDoublingVolume(50) Add Python
steppables here steppableRegistryCompuCellSetup.g
etSteppableRegistry() from cellsort_2D_field_modu
les import VolumeConstraintSteppable volumeConstra
intVolumeConstraintSteppable(sim) steppableRegist
ry.registerSteppable(volumeConstraint) CompuCellS
etup.mainLoop(sim,simthread,steppableRegistry)
52Mitosis function is a type of plugin that
monitors lattice (field3DWatcher). Most of the
mitosis setup is handled inside base class
MitosisPyPluginBase from random import
random from PyPluginsExamples import
MitosisPyPluginBase class CellsortMitosis(Mitosis
PyPluginBase) inherit base class def
__init__(self , _simulator , _changeWatcherRegistr
y , _stepperRegistry) MitosisPyPluginBase._
_init__(self,_simulator,_changeWatcherRegistry,
_stepperRegistry) def updateAttributes(self)
called after mitosis is done
self.parentCell.targetVolume/2.0
self.childCell.targetVolumeself.parentCell.target
Volume self.childCell.lambdaVolumeself.pare
ntCell.lambdaVolume if (random()lt0.5)
self.childCell.typeself.parentCell.type
else self.childCell.type3
53Mitosis example results
t1000 MCS
t200 MCS
t600 MCS
Green cells grow in response to diffusing FGF.
Once they reach doubling volume they divide. They
have 50 probability of differentiating into
red cells.
54Mitosis was our first example of a plugin
implemented in Python. We can implement other
plugins for example energy function in Python as
well class VolumeEnergyFunctionPlugin(EnergyFunct
ionPy) def __init__(self,_energyWrapper)
proper initialization EnergyFunctionPy.__i
nit__(self) self.energyWrapper_energyWrappe
r self.vt0.0 self.lambda_v0.0
def setParams(self,_lambda,_targetVolume)
configuration of the plugin
self.lambda_v_lambda self.vt_targetVolume
def changeEnergy(self) core function of
energy function plugin energy0.0
if(self.energyWrapper.newCell)
energyself.lambda_v(12(self.energyWrapper.new
Cell.volume-self.vt)) if(self.energyWrapper.
oldCell) energyself.lambda_v(1-2(sel
f.energyWrapper.oldCell.volume-self.vt))
return energy
55Full script import sys from os import
environ from os import getcwd import
string sys.path.append(environ"PYTHON_MODULE_PAT
H") sys.path.append(getcwd()"/examples_PythonTut
orial") import CompuCellSetup sim,simthread
CompuCellSetup.getCoreSimulationObjects() Create
extra player fields here or add attributes or
plugins energyFunctionRegistryCompuCellSetup.getE
nergyFunctionRegistry(sim) from
cellsort_2D_plugins import VolumeEnergyFunctionPlu
gin volumeEnergyVolumeEnergyFunctionPlugin(energy
FunctionRegistry) volumeEnergy.setParams(2.0,25.0)
energyFunctionRegistry.registerPyEnergyFunction(
volumeEnergy) CompuCellSetup.initializeSimulation
Objects(sim,simthread) Add Python steppables
here steppableRegistryCompuCellSetup.getSteppable
Registry() CompuCellSetup.mainLoop(sim,simthread,
steppableRegistry)
56XML file ltCompuCell3Dgt ltPottsgt ltDimensions
x"100" y"100" z"1"/gt ltStepsgt10000lt/Stepsgt
ltTemperaturegt10lt/Temperaturegt lt/Pottsgt
lt!--Notice we eliminated Volume plugin but need
to keep VolumeTracker Plugin? ltPlugin
Name"VolumeTracker"/gt ltPlugin
Name"CellType"gt ltCellType TypeName"Medium"
TypeId"0"/gt ltCellType TypeName"Condensing"
TypeId"1"/gt ltCellType TypeName"NonCondensing
" TypeId"2"/gt lt/Plugingt ltPlugin
Name"Contact"gt ltEnergy Type1"Medium"
Type2"Medium"gt0lt/Energygt ltEnergy
Type1"NonCondensing" Type2"NonCondensing"gt16lt/En
ergygt lt/Plugingt ltSteppable
Type"BlobInitializer"gt ltGapgt0lt/Gapgt
ltWidthgt5lt/Widthgt lt/Steppablegt lt/CompuCell3Dgt
57Simulation Steering
- By steering we mean the ability to change any
simulation parameter while the simulation is
running - Steering is essential to build realistic
simulations because biological parameters do vary
in time. - Primitive way of steering would be to run a
simulation stop it change parameters restart the
simulation and so on. - Starting with 3.2.1 version of CompuCell3D we
can implement much more convenient way to steer
the simulation. It requires developing simple
steppable where we change simulation parameters. - Notice even with earlier versions of CompuCell3D
you had an opportunity to partially steer the
simulation whenever you were using, for example,
VolumeLocalFlex, SurfaceLocalFlex or
ContactLocalFlex plugins - Lets take a look at what is needed to have
steerable CompuCell3D simulation
58Simplest steering steppable will increase
target volume of the Volume plugin every
MCS class VolumeConstraintSteering(SteppablePy)
def __init__(self,_simulator,_frequency10)
SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.volumeParseDataCompuCellSetup.getModuleParse
Data("Volume") def step(self, _mcs)
self.volumeParseData.targetVolume1
CompuCellSetup.steer(self.volumeParseData)
59- Steering Checklist
- Create Steering Steppable. In the constructor ff
the steppable get ParseData for the module you
wish to steer - class VolumeConstraintSteering(SteppablePy)
- def __init__(self,_simulator,_frequency1)
- SteppablePy.__init__(self,_frequency)
- self.simulator_simulator
- self.volumeParseDataCompuCellSetup.getModul
eParseData("Volume") - In the step funuction implement your steering
algorithm update parameter values in ParseData
objects. Make sure to call CompuCellSetup.steer
function - def step(self, _mcs)
- self.volumeParseData.targetVolume1
- CompuCellSetup.steer(self.volumeParseData)
- CompuCellSetup.steer(self.volumeFlexParseDat
a) remember to call steer function - See the following examples in the CompuCell3D
package - -steering.py
60Steering Bacterium-Macrophage simulation
periodically decrease chemotaxis constant for
Macrophage. Macrophage will be attracted to
secreting bacterium and then will become repealed
Steering Steppable class ChemotaxisSteering(Step
pablePy) def __init__(self,_simulator,_frequen
cy1) SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.chemotaxisParseDataCompuCellSetup.getModuleP
arseData("Chemotaxis") def step(self, _mcs)
if _mcsgt100 and not _mcs100
cfdself.chemotaxisParseData.getChemotaxisFieldDat
a\ ("FastDiffusionSolver2DFE","ATTR")
cdcfd.getChemotaxisData(0) get 0th
element of the ChemotaxisData vector
lmcd.getLambda() cd.Lambda(lm-0.2)
decrease chemotaxis constant
CompuCellSetup.steer(self.chemotaxisParseData)
61Lets not forget to instantiate and register the
newly created steppable import sys from os
import environ import string sys.path.append(envir
on"PYTHON_MODULE_PATH") import
CompuCellSetup sim,simthread
CompuCellSetup.getCoreSimulationObjects() configu
reSimulation(sim) CompuCellSetup.initializeSimula
tionObjects(sim,simthread) from PySteppables
import SteppableRegistry steppableRegistrySteppab
leRegistry() from steering_steppables_examples
import ChemotaxisSteering csChemotaxisSteering(si
m,100) steppableRegistry.registerSteppable(cs) Co
mpuCellSetup.mainLoop(sim,simthread,steppableRegis
try)
62Steerable Bacterium-Macrophage Simulation -
Screenshots
t1700 MCS
t700 MCS
t900 MCS
t1400 MCS
Macrophage is first attracted and then repealed
from the bacterium. This behavior is altered
during simulation runtime.
63Steering LengthConstraint plugin import
sys from os import environ import
string sys.path.append(environ"PYTHON_MODULE_PATH
") import CompuCellSetup sim,simthread
CompuCellSetup.getCoreSimulationObjects() configu
reSimulation(sim) CompuCellSetup.initializeSimula
tionObjects(sim,simthread) from PySteppables
import SteppableRegistry steppableRegistrySteppab
leRegistry() from steering_steppables_examples
import LengthConstraintSteering lcsLengthConstrai
ntSteering(sim,100) steppableRegistry.registerStep
pable(lcs) CompuCellSetup.mainLoop(sim,simthread,
steppableRegistry)
64Steerable steppable will modify LengthConstraint
and Connectivity plugins data class
LengthConstraintSteering(SteppablePy) def
__init__(self,_simulator,_frequency1)
SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.lengthConstraintParseDataCompuCellSetup.getM
oduleParseData\ ("LengthConstraint")
self.connectivityParseDataCompuCellSetup.getModul
eParseData("Connectivity") def
step(self, _mcs) if _mcsgt100 and not
_mcs100 increase target length by 1 every 100
MCS lpself.lengthConstraintParseData.\
getLengthEnergyParametersByTypeName("Body1
") lp.targetLength1 CompuCellSetup.stee
r(self.lengthConstraintParseData) if
_mcsgt3000 release connectivity constraint
after 3100 MCS self.connectivityParseData
.penalty0 CompuCellSetup.steer(self.conn
ectivityParseData)
65Screenshots of steerbaly length constraint
simulations
t500 MCS
t1500 MCS
t2500 MCS
t3200 MCS
Connectivity constraint released but length
constraint still present. Green cell fragments
into two pieces satisfying moment of inertia
constraint of the LengthConstraint plugin
66Steering PDE solver parameters import
CompuCellSetup class DiffusionSolverSteering(Stepp
ablePy) def __init__(self,_simulator,_frequenc
y1) SteppablePy.__init__(self,_frequency)
self.simulator_simulator get
access to ParseData self.diffusionParseData
\ CompuCellSetup.getModuleParseData("FastDif
fusionSolver2DFE") def step(self, _mcs)
get diffusion and secretion data constants
diffusionDataself.diffusionParseData.getDiffusio
nDataByFieldName("ATTR") secretionDataself.
diffusionParseData.getSecretionDataByFieldName("AT
TR") change diffusion constant
diffusionData.diffConst0.01 change
secretion secrConstsecretionData.getSimpleS
ecretionConstByTypeName("Bacterium")
secretionData.setSimpleSecretionConstByTypeName("B
acterium",secrConst-100) if _mcsgt500
secretionData.setSimpleSecretionConstByTypeName
("Macrophage",100) CompuCellSetup.steer(self
.diffusionParseData) remember to call steer
function
67The result
t1000 MCS
t1600 MCS
t1800 MCS
t1700 MCS
Numerical instabilities in Forward-Euler solver
68When diffusion constant gets too large
instabilities arise. The solution to this is to
either use implicit solvers (might be time
consuming) or use PDESolverCaller plugin which
calls numerical algorithm user-specified times
per MCS class PDESolverCallerSteering(SteppableP
y) def __init__(self,_simulator,_frequency1)
SteppablePy.__init__(self,_frequency)
self.simulator_simulator
self.pdeSolverCallerParseData\
CompuCellSetup.getModuleParseData("PDESolverCaller
") def step(self, _mcs) if _mcsgt100 and
not _mcs100 sdself.pdeSolverCallerPars
eData.\ getPDESolverCallerDataBySolverNam
e("FastDiffusionSolver2DFE")
sd.extraTimesPerMC1 CompuCellSetup.stee
r(self.pdeSolverCallerParseData)
69- Dealing with diffusion constants especially
when they are too large - Diffusion constant has units of m2/s
- Pick lattice spacing and the time scale i.e. how
many seconds/MCS
If the last condition is not satisfied you will
get instabilities. In such a case decrease Dt and
use PDESolverCaller to call PDE solver extra
times. For example
70If you dont decrease time step Dt you get
approximate relation between ExtraTimesPerMCS and
diffusion constant
fixed between multiple calls
71The relation derived above is approximate at best
(for small n). The correct way to deal with
large diffusion constants is to manipulate Dt, Dx
and extraTimesPerMCS parameters or even better us
implicit diffusion solver when accuracy is
needed. Dx - ltDeltaXgt -CC3DML or deltaX
Python Dt - ltDeltaTgt -CC3DML or deltaT Python
72Steering using GUI There is only a prototype
73- Benefits of using Python
- Removes limitations of CC3DML
- Gives access to 3 party libraries
- Makes CompuCell3D simulation environment
- Future GUI will be implemented using Python
users will be able to write their own control
panels - Steering is done from Python level
- Enables Model Sharing cross platform (but be
careful here) - Allows for easy extensibility of CompuCell3D
e.g. parameter sweeps, output of results,
analysis of results etc.