Event Trace - openmpp/openmpp.github.io GitHub Wiki
Home > Model Development Topics > Event Trace
This topic describes a model developer feature which reports the evolution of individual entities during a simulation.
- Introduction and outline
- Quick start How to build and run a model with event trace capability
- Worked example 1 Using filters
- Worked example 2 Tracing attributes
- Worked example 3 Tracing links and multilinks
- Worked example 4 Tracing table increments
- General information General information
- Event trace columns The seven columns of event trace output
- Event trace messages The different kinds of messages in event trace output
- Event trace options Reference to all event trace options
- Trace file options Technical: Run options to specify trace file name, etc.
- Trace file API Technical: How to toggle trace output from model code
Event trace allows a model developer to probe the simulation of individual entities or groups of entities in detail. This can help to understand a model, to verify that it is working as intended, or to probe anomalies.
After an entity enters the simulation it undergoes a series of events which change attributes, either its own or those of linked entities. Changes in attributes can in turn condition the time of future events. An entity in a model with event trace capability generates event trace messages when it enters the simulation and during events. Event trace messages include simulation entry, simulation exit, event occurrence, conditional times of future events, and changes in attributes, links, and multilinks. Event trace messages are blocked or passed depending on run-time event trace options. Unblocked messages are written to the run trace file in a readable columnar format designed for visual scanning. Alternatively, messages can be written in a csv format to facilitate use in external applications.
Quick Start shows how to build a model with event trace capability and how to enable that capability in a model run.
The quick start is followed by several worked examples with illustrative inputs and outputs using the RiskPaths
and Alpha2
models:
Worked example 1 which illustrates tracing events,
Worked example 2 which illustrates tracing attributes,
Worked example 3 which illustrates tracing links and multilinks.
and Worked example 4 which illustrates tracing table increments.
Please note that the output of the quick start and worked examples shown in this topic may differ slightly due to OpenM++ version differences.
The worked examples are followed by general information about event trace.
This is followed by three subtopics with reference material:
Event trace columns which describes the meaning of the output columns,
Event trace messages which describes all possible event trace messages,
and Event trace options which decribes all options to control and filter event trace messages.
This topic concludes with two specialized technical subtopics related to event trace.
This quick start example uses the RiskPaths
model in OM_ROOT/models/RiskPaths
in the OpenM++ distribution.
By default a model is not built with event trace functionality, and without it the examples in this topic will not work.
This subtopic contains the following sections.
- 1. Build model with event trace capability
- 2. Create model
ini
file with event trace options - 3. Run model using event trace
[continue to worked example 1]
[back to topic contents]
Edit the model source code file RiskPaths/code/TraceOptions.mpp
to change the event_trace
option from off
to on
:
options event_trace = on;
Build the Release version of RiskPaths.
In Windows, the model executable will be RiskPaths/ompp/bin/RiskPaths.exe
.
In Linux, the model executable will be RiskPaths/ompp-linux/bin/RiskPaths
.
[back to quick start]
[back to topic contents]
In the same folder as the RiskPaths executable there may already be a copy of the default model ini
file RiskPaths.ini
.
If not create it using your IDE or a text editor such as Notepad.
Edit RiskPaths.ini
to have the following content:
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 5
[EventTrace]
ReportStyle = readable
The following Windows screenshot shows RiskPaths.ini
being edited in Visual Studio in the RiskPaths
project:
[back to quick start]
[back to topic contents]
Launch the model in its bin
directory using the ini
file created in the previous step, being sure to also specify the OpenM.IniAnyKey
option.
RiskPaths -ini RiskPaths.ini -OpenM.IniAnyKey true
In Windows you can run the Release version of RiskPaths from inside Visual Studio as follows:
-
Solution Configurations
toRelease
andSolution Platforms
tox64
-
Project Properties > Configuration Properties > Debugging > Command Arguments
to
-ini RiskPaths.ini -OpenM.IniAnyKey true
-
Project Properties > Configuration Properties > Debugging > Working Directory
to$(TargetDir)
- To launch the model, do
Debug > Start without debugging
or PressCtrl-F5
.
After the model runs the trace file RiskPaths.trace.txt
should be present in the model bin
directory and look like this:
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 1 ENTER
24.260999 Person 24.260999 1 EVENT Union1FormationEvent
26.537813 Person 26.537813 1 EVENT FirstPregEvent
27.260999 Person 27.260999 1 EVENT UnionPeriod2Event
100.000000 Person 100.000000 1 EVENT DeathEvent
100.000000 Person 100.000000 1 EXIT
0.000000 Person 0.000000 2 ENTER
22.052373 Person 22.052373 2 EVENT Union1FormationEvent
24.678078 Person 24.678078 2 EVENT FirstPregEvent
25.052373 Person 25.052373 2 EVENT UnionPeriod2Event
100.000000 Person 100.000000 2 EVENT DeathEvent
100.000000 Person 100.000000 2 EXIT
0.000000 Person 0.000000 3 ENTER
17.050111 Person 17.050111 3 EVENT Union1FormationEvent
20.024665 Person 20.024665 3 EVENT FirstPregEvent
20.050111 Person 20.050111 3 EVENT UnionPeriod2Event
100.000000 Person 100.000000 3 EVENT DeathEvent
100.000000 Person 100.000000 3 EXIT
0.000000 Person 0.000000 4 ENTER
17.410717 Person 17.410717 4 EVENT FirstPregEvent
100.000000 Person 100.000000 4 EVENT DeathEvent
100.000000 Person 100.000000 4 EXIT
0.000000 Person 0.000000 5 ENTER
24.157739 Person 24.157739 5 EVENT FirstPregEvent
100.000000 Person 100.000000 5 EVENT DeathEvent
100.000000 Person 100.000000 5 EXIT
The following Windows screenshot shows RiskPaths.trace.txt
open in Visual Studio in the RiskPaths
project.
The screenshot also shows the command window and log output for the run, and highlights the expected warning generated by a model with event trace capability.
[back to quick start]
[back to topic contents]
This section continues the quick start example to explore using EventTrace filters to find and probe entities in the simulation.
This subtopic contains the following sections:
- Find entities with a specific event
- Report on specific entities
- Report detailed history for a given entity
- Probe a time window
RiskPaths simulates how first and second unions affect first birth frequency.
To probe entities which experience a second union, change SelectedEvents
to only show the event Union2FormationEvent
.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 5
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = yes
SelectedEvents = Union2FormationEvent
The trace file RiskPaths.trace.txt
now looks like this:
That's right, it's empty! That's because the run had only 5 cases and in those 5 cases the Union2FormationEvent
never occurred.
Expand the run to 10,000 cases by changing SimulationCases
and set MaximumLines
to report only the first 10.
The width of the name column has been shortened to 20 from the default of 40 for more compact output.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 10000
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
MaximumLines = 10
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = yes
SelectedEvents = Union2FormationEvent
The trace file looks like this:
Time Entity Age Id Trace Value Name Remarks
85.748654 Person 85.748654 11 EVENT Union2FormationEvent
46.987741 Person 46.987741 13 EVENT Union2FormationEvent
24.942941 Person 24.942941 65 EVENT Union2FormationEvent
26.208783 Person 26.208783 94 EVENT Union2FormationEvent
67.733676 Person 67.733676 101 EVENT Union2FormationEvent
36.152105 Person 36.152105 135 EVENT Union2FormationEvent
22.466353 Person 22.466353 211 EVENT Union2FormationEvent
20.010964 Person 20.010964 222 EVENT Union2FormationEvent
60.116048 Person 60.116048 262 EVENT Union2FormationEvent
Maximum lines exceeded, increase using EventTrace.MaximumLines
[back to worked example 1]
[back to topic contents]
In the previous section, the entity_id
of the youngest of the 10 is 222 and the oldest is 266.
To probe those two entities in more detail, set MaximumLines
to 1000, set SelectedEvents
to empty to report on all events, and set SelectedEntities
to report only on those two entities. Also, set SimulationCases
to 500 to increase run speed (RiskPaths has only one entity in each case, so this is sufficient to simulate the two cases we're after).
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 500
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
MaximumLines = 1000
; filters
SelectedEntities = 222,266
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = yes
SelectedEvents =
Re-run RiskPaths. The trace file now looks like this:
Time Entity Age Id Trace Value Name Remarks
18.198452 Person 18.198452 222 EVENT Union1FormationEvent
19.944885 Person 19.944885 222 EVENT Union1DissolutionEvent
20.010964 Person 20.010964 222 EVENT Union2FormationEvent
20.212818 Person 20.212818 222 EVENT FirstPregEvent
21.198452 Person 21.198452 222 EVENT UnionPeriod2Event
100.000000 Person 100.000000 222 EVENT DeathEvent
39.395331 Person 39.395331 266 EVENT Union1FormationEvent
42.395331 Person 42.395331 266 EVENT UnionPeriod2Event
65.159506 Person 65.159506 266 EVENT Union1DissolutionEvent
87.325967 Person 87.325967 266 EVENT Union2FormationEvent
100.000000 Person 100.000000 266 EVENT DeathEvent
The evolution of entity_id
222 looks a bit odd.
RiskPaths documents UnionPeriod2Event
as a 3-year period after first union formation which can affect fertility:
/*NOTE(Person.UnionPeriod2Event, EN)
Clock event which changes the union duration state union_status from
US_FIRST_UNION_PERIOD1 to US_FIRST_UNION_PERIOD2. This event occurs
after 3 years in 1st union. The clock is set at first union formation.
*/
The event trace shows that for entity_id
222 a second union occurred at time=20.010964 and UnionPeriod2Event
occurred later at time=21.198452 (exactly 3 years after the Union1FormationEvent
event). It would be incoherent for union_status
, which affects fertility, to change 3 years after the start of a first union if the Person is already in a second union. It might be good to investigate the model logic to confirm that the UnionPeriod2Event
event has no effect if a second union has already formed.
[back to worked example 1]
[back to topic contents]
Probe entity_id
222 in more detail by setting SelectedEntities
to 222 and observing scheduled future event times by turning on ShowQueuedEvents
.
All model events except for DeathEvent
are listed in SelectedEvents
to remove DeathEvent
messages from the report.
Otherwise, the report would be cluttered with lines showing the recomputation of time of death because the mortality rate changes at each birthday.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 500
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 25
MaximumLines = 10000
; filters
SelectedEntities = 222
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = yes
ShowQueuedEvents = yes
SelectedEvents = \
FirstPregEvent, \
Union1FormationEvent, \
Union1DissolutionEvent, \
Union2FormationEvent, \
Union2DissolutionEvent, \
UnionPeriod2Event
The line continuation character \
is used to split the list of event names into multiple lines for readability and ease of editing.
The resulting trace report looks like this:
Time Entity Age Id Trace Value Name Remarks
15.000000 Person 15.000000 222 queued 81.828627 FirstPregEvent was inf
15.000000 Person 15.000000 222 queued 58.463729 Union1FormationEvent was inf
17.500000 Person 17.500000 222 queued 18.987406 FirstPregEvent was 81.828627
17.500000 Person 17.500000 222 queued 18.198452 Union1FormationEvent was 58.463729
18.198452 Person 18.198452 222 EVENT Union1FormationEvent
18.198452 Person 18.198452 222 queued 20.173365 FirstPregEvent was 18.987406
18.198452 Person 18.198452 222 queued 53.059542 Union1DissolutionEvent was inf
18.198452 Person 18.198452 222 queued inf Union1FormationEvent was 18.198452
18.198452 Person 18.198452 222 queued 21.198452 UnionPeriod2Event was inf
19.198452 Person 19.198452 222 queued 19.944885 Union1DissolutionEvent was 53.059542
19.944885 Person 19.944885 222 EVENT Union1DissolutionEvent
19.944885 Person 19.944885 222 queued 43.387166 FirstPregEvent was 20.173365
19.944885 Person 19.944885 222 queued inf Union1DissolutionEvent was 19.944885
19.944885 Person 19.944885 222 queued 20.010964 Union2FormationEvent was inf
20.000000 Person 20.000000 222 queued 55.173852 FirstPregEvent was 43.387166
20.010964 Person 20.010964 222 EVENT Union2FormationEvent
20.010964 Person 20.010964 222 queued 20.212818 FirstPregEvent was 55.173852
20.010964 Person 20.010964 222 queued 59.958810 Union2DissolutionEvent was inf
20.010964 Person 20.010964 222 queued inf Union2FormationEvent was 20.010964
20.212818 Person 20.212818 222 EVENT FirstPregEvent
20.212818 Person 20.212818 222 queued inf FirstPregEvent was 20.212818
20.212818 Person 20.212818 222 queued inf Union2DissolutionEvent was 59.958810
21.198452 Person 21.198452 222 EVENT UnionPeriod2Event
21.198452 Person 21.198452 222 queued inf UnionPeriod2Event was 21.198452
No events of interest occurred in entity_id
222 after UnionPeriod2Event
.
On the other hand, this entity does not probe what might happen if a first birth had not already occurred prior to UnionPeriod2Event
.
In this trace report, we see recalculation of future events triggered by other events.
Recalculations are triggered by changes in an entity's attributes, and that only happens at events.
The report shows, however, a recomputation of the time of event Union1DissolutionEvent
occurring at time=19.198452, exactly one year after Union1FormationEvent
occurs, with no associated event.
This must be due to a self-scheduling event which is not shown in the output.
[back to worked example 1]
[back to topic contents]
To probe in detail what's happening in entity_id
222 at time 19.198452 (the time of the event not shown in the previous run), turn on ShowSelfSchedulingEvents
and ShowQueuedSelfSchedulingEvents
, and set up a time restriction window which brackets that time by setting
MinimumTime=19.1
and MaximumTime=19.2
.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 500
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 45
MaximumLines = 10000
; filters
SelectedEntities = 222
MinimumTime = 19.1
MaximumTime = 19.2
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = yes
ShowSelfSchedulingEvents = yes
ShowQueuedEvents = yes
ShowQueuedSelfSchedulingEvents = yes
SelectedEvents = \
FirstPregEvent, \
Union1FormationEvent, \
Union1DissolutionEvent, \
Union2FormationEvent, \
Union2DissolutionEvent, \
UnionPeriod2Event
The trace report looks like this:
Time Entity Age Id Trace Value Name Remarks
19.198452 Person 19.198452 222 EVENT self_scheduling_split(active_spell_duration(in_union,true),UNION_DURATION)
19.198452 Person 19.198452 222 queued 21.198452 self_scheduling_split(active_spell_duration(in_union,true),UNION_DURATION)
19.198452 Person 19.198452 222 queued 19.944885 Union1DissolutionEvent was 53.059542
The missing event is revealed to be the self-scheduling attribute self_scheduling_split(active_spell_duration(in_union,true),UNION_DURATION)
.
Perusing the RiskPaths code reveals that this self-scheduling attribute is assigned to the identity attribute union_duration
, which is in turn used in the computation of the time of the Union1DissolutionEvent
event.
[back to worked example 1]
[back to topic contents]
This subtopic illustrates tracing attributes. It contains the following sections:
- Attributes with event context
- Attributes without event context
- Find entities using an attribute
- Using the
case_seed
attribute
Worked example 1 suggested that the derived attribute union_duration
played a role in explaining the recomputation of an event time.
Trace that attribute as well as in_union
by turning on attribute tracing with ShowAttributes
, and specifying the attributes to be traced with SelectedAttributes
.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 500
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
MaximumLines = 10000
; filters
SelectedEntities = 222
; events
ShowEnterSimulation = yes
ShowExitSimulation = yes
ShowEvents = yes
; attributes
ShowAttributes = yes
SelectedAttributes = \
in_union, \
union_duration
The trace output looks like this:
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 222 ENTER
0.000000 Person 0.000000 222 attr 0 in_union initial
0.000000 Person 0.000000 222 attr 0 union_duration initial
18.198452 Person 18.198452 222 EVENT Union1FormationEvent
18.198452 Person 18.198452 222 attr 1 in_union was 0
19.198452 Person 19.198452 222 attr 1 union_duration was 0
19.944885 Person 19.944885 222 EVENT Union1DissolutionEvent
19.944885 Person 19.944885 222 attr 0 in_union was 1
19.944885 Person 19.944885 222 attr 0 union_duration was 1
20.010964 Person 20.010964 222 EVENT Union2FormationEvent
20.010964 Person 20.010964 222 attr 1 in_union was 0
20.212818 Person 20.212818 222 EVENT FirstPregEvent
21.010964 Person 21.010964 222 attr 1 union_duration was 0
21.198452 Person 21.198452 222 EVENT UnionPeriod2Event
23.010964 Person 23.010964 222 attr 2 union_duration was 1
25.010964 Person 25.010964 222 attr 3 union_duration was 2
29.010964 Person 29.010964 222 attr 4 union_duration was 3
33.010964 Person 33.010964 222 attr 5 union_duration was 4
100.000000 Person 100.000000 222 EVENT DeathEvent
100.000000 Person 100.000000 222 EXIT
The output shows the the initial values of the attributes when the entity enters the simulation and changes in attributes as the simulation progresses.
The attribute in_union
changes in response to union formation events as expected.
The attribute union_duration
changes with no preceding event message because self-scheduling event messages are blocked with these EventTrace
settings.
[back to worked example 2]
[back to topic contents]
Event messages can be be removed from the output by setting ShowEvents
to off
.
The following settings trace some key attributes of RiskPaths
for a single case.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 500
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
MaximumLines = 10000
; filters
SelectedEntities = 222
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = no
; attributes
ShowAttributes = yes
SelectedAttributes = \
case_seed, \
union_status, \
parity_status, \
union_duration, \
dissolution_duration
The trace output looks like this:
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 222 attr 1214330268 case_seed initial
0.000000 Person 0.000000 222 attr 0 dissolution_duration initial
0.000000 Person 0.000000 222 attr 0 parity_status initial
0.000000 Person 0.000000 222 attr 0 union_duration initial
0.000000 Person 0.000000 222 attr 0 union_status initial
18.198452 Person 18.198452 222 attr 1 union_status was 0
19.198452 Person 19.198452 222 attr 1 union_duration was 0
19.944885 Person 19.944885 222 attr 0 union_duration was 1
19.944885 Person 19.944885 222 attr 3 union_status was 1
20.010964 Person 20.010964 222 attr 4 union_status was 3
20.212818 Person 20.212818 222 attr 1 parity_status was 0
21.010964 Person 21.010964 222 attr 1 union_duration was 0
23.010964 Person 23.010964 222 attr 2 union_duration was 1
25.010964 Person 25.010964 222 attr 3 union_duration was 2
29.010964 Person 29.010964 222 attr 4 union_duration was 3
33.010964 Person 33.010964 222 attr 5 union_duration was 4
[back to worked example 2]
[back to topic contents]
In this example, we use event trace to identify entities which were pregnant during a second union, and output a detailed history of the oldest.
First, we add the new attribute my_filter
to RiskPaths
by editing Fertility.mpp
and adding the following lines:
actor Person
{
//EN Pregnant in second union
bool my_filter = (parity_status == PS_PREGNANT) && (union_status == US_SECOND_UNION);
};
and rebuild RiskPaths
.
Next we set event trace options to block all messages except attribute messages for my_filter
which have the value true
.
In C++ true
has the value 1 and false
has the value 0.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 500
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
MaximumLines = 10000
; filters
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = no
; attributes
ShowAttributes = yes
SelectedAttributes = my_filter
MinimumAttribute = 1
MaximumAttribute = 1
The output is:
Time Entity Age Id Trace Value Name Remarks
26.196550 Person 26.196550 65 attr 1 my_filter was 0
26.395338 Person 26.395338 94 attr 1 my_filter was 0
24.133799 Person 24.133799 211 attr 1 my_filter was 0
20.212818 Person 20.212818 222 attr 1 my_filter was 0
33.073613 Person 33.073613 279 attr 1 my_filter was 0
32.492563 Person 32.492563 479 attr 1 my_filter was 0
23.148798 Person 23.148798 481 attr 1 my_filter was 0
The output displays the 7 entities among the 500 which satisfied the condition during their lifetime.
The Id
column shows the entity_id
of each, and the Age
column shows the age at which the condition first become true.
Among the 7, the oldest was entity_id
279.
The following settings probe the lifetime of that entity in more detail:
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 500
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
MaximumLines = 10000
; filters
SelectedEntities = 279
; events
ShowEnterSimulation = yes
ShowExitSimulation = yes
ShowEvents = yes
The output is
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 279 ENTER initial time=0.000000,age=0.000000
27.167907 Person 27.167907 279 EVENT Union1FormationEvent
29.155224 Person 29.155224 279 EVENT Union1DissolutionEvent
30.167907 Person 30.167907 279 EVENT UnionPeriod2Event
32.105193 Person 32.105193 279 EVENT Union2FormationEvent
33.073613 Person 33.073613 279 EVENT FirstPregEvent
100.000000 Person 100.000000 279 EVENT DeathEvent
100.000000 Person 100.000000 279 EXIT
[back to worked example 2]
[back to topic contents]
The example Attributes without event context above traced case_seed
, which is a built-in attribute of a case-based model.
Case seeds of interest can also be obtained from aggregate output tables using an expression like max_value_out(case_seed)
to identify the seed of a case for each populated cell of a table.
case_seed
can be useful to speed exploration of a specific case in a case-based model by arranging that a run simulate only that single case.
The following settings set the parameter SimulationSeed
to 1214330268 from the previous trace output.
The number of cases is also reduced from 500 to 1, for a very fast run.
The SelectedEntities
filter was removed.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 1
SimulationSeed = 1214330268
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
MaximumLines = 10000
; filters
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = no
; attributes
ShowAttributes = yes
SelectedAttributes = \
case_seed, \
union_status, \
parity_status, \
union_duration, \
dissolution_duration
With these settings, the trace file looks like this:
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 1 attr 1214330268 case_seed initial
0.000000 Person 0.000000 1 attr 0 dissolution_duration initial
0.000000 Person 0.000000 1 attr 0 parity_status initial
0.000000 Person 0.000000 1 attr 0 union_duration initial
0.000000 Person 0.000000 1 attr 0 union_status initial
18.198452 Person 18.198452 1 attr 1 union_status was 0
19.198452 Person 19.198452 1 attr 1 union_duration was 0
19.944885 Person 19.944885 1 attr 0 union_duration was 1
19.944885 Person 19.944885 1 attr 3 union_status was 1
20.010964 Person 20.010964 1 attr 4 union_status was 3
20.212818 Person 20.212818 1 attr 1 parity_status was 0
21.010964 Person 21.010964 1 attr 1 union_duration was 0
23.010964 Person 23.010964 1 attr 2 union_duration was 1
25.010964 Person 25.010964 1 attr 3 union_duration was 2
29.010964 Person 29.010964 1 attr 4 union_duration was 3
33.010964 Person 33.010964 1 attr 5 union_duration was 4
The trace output (and simulation) is identical to the previous output except for the Id
column, which changed from 222 to 1.
The Id
column shows the entity_id
of the entity which produced the message.
In a case-based model, entity_id
is a unique sequentially increasing counter for entities in the run.
Case-based models which construct cases by reading a file of microdata may not be able to reproduce a case of interest using this technique.
OzProj
in the OpenM++ distribution is an example.
Such models can filter on one or more case seeds directly using SelectedCaseSeeds
, as in the following example.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 500
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
MaximumLines = 10000
; filters
SelectedCaseSeeds = 1214330268
; events
ShowEnterSimulation = no
ShowExitSimulation = no
ShowEvents = no
; attributes
ShowAttributes = yes
SelectedAttributes = \
case_seed, \
union_status, \
parity_status, \
union_duration, \
dissolution_duration
With these options, the output is as before.
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 222 attr 1214330268 case_seed initial
0.000000 Person 0.000000 222 attr 0 dissolution_duration initial
0.000000 Person 0.000000 222 attr 0 parity_status initial
0.000000 Person 0.000000 222 attr 0 union_duration initial
0.000000 Person 0.000000 222 attr 0 union_status initial
18.198452 Person 18.198452 222 attr 1 union_status was 0
19.198452 Person 19.198452 222 attr 1 union_duration was 0
19.944885 Person 19.944885 222 attr 0 union_duration was 1
19.944885 Person 19.944885 222 attr 3 union_status was 1
20.010964 Person 20.010964 222 attr 4 union_status was 3
20.212818 Person 20.212818 222 attr 1 parity_status was 0
21.010964 Person 21.010964 222 attr 1 union_duration was 0
23.010964 Person 23.010964 222 attr 2 union_duration was 1
25.010964 Person 25.010964 222 attr 3 union_duration was 2
29.010964 Person 29.010964 222 attr 4 union_duration was 3
33.010964 Person 33.010964 222 attr 5 union_duration was 4
If a case-based model is designed to generate multiple cloned entities within a case,
SelectedCaseSeeds
can be helpful to probe all clones within a case.
[back to worked example 2]
[back to topic contents]
This subtopic illustrates tracing link attributes and multilinks. It contains the following sections:
This section uses the Alpha2
model, which is part of the OpenM++ distribution.
To make Alpha2
capable of event trace, the statement
options event_trace = on;
was added to the model source module ompp_framework.ompp
,
and a default ini
file Alpha2.ini
added to the model bin
folder, as described in Quick start.
Also as described in Quick start, the model command line arguments were set to
-ini Alpha2.ini -OpenM.IniAnyKey true
Alpha2
has several different kinds of entities, two of which are Person
and Thing
.
A one-to-one link between a Person
and a Thing
is declared in the model source statement
link Person.my_thing1 Thing.my_person1;
which declares the link attribute my_thing1
in Person
and the reciprocal link my_person1
in Thing
.
Both Person
and Thing
have an event named MortalityEvent
.
Person
has a SpawnEvent
which occurs immediately after a Person
enters the simulation and which creates other entities.
The following run settings in Alpha2.ini
trace selected events and attributes for entities 1 and 2.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 1
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
; filters
SelectedEntities = 1,2
; events
ShowEnterSimulation = yes
ShowExitSimulation = yes
ShowEvents = yes
SelectedEvents = \
SpawnEvent, \
MortalityEvent
; attributes
ShowAttributes = yes
SelectedAttributes = \
my_thing1, \
my_person1
The resulting trace output looks like this:
The answer is 42!
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 1 ENTER
0.000000 Person 0.000000 1 link nullptr my_thing1 initial
0.000000 Person 0.000000 1 EVENT SpawnEvent
0.000000 Thing 0.000000 2 ENTER
0.000000 Thing 0.000000 2 link nullptr my_person1 initial
0.000000 Person 0.000000 1 link 2 my_thing1 was nullptr
0.000000 Thing 0.000000 2 link 1 my_person1 was nullptr
48.288955 Person 48.288955 1 EVENT MortalityEvent
48.288955 Person 48.288955 1 EXIT
48.288955 Thing 48.288955 2 link nullptr my_person1 was 1
117.760965 Thing 117.760965 2 EVENT MortalityEvent
117.760965 Thing 117.760965 2 EXIT
The first line in the trace output is produced by model code in Alpha2
which tests the trace file API.
It is irrelevant to this example, but does illustrate that the trace file can contain output from model code, not just from event trace.
The kind of entity (Person
or Thing
) is shown in the Entity
column and the entity_id
which produced the message is shown in the Id
column.
MortalityEvent
is actually two different events with the same name, one in Person
and one in Thing
.
SpawnEvent
in Person
1 creates a Thing
(entity_id
2) and links to it through the link attribute my_thing1
.
Here's the corresponding model code extract:
void Person::SpawnEvent()
{
// Create things and add to simulation
Thing *thing1 = new Thing;
thing1->Start();
// Link Person to thing1
my_thing1 = thing1;
...
When MortalityEvent
causes Person
1 to exit the simulation, all its links are automatically emptied.
That causes the link my_person1
in Thing
2 to become nullptr
as shown in the trace output above.
[back to worked example 3]
[back to topic contents]
In Alpha2
each Person
can have more than one Thing
.
The relationship is declared in the one-to-many link
statement in model code
link Thing.spawner Person.things[];
which associates the link attribute spawner
in Thing
to the Person
that spawned the Thing
.
A Person
has a reciprocal multilink things
which contains all the Thing
entities it spawned.
The following model code extract adds two Thing
entities to the things
multilink:
void Person::SpawnEvent()
{
// Create things and add to simulation
Thing *thing1 = new Thing;
thing1->Start();
Thing *thing2 = new Thing;
thing2->Start();
// populate multi-link of things
things->Add(thing1);
things->Add(thing2);
...
}
The statement things->Add(thing1);
automatically assigns the reciprocal spawner
attribute in Thing
to the Person
entity.
The following run settings explore the multilink things
and the reciprocal spawner
link attribute.
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 1
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
; filters
SelectedEntities = 1,2,13
; events
ShowEnterSimulation = yes
ShowExitSimulation = yes
ShowEvents = yes
SelectedEvents = \
SpawnEvent, \
MortalityEvent
; attributes
ShowAttributes = yes
SelectedAttributes = \
spawner, \
things
The resulting trace output is:
The answer is 42!
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 1 ENTER
0.000000 Person 0.000000 1 multi things initial {}
0.000000 Person 0.000000 1 EVENT SpawnEvent
0.000000 Thing 0.000000 2 ENTER
0.000000 Thing 0.000000 2 link nullptr spawner initial
0.000000 Thing 0.000000 13 ENTER
0.000000 Thing 0.000000 13 link nullptr spawner initial
0.000000 Person 0.000000 1 multi++ 2 things is {2}
0.000000 Thing 0.000000 2 link 1 spawner was nullptr
0.000000 Person 0.000000 1 multi++ 13 things is {2,13}
0.000000 Thing 0.000000 13 link 1 spawner was nullptr
48.288955 Person 48.288955 1 EVENT MortalityEvent
48.288955 Person 48.288955 1 EXIT
48.288955 Thing 48.288955 2 link nullptr spawner was 1
48.288955 Thing 48.288955 13 link nullptr spawner was 1
117.760965 Thing 117.760965 2 EVENT MortalityEvent
117.760965 Thing 117.760965 2 EXIT
144.675208 Thing 144.675208 13 EVENT MortalityEvent
144.675208 Thing 144.675208 13 EXIT
Each trace message for the things
multilink shows the current contents of the multilink in the Remarks
column.
The initial value of things
is empty, and multi++
in the Trace
column notes when an entity is added to the multilink.
There are no multi--
messages in this example, because the two Thing
entities happened to outlive the Person
entity.
The spawner
link attribute in each Thing
was set automatically to nullptr
when the Person
exited the simulation during age 48.
Incidentally, the second Thing
has entity_id
13 because each Thing
spawns 10 Toy
entities, but that's another story!
[back to worked example 3]
[back to topic contents]
This example uses the option SelectLinkedEntities
to automatically select entities added through a link or multilink to an active selected entity.
The following settings set selected entities to the single entity with 'entity_id' 1.
[OpenM]
TraceToFile = true
ProgressPercent = 25
[Parameter]
SimulationCases = 1
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
; filters
SelectedEntities = 1
SelectLinkedEntities = yes
; events
ShowEnterSimulation = yes
ShowExitSimulation = yes
ShowEvents = yes
SelectedEvents = \
SpawnEvent, \
MortalityEvent
The trace output is
The answer is 42!
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 1 ENTER
0.000000 Person 0.000000 1 EVENT SpawnEvent
0.000000 Person 0.000000 1 selected++ 2 my_thing1
0.000000 Person 0.000000 1 selected++ 13 my_thing2
48.288955 Person 48.288955 1 EVENT MortalityEvent
48.288955 Person 48.288955 1 EXIT
117.760965 Thing 117.760965 2 EVENT MortalityEvent
117.760965 Thing 117.760965 2 EXIT
144.675208 Thing 144.675208 13 EVENT MortalityEvent
144.675208 Thing 144.675208 13 EXIT
The messages with selected++
in the Trace
column show two entities 2 and 13 added to the set of selected entities.
Subsequent messages include contributions from the three entities 1,2, and 13.
Had entity 2 or 3 added links to other entities during the simulation, the set of selected entities would have been expanded to include them, too.
[back to worked example 3]
[back to topic contents]
This worked example illustrates Event Trace options which show RiskPaths
pushing table increments to accumulators for the entity table T06_BirthsByUnion
.
Generally, model developers don't need to probe the low-level mechanics of entity tabulation in OpenM++,
but it can sometimes be useful.
Here's the declaration of that table:
table Person T06_BirthsByUnion //EN Pregnancies by union status & order
[trigger_entrances(parity_status, PS_PREGNANT)]
{
{
unit //EN Number of pregnancies
}
* union_status+ //EN Union Status at pregnancy
};
With a 5,000 case run, that table looks like this:
Union Status at pregnancy | Number of pregnancies |
---|---|
Never in union | 1,285 |
First union < 3 years | 2,986 |
First Union > 3 years | 293 |
After first union | 11 |
Second union | 57 |
After second union | 1 |
All | 4,633 |
When analyzing table increments, it's generally best to restrict the table to a single entity of interest, because otherwise the output may be too voluminous to be useful.
Here's what that table looks like in a run with only 1 case:
Union Status at pregnancy | Number of pregnancies |
---|---|
Never in union | 0 |
First union < 3 years | 1 |
First Union > 3 years | 0 |
After first union | 0 |
Second union | 0 |
After second union | 0 |
All | 1 |
The table shows that the one Person
in the run had a single pregnancy
which occurred in the first 3 years of the first union.
The marginal total over all union_status
categories is necessarily also 1.
The following run settings trace events,
increments to this table,
and changes to the two attributes parity_status
and union_status
used in the table declaration:
[OpenM]
TraceToFile = true
[Parameter]
SimulationCases = 1
[EventTrace]
ReportStyle = readable
NameColumnWidth = 25
MaximumLines = 20000
ShowEnterSimulation = yes
ShowExitSimulation = yes
ShowAttributes = yes
SelectedAttributes = parity_status, union_status
ShowEvents = yes
ShowTableIncrements = yes
SelectedTables = T06_BirthsByUnion
With these settings, the trace output looks like this:
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 1 ENTER
0.000000 Person 0.000000 1 attr 0 parity_status initial
0.000000 Person 0.000000 1 attr 0 union_status initial
24.260999 Person 24.260999 1 EVENT Union1FormationEvent
24.260999 Person 24.260999 1 attr 1 union_status was 0
26.537813 Person 26.537813 1 EVENT FirstPregEvent
26.537813 Person 26.537813 1 attr 1 parity_status was 0
27.260999 Person 27.260999 1 EVENT UnionPeriod2Event
27.260999 Person 27.260999 1 INCREMENT 1 T06_BirthsByUnion.acc0 cell=[1] accumulator=1
27.260999 Person 27.260999 1 INCREMENT 1 T06_BirthsByUnion.acc0 cell=[6] accumulator=1
27.260999 Person 27.260999 1 attr 2 union_status was 1
100.000000 Person 100.000000 1 EVENT DeathEvent
100.000000 Person 100.000000 1 EXIT
The trace output is coherent with the table shown above:
The Person
experienced a FirstPregEvent
at age 26.537813
,
when union_status
was at its second level First union < 3 years
(which has integer value 1).
The event trace shows two INCREMENT
lines.
The first pushes an increment with value 1 to cell [1]
of the table,
which is correct (index [1]
is the second cell, corresponding to First union < 3 years
).
The second pushes the same increment to cell [6]
of the table.
That's correct because [6]
is the margin index for the table dimension.
An increment is always pushed to the body and to all margin dimensions,
and to all crossings of margin dimensions.
For example, if a table has two dimensions and both have a margin,
an increment will be pushed to 4 cells:
one for the table body, one for each margin, and one for the crossed margins.
The INCREMENT
lines above are correct, but their timing in the Person
timeline may be puzzling.
That's because by design a table increment is pushed to an accumulator ‘lazily’.
The push happens only when an upcoming attribute change would invalidate the pending increment.
Pushes can also happen when the entity exits the simulation.
So, an increment may appear in the timeline later than might be expected.
You can see that in action in the event trace output above when an upcoming change
to union_status
at time 27.260999
causes the pending increment
to be pushed immediately before union_status
changes.
That increment was originally created when the table filter flashed true
at time 26.537813
when the pregnancy occurred.
Table increments are 'lazy' to ensure that changes in multiple classificatory dimensions and/or filter settle down before being treated as a single finalized and coherent table increment.
For INCREMENT
rows, the Value column is the value of the increment being pushed to an accumulator (always 1 in this example because ‘unit’).
There are two increments shown, one is for the body of the table, the other for the margin.
Each cell of a table has an accumulator (more than one if table expressions use multiple accumulators).
The cell indices of the increment/accumulator are shown in the Remarks column, as is the value of the accumulator after the increment (from all cases so far in the sub).
The two accumulators shown in the trace output are both 1 because the run had no other cases.
A model built with event trace capability can be run repeatedly with different trace options with no need to rebuild.
Event trace works with Release versions of models, so can be used to probe details in large simulations.
Event trace is intended for model development, not production. A model built with event trace will output the following warning to the log whenever it is run:
Warning : possible performance impact - model built with event_trace = on
A model built with event trace will also output the following warning to the log whenever it is run:
Warning : model can expose microdata at run-time with event_trace = on
If this is not a concern, for example the model generates a synthetic population, this warning can be disabled by the following statement:
options event_trace_warning = off;
Some entity attributes are created by the OpenM++ compiler to implement model functionality. For example, if an entity table has a filter, an identity attribute is created to implement it. These internal generated attributes are normally hidden but they can be made visible by the following statement:
options all_attributes_visible = on;
An event trace message can only be produced by an active entity. Event trace messages are not produced before the entity enters the simulation or after the entity exits the simulation.
Event trace messages are produced directly and immediately as model code executes.
The messages are output to the trace file if EventTrace
filter conditions are met.
For example, if an attribute is selected, an event trace message will be produced immediately whenever the valus changes.
If the attribute is changed more than once during the implementation of an event, each change will produce a separate message.
Trace output is disabled by default when a model is run.
Use OpenM.TraceToFile
to enable it, e.g.
[OpenM]
TraceToFile = true
See the subtopic Trace file options for a complete listing of trace file options.
Event trace options are processed only if the model is run with the command line option -OpenM.IniAnyKey true
.
Unlike other options, OpenM.IniAnyKey
must be specified on the command line, not in an ini
file.
To avoid confusing output, event trace should be used in runs with a single sub/replicate/member.
A model can write lines to the trace file directly, in which case those lines will be interleaved with any event trace messages.
Each event trace message has up to 8 columns of information.
Values for Time
, Entity
, Age
, Id
, and Trace
are always present.
Values for Value
, Name
, and Remarks
may be absent, depending on the nature of the message.
The order, left- or right-justification, capitalization, and indentation of columns varies by message to help peruse voluminous output for salient features.
Column | Column header | Description |
---|---|---|
1 | Time | The time of the entity when it produced the message. |
2 | Entity | The type of entity which produced the message, e.g. Person . |
3 | Age | The age of the entity when it produced the message. |
4 | Id | The entity_id of the entity which produced the message. |
5 | Trace | The kind of message, e.g. EVENT is a message for event occurrence. See Event trace messages for all possible values. |
6 | Value | A value associated with the message, e.g. the current value of an attribute. |
7 | Name | A name associated with the message, e.g. the name of the event or attribute. |
8 | Remarks | Supplementary information, e.g. the value of the attribute before it changed, or the contents of a multilink |
If ReportStyle
is csv
, an additional leading column Line
is present.
For more information, see Event trace options - format.
The following table lists all possible kinds of event trace message. Values noted as 'initial' are those when the entity first enters the simulation before it experiences any events. The initial value of time does not necessarily correspond to the global time when the message was produced.
Kind of message | Trace (5) | Value (6) | Name (7) | Remarks (8) |
---|---|---|---|---|
Entity enters simulation | ENTER |
|||
Entity exits simulation | EXIT |
|||
Event occurrence | EVENT |
event name | ||
Event future time | queued |
The future time | event name | The previous value of the future event time. |
Attribute - initial | attr |
The initial value | attribute name | |
Attribute - change | attr |
The current value | attribute name | The previous value of the attribute. |
Link - initial | link |
The entity_id or nullptr
|
link name | |
Link - change | link |
The entity_id or nullptr
|
link name | The previous value of the link. |
Multilink - initial | multi |
multilink name | A list of all entities in the multilink. | |
Multilink - add | multi++ |
The entity_id of the added entity |
multilink name | A list of all entities in the multilink. |
Multilink - remove | multi-- |
The entity_id of the removed entity |
multilink name | A list of all entities in the multilink. |
Entity added to list of selected entities | selected++ |
The entity_id of the added entity |
link or multilink name | |
Table increment pushed to accumulator | INCREMENT |
The value of the increment | table name and accumulator # | The table cell indices of the accumulator to which the increment was pushed, and the updated value of the accumulator. |
[back to topic contents] |
Event trace options fall into five broad categories which are described in the following sections.
-
Format
ReportStyle
,MaximumLines
,NameColumnWidth
- Filters Block/pass messages based on entity characteristics
- Events Block/pass messages on events and entity life cycle
- Attributes Block/pass messages on attribute changes
- Increments Block/pass messages on push table increment to accumulator
For reference, here is an extract of a model run .ini
file with all event trace options:
;#============================================================================
;#
;# event trace model development options
;#
;# Requires activation of model development options using -OpenM.IniAnyKey (see above).
;# Requires that model code contains the statement
;# options event_trace = on;
;# Requires OpenM.TraceToFile = true
;#
;# See wiki for explanation of EventTrace options
;
; [EventTrace]
;
; format
;
; ReportStyle = readable ; "modgen", "readable", or "csv", default: modgen
; MaximumLines = 100000 ; integer value, default: 20000
; NameColumnWidth = 20 ; integer value, default: 40
;
; filters
;
; SelectedEntityKinds = e1,e2,e3 ; comma separated list of entity kinds, if empty all entity kinds
; SelectedEntities = 1,2,3 ; comma separated list of integers, if empty all entities
; SelectLinkedEntities = no ; default: no
; SelectedCaseSeeds = 1,2,3 ; comma separated list of case seeds, if empty all cases
; MinimumTime = 2025 ; double value, default: -inf
; MaximumTime = 2025 ; double value, default: +inf
; MinimumAge = 65 ; double value, default: -inf
; MaximumAge = 66 ; double value, default: +inf
;
; events
;
; ShowEnterSimulation = yes ; default: yes
; ShowExitSimulation = yes ; default: yes
; ShowEvents = yes ; default: yes
; SelectedEvents = e1,e2,e3 ; comma separated list of event names, if empty all events
; ShowQueuedEvents = no ; default: no
; ShowQueuedUnchanged = no ; default: no
; ShowSelfSchedulingEvents = no ; default: no
; ShowQueuedSelfSchedulingEvents = no ; default: no
;
; attributes
;
; ShowAttributes = no ; default: no
; SelectedAttributes = year,alive ; comma separated list of attribute names, if empty all attributes
; MinimumAttribute = 1 ; double value, default: -inf
; MaximumAttribute = 1 ; double value, default: +inf
;
; table increments
;
; ShowTableIncrements = no ; default: no
; SelectedTables = t1,t2,t3 ; comma separated list of table names, if empty all tables
Option | Type | Default | Description |
---|---|---|---|
ReportStyle | string | modgen |
One of readable , csv , or modgen (see below in this section). |
MaximumLines | integer | 20000 | Blocks messages if the line count exceeds this value. A final message is written to the trace. |
NameColumnWidth | integer | 40 | The width of the Name column (column 7) in message output. |
The ReportStyle
option specifies the content and format of trace output.
It can be readable
, csv
, or modgen
.
For compatibility for x-compatible models, the default value is modgen
.
The examples earlier in this topic illustrate the readable
style.
The csv
style has almost the same content and layout as the readable
style,
except transformed into csv
format for use by downstream applications such as Excel.
The csv
style contains an additional leading column Line
which contains the original line number.
This can be useful as a secondary sort key to disambiguate the order of otherwise tied records.
In the example below, lines 8 and 9 have identical Time
but Line
indicates the order in which the two attributes changed value.
The exact order can be particularly important if events have tied times, or if an attribute changes value more than once at a given time.
In csv
format some columns may have additional numeric precision compared to readable
format.
The trace file name extension can be changed from the default .txt
to .csv
using the OpenM.TraceFilePath
model run option, e.g. in a run ini
file. See Trace file options.
Here is the output for the previous example Attributes with event context
using ReportStyle = csv
:
Line,Time,Entity,Age,Id,Trace,Value,Name,Remarks
1,0,"Person",0,222,"ENTER",,,
2,0,"Person",0,222,"attr",0,"in_union","initial"
3,0,"Person",0,222,"attr",0,"union_duration","initial"
4,18.19845239664,"Person",18.19845239664,222,"EVENT",,"Union1FormationEvent",
5,18.19845239664,"Person",18.19845239664,222,"attr",1,"in_union","was 0"
6,19.19845239664,"Person",19.19845239664,222,"attr",1,"union_duration","was 0"
7,19.94488519046,"Person",19.94488519046,222,"EVENT",,"Union1DissolutionEvent",
8,19.94488519046,"Person",19.94488519046,222,"attr",0,"in_union","was 1"
9,19.94488519046,"Person",19.94488519046,222,"attr",0,"union_duration","was 1"
10,20.01096416538,"Person",20.01096416538,222,"EVENT",,"Union2FormationEvent",
11,20.01096416538,"Person",20.01096416538,222,"attr",1,"in_union","was 0"
12,20.21281842274,"Person",20.21281842274,222,"EVENT",,"FirstPregEvent",
13,21.01096416538,"Person",21.01096416538,222,"attr",1,"union_duration","was 0"
14,21.19845239664,"Person",21.19845239664,222,"EVENT",,"UnionPeriod2Event",
15,23.01096416538,"Person",23.01096416538,222,"attr",2,"union_duration","was 1"
16,25.01096416538,"Person",25.01096416538,222,"attr",3,"union_duration","was 2"
17,29.01096416538,"Person",29.01096416538,222,"attr",4,"union_duration","was 3"
18,33.01096416538,"Person",33.01096416538,222,"attr",5,"union_duration","was 4"
19,100,"Person",100,222,"EVENT",,"DeathEvent",
20,100,"Person",100,222,"EXIT",,,
Here is the same output, displayed in a table as it might look in Excel:
Line | Time | Entity | Age | Id | Trace | Value | Name | Remarks |
---|---|---|---|---|---|---|---|---|
1 | 0 | Person | 0 | 222 | ENTER | |||
2 | 0 | Person | 0 | 222 | attr | 0 | in_union | initial |
3 | 0 | Person | 0 | 222 | attr | 0 | union_duration | initial |
4 | 18.19845239664 | Person | 18.19845239664 | 222 | EVENT | Union1FormationEvent | ||
5 | 18.19845239664 | Person | 18.19845239664 | 222 | attr | 1 | in_union | was 0 |
6 | 19.19845239664 | Person | 19.19845239664 | 222 | attr | 1 | union_duration | was 0 |
7 | 19.94488519046 | Person | 19.94488519046 | 222 | EVENT | Union1DissolutionEvent | ||
8 | 19.94488519046 | Person | 19.94488519046 | 222 | attr | 0 | in_union | was 1 |
9 | 19.94488519046 | Person | 19.94488519046 | 222 | attr | 0 | union_duration | was 1 |
10 | 20.01096416538 | Person | 20.01096416538 | 222 | EVENT | Union2FormationEvent | ||
11 | 20.01096416538 | Person | 20.01096416538 | 222 | attr | 1 | in_union | was 0 |
12 | 20.21281842274 | Person | 20.21281842274 | 222 | EVENT | FirstPregEvent | ||
13 | 21.01096416538 | Person | 21.01096416538 | 222 | attr | 1 | union_duration | was 0 |
14 | 21.19845239664 | Person | 21.19845239664 | 222 | EVENT | UnionPeriod2Event | ||
15 | 23.01096416538 | Person | 23.01096416538 | 222 | attr | 2 | union_duration | was 1 |
16 | 25.01096416538 | Person | 25.01096416538 | 222 | attr | 3 | union_duration | was 2 |
17 | 29.01096416538 | Person | 29.01096416538 | 222 | attr | 4 | union_duration | was 3 |
18 | 33.01096416538 | Person | 33.01096416538 | 222 | attr | 5 | union_duration | was 4 |
19 | 100 | Person | 100 | 222 | EVENT | DeathEvent | ||
20 | 100 | Person | 100 | 222 | EXIT |
The modgen
output style looks like this:
Person - actor_id=1 - case_seed=1 - : event=timeDeathEvent - time=100.000000000000000
Person - actor_id=1 - case_seed=1 - : event=timeFirstPregEvent - time=inf
Person - actor_id=1 - case_seed=1 - : event=timeUnion1DissolutionEvent - time=inf
Person - actor_id=1 - case_seed=1 - : event=timeUnion1FormationEvent - time=inf
Person - actor_id=1 - case_seed=1 - : event=timeUnion2DissolutionEvent - time=inf
Person - actor_id=1 - case_seed=1 - : event=timeUnion2FormationEvent - time=inf
Person - actor_id=1 - case_seed=1 - : event=timeUnionPeriod2Event - time=inf
Person - actor_id=1 - case_seed=1 - : event=scheduled - 0 - time=1.000000000000000
Person - actor_id=1 - case_seed=1 - : event=timeDeathEvent - time=100.000000000000000
Person - actor_id=1 - case_seed=1 - : event=scheduled - 0 - time=2.000000000000000
Person - actor_id=1 - case_seed=1 - : event=timeDeathEvent - time=100.000000000000000
...
The modgen
report style allows detailed comparison of modgen and ompp versions of a x-compatible model.
The Test Models utility rearranges, reformats, and normalizes modgen
style of event trace output of both Modgen and OpenM++ versions of a model to improve comparability and help understand differences.
[back to event trace options]
[back to topic contents]
Filter options pass or block any kind of event trace message based on the characteristics of the entity when it produced the message.
Option | Type | Default | Description |
---|---|---|---|
SelectedEntityKinds | comma separated list | empty | Block any message if entity kind (e.g. Person ) not in this list (unless list is empty). |
SelectedEntities | comma separated list | empty | Block any message if entity not in this list (unless list is empty). |
SelectLinkedEntities | yes/no | no | An active entity in SelectedEntities will add new linked entities to SelectedEntities . |
SelectedCaseSeeds | comma separated list | empty | Block any message if case seed not in this list (unless list is empty). |
MinimumTime | floating point number | -inf | Block any message if global time < this. |
MaximumTime | floating point number | +inf | Block any message if global time > this. |
MinimumAge | floating point number | -inf | Block any message if entity age < this. |
MaximumAge | floating point number | +inf | Block any message if entity age > this. |
For examples, see Worked example 1 Using filters
[back to event trace options]
[back to topic contents]
Event options pass or block specific kinds of message associated with entity lifecycle and events.
Option | Type | Default | Description |
---|---|---|---|
ShowEnterSimulation | yes/no | yes | Pass/block entity entrance message. |
ShowExitSimulation | yes/no | yes | Pass/block entity exit message. |
ShowEvents | yes/no | yes | Pass/block event occurrence message. |
SelectedEvents | comma separated list | empty | Block event message if event not in this list (unless list is empty). |
ShowQueuedEvents | yes/no | no | Pass/block event time message. |
ShowQueuedUnchanged | yes/no | no | Pass/block event time message if future time did not change. |
ShowSelfSchedulingEvents | yes/no | no | Pass/block self-scheduling event occurrence message. |
ShowQueuedSelfSchedulingEvents | yes/no | no | Pass/block self-scheduling event time message. |
An entity produces a message when it recalculates the future scheduled time of an event.
However, the default setting ShowQueuedUnchanged = no
blocks the message if the recalculated future scheduled time did not change.
For examples, see Worked example 1 Using filters
[back to event trace options]
[back to topic contents]
Attribute options pass or block messages for attributes, links, and multilinks. An entity produces a message for an attribute when it enters the simulation and whenever the attribute changes.
Option | Type | Default | Description |
---|---|---|---|
ShowAttributes | yes/no | no | Pass/block attribute message |
SelectedAttributes | comma separated list | empty | Block attribute message if attribute not in this list (unless list is empty). |
MinimumAttribute | floating point number | -inf | Block attribute message if attribute value < this. |
MaximumAttribute | floating point number | +inf | Block attribute message if attribute value > this value. |
If SelectedAttributes
is not specified, all attribute messages are passed, including for attributes created by the OpenM++ compiler.
MinimumAttribute
and MaximumAttribute
apply only to normal numerical attributes, not links or multilinks.
The value of an attribute of type bool
is 0 for false
and 1 for true
.
The value of an attribute of type classification or partition is {0,1,2,...}
.
For examples, see
Worked example 2 Tracing attributes
Worked example 3 Tracing links and multilinks
[back to event trace options]
[back to topic contents]
Table increment options pass or block messages related to pushing table increments to accumulators. An entity produces a table increment message whenever it pushes a completed increment to an accumulator.
Option | Type | Default | Description |
---|---|---|---|
ShowTableIncrements | yes/no | no | Pass/block push increment message |
SelectedTables | comma separated list | empty | Block table increment message if table not in this list (unless list is empty). |
If SelectedTables
is not specified, all push increment messages are passed.
For an example, see Worked example 4.
[back to event trace options]
[back to topic contents]
A number of OpenM
options control if, how, and where the trace file is produced.
The following is extracted from OM_ROOT/props/model/Model-example.ini
.
;# trace settings:
;# trace can be enabled/disabled for 3 independent streams:
;# console - cout stream
;# "last run" file - trace file with specified name, overwritten on every model run
;# "stamped" file - trace file with unique name, created for every model run
;#
;# "stamped" name produced from "last run" name by adding time-stamp and/or pid-stamp, i.e.:
;# trace.txt => trace.2012_08_17_16_04_59_148.987654.txt
;#
;# If trace to file is enabled
;# then existing "last run" trace file is overwritten even if model does not write anything to trace output
;
; TraceToConsole = false ; trace to console, default false
; TraceToFile = false ; trace to file
; TraceToStampedFile = false ; trace to "stamped" file
; TraceFilePath = trace.txt ; trace file path, default: current/dir/modelExeName.trace.txt
; TraceUseTimeStamp = false ; use time-stamp in trace "stamped" file name
; TraceUsePidStamp = false ; use pid-stamp in trace "stamped" file name
; TraceNoMsgTime = true ; if true then do not prefix trace messages with date-time
; TraceRank = false ; if true then prefix trace messages with MPI process rank
Trace output can be toggled off or on from model code provided the model was built with event trace capability. The API consists of the two functions
void StartEventTrace(void);
void StopEventTrace(void);
This can be helpful in situations where the filtering functionality described in this topic is insufficient.
For example, a rare condition in model code can be used to toggle event trace on to identify entities which experienced the condition for further exploration.
Event trace is on at the beginning of a run, so an initial call to StopEventTrace
at the beginning of a run (or case) is required for a subsequent call to StartEventTrace
to have an effect.