forio Toggle navigation

Model Creation in Stella

When you create a model in Stella, you can use it with the Epicenter platform by:

Then, when you create a user interface for your Stella model on Epicenter, each user's interaction includes:

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 Stella Time units, rounded to the nearest multiple of Stella Timesteps. It has one optional argument, a floating point number for steps (Stella Time units) to advance. The default value is 1. The return value is the current Timestep.
  • 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 Stella Stop 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 first step 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:

BudgetStep
800
1001
1202
1303

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, ApplesSales, OrangesStep
801800
1002001
1202202
1302303
1402404

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, or Time 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 units) to advance. If not provided, 1 is assumed.
    • Result: Advances the run the specified number of Stella Time units, rounded to the nearest multiple of Stella Timestep. Returns the current Timestep.
    • More info
  • 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 the Time 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 Stella Stop 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 Stella TimeStep 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
}