forio Toggle navigation

Model Context

In addition to your model code, you can optionally provide Epicenter with additional information about the context in which your model should be run. This context information determines how your model is configured in the Epicenter backend, including how some model variables are stored and saved.

How do I ... ?

Creating and Naming the Context File

Your model context file must have the same name as your primary model file. For example, if your model is "my_model.py", then your context file must be "my_model.ctx". It must be saved in your project's Model folder.

The context file is a text file that contains a single JSON object.

Back to top

Saving Model Variables to the Epicenter Database

Runs must be in memory in order for end users to update variables or call operations on them. Runs are automatically removed from memory, and sent to the Epicenter backend database, once the project's Model Session Timeout has elapsed without any end user interaction. For example, if the Model Session Timeout is 30 minutes and no one has called an operation on a run for 30 minutes, the run is removed from memory. Later, the run can be loaded from the database back into memory. This is called "restoring" the run, and it happens automatically by default if you are using Epicenter.js.

When you update a model variable — or call a model operation which does — you need to explicitly save the updated variables in order for the changes to be visible when you restore the run.

Often, only variables that end users interact with need to be saved. For example, variables that are internal to the model may be recalculated anyway as the model advances. However, you should evaluate your model carefully to determine what's best.

In Python, Julia, and R, you save model variables by adding an Epicenter.record() call to the model whenever the variable should be saved — for instance, at the end of a model operation.

In Vensim, Stella, and Powersim, you save model variables by adding a line to your model context file. Then, the variables are saved at each step as the model advances.

  • If you want to save all model variables at each time step, add a simulation to the top-level JSON object in your model context file, and set its save property to true:

      "simulation": { "save": true }
    
  • If you want to save only a few model variables at each time step, add a variables to the top-level JSON object in your model context file, then add a simulation to each variable and set its save property to true:

      "variables": { 
          "myVarName1": { 
              "simulation": { "save": true }
          },
          "myVarName2": {
              "simulation": { "save": true }
          }
      }
    
  • If you want to make sure that some model variables are not saved, use the same format but set the save property to false. For example, explicitly not saving some variables may help performance in large models.

Here's a complete example. This example lists two model variable that should be saved with each time step: Price and Profit. Other model variables will not be saved.

# my_model.ctx

{
    "simulation": {
        "save": false
    },
    "variables": {
        "Price": {
            "simulation": {
                "save": true
            }
        },
        "Profit": {
            "simulation": {
                "save": true
            }
        }
    }
}

Back to top

Optimizing Model Performance using a Model Context File

You can use the model context file to add configuration information that helps optimize the performance of your model when it runs on Epicenter. Typically, these optimizations are not necessary unless you have a particularly complex model.

Adjusting Granularity for Key Variables, in Vensim, Stella, or Powersim

Sometimes models are very granular in order to properly model the underlying equations. However, even if your model is doing calculations based on a large number of time steps, you may only care about the values at certain intervals. For example, maybe the model needs to calculate interest each week, but you only report out on totals each year, and each time unit is a year.

  • You can add a simulation to the top-level JSON object in your model context file, and set its savePer property to specify how often, in time units, the values of all variables are saved in Epicenter.

      "simulation": { "savePer": 2 }
    
  • You can add a simulation to the top-level JSON object in your model context file, and set its reportPer property to specify how often, in time units, the values of all variables are reported to Epicenter.

      "simulation": { "reportPer": 2 }
    
  • You can also change these on a per-variable basis: add a variables to the top-level JSON object in your model context file, then add a simulation to each variable and set its savePer and reportPer properties respectively.

      "variables": {
          "myVarName": {
              "simulation": {
                  "savePer": 4,
                  "reportPer": 4
              }
          }
      }
    

Determining How Runs are Retrieved from the Database

Runs must be in memory in order for you to update variables or call operations on them. Runs are automatically removed from memory, and sent to the Epicenter backend database, once the project's Model Session Timeout has elapsed without any end user interaction. For example, if the Model Session Timeout is 30 minutes and no one has called an operation on a run for 30 minutes, the run is removed from memory. Later, the run can be loaded from the database back into memory. This is called "replaying" or "restoring" the run, and it happens automatically by default if you are using Epicenter.js.

When Epicenter restores the run, there are several ways it can do this. Depending on your model, explicitly specifying how this happens can improve performance.

  • By default, all commands in the run's history are replayed, in order, when the run is brought back into memory. These commands include all of the end user interactions (updating model variables and calling model operations), from the creation of the run up to the time it was last persisted in the database. To use this option, you can either do nothing (this is the default behavior), or add restorations[{"replay": {}}] to your model context file.

    • Performance tip: This option can be slower to restore runs, especially if each run has a large number of operations called on it, or if some of these operations take a long time. However, this option may be required if your model's complete state can only be expressed by a combination of operations and variables.
  • To restore state by only loading model variables, add restorations[{"snapshot": { "variables": [ "varName1", "varName2" ] }}] to your model context file. In this case, the run is restored by restoring the most recently saved values of the variables listed. Specific end user inputs and operations are NOT replayed.

    • Performance tip: If your model state is completely captured in a small set of variables, this approach can save a significant amount of time during the restoration of a run. However, it should only be used if your model's complete state can be appropriately captured in variables. (This will depend both on the nature of your model and on how your variables are structured — for example, if your variables store only values from the most recent time step, or from all steps in the model.)
  • To restore state by replaying only a subset of the commands in the run's history, add restorations[{"replay": {"operations": [ <list of operations which should NOT be replayed> ]}}] to your model context file. This type of replay is NOT common, and can be very difficult to debug if you try it and your restored runs are not in the state you expect. For details on how to specify the operations, check the Model State API to view the syntax in which these are stored internally. Each operation (array element) is an object including commandType, commandName, and operationType for the command to replay.

    • Performance tip: This is another option that can help improve performance during run restoration, depending on the structure of your model. As noted, however, it can be difficult to diagnose problems with restored runs using this option.

General Guidelines.

A good general guideline for determining which option to use for restoring runs is:

  • Models with a small number of operations are well-suited to restoring runs via replay;

  • Models with a small number of variables are well-suited to restoring runs via snapshot.

It's also important to consider the use cases of your project.

  • In some projects, an end user's entire interaction with a run occurs in one session. In this case, the default "replay" behavior is fine, because it's not common that users come back to work with a run they've used previously.

  • In other projects, several end users work on a shared run over the course of several days. Here, it's important that a run can be restored quickly, because it's frequent that end users are requesting to work with runs currently in the database. However, it's worth doing some testing to get a sense of the performance differences. Unless your project has a large number of relatively long-running model operations, any restoration method will probably work fine from a performance perspective. You'll have to balance the potential performance improvement with any changes that may be needed to your model to support a particular restoration strategy.

Back to top

Configuring the Model Context for Forio SimLang, Powersim, Stella, or Vensim Models

The following options are available for configuring Forio SimLang, Powersim, Stella, or Vensim models using a model context (.ctx) file.

Key Value Default Example
language Optional. The modeling language for this simulation. Automatically set based on the file extension of the model file used to create the run. To explicitly set this, use one of:
  • "language": "simlang"
  • "language": "powersim"
  • "language": "stella"
  • "language": "vensim"
inceptionGracePeriodSeconds Optional. Configurable timeout for creating a new run or replaying a run. If the run cannot be created within the specified time, an error is thrown. 30 seconds In most cases there is no need to change the default. However, some models have a very long running initial operation and need additional time here.
mappedFiles Optional. Only available for Vensim. An object with key : value pairs for files to be read by your model. Each key may be used as an identifier in your model code. Each value must be the name of a file in your Model folder. This property is optional; even without including it, you can access the data from a file in your Model folder using the GET DIRECT DATA construction in your Vensim model. You need to use this property only if you want to access the data within a file by identifier (key) rather than just by file name. Only available for Vensim. See more information on how to use external data with Vensim.
restorations Optional. Information about how to restore runs from the Epicenter database back into memory, so that you can update variables and call operations. If not included in the model context file, the default value is "restorations": [{ "replay": {} }], meaning all commands in the run's history are replayed, in order, when the run is brought back into memory. It is not common to include this option in your model context file. If you do include it, the format is an array, and each run is restored following the instructions in each element of the array, one after the other.
restorations[{"replay": {}}] Optional. The run is restored by re-executing all of the end user interactions (including updating model variables and calling model operations), from the creation of the run up to the time it was last persisted in the database, excluding any operations listed. If no operations are listed, all of the end user interactions are re-executed.

Optionally, the replay object can include an operations object with an array of operations to NOT replay. Each operation (array element) is an object including commandType, commandName, and operationType for the command to replay. You can check the Model State API to view the commands for a run to confirm which you want to include or not in the restorations here.
See Determining How Runs are Retrieved from the Database for more information.
restorations[{"snapshot": {}}] Optional. The run is restored by copying in variables listed. Specific end user inputs and operations are NOT replayed. If no variables are listed, then no variables are restored. Restore two variables: "restorations": [ {"snapshot": {"variables": ["varName1", "varName2"] } } ]. Restore no variables: "restorations": [{ "snapshot": {} }]. See Determining How Runs are Retrieved from the Database for more information.
simulation.dialect Optional. If set to POINT_IN_TIME, then for all model variables, retrieve only the value from the current time step. By default, this is not set; retrieving a model variable returns an array of that variable's values over time. Not available for SimLang.
Example: "simulation" { "dialect": "POINT_IN_TIME" }
simulation.reportPer Optional. This is how often the values of variables are reported, in time units. 1 Sometimes models are very granular in order to properly model the underlying equations, however, not every value needs to be available for end users to view or manipulate. See Optimizing Model Performance using a Model Context File for additional examples.
simulation.save Optional. Whether or not all model variables should be saved. Model variables must be saved if they need to be available after the Model Session Timeout for the project. false Explicitly not saving some variables may help performance in large models. See Saving Model Variables to the Epicenter Database for more information.
simulation.savePer Optional. This is how often, in time units, the values of variables are saved.   Even if your model is doing calculations based on a large number of time steps, you may only care about the values at particular steps (e.g. years, if you are modeling each time unit as a year). See Optimizing Model Performance using a Model Context File for additional examples.
variables.[varName].simulation.reportPer Optional. This is how often the values of variables are reported, in time units. Defaults to the value of simulation.reportPer (which itself defaults to 1). If provided, overrides that value for this variable only. Sometimes models are very granular in order to properly model the underlying equations, however, not every value needs to be available for end users to view or manipulate. See Optimizing Model Performance using a Model Context File for additional examples.
variables.[varName].simulation.save Optional. Whether or not the variable should be saved. Model variables must be saved if the need to be available after the Model Session Timeout for the project. Defaults to the value of simulation.save (which itself defaults to false). If provided, overrides that value for this variable only. Explicitly not saving some variables may help performance in large models. See Saving Model Variables to the Epicenter Database for more information.
variables.[varName].simulation.savePer Optional. This is how often, in time units, the values of variables are saved. Defaults to the value of simulation.savePer. Even if your model is doing calculations based on a large number of time steps, you may only care about the values at particular steps (e.g. years, if you are modeling each time unit as a year). See Optimizing Model Performance using a Model Context File for additional examples.
version Optional. The version of the Model Context structure. If not included, assumed to be v1. "version": "v1"
workerImage Optional. The name of the Epicenter backend server ("worker") to use with this model. If not provided, the default value is default. There is only one worker image for each of these modeling languages (Forio SimLang, Powersim, Stella, Vensim).

Back to top

Configuring the Model Context for Python, Julia, and R Models

The following options are available for configuring Python, Julia, and R models using a model context (.ctx) file.

Key Value Default Example
language Optional. The modeling language for this simulation. Automatically set based on the file extension of the model file used to create the run. By default, .py files are set to python2. If you want to explicitly set this, options are:
  • python2
  • python3
  • r
  • julia
inceptionGracePeriodSeconds Optional. Configurable timeout for creating a new run or replaying a run. If the run cannot be created within the specified time, an error is thrown. 30 seconds In most cases there is no need to change the default. However, some models have a very long running initial operation and need additional time here.
mappedFiles Optional. An object with key : value pairs for files to be read by your model. Each key may be used as an identifier in your model code. Each value must be the name of a file in your Model folder. None: If not included, no file identifiers are available for use within your model. (However, you can still load files directly from your model file. For example, in R: mydata <- read.table("historic_data.csv") if "historic_data.csv" is in your project's Model folder.) "mappedFiles": { "myData": "historic_data.csv" } means you can use the identifier myData in your model code to access the "historic_data.csv" file.
restorations Optional. Information about how to restore runs from the Epicenter database back into memory, so that you can update variables and call operations. If not included in the model context file, the default value is "restorations": [{ "replay": {} }], meaning all commands in the run's history are replayed, in order, when the run is brought back into memory. It is not common to include this option in your model context file. If you do include it, the format is an array, and each run is restored following the instructions in each element of the array, one after the other.
restorations[{"replay": {}}] Optional. The run is restored by re-executing all of the end user interactions (including updating model variables and calling model operations), from the creation of the run up to the time it was last persisted in the database, excluding any operations listed. If no operations are listed, all of the end user interactions are re-executed.

Optionally, the replay object can include an operations object with an array of operations to NOT replay. Each operation (array element) is an object including commandType, commandName, and operationType for the command to replay. You can check the Model State API to view the commands for a run to confirm which you want to include or not in the restorations here.
See Determining How Runs are Retrieved from the Database for more information.
restorations[{"snapshot": {}}] Optional. The run is restored by copying in variables listed. Specific end user inputs and operations are NOT replayed. If no variables are listed, then no variables are restored. Restore two variables: "restorations": [ {"snapshot": {"variables": ["varName1", "varName2"] } } ]. Restore no variables: "restorations": [{ "snapshot": {} }]. See Determining How Runs are Retrieved from the Database for more information.
version Optional. The version of the Model Context structure. If not included, assumed to be v1. "version": "v1"
workerImage Optional. The name of the Epicenter backend server ("worker") to use with this model. If not provided, the default value is default. Options are:
  • default: there is a default worker for all languages
  • sklearn: for Python only, you can choose to run your model on a server that already includes the "scikit-learn" library.

Back to top

Examples of Model Context Files

Python.

This example sets the model language to Python 3.

{
    "language": "python3"
}

Vensim.

This example explicitly lists two model variable that should be saved with each time step: Price and Profit. Other model variables will not be saved. Explicitly not saving some variables — such as those that are internal to the model calculations, and never exposed to users — may help performance in large models.

{
    "simulation": {
        "save": false
    },
    "variables": {
        "Price": {
            "simulation": {
                "save": true
            }
        },
        "Profit": {
            "simulation": {
                "save": true
            }
        }
    }
}

Back to top

Using the Model Configuration (.cfg) File

If you are using the v1 Epicenter APIs to create runs for your project, you need to specify your model context information in a *.cfg file ("configuration file" or "config file"). This is an older file format, but has the same purpose as the *.ctx file discussed above.

  • Not sure which API version you are using? If you are using Epicenter.js version 1.8.1 or earlier, or if you are using Flow.js version 0.10.0 or earlier, then you're using v1. If you are prefacing your REST API calls with "/v2/", or if you are using Epicenter.js version 2.0 or later, then you're using v2. See more information on version history.
Key Value Default Modeling Languages Example
environment None. This is a top-level object. n/a All n/a
environment.workerImage Optional. The name of the Epicenter backend container ("worker") for this modeling language. The default for Python is the Python2 worker (Python 2.7.6). Other languages only have one valid option; if this option is not present, it defaults to the current (most up-to-date) worker for that language. All Options are:
  • Forio SimLang: standard-1.0
  • Julia: standard-1.0
  • Python: python3-standard-1.0 (Python 3.4), standard-1.0 (Python 2.7.6)
  • R: standard-1.0
  • Vensim: standard-1.4
files Optional. The files object describes external files (for example, Excel files) with data to load as part of the model. Inside the files object, include a key : value pair for each file included. Each name can be any designation you like (for example: data or file1). The value is name of the file to load. This file must be in your project's Model folder. n/a Vensim For example: "files": {"data": "myData.xlsx"} or "files": {"file1": "myFirstFile.xlsx", "file2": "mySecondFile.xlsx"}. Note that in addition to listing the files here, you also need to pass this files object as an argument when you create a run. For more information on working with external resources, see How To: Use External Data in Vensim.
model None. This is a top-level object. n/a All n/a
model.autoRestore Describes when runs should be restored (replayed) into memory from the database. (See more on Run Persistence.) Runs must be in memory in order for you to update variables or call operations on them. If not included, the default value is change. All Possible values are:
  • none: Never restore a run.
  • always: Always restore a run.
  • change: Only restore a run if needed, that is, if a model variable is being updated or a model operation is being called.
model.restoreMode Optional. Describes how restoring runs should occur. By default, runs are restored (if needed) when model operations are called or model variables are updated. They are also explicitly restored when you call the Model State API to bring an existing, persisted run from the database back into memory. The default value is REPLAY if restoreMode is not included in the .cfg file, or if there is no .cfg file. Python, R, Julia Options are:
  • REPLAY: when a run is restored, all of the end user interactions, from the creation of the run up to the time it was last persisted in the database, are re-run.
  • SNAPSHOT: the run is instead restored only by copying in variables that have a restore attribute of true (see below). Specific end user inputs and operations are NOT replayed.
model.restore Optional. Governs whether variables are copied into the run when the run is replayed, if the run is using restoreMode: "SNAPSHOT". The default value is false. Python, R, Julia
  • If set to true, all of the model variables are copied into the run when the run is replayed, if the run is using restoreMode: "SNAPSHOT".
  • If set to false, only the model variables with variables.[variableName].restore property set to true are restored.
model.reportPer Optional. This is how often the values of variables are reported, in Vensim TIMESTEP units or SimLang TimeStep units. 1 Forio SimLang, Vensim Sometimes models are very granular in order to properly model the underlying equations, however, not every value needs to be available for end users to view or manipulate. For example, the combination of an M TimeStep 0.5 in your SimLang model and "reportPer": 2 in your .cfg file means that your variables are reported once each time unit.
model.savePer Optional. This is how often, in Vensim or SimLang time units, the values of variables are saved.
  • In SimLang, the default value is 1.
  • In Vensim, the default value is the "SavePer" value in the Vensim model.
Forio SimLang, Vensim Even if your model is doing calculations based on a large number of time steps, you may only care about the values at particular steps (e.g. years, if you are modeling each time unit as a year).
model.subscriptFormat Optional. For accessing Vensim arrayed variables, specify whether the step (the array index) is the first or last index passed in during a request to read or write this variable. Valid values are time_first and time_last. time_last Vensim Suppose you have the variable: price[apple, orange, banana].
  • If you want the value from the second step, with time_last, you request price[apple,2].
  • If you want the value from the second step, with time_first, you instead request price[2,apple].
For arrayed constants, there is no time index.

Important: In the model context file, there is no way to specify this; the time step is always the last index.
model.timeFormat Optional. If provided, must be vector. vector Vensim "timeFormat": "vector"
variables None. This is a top-level object. n/a All n/a
variables.[varName] None. This is an enclosing object. n/a All n/a
variables.[varName].restore Optional. This property allows you to override the model.restore property for particular variables. That is, it governs whether variables are copied into the run when the run is replayed, if the run is using restoreMode: "SNAPSHOT". The default value is the value of model.restore (which, if not specified, defaults to false). Python, R, Julia
  • If set to true, this model variable is copied into the run when the run is replayed, if the run is using restoreMode: "SNAPSHOT".
  • If set to false, this model variable is not copied into the run.
variables.[varName].resetDecision Optional. Describes whether the decision is recalculated at each time step. This property is available only at the variables level. This property is optional. If not included, the default value is false. Forio SimLang "variables": { "Price": { "resetDecision": "true" } }
variables.[varName].save Optional. Whether or not the variable should be saved. This property is available only at the variable level. This property is optional. Including a savePer in the entry for this variable implies save with a value of true. If both save (at the variable level) and savePer (at either the model or variable level) are not included, the variable is saved. Forio SimLang, Vensim Explicitly not saving some variables may help performance in large models. For example, in Forio SimLang models typically you only need to save those decisions ("D" variables, or model elements subject to user control) and variables ("V" variables, or model elements calculated each time step) that you want to display directly to the user.
variables.[varName].savePer Optional. This is how often, in Vensim or SimLang time units, the values of variables are saved. The default value is the value of model.savePer (which, if not specified, defaults to 1 for Forio SimLang models or the "SavePer" value in the Vensim model). Forio SimLang, Vensim Even if your model is doing calculations based on a large number of time steps, you may only care about the values at particular steps (e.g. years, if you are modeling each time unit as a year).
variables.[varName].timeFormat Optional. If provided, must be vector. vector Vensim "variables": { "Price": { timeFormat": "vector" } }

Model Configuration Examples

Python.

This example sets the Python version to 3.4 instead of the default 2.7.6. (No .cfg file is needed if you prefer 2.7.6.)

Also, this example sets the model's restore mode to "snapshot." Because the model.restore property is set to true, all recorded variables are copied into the restored run except for variables with explicit properties of restore set to false (such as "profit" in the example below).

{
    "environment": {
        "workerImage": "python3-standard-1.0"
    },
    "model": {
        "restoreMode": "SNAPSHOT",
        "restore": true // all recorded variables are restored
    },
    "variables": {
        "profit": {
            "restore": false  // except for Profit 
        }
    }
}        

As an alternative, this example also sets the restore mode to "snapshot," but explicitly marks each variable with a restore property value of true that will be copied into the run.

{
    "environment": {
        "workerImage": "python3-standard-1.0"
    },
    "model": {
        "restoreMode": "SNAPSHOT",
        "restore": false // none of the recorded variables are restored
    },
    "variables": {
        "time": {
            "restore": true  // except for Time
        }
    }
}

Vensim.

This example sets saving and reporting preferences for several model variables. It also includes a reference to external files (here, an Excel file) with data to load as part of the model.

{
    "environment": {
        "workerImage": "standard-1.4"
    },
    "files": {
        "data": "myData.xlsx"
    },
    "model": {
        "timeFormat": "vector",
        "subscriptFormat": "time_last",
            // reportPer is twelve times per time unit, 
            // implying Vensim TIMESTEP of 0.08333
        "reportPer": 12, 
        "savePer": 1
    },
    "variables": {
        "Sales": {
            "timeFormat": "vector",
            "save": true
        },
        "Revenue": {
            "timeFormat": "vector",
            "savePer": 0.25 // four times per time unit
        },
        "Total Revenue": {
            "timeFormat": "vector",
            "savePer": 1
        }
    }
}

Back to top