Adding CPM Constraints
One of the strengths of the CPM is that it can incorporate different processes of interest as separate "rules" given to the model. These rules can be mixed and matched to get a simulation of interest, making the CPM a very flexible framework. Artistoo implements a diverse set of model rules, called Constraints. This tutorial will walk you through how to use these constraints in your models.
Soft versus hard constraints
In Artistoo, we distinguish two types of constraints: "hard" and "soft" constraints.
Soft constraints
"Soft" constraints are the classical CPM energy rules. They are the terms of the model's Hamiltonian, or energy equation. When a copy attempt would break such a rule, this becomes visible as an energetic penalty making that copy attempt less likely. But a soft constraint is more a guideline than an actual rule; the model will mostly adhere to it, but not always.
For example, suppose we have a cell with a volume constraint, and that cell is already larger than its target volume. A copy attempt that would add another pixel to that cell would be associated with a $ΔH_\text{vol} \gt 0$. However, that does not mean that this copy attempt will always fail to go through. First, it may be that there are other constraints acting on the model for which this copy attempt is favourable, compensating for the volume penalty such that the global $ΔH$ is still negative. Second, even if the global $ΔH$ is positive, a copy attempt may still be accepted with a chance $e^{-ΔH T}$. Thus, soft constraints make some changes more likely to happen than others, but they can balance each other out and are not always listened to.
Most CPM constraints are soft constraints. But sometimes, there are things we would like to forbid completely. For that, we can use a hard constraint.
Hard constraints
Whereas soft constraints are more guidelines than rules, "hard" constraints are set in stone. Before the $ΔH$ of a copy attempt is even computed, Artistoo checks whether it violates one of the hard constraints. If it does, it won't go through — ever.
Not many constraints are hard constraints, and in a typical CPM, you should be careful using them. But examples are the HardVolumeRangeConstraint, the BarrierConstraint, and the hard ConnectivityConstraint. See also this example of a 'particle' following a random walk, where we constrained the volume such that the cell can only be one or two pixels big:
Adding a constraint to a model
There are two ways of adding a constraint to your model, which we will explain here.
Method 1: via the conf object
The first method is to add the relevant constraint parameters to the conf
object. This is the easiest method to add a constraint, but it only works for a few of the
most used constraints (see this page for a list of the constraints for which this works).
For example:
let myCPM = new CPM.CPM(
[ 200, 200 ],
{
T : 20,
J : [[0,20],[20,0]],
V : [0,500],
LAMBDA_V: [ 0, 50]
}
)
will automatically create a CPM with an adhesion and a volume constraint inside it. If we open the browser console from a page with an Artistoo simulation in it, e.g. this one, we can check this. Go to the page, right click anywhere on the page outside of the grid, select "inspect" and then "console". Copy-paste the above code in the console and hit enter. If you now type:
myCPM.soft_constraints
and hit enter, you should see that there are two soft constraints in the model now:
an Adhesion
and a VolumeConstraint
.
This works the same if we use the
Simulation
class,
because the config.conf
is passed along internally to the CPM constructor.
So if we type:
let mySim = new CPM.Simulation(
{
field_size : [200,200],
conf : {
T : 20,
J : [[0,20],[20,0]],
V : [0,500],
LAMBDA_V: [ 0, 50]
},
simsettings : {
NRCELLS : [1]
}
}
)
mySim.C.soft_constraints
we again see our two constraints appear.
Method 2: via the add() method
Note that, as mentioned, the first method does not work for all constraints. If we try to add
an
AttractionPointConstraint
(another soft constraint) in this way:
let myCPM = new CPM.CPM(
[ 200, 200 ],
{
T : 20,
J : [[0,20],[20,0]],
V : [0,500],
LAMBDA_V: [ 0, 50],
LAMBDA_ATTRACTIONPOINT : [0,100],
ATTRACTIONPOINT: [[0,0],[100,100]]
}
)
then if we type:
myCPM.soft_constraints
we still only have our Adhesion
and a VolumeConstraint
.
The AttractionPointConstraint
has not been added.
To add this constraint, we must use the
add()
method of the CPM class. If we have already put the relevant parameters
in the conf
object, this is easy:
//add constraint
myCPM.add( new CPM.AttractionPointConstraint( myCPM.conf ) )
myCPM.soft_constraints
you should now see an AttractionPointConstraint
in the list of
soft constraints. We've given the entire conf
object of the CPM to the
constraint's constructor, but it will just ignore the parameters that are not relevant
to this constraint. However, we can also just give it it's own conf
object.
For example, we might add a second attraction point like this:
//add another constraint
myCPM.add( new CPM.AttractionPointConstraint( {
LAMBDA_ATTRACTIONPOINT : [0,100],
ATTRACTIONPOINT: [[0,0],[150,150]]
} ) )
myCPM.soft_constraints
You should now see two attraction point constraints in your list.
A word of warning: when you add a new constraint, the model will use it. It won't check
if another constraint of the same type was already present. For the example above, that's
perfectly fine because we might want to have two different points of attraction.
However, for other constraints such as the
Adhesion
,
this might not be what you want (basically, this will be the same as having only one
adhesion constraint where the parameters are twice as large. But someone checking your
code may overlook your second adhesion constraint and think that the adhesion parameters
are set lower than they actually are...).
Accessing a constraint in your model
Once you've put a constraint in your model, you may want to access it from outside.
The method getConstraint()
allows you to do that. For
example:
//get volumeconstraint
myCPM.getConstraint( "VolumeConstraint" )
will return the VolumeConstraint
that is currently in your model.
If there are multiple constraints of the same name in your model, this method automatically gives you the first one:
//get the first attraction point constraint
myCPM.getConstraint( "AttractionPointConstraint" )
This yields the first attraction point we added (from the browser console, you can
click the little triangle on the left to see more about the object. If you look at its
conf
object, you see that this is the settings we gave to our first
attraction point constraint).
If we want to access the second attraction point, we can type:
//get the second attraction point constraint
myCPM.getConstraint( "AttractionPointConstraint", 1 )
(Note here that JavaScript uses zero-based indexing, so an element with number
1
is actually the second element)
Implementation details
Constraints in Artistoo are implemented as separate classes, of which an instance
can be added to a CPM model
(See above for an explanation how). The base
Constraint
class underlies all of them, and has two subclasses: SoftConstraint
and
HardConstraint
.
These are never used by themselves, but can be extended to create a constraint
(see also this tutorial to see how to develop custom modules).