4.1.8.4. causality/Stochsim

Added in version 1.1.

The causality.Simulator class implements the Stochastic Simulation Algorithm, also known as the Gillespie algorithm, but with the ability to generate the underlying network as needed, similarly to how a derivation graph, DG, can be created, and in particular the generation through graph transformation rules and strategies, Derivation Graph Strategies.

class causality.Simulator

The main class for performing stochastic simulations of chemical systems.

__init__(*, labelSettings=LabelSettings(LabelType.String, LabelRelation.Isomorphism), graphDatabase=[], graphPolicy=IsomorphismPolicy.Check, expandNetwork, initialState, draw=..., drawTime=..., withSetCompare=...)
Parameters:
  • labelSettings (LabelSettings) – a settings object that will be passed to DG.__init__().

  • graphDatabase (list[Graph]) – a list of graphs that will be passed to DG.__init__().

  • graphPolicy (IsomorphismPolicy) – the policy that will be passed to DG.__init__().

  • expandNetwork (Callable[[DG.Builder, list[Graph], list[Graph]], bool]) –

    a callback which will be called when the simulator needs new hyperedge/reaction information. The callback will be given:

    1. the DG builder object for the underlying derivation graph.

    2. a list of graphs that were newly discovered in the last iteration.

    3. a list of all graphs in the current state.

    The callback must return a boolean which indicates whether it should be called again.

    If you have a derivation graph expansion strategy, DGStrat, you can use ExpandByStrategy as a shorthand to create an appropriate callback. E.g., if you simply want to use all loaded rules you can give ExpandByStrategy(inputRules) as the callback.

    If you wish to simply provide a static network without dynamic expansion, your callback could be

    def expandNetwork(b, subset, universe):
        # use the DG.Builder b to add reactions/hyperedges as needed to create the network
        return False  # don't call again, we have added everything we need.
    

  • initialState (dict[Graph, int]) –

    the initial simulation state in terms of the number of copies of each graph/molecule. The graphs/molecules not mentioned are not considered part of the simulation yet, and are thus implicitly assumed to be 0.

    Caution

    If you use input flow through DrawMassAction then the input rate is only queried once a graph/molecule is known to the simulation, and you must thus mention them in initialState if they should be queried immediately in the simulation.

  • draw (Callable[[DG], DrawFunction]) – The simulator will initially create a DG which is given to this function. It must then return a callable that is used in each simulation step to draw the next hyperedge/reaction. Defaults to a default constructed instance of DrawMassAction.

  • drawTime (Callable[[float], float]) – The function to use for drawing the time increment in each simulation step. The function will be given the reactivity, and must return the time increment. Defaults to an instance of DrawTimeExponential.

  • withSetCompare (bool) – Whether to skip network expansion if a larger subset of graphs has been used for expansion before. Defaults to True.

Raises:

LogicError if draw(dg) returns None for the internally created derivation graph dg.

property dg

(Read-only) The internal DG underlying the simulation.

Type:

DG

property iteration

(Read-only) The current iteration number. It starts at 0 and is incremented in the beginning of each iteration.

Type:

int

property time

(Read-only) The current simulation time.

Type:

float

state(vg)
Parameters:

vg (DG.Vertex or Graph) – the vertex/graph to query the current state with.

Returns:

the number of occurrences of the given vertex/graph in the current state.

property trace

(Read-only) Returns a copy of the event trace for the entire simulation.

Type:

EventTrace

isNetworkOpen

(Read-only) Query whether the underlying network is still open for expansion. See also the keepNetworkOpen parameter of simulate().

Type:

bool

closeNetwork()

Manually close the network for expansion, instead of letting the simulate() method do it. The method does nothing if the network is already closed. If the user saved the DG.Builder object in the expansion callback, this method also does nothing.

setOnIterationBegin(callback, interval)

Set/remove a callback invoked in the very beginning of iterations of the simulation. just after iteration has been incremented. It is called at every interval th iteration, The callback is invoked with the simulator object as argument.

Parameters:

callback (None or Callable[[Simulator], None]) – The callback to set, or None to remove the callback.

Raises:

LogicError if interval is non-positive.

onIterationEnd

(Read-only) A callback invoked in the very end of each iteration of the simulation, after the drawn action has been carried out and the time advanced. It is called with the simulator object, and it must return a boolean indicating whether to continue the simulation, i.e., True means continue.

Type:

Callable[[Simulator], bool]

onDeadlock

(Read-only) A callback invoked if there are no events out of the current state. It is called with the simulator object as argument.

Type:

Callable[[Simulator], None]

onExpand

(Read-only) A callback invoked when the simulator is about to request events out of the current state. It is called with the simulator object as argument.

Type:

Callable[[Simulator], None]

onExpandAvoided

(Read-only) A callback invoked when the simulator detected is already had all events out of the current state. It is called with the simulator object as argument.

Type:

Callable[[Simulator], None]

simulate(*, time=None, advanceToEndTime=False, iterations=None, keepNetworkOpen=False)

Start/continue the simulation.

Simulate an additional amount of time or number of iterations, whichever is reached first, or until no further events are possible (a deadlock).

Parameters:
  • time (Optional[float]) – the additional amount of time to simulate, or None for unbounded. Defaults to None.

  • advanceToEndTime (bool) – if a time bound is given and the simulation stops due to this bound, advance the current time to the time bound, instead of staying at the time of the last event. Defaults to False.

  • iterations (Optional[int]) – the additional number of iterations to simulate, or None for unbounded. Defaults to None.

  • keepNetworkOpen (bool) – if False the internal DG.Builder object will be deleted before returning. Defaults to False.

Returns:

a copy of the event trace for the entire simulation.

Return type:

EventTrace

class causality.Simulator.DrawTimeExponential

A shorthand for drawing time from an exponential distribution.

call(activitySum)
Parameters:

activitySum (float) – the total sum of activity in the system.

Returns:

\(\frac{-\ln r}{activitySum}\), where \(r\) is a random number in \([0, 1)\) drawn with rngUniformReal().

Return type:

float

class causality.Simulator.ExpandByStrategy

A shorthand for an expansion callback that executes a strategy.

__init__(strat)
Parameters:

strat – a strategy to execute each time more neighbourhood is needed for the simulation. It can be any object that can be used as a strategy, see Derivation Graph Strategies.

__call__(b, subset, universe)

Executes the stored strategy on the given subset and universe, and returns True. It is equivalent to the following callback implementation.

def expandNetwork(b, subset, universe):
    b.execute(addSubset(subset) >> addUniverse(universe) >> strat, verbosity=0)
    return True  # call again when the simulation
Parameters:
  • b (DG.Builder) – the builder for the derivation graph underlying the simulation.

  • s (list[Graph]) – the set of new molecules in this iteration.

  • u (list[Graph]) – the set of molecules in the current state.

Returns:

True

Return type:

bool

class causality.Simulator.DrawFunction

The base class that event drawing functions must inherit from.

In each iteration a causality.Simulator must draw the next event that should happen. How to do this drawing can be customized, but such a drawing function needs detailed information about the underlying network and as the network expands, the drawing function must be kept in sync with the network- The drawing function customization is therefore done when a slightly indirect manner. Instead of giving the drawing function directly, you give a function that can create a drawing function. That is, the causality.Simulator will create an internal causality.Marking and give it as argument to the function you give. Your function must then create an actual drawing function, which must inherit from causality.Simulator.DrawFunction and implement the appropriate methods.

For an example of a drawing function, see causality.Simulator.DrawMassAction.Function, and its creator function causality.Simulator.DrawMassAction, which is the one users interact with.

syncSize()

Called whenever the underlying derivation graph has changed size. If the drawing function has internal data structures, this method is where such data structures can be resized. The derivation graph must be given to this object by its creator.

draw()

Called in order to draw the next event.

Returns:

the drawn action to take and a number indicating the activity of the system.

Return type:

tuple[Choice, float]

stateUpdated()

Updates internal caches after the state has been updated. This function must be invoked inbetween calls to draw().

class causality.Simulator.DrawFunction.Choice

The class used in the return type of causality.Simulator.DrawFunction.draw(). It a union type of causality.EdgeAction, causality.InputAction, and causality.OutputAction. It can be constructed from either of these types.

asAction()
Returns:

the represented action.

Return type:

causality.EdgeAction | causality.InputAction | causality.OutputAction.

class causality.Simulator.DrawMassAction

A creator for a drawing function implementing the law of mass action.

It supports assigning a rate for input actions, output actions, and reactions, by taking a callback (or constant) for each type. To avoid the overhead of calling these callbacks in each iteration, a returned rate can be cached. Therefore, the return value of each callback (or the constant of each type) is a pair with the first entry being the rate, and the second entry a boolean indicating whether rate should be cached.

Each of the rate function can also be set to None, which means a default rate is used: input rate 0.0, reaction rate 1.0, output rate 0.0.

Parameters:
  • inputRate (Callable[[DG.Vertex], Tuple[float, bool]] or Tuple[float, bool] or None) – the rate used for pseudo-reactions for creating molecules. Defaults to None.

  • reactionRate (Callable[[DG.Vertex], Tuple[float, bool]] or Tuple[float, bool] or None) – the rate used for each reaction in the system. Defaults to None.

  • outputRate (Callable[[DG.Vertex], Tuple[float, bool]] or Tuple[float, bool] or None) – the rate used for pseudo-reactions for destroying molecules. Defaults to None.

__call__(state)
Parameters:

state (Marking) – the state of the underlying simulation. It must be kept alive as long as the returned drawing function is kept alive.

Returns:

a drawing function implementing the law of mass action.

Return type:

DrawMassAction.Function

class Function(causality.Simulator.DrawFunction)