Difference between revisions of "Descrete events"
Ilya Kiselev (Talk | contribs) |
Ilya Kiselev (Talk | contribs) |
||
(5 intermediate revisions by one user not shown) | |||
Line 5: | Line 5: | ||
Events handling is independent from time course simulation and can be used in different types of models including ODE solving, stochastic simulation, algebraic models. Solver should be able to recognize that event was triggered, calculate specific time point at which it happened and stop simulation. Special wrapper solver EventLoopSimulator takes control, processes triggered events changes model variable values, reinits main solver and restarts it. Most solvers which are able to detect events have option ''Locate event'' which is set to ''true'' by default. | Events handling is independent from time course simulation and can be used in different types of models including ODE solving, stochastic simulation, algebraic models. Solver should be able to recognize that event was triggered, calculate specific time point at which it happened and stop simulation. Special wrapper solver EventLoopSimulator takes control, processes triggered events changes model variable values, reinits main solver and restarts it. Most solvers which are able to detect events have option ''Locate event'' which is set to ''true'' by default. | ||
− | == | + | ==Basics== |
− | + | In general event for model with two variables A and B and two assignments looks like this: | |
+ | <code> | ||
+ | :When f(time, A, B) | ||
+ | :do: | ||
+ | ::A = g_1(time, A, B) | ||
+ | ::B = g_k(time, A, B) | ||
+ | </code> | ||
+ | Here f is an event trigger - boolean function taking values '''true''' or '''false''', g_1, g_2 are assignment functions. | ||
+ | |||
+ | Important thing is that functions g_1(time, A, B) and g_2(time, A, B) are calculated '''before''' assigment to corresponding variables. Thus order of assignments '''does not matter''' and it is possible to create events like: | ||
+ | <code> | ||
+ | :When time > 10 | ||
+ | :do: | ||
+ | ::A = B | ||
+ | ::B = A | ||
+ | </code> | ||
+ | |||
+ | Here when model time will exceed 10 - variables B and A will be swapped | ||
+ | |||
+ | <code> | ||
+ | :When B > 10 | ||
+ | :do: | ||
+ | ::A = A + 1 | ||
+ | </code> | ||
+ | Here variable A will be incremented | ||
+ | |||
+ | Another important issue is that event is considered triggered when value of trigger function '''changes''' value from '''false''' to '''true''' thus it is strongly discouraged to use triggers like f(time, A, B) == 0 because time interval with '''true''' value may be too small (or even be a single time point) and may be simply missed during simulation. If trgger takes form f(time, A, B) > 0 simulator will detect that f changed its sign and then will try to find exact time point at which it happened (which corersponds to f(time, A, B) = 0). | ||
+ | |||
+ | It also should be noted that in boolean values opeartors '''&&''', '''||''' and '''==''' should be used instead of '''&''', '''|''' and '''='''. | ||
+ | |||
+ | ==Multiple events== | ||
+ | More than one event may be triggered at the same if this happens - their '''priorities''' defines order of their execution. If two events have the same priority - they will be executed in unpredictable order. By default those events can not affect each other as assignment values will be calculated before either of them executed. However oe event can activate another one as in given example first evnt will activate second: | ||
+ | <code> | ||
+ | :When time > 10 | ||
+ | :do: | ||
+ | ::A = 5 | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | :When time > 10 && A == 5 | ||
+ | :do: | ||
+ | ::B = 5 | ||
+ | </code> | ||
+ | |||
+ | Moreover events may activate one another in (posssibili infinite) event cascade | ||
+ | |||
+ | ==Behavior details== | ||
Event attributes: | Event attributes: | ||
*'''Trigger''' specifies conditions for event to occur. It is a mathematicla boolean expression from model variables. If during simulation this expression transits from ''false'' to ''true'' - event is considered as triggered. It is usually better to formulate trigger in terms of inequalities: <code>time > 9</code>, <code>x+y > z</code>. | *'''Trigger''' specifies conditions for event to occur. It is a mathematicla boolean expression from model variables. If during simulation this expression transits from ''false'' to ''true'' - event is considered as triggered. It is usually better to formulate trigger in terms of inequalities: <code>time > 9</code>, <code>x+y > z</code>. | ||
*'''Assignments''' - list of assignments which should be performed when event is executed. Each assignment consists of variable and mathematical expression. When event is executed, expressions are evalueated and results are assigned to variables. | *'''Assignments''' - list of assignments which should be performed when event is executed. Each assignment consists of variable and mathematical expression. When event is executed, expressions are evalueated and results are assigned to variables. | ||
− | *'''Priority''' - defines order of events execution in the case when several events are to be executed at the same time. Prioity is a evaluated expression from model variables and is recalculated each time it is checked. | + | *'''Priority''' - defines order of events execution in the case when several events are to be executed at the same time. Prioity is a evaluated expression from model variables and is recalculated each time it is checked. If prioirty is not set - event will have minimal priority ('''Note:''' behaviour for this case is not specified by SBML specification and left to particular software to decide). |
*'''Delay''' - defines time delay between event triggering and execution. Delay should be assgined by numerical value and can not be changed during simulation. | *'''Delay''' - defines time delay between event triggering and execution. Delay should be assgined by numerical value and can not be changed during simulation. | ||
− | *'''Use trigger time values''' - if true then assignment expressions are calculated using values of variables at the time of triggering. If false - at the time of execution. | + | *'''Use trigger time values''' - if true then assignment expressions are calculated using values of variables at the time of triggering. If false - at the time of execution. Note: these values may be different due to two reasons: |
+ | #trigger and execution are perforemd at different time points | ||
+ | #trigger and execution are perforemd at the same time point but other event with higher priority changed these variables | ||
*'''Persistent tigger''' - if true then once event is triggered - it will be executed no matter what happends before execution time. If ''false'' and event tigger transits from true to false after event is triggered then event is considered ''switched off'' and will not be executed. Note that if then trigger will transit from ''false'' to ''true'' again - event will be triggered again. | *'''Persistent tigger''' - if true then once event is triggered - it will be executed no matter what happends before execution time. If ''false'' and event tigger transits from true to false after event is triggered then event is considered ''switched off'' and will not be executed. Note that if then trigger will transit from ''false'' to ''true'' again - event will be triggered again. | ||
− | *'''Trigger initial value''' - defines whether event may be triggered at the start of the simulation (i.e. <code>time = 0</code>). If set to ''true'' then event can not be triggered at <code>time = 0</code> even if Trigger expression is true at this time. If set to '' | + | *'''Trigger initial value''' - defines whether event may be triggered at the start of the simulation (i.e. <code>time = 0</code>). If set to ''true'' then event can not be triggered at <code>time = 0</code> even if Trigger expression is true at this |
+ | |||
+ | Logic of events can be quite complicated. Time point at which event should be executed may be different totime point at which it is executed due to preset time delay. Events execution may affect other events causing them to trigger or deactivating already triggered events. If several events are to be executed at the same time - order of execution is managed according to their priorities which are represented by mathematical expressions and may also be changed when other events are executed. It should be noted that events may form infinite loop triggering each other, so model creator should be cautious while using events in models. | ||
+ | |||
+ | If trigger is set to inequality of type <code>A > B</code> and during simulation A transits from <code>B - eps</code> to <code>B + eps</code>, where <code>eps > 0</code> is some positive number then event is considered to be triggered exactly at the time point when <code>A = B</code>. The same behaviour may be achieved with trigger <code>A = B</code>, however this type of triggers should be used with cautious because it will be evaluated to ''true'' at one exact moment of time which can be accidentally skipped by solver. Whereas trigger <code>A > B</code> will be evaluated to ''true'' for longer time period and it will be spotted by solver. After that solver will use bisection method to find exact time point at which transition from ''false'' to ''true'' happened (which is <code>A = B</code>). | ||
+ | |||
+ | Similarly, sometimes events may be triggered even if model does not assume that A may ever exceed B. For example: | ||
+ | <code> | ||
+ | :B(t)= B(0) = 5, | ||
+ | :dA/dt = 5 - A(t), A(0) = 0. | ||
+ | </code> | ||
+ | Due to numerical error, there may be point in time when <code>A</code> will be slightly larger than <code>B</code> which will trigger event. | ||
+ | |||
+ | When event is executed, for each assignment, right hand side is evaluated and assigned to correspondent variable. Values of variables used in right hand side are fixed before execution and thus order of assignments does not matter. Let's consider example: | ||
+ | <code> | ||
+ | :Trigger: x > 1 | ||
+ | :Delay: 3 | ||
+ | :Priority: y + z | ||
+ | :Assignments: | ||
+ | ::x = y + 5, | ||
+ | ::y = x - 2, | ||
+ | ::z = z + 1. | ||
+ | :Before event execution: x = 1, y = 2, z = 3. | ||
+ | :After event execution: x = 7, y = -1, z = 4. | ||
+ | </code> | ||
==Implementation== | ==Implementation== | ||
+ | |||
+ | In BioUML each Event is broken into two events: | ||
+ | *''preparational'' event calculates right hand side expressions and stores obtained values. It also calulates time point at which assignments should be performed by taking current time and adding delay value of base event: <code>DelayedTime = time + Delay</code>. It have the same trigger as base event and priority = Infinity, so it will be executed prior to any actual assignments. | ||
+ | *''executional'' event actually assignes values calculated by ''preparational'' event to left hand side variables. If base event has delay then It has trigger <code>time > DelayedTime</code>. In that case event is triggered and executed in DelayedTime after preparational. Otherwise trigger is the same as for base event and both events will be executed simultaneously, but priority of the ''executional'' event is the same as for base event. | ||
+ | |||
+ | Thus each event is executed at the very same time point when it was triggered, all ''preparational'' events are executed before any ''executional'' and order of ''executional'' events is defined by priorities. | ||
+ | |||
+ | Let's consider what happends with event discussed earlier: | ||
+ | <code> | ||
+ | :Preparational event | ||
+ | :Trigger: x > 1 | ||
+ | :Priority: Infinity | ||
+ | :Assignments: | ||
+ | ::tempx = y + 5, | ||
+ | ::tempy = x - 2, | ||
+ | ::tempz = z + 1, | ||
+ | ::DelayedTime = time + 7. | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | :Executional event | ||
+ | :Trigger: time > DelayedTime | ||
+ | :Priority: y + z | ||
+ | :Assignments: | ||
+ | ::x = tempx, | ||
+ | ::y = tempy, | ||
+ | ::z = tempz. | ||
+ | </code> | ||
Processing of events done by EventLoopSimulator goes as follows: | Processing of events done by EventLoopSimulator goes as follows: | ||
− | + | # Check which events were triggered. Add all these events to the pool of pending events. | |
− | + | # Calculate prioirty for each of triggered events - choose one event with the highest priority, or if there are several events with maximal priority - choose one of them randomly. | |
− | + | # Process chosen event | |
− | + | # Recalculate triggers of all other events. | |
− | + | # If it was not triggered before step 3 but is triggered now (it was switched on by executed event) - add it to the pool of pending events. | |
− | + | # If event has '''Persistent trigger = false''' and its trigger expression evaluates to false - remove it from the pool (it was switched off). | |
− | + | # If list of pending events is empty - reinit solver and start it with new values. Else - goto 2. |
Latest revision as of 16:16, 15 May 2023
Contents |
[edit] General definition
Descrete events are used to instantaneously change values of model variables when given conditions are met. For example when model time reaches certain value or when boolean expression becomes true. Generally event consists of two parts: trigger - which defines conditions of event and execution - actions which should be performed after event is triggered. In BioUML events are handling according to latest SBML specification.
Events handling is independent from time course simulation and can be used in different types of models including ODE solving, stochastic simulation, algebraic models. Solver should be able to recognize that event was triggered, calculate specific time point at which it happened and stop simulation. Special wrapper solver EventLoopSimulator takes control, processes triggered events changes model variable values, reinits main solver and restarts it. Most solvers which are able to detect events have option Locate event which is set to true by default.
[edit] Basics
In general event for model with two variables A and B and two assignments looks like this:
- When f(time, A, B)
- do:
- A = g_1(time, A, B)
- B = g_k(time, A, B)
Here f is an event trigger - boolean function taking values true or false, g_1, g_2 are assignment functions.
Important thing is that functions g_1(time, A, B) and g_2(time, A, B) are calculated before assigment to corresponding variables. Thus order of assignments does not matter and it is possible to create events like:
- When time > 10
- do:
- A = B
- B = A
Here when model time will exceed 10 - variables B and A will be swapped
- When B > 10
- do:
- A = A + 1
Here variable A will be incremented
Another important issue is that event is considered triggered when value of trigger function changes value from false to true thus it is strongly discouraged to use triggers like f(time, A, B) == 0 because time interval with true value may be too small (or even be a single time point) and may be simply missed during simulation. If trgger takes form f(time, A, B) > 0 simulator will detect that f changed its sign and then will try to find exact time point at which it happened (which corersponds to f(time, A, B) = 0).
It also should be noted that in boolean values opeartors &&, || and == should be used instead of &, | and =.
[edit] Multiple events
More than one event may be triggered at the same if this happens - their priorities defines order of their execution. If two events have the same priority - they will be executed in unpredictable order. By default those events can not affect each other as assignment values will be calculated before either of them executed. However oe event can activate another one as in given example first evnt will activate second:
- When time > 10
- do:
- A = 5
- When time > 10 && A == 5
- do:
- B = 5
Moreover events may activate one another in (posssibili infinite) event cascade
[edit] Behavior details
Event attributes:
- Trigger specifies conditions for event to occur. It is a mathematicla boolean expression from model variables. If during simulation this expression transits from false to true - event is considered as triggered. It is usually better to formulate trigger in terms of inequalities:
time > 9
,x+y > z
. - Assignments - list of assignments which should be performed when event is executed. Each assignment consists of variable and mathematical expression. When event is executed, expressions are evalueated and results are assigned to variables.
- Priority - defines order of events execution in the case when several events are to be executed at the same time. Prioity is a evaluated expression from model variables and is recalculated each time it is checked. If prioirty is not set - event will have minimal priority (Note: behaviour for this case is not specified by SBML specification and left to particular software to decide).
- Delay - defines time delay between event triggering and execution. Delay should be assgined by numerical value and can not be changed during simulation.
- Use trigger time values - if true then assignment expressions are calculated using values of variables at the time of triggering. If false - at the time of execution. Note: these values may be different due to two reasons:
- trigger and execution are perforemd at different time points
- trigger and execution are perforemd at the same time point but other event with higher priority changed these variables
- Persistent tigger - if true then once event is triggered - it will be executed no matter what happends before execution time. If false and event tigger transits from true to false after event is triggered then event is considered switched off and will not be executed. Note that if then trigger will transit from false to true again - event will be triggered again.
- Trigger initial value - defines whether event may be triggered at the start of the simulation (i.e.
time = 0
). If set to true then event can not be triggered attime = 0
even if Trigger expression is true at this
Logic of events can be quite complicated. Time point at which event should be executed may be different totime point at which it is executed due to preset time delay. Events execution may affect other events causing them to trigger or deactivating already triggered events. If several events are to be executed at the same time - order of execution is managed according to their priorities which are represented by mathematical expressions and may also be changed when other events are executed. It should be noted that events may form infinite loop triggering each other, so model creator should be cautious while using events in models.
If trigger is set to inequality of type A > B
and during simulation A transits from B - eps
to B + eps
, where eps > 0
is some positive number then event is considered to be triggered exactly at the time point when A = B
. The same behaviour may be achieved with trigger A = B
, however this type of triggers should be used with cautious because it will be evaluated to true at one exact moment of time which can be accidentally skipped by solver. Whereas trigger A > B
will be evaluated to true for longer time period and it will be spotted by solver. After that solver will use bisection method to find exact time point at which transition from false to true happened (which is A = B
).
Similarly, sometimes events may be triggered even if model does not assume that A may ever exceed B. For example:
- B(t)= B(0) = 5,
- dA/dt = 5 - A(t), A(0) = 0.
Due to numerical error, there may be point in time when A
will be slightly larger than B
which will trigger event.
When event is executed, for each assignment, right hand side is evaluated and assigned to correspondent variable. Values of variables used in right hand side are fixed before execution and thus order of assignments does not matter. Let's consider example:
- Trigger: x > 1
- Delay: 3
- Priority: y + z
- Assignments:
- x = y + 5,
- y = x - 2,
- z = z + 1.
- Before event execution: x = 1, y = 2, z = 3.
- After event execution: x = 7, y = -1, z = 4.
[edit] Implementation
In BioUML each Event is broken into two events:
- preparational event calculates right hand side expressions and stores obtained values. It also calulates time point at which assignments should be performed by taking current time and adding delay value of base event:
DelayedTime = time + Delay
. It have the same trigger as base event and priority = Infinity, so it will be executed prior to any actual assignments. - executional event actually assignes values calculated by preparational event to left hand side variables. If base event has delay then It has trigger
time > DelayedTime
. In that case event is triggered and executed in DelayedTime after preparational. Otherwise trigger is the same as for base event and both events will be executed simultaneously, but priority of the executional event is the same as for base event.
Thus each event is executed at the very same time point when it was triggered, all preparational events are executed before any executional and order of executional events is defined by priorities.
Let's consider what happends with event discussed earlier:
- Preparational event
- Trigger: x > 1
- Priority: Infinity
- Assignments:
- tempx = y + 5,
- tempy = x - 2,
- tempz = z + 1,
- DelayedTime = time + 7.
- Executional event
- Trigger: time > DelayedTime
- Priority: y + z
- Assignments:
- x = tempx,
- y = tempy,
- z = tempz.
Processing of events done by EventLoopSimulator goes as follows:
- Check which events were triggered. Add all these events to the pool of pending events.
- Calculate prioirty for each of triggered events - choose one event with the highest priority, or if there are several events with maximal priority - choose one of them randomly.
- Process chosen event
- Recalculate triggers of all other events.
- If it was not triggered before step 3 but is triggered now (it was switched on by executed event) - add it to the pool of pending events.
- If event has Persistent trigger = false and its trigger expression evaluates to false - remove it from the pool (it was switched off).
- If list of pending events is empty - reinit solver and start it with new values. Else - goto 2.