-
Notifications
You must be signed in to change notification settings - Fork 0
Entity Tables
Home > Model Development Topics > Entity Tables
This topic describes entity tables in depth. This topic is under construction and consists mostly of stub subtopics.
- Introduction and concepts
- Snapshot tables
- Duration tables
- Increments
- Accumulators
- Shorthand
- Increment Validity Increment validity
- Operators
Content to follow. Topic outline is incomplete. The only complete subtopic is Increment Validity.
Entity tables are computed for each sub,
and run-level results computed from the sub-level results.
Several methods are available to compute run-level results
through the measures_method
option, as follows:
measures_method |
Description of run result |
---|---|
average |
Measures are averaged across subs. ex #1: measure count run: AVG(count) ex #2: measure income run: AVG(income) ex #3: measure: income/count run: AVG(income/count)
|
aggregate |
accumulators are averaged over subs, then the measure calculated using those. ex #1: measure: count run: AVG(count) ex #2: measure: income run: AVG(income) ex #3: measure: income/count run: AVG(income)/(AVG(count)
|
assemble |
accumulators are summed over subs, and the measure computed using those ex #1: measure: count run: SUM(count) ex #2: measure: income run: SUM(income) ex #2: measure: income/count run: SUM(income)/SUM(count)
|
In these examples, income
and count
are sums which vary over subs,
and the run result shows the operations performed on those subs to produce the run result.
An increment is based on the value of an attribute when an entity enters a table cell and the value when it exits the cell.
An entity enters a table cell at simulation entry or when the table filter becomes true
.
An entity leaves a table cell at simulation exit or when the table filter becomes false
.
An entity changes cell when attributes used in the classification dimensions of the table change value.
Keyword | Description |
---|---|
value_in | The attribute value when the entity enters the table cell. |
value_out | The attribute value when the entity leaves the table cell. |
delta | The difference in the attribute value between cell exit and cell entrance. |
nz_value_in | The non-zero count of attribute value on entrance. |
nz_value_out | The non-zero count of attribute value on exit. |
nz_delta | The non-zero count of the difference in value between exit and entrance. |
value_in2 | The square of the value on entrance. |
value_out2 | The square of the value on exit. |
delta2 | The square of the difference in value between exit and entrance. |
Keyword | Description |
---|---|
unit | |
sum | |
minimum | |
maximum | |
gini | |
P1 | |
P2 | |
P5 | |
P10 | |
P20 | |
P25 | |
P30 | |
P40 | |
P50 | median |
P60 | |
P70 | |
P75 | |
P80 | |
P90 | |
P95 | |
P98 | |
P99 |
These keywords are a more compact way of specifying commonly-used combinations of increments and accumulators.
Keyword | Equivalent |
---|---|
delta(x) | sum(delta(x)) |
delta2(x) | sum(delta2(x)) |
nz_delta(x) | sum(nz_delta(x)) |
value_in(x) | sum(value_in(x)) |
value_in2(x) | sum(value_in2(x)) |
nz_value_in(x) | sum(nz_value_in(x)) |
value_out(x) | sum(value_out(x)) |
value_out2(x) | sum(value_out2(x)) |
nz_value_out(x) | sum(nz_value_out(x)) |
max_delta(x) | maximum(delta(x)) |
max_value_in(x) | maximum(value_in(x)) |
max_value_out(x) | maximum(value_out(x)) |
min_delta(x) | minimum(delta(x)) |
min_value_in(x) | minimum(value_in(x)) |
min_value_out(x) | minimum(value_out(x)) |
This subtopic contains the following sections:
- Non-numeric floating point values
- Non-numeric values in OpenM++
- Increments and accumulators
- Invalid table increments
- Disabling table increment errors
A floating point number in OpenM++ is a C++ IEEE double
or float
, which is supported on most CPU hardware.
It can hold an exact value like 123
or 0.5
or an approximation to a Real number like 0.1
or pi
.
A floating point number can also hold one of three special non-numeric values: +inf
, -inf
, or NaN
(indeterminate).
Non-numeric values arise naturally from arithmetic operations or function calls, e.g.
Expression | Result |
---|---|
1.0 / 0.0 |
+inf |
-1.0 / 0.0 |
-inf |
0.0 / 0.0 |
NaN |
log(0.0) |
-inf |
log(-1.0) |
NaN |
sqrt(-1.0) |
NaN |
exp(710.0) |
+inf |
Note: The C++ specification for std::exp
guarantees a result of +inf if the argument is greater than 709.8
.
Numeric values can sometimes result from floating point operations or function calls with non-numeric arguments, e.g.
Expression | Result |
---|---|
1.0 / +inf |
0.0 |
atan(+inf) |
pi/2 |
exp(-inf) |
0.0 |
exp(log(0.0)) |
0.0 |
Logical comparison operators can have non-numeric arguments, e.g.
Expression | Result |
---|---|
+inf > 42.0 |
true |
-inf < +inf |
true |
NaN < +inf
|
false |
NaN == NaN
|
false |
NaN != NaN
|
false |
Note: The C++ specification states that all operators with NaN return NaN, including all comparison operators,
notably the ==
operator in the preceding table.
The C++ library contains functions to determine non-numeric values:
std::isnan
determines if a floating point number is NaN,
std::isinf
if it is +inf or -inf,
and
std::isfinite()
if it is finite, i.e. a garden variety floating point value.
Arithmetic operations involving +inf or -inf typically result in non-numeric values, e.g.
Expression | Result |
---|---|
+inf + 1.0 |
+inf |
+inf - 1.0 |
+inf |
+inf + +inf |
+inf |
sqrt(+inf) |
+inf |
inf / inf |
NaN |
This is notably the case for NaN
, which propagates in arithmetic operations and mathematical functions, e.g.
Expression | Result |
---|---|
NaN + 1.0 |
NaN |
+inf + NaN |
NaN |
sqrt(NaN) |
NaN |
Sometimes operations involving +inf
or -inf
can produce NaN
, e.g.
Expression | Result |
---|---|
+inf - +inf |
NaN |
+inf / +inf |
NaN |
+inf / 0.0 |
NaN |
A general rule of thumb is that non-numeric floating point values propagate to results in arithmetic operations and mathematical functions.
[back to increment validity]
[back to topic contents]
Non-numeric values are used in several ways in OpenM++:
- Global time is initialized to
-inf
before each case or replicate/sub. - All event times are initialized to
+inf
before each case or replicate/sub. - Derived parameters of floating point type are initialized to
NaN
(all cells). - An attribute of floating point type (
float
,double
,real
, orTime
) can have a non-numeric value, depending on model logic. - A
maximum
table accumulator is initialized to-inf
, and aminimum
table accumulator to+inf
.
[back to increment validity]
[back to topic contents]
Each cell of an entity table contains one or more accumulators specified in the expression dimension of the table.
As attributes change value during a run,
increments
are pushed to
accumulators
of the current cell of the table.
An accumulator might be a running count of increments, the running sum of increments,
the current maximum value,
or a collection of all pushed values.
When a run completes,
statistics are extracted from the table accumulators for each cell to compute final values for that table cell.
For example,
the median P50
for an attribute in a table cell is extracted from the accumulator underlying P50
,
which is a collection of all increments pushed to the cell during the run.
The P50
statistic is computed by sorting that collection and finding the middle value
(or the average of the two middle values if the number of increments in the collection is even).
[back to increment validity]
[back to topic contents]
Some accumulators handle increments of +inf or -inf in an expected and natural way, e.g.
an increment of +inf to a maximum
accumulator,
or an increment of +inf or -inf to a P50
accumulator.
However, a non-numeric increment can cause an accumulator to become pegged to a non-numeric value. This is particularly true for a NaN increment.
Specifically,
- Pushing an increment with value
+inf
or-inf
to asum
orgini
accumulator nullifies the effect of any previous or subsequent increment. - Pushing an increment with value
NaN
to any accumulator nullifies the effect of any previous or subsequent increments.
In other words, an increment of one single entity, perhaps the result of a rarely occurring corner condition in model code, can cause an entire table cell to become empty. OpenM++ treats that as an error in table design or model logic, halts the run, and writes a log message like
Simulation error: Invalid increment -inf in table 'IncrementTestTable' using attribute 'my_dbl' on or after event 'MortalityEvent' in entity_id 208 in simulation member 0 with combined seed 1637697257 when current time is 88.06346668067070
This particular error message manifested in a version of the Alpha2
model
which was modified to deliberately produce an increment error in the table
table Person IncrementTestTable
[integer_age >= 50]
{
{
value_out(my_dbl)
}
};
The root cause of an invalid increment often occurs in a different event than the one responsible for pushing the increment.
In the error message above, the invalid increment was detected when the entity was exiting the simulation after the MortalityEvent
.
The attribute my_dbl
likely assumed a non-numeric value earlier in the simulation causing the invalid increment later.
The root cause of an invalid increment can be probed using Event Trace to examine the evolution of the specific attribute in the specific entity given in the runtime error message.
To enable event trace in the model, the following statement must be added to model code:
options event_trace = on;
and the model executable must be invoked with the argument -OpenM.IniAnyKey
.
The following EventTrace
settings (in an ini
file) output all events and all changes in my_dbl
in entity 208:
[OpenM]
LogToFile = true
TraceToFile = true
[EventTrace]
; format
ReportStyle = readable
NameColumnWidth = 20
; filters
SelectedEntities = 208
; events
ShowEvents = yes
; attributes
ShowAttributes = yes
SelectedAttributes = my_dbl
This produces the following trace file output:
Time Entity Age Id Trace Value Name Remarks
0.000000 Person 0.000000 208 ENTER
0.000000 Person 0.000000 208 attr 0 my_dbl initial
0.000000 Person 0.000000 208 EVENT SpawnEvent
0.500000 Person 0.500000 208 EVENT EyeColourChangeEvent
1.000000 Person 1.000000 208 EVENT FirstBirthdayEvent
2.632435 Person 2.632435 208 EVENT HappinessReversalEvent
2.632435 Person 2.632435 208 attr -inf my_dbl was 0
10.105425 Person 10.105425 208 EVENT MoveEvent
25.755745 Person 25.755745 208 EVENT HappinessReversalEvent
26.741666 Person 26.741666 208 EVENT StartPlayingEvent
30.141256 Person 30.141256 208 EVENT MoveEvent
32.641206 Person 32.641206 208 EVENT MoveEvent
34.927079 Person 34.927079 208 EVENT HappinessReversalEvent
54.778775 Person 54.778775 208 EVENT HappinessReversalEvent
59.496134 Person 59.496134 208 EVENT StartPlayingEvent
60.500447 Person 60.500447 208 EVENT HappinessReversalEvent
68.935493 Person 68.935493 208 EVENT MoveEvent
76.110163 Person 76.110163 208 EVENT HappinessReversalEvent
78.448787 Person 78.448787 208 EVENT StartPlayingEvent
79.197382 Person 79.197382 208 EVENT MoveEvent
87.282644 Person 87.282644 208 EVENT HappinessReversalEvent
88.063467 Person 88.063467 208 EVENT MortalityEvent
88.063467 Person 88.063467 208 EXIT
This trace output shows that the my_dbl
attribute first assumed the non-numeric value -inf
during the HappinessReversalEvent
at an early age,
before the entity was in scope of the table filter.
Here's the model code responsible for the invalid increment error later in the simulation:
entity Person
{
double my_dbl;
void update_funny_numbers(void);
hook update_funny_numbers, HappinessReversalEvent, 43;
};
void Person::update_funny_numbers(void)
{
double x = 0.0;
my_dbl = std::log(x); // is -inf
}
If necessary, a Debug version of the model can be built and run with a conditional break point added to the first line of code in the event identified by Event Trace.
In this example, the break point could be set to the first line of HappinessReversalEvent
,
with condition entity_id == 208
.
Here's the model source code of the event which was the root cause of the invalid increment.
void Person::HappinessReversalEvent()
{
happy = !happy;
if ( !happy && playing ) {
// stop playing if unhappy
playing = FALSE;
}
if (happy && my_first_happy_time == TIME_INFINITE) {
my_first_happy_time = time;
}
hook_HappinessReversalEvent();
}
When the break point is hit,
execution can be stepped line by line in the debugger
until the code responsible for setting my_dbl
to a non-numeric value is found.
[back to increment validity]
[back to topic contents]
Normal handling of an invalid table increment can be controlled by the following option:
options verify_valid_table_increment = off; // default is on
If this option is off
, a warning like the following will be written to the log on each run:
Warning : invalid table increment is not detected with verify_valid_table_increment = off
A table with a non-numeric cell will display as empty in the UI and in csv
export.
[back to increment validity]
[back to topic contents]
Keyword | Description |
---|---|
interval | |
event |
- Windows: Quick Start for Model Users
- Windows: Quick Start for Model Developers
- Linux: Quick Start for Model Users
- Linux: Quick Start for Model Developers
- MacOS: Quick Start for Model Users
- MacOS: Quick Start for Model Developers
- Model Run: How to Run the Model
- MIT License, Copyright and Contribution
- Model Code: Programming a model
- Windows: Create and Debug Models
- Linux: Create and Debug Models
- MacOS: Create and Debug Models
- MacOS: Create and Debug Models using Xcode
- Modgen: Convert case-based model to openM++
- Modgen: Convert time-based model to openM++
- Modgen: Convert Modgen models and usage of C++ in openM++ code
- Model Localization: Translation of model messages
- How To: Set Model Parameters and Get Results
- Model Run: How model finds input parameters
- Model Output Expressions
- Model Run Options and ini-file
- OpenM++ Compiler (omc) Run Options
- OpenM++ ini-file format
- UI: How to start user interface
- UI: openM++ user interface
- UI: Create new or edit scenario
- UI: Upload input scenario or parameters
- UI: Run the Model
- UI: Use ini-files or CSV parameter files
- UI: Compare model run results
- UI: Aggregate and Compare Microdata
- UI: Filter run results by value
- UI: Disk space usage and cleanup
- UI Localization: Translation of openM++
- Authored Model Documentation
- Built-in Attributes
- Censor Event Time
- Create Import Set
- Derived Tables
- Entity Attributes in C++
- Entity Function Hooks
- Entity Member Packing
- Entity Tables
- Enumerations
- Events
- Event Trace
- External Names
- Generated Model Documentation
- Groups
- Illustrative Model
Align1
- Lifecycle Attributes
- Local Random Streams
- Memory Use
- Microdata Output
- Model Code
- Model Documentation
- Model Languages
- Model Localization
- Model Metrics Report
- Model Resource Use
- Model Symbols
- Parameter and Table Display and Content
- Population Size and Scaling
- Screened Tables
- Symbol Labels and Notes
- Tables
- Test Models
- Time-like and Event-like Attributes
- Use Modules
- Weighted Tabulation
- File-based Parameter Values
- Oms: openM++ web-service
- Oms: openM++ web-service API
- Oms: How to prepare model input parameters
- Oms: Cloud and model runs queue
- Use R to save output table into CSV file
- Use R to save output table into Excel
- Run model from R: simple loop in cloud
- Run RiskPaths model from R: advanced run in cloud
- Run RiskPaths model in cloud from local PC
- Run model from R and save results in CSV file
- Run model from R: simple loop over model parameter
- Run RiskPaths model from R: advanced parameters scaling
- Run model from Python: simple loop over model parameter
- Run RiskPaths model from Python: advanced parameters scaling
- Windows: Use Docker to get latest version of OpenM++
- Linux: Use Docker to get latest version of OpenM++
- RedHat 8: Use Docker to get latest version of OpenM++
- Quick Start for OpenM++ Developers
- Setup Development Environment
- 2018, June: OpenM++ HPC cluster: Test Lab
- Development Notes: Defines, UTF-8, Databases, etc.
- 2012, December: OpenM++ Design
- 2012, December: OpenM++ Model Architecture, December 2012
- 2012, December: Roadmap, Phase 1
- 2013, May: Prototype version
- 2013, September: Alpha version
- 2014, March: Project Status, Phase 1 completed
- 2016, December: Task List
- 2017, January: Design Notes. Subsample As Parameter problem. Completed
GET Model Metadata
- GET model list
- GET model list including text (description and notes)
- GET model definition metadata
- GET model metadata including text (description and notes)
- GET model metadata including text in all languages
GET Model Extras
GET Model Run results metadata
- GET list of model runs
- GET list of model runs including text (description and notes)
- GET status of model run
- GET status of model run list
- GET status of first model run
- GET status of last model run
- GET status of last completed model run
- GET model run metadata and status
- GET model run including text (description and notes)
- GET model run including text in all languages
GET Model Workset metadata: set of input parameters
- GET list of model worksets
- GET list of model worksets including text (description and notes)
- GET workset status
- GET model default workset status
- GET workset including text (description and notes)
- GET workset including text in all languages
Read Parameters, Output Tables or Microdata values
- Read parameter values from workset
- Read parameter values from workset (enum id's)
- Read parameter values from model run
- Read parameter values from model run (enum id's)
- Read output table values from model run
- Read output table values from model run (enum id's)
- Read output table calculated values from model run
- Read output table calculated values from model run (enum id's)
- Read output table values and compare model runs
- Read output table values and compare model runs (enun id's)
- Read microdata values from model run
- Read microdata values from model run (enum id's)
- Read aggregated microdata from model run
- Read aggregated microdata from model run (enum id's)
- Read microdata run comparison
- Read microdata run comparison (enum id's)
GET Parameters, Output Tables or Microdata values
- GET parameter values from workset
- GET parameter values from model run
- GET output table expression(s) from model run
- GET output table calculated expression(s) from model run
- GET output table values and compare model runs
- GET output table accumulator(s) from model run
- GET output table all accumulators from model run
- GET microdata values from model run
- GET aggregated microdata from model run
- GET microdata run comparison
GET Parameters, Output Tables or Microdata as CSV
- GET csv parameter values from workset
- GET csv parameter values from workset (enum id's)
- GET csv parameter values from model run
- GET csv parameter values from model run (enum id's)
- GET csv output table expressions from model run
- GET csv output table expressions from model run (enum id's)
- GET csv output table accumulators from model run
- GET csv output table accumulators from model run (enum id's)
- GET csv output table all accumulators from model run
- GET csv output table all accumulators from model run (enum id's)
- GET csv calculated table expressions from model run
- GET csv calculated table expressions from model run (enum id's)
- GET csv model runs comparison table expressions
- GET csv model runs comparison table expressions (enum id's)
- GET csv microdata values from model run
- GET csv microdata values from model run (enum id's)
- GET csv aggregated microdata from model run
- GET csv aggregated microdata from model run (enum id's)
- GET csv microdata run comparison
- GET csv microdata run comparison (enum id's)
GET Modeling Task metadata and task run history
- GET list of modeling tasks
- GET list of modeling tasks including text (description and notes)
- GET modeling task input worksets
- GET modeling task run history
- GET status of modeling task run
- GET status of modeling task run list
- GET status of modeling task first run
- GET status of modeling task last run
- GET status of modeling task last completed run
- GET modeling task including text (description and notes)
- GET modeling task text in all languages
Update Model Profile: set of key-value options
- PATCH create or replace profile
- DELETE profile
- POST create or replace profile option
- DELETE profile option
Update Model Workset: set of input parameters
- POST update workset read-only status
- PUT create new workset
- PUT create or replace workset
- PATCH create or merge workset
- DELETE workset
- POST delete multiple worksets
- DELETE parameter from workset
- PATCH update workset parameter values
- PATCH update workset parameter values (enum id's)
- PATCH update workset parameter(s) value notes
- PUT copy parameter from model run into workset
- PATCH merge parameter from model run into workset
- PUT copy parameter from workset to another
- PATCH merge parameter from workset to another
Update Model Runs
- PATCH update model run text (description and notes)
- DELETE model run
- POST delete model runs
- PATCH update run parameter(s) value notes
Update Modeling Tasks
Run Models: run models and monitor progress
Download model, model run results or input parameters
- GET download log file
- GET model download log files
- GET all download log files
- GET download files tree
- POST initiate entire model download
- POST initiate model run download
- POST initiate model workset download
- DELETE download files
- DELETE all download files
Upload model runs or worksets (input scenarios)
- GET upload log file
- GET all upload log files for the model
- GET all upload log files
- GET upload files tree
- POST initiate model run upload
- POST initiate workset upload
- DELETE upload files
- DELETE all upload files
Download and upload user files
- GET user files tree
- POST upload to user files
- PUT create user files folder
- DELETE file or folder from user files
- DELETE all user files
User: manage user settings
Model run jobs and service state
- GET service configuration
- GET job service state
- GET disk usage state
- POST refresh disk space usage info
- GET state of active model run job
- GET state of model run job from queue
- GET state of model run job from history
- PUT model run job into other queue position
- DELETE state of model run job from history
Administrative: manage web-service state
- POST a request to refresh models catalog
- POST a request to close models catalog
- POST a request to close model database
- POST a request to open database file
- POST a request to cleanup database file
- GET the list of database cleanup log(s)
- GET database cleanup log file(s)
- POST a request to pause model run queue
- POST a request to pause all model runs queue
- PUT a request to shutdown web-service