Model Creation in Stella
When you create a model in Stella, you can use it with the Epicenter platform by:
Creating and uploading your model file to the Model folder of your project.
Optionally, creating a model context file and uploading it to the Model folder of your project.
Then, when you create a user interface for your Stella model on Epicenter, each user's interaction includes:
- Logging in and creating a run
- Calling the
step
orstepTo
method to advance the Stella model - Retrieving and updating variables, based on user decisions and the appropriate time or step.
- Index of available Stella operations
- Index of available Stella variables
Creating and Uploading your Model File
To use a Stella model, save it in .stmx format. This
Use the Epicenter user interface to upload your model file (.stmx) to the Model folder within your project.
Creating a Run
A "run" is a collection of end user interactions with the project and its model. Every time an end user wants to interact with a project, you as the project author need to create a new run.
If you are using the Interface Builder to create your interface, the name of your model file is detected automatically, and a run is created automatically when an end user visits this project page.
If you are using one of the Epicenter APIs, you'll need to create the run yourself. Stella is only available with the Epicenter v2 APIs and later (see more on the version history).
For example, using the Run API Service (JavaScript), you might use:
var rs = new F.service.Run({
account: 'acme-simulations',
project: 'supply-chain-game',
token: 'eyJhbGciOiJSUzI1NiJ9'
});
rs.create('supply-chain-model.stmx');
Or if you're using the Run API (RESTful), you might use:
curl -X POST \
'https://api.forio.com/v2/run/acme-simulations/supply-chain-game' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"model": "supply-chain-model.stmx"}'
Advancing the Model
The Interface Builder and Epicenter APIs both allow you to manipulate a run using operations exposed by the model. For Stella models, there are two available operations: step
and stepTo
.
To advance the Stella model for a particular run, use the step
or stepTo
operation.
- The
step
operation advances the run a specified number of StellaTime unit
s, rounded to the nearest multiple of StellaTimestep
s. It has one optional argument, a floating point number for steps (StellaTime unit
s) to advance. The default value is1
. The return value is the currentTimestep
. - The
stepTo
operation advances the run up to a particular Stella time, or the end of the model. It has one argument, which can be either:- An integer: step the model to that time but not past.
- The string
"end"
: step the run to the end (the StellaStop time
).
If you are using the Interface Builder to create your project's interface, you can select Step
under Add Operations for the Properties of a button. Optionally, you can select from the Parameters drop-down to choose how far to step (1 step, 10 steps, or to the end of the model). There is not an explicit stepTo
available from the Interface Builder.
If you are using one of the Epicenter APIs, for example, you could advance the model by three steps using the Epicenter.js Run API Service:
rs.load('runID').then(function()
{ rs.do('step', [3]); });
Or if you're using the Run API (RESTful), you might use:
curl -X POST \
'https://api.forio.com/v2/run/acme-simulations/supply-chain-game/runID/operations/step' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"arguments": [3]}'
Retrieving and Updating Variables
You can retrieve and update Stella variables for each Stella project using the variable name.
In the Interface Builder, enter the variable name under the Variable property of decisions, tables, or other components. In Flow.js, add the variable to an element on the page, for example using data-f-bind
.
Unlike some other modeling languages supported by Epicenter, Stella models are necessarily time-based: they deal in discrete steps, and the model advances over time. For this reason, each variable is actually an array of values over steps.
Important Notes on Variables
Steps are 0-based. Including the step is optional when you reference a variable. Leaving it off returns the entire array. Only variables in the current step can be updated. The value from any step (including the current step) can be retrieved.
To retrieve the value of a variable in the current time step, you can either include the current time step as an array index, or append
.POINT_IN_TIME
to the name of the variable when you look it up.To retrieve the value of an arrayed variable with the array collapsed for each step, append
.COLLAPSED_ARRAY
to the name of the variable when you look it up.Variables that are marked as
Start-up
variables in Stella can only be updated before the firststep
call to advance the model. Other variables may be upated at any time. (If you're not sure about a particular variable, you can Introspect the run and check the access field for that variable:BEFORE
means you can only update the variable before the model is advanced;ALWAYS
means you can update the variable any time after the run is created.)Variable names are not case sensitive in Stella, but they are once you use them in Epicenter. For example, you should make sure that the variable names in your project's user interface match their case with the variable names in your model context file.
Variables that you want to save in the Epicenter backend database need to be noted in the model context file.
Scalars
To update or reference a scalar variable, use the variable name. Optionally, include the step in square brackets, [s]
. Only variables in the current step can be updated. The value from any step (including the current step) can be retrieved.
Unlike some other modeling languages supported by Epicenter, Stella models are necessarily time-based: they deal in discrete steps, and the model advances over time. For this reason, each variable is actually an array of values over steps.
For example, suppose you have the variable Budget
, which changes over time:
Budget | Step |
80 | 0 |
100 | 1 |
120 | 2 |
130 | 3 |
If you are using Flow.js, by default the value at the current step is selected. You can also specify a particular step. This looks like:
<!-- update Budget for current step -->
<input data-f-bind="Budget"></input>
<!-- Budget for step 2: returns "120". can reference, but not update -->
<span data-f-bind="Budget[2]"></span>
You can list values of an array (that is, your variable over all steps) using the data-f-foreach
attribute.
And if you are using the Run API, this looks like:
<!-- update Budget for current step -->
curl -X PATCH \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"Budget": 95}'
<!-- Budget for step 2: returns "120". can reference, but not update -->
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables/Budget[2]' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
<!-- Budget for current step, using the ".POINT_IN_TIME" notation: returns 130 -->
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables/Budget.POINT_IN_TIME' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
Using the Run API, you can also ask for the variable over all steps. For example:
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables/Budget' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
returns:
[
80,
100,
120,
130
]
Arrays
To update or reference an element of an array, use square brackets and strings to describe the index of the array: [indexName]
. Optionally, include the step as the second subscript: [indexName,s]
. Only variables in the current step can be updated. The value from any step (including the current step) can be retrieved.
For example, suppose in Stella you have:
Sales, Apples | Sales, Oranges | Step |
80 | 180 | 0 |
100 | 200 | 1 |
120 | 220 | 2 |
130 | 230 | 3 |
140 | 240 | 4 |
If you are using Flow.js, this looks like:
<!-- get sales of apples in step 2: returns 120 -->
<span data-f-bind="Sales[apples,2]"></span>
<!-- set sales of apples and oranges sold in current step
(step 4), requires two different inputs -->
<input data-f-bind="Sales[apples]"></input>
<input data-f-bind="Sales[oranges]"></input>
You can list values of an array (that is, your variable over all steps) using the data-f-foreach
attribute.
And if you are using the Run API, this looks like:
<!-- get sales of apples in step 2: returns 120 -->
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables/Sales[apples,2]' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
<!-- set sales of apples and oranges sold in current step
(step 4), requires two different updates -->
curl -X PATCH \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"Sales[apples]": 150, "Sales[oranges]": 250}'
Using the Run API, you can also ask for the variable over all steps. For example:
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables/Sales' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
returns:
{
"apples": [
80,
100,
120,
130,
140
],
"oranges": [
180,
200,
220,
230,
240
]
}
This format is easier to parse if you are looking for the values from a specific dimension of your array.
To retrieve the values in the current time step only, append .POINT_IN_TIME
to the name of the variable when you look it up:
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables/Sales.POINT_IN_TIME' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
returns:
{
"apples": 140,
"oranges": 240
}
To retrieve the values of your arrayed variable with the array collapsed for each step, append .COLLAPSED_ARRAY
to the name of the variable when you look it up:
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-stella-model/000001576cef3f70efd8cdea64036fa396ec/variables/Sales.COLLAPSED_ARRAY' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
returns:
[
[
80, // "apples" dimension for the first step
180 // "oranges" dimension for the first step
],
[
100, // "apples" dimension for the second step
200 // "oranges" dimension for the second step
],
[
120, // etc.
220
],
[
130,
230
],
[
140,
240
]
]
This format is easier to parse if you are looking for all values from a specific step of your model, and can be helpful for example if you are graphing the values over steps.
Note that you cannot update variables which do not exist (including arrayed variables, for example Sales[pineapple]
if your only products are apples
and oranges
). In other words, you cannot create new variables this way; your variables must already be defined in your model.
Determining the Current Time or Step
In some situations, you may know already the time or step for which you want to view or update variables. If you are not sure, can ask the model:
For the current step, read from the
Step
variable. This variable is automatically included for you and always holds the current Stella step. (It is a scalar value, not an array.)For example, using the Run API Service (JavaScript), you might use:
rs.load('runID', {include: 'Step'});
Or if you're using the Run API (RESTful), you might use:
curl -G \ 'https://api.forio.com/v2/run/acme-simulations/supply-chain-game/runID/variables/Step' \ --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
For information on what has been simulated so far, read from the
Time
variable. This variable is automatically included for you and always holds an array of the time values that have been stepped to so far.For example, using the Run API Service (JavaScript), you might use:
rs.load('runID', {include: 'Time'});
Or if you're using the Run API (RESTful), you might use:
curl -G \ 'https://api.forio.com/v2/run/acme-simulations/supply-chain-game/runID/variables/Time' \ --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
For additional time details, read from the
Start Time
,Final Time
, orTime Step
variables.
Index of Available Stella Operations
reset
- Arguments: none
- Result: Returns a new run, that is, a new instantiation of your model for an end user to play with. (Remember that a run is a collection of interactions with a model.) For example, this is useful if your end user needs to "start over" to create a new scenario within your project.
- Note that this can ONLY be called from your project's user interface if you are using the Interface Builder or Flow.js. (Under the hood, this is not an operation as defined for the RESTful Run API. If you are building your project's user interface with the Epicenter RESTful APIs, you should just create a new run instead of calling
clear
.)
step
- Arguments:
- Optional, floating point number for steps (Stella
Time unit
s) to advance. If not provided,1
is assumed.
- Optional, floating point number for steps (Stella
- Result: Advances the run the specified number of Stella
Time unit
s, rounded to the nearest multiple of StellaTimestep
. Returns the currentTimestep
. - More info
- Arguments:
stepTo
Arguments:
Integer, the Stella
Time unit
to step to (but not past). Note that this is independent of the initial time. For example, if theTime unit
is months,stepTo(6)
always goes to month 6 — regardless of whether the initial time is 0 or 2.or
- The string
"end"
, step the run to the end (the StellaStop time
).
Result: Advances the run up a particular Stella
Time unit
, or the end of the model.- More info
Index of Available Stella Variables
In addition to any variables in your Stella model, the following variables are available for reference when you are running a Stella model on Epicenter.
Final Time
: The end of your simulation.Time
: An array of the simulation times that you have stepped through so far.Time Step
: The value of the StellaTimeStep
variable.Time Unit
: The time unit from Stella, e.g. "months".Start Time
: The beginning of your simulation.Step
: The current step. Steps are 0-based.
For example, in a model in which we have stepped twice and then asked for all of these variables, using the Run API (RESTful):
curl -G \
'https://api.forio.com/v2/run/acme-simulations/supply-chain-game/000001577c0c5359720faa8b0c4b32e182d9/variables?include=Time,Start Time,Final Time,Time Step' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
which returns:
{
"Start Time": 2015,
"Final Time": 2020,
"Time": [
2015,
2016,
2017
],
"Time Step": 1,
"Step": 2
}