OpenMOLE Model Exploration
This tutorial explains how to run a Cormas model in OpenMOLE to perform parameter exploration, sensitivity analysis, calibration, or large-scale simulation experiments.
What is OpenMOLE?โ
Cormas allows you to run simulations interactively and explore scenarios manually.
When you need to:
- run hundreds or thousands of simulations,
- test many parameter combinations,
- evaluate the impact of randomness,
- perform sensitivity analysis,
- calibrate a model,
- execute simulations on clusters or remote machines,
it becomes impractical to launch simulations manually.
OpenMOLE is a scientific workflow engine designed for large-scale model exploration. It can automatically execute a Cormas model many times with different parameters and collect the results for analysis.

Prerequisitesโ
Before using OpenMOLE, make sure that:
- Cormas is installed (see Download).
- Your model runs correctly inside Cormas.
- Your model defines parameters and probes.
- OpenMOLE is installed (follow the instructions on the Official OpenMOLE Website).
You can also try the OpenMOLE demo website: http://demo.openmole.org/app
Overviewโ
The workflow consists of four steps:
- Export the model from Cormas as a .cmx file.
- Create an OpenMOLE workflow describing the experiments.
- Run the workflow.
- Analyze the generated results.
Cormas model
โ
model.cmx
โ
OpenMOLE
โ
Thousands of simulations
โ
CSV
โ
Statistical analysis
Step 0. Get Yourself a Modelโ
In this tutorial we will use the Firefighters model as an example. However, the same workflow can be applied to any Cormas model.
Open Cormas and select "Models in this Image" from the top menu.
In the model browser:
- Select Firefighters from the list of available models.
- Click Load.

Once the model is loaded, you can run the simulation normally inside Cormas to verify that everything works correctly before using OpenMOLE.
Step 1. Export the Model to a Fileโ
Before OpenMOLE can execute a Cormas model, the model must be exported as a .cmx file.
Open the Models in this Image window again.
- Select the model you want to export.
- Click the small Export button represented by a floppy disk icon.
- Choose a destination directory.
- Save the file.
Cormas will create a .cmx file containing the complete model. This file contains everything needed to execute the model and can be transferred to another machine.
The remainder of this tutorial assumes that you have successfully exported a .cmx file.
Step 2. Prepare OpenMOLEโ
At this point you should have a model file such as: Firefighters.cmx. Open OpenMOLE and create a new empty project. Upload your model file to the project.
You will also need a helper file named cormas.oms. Download it from cormas.oms.
At the end of this tutorial your OpenMOLE project will contain four files:
Firefighters.cmx- the exported Cormas model,cormas.oms- the generic bridge between OpenMOLE and Cormas,firefighters.oms- the workflow describing the experiment.summary.omr- the results that will be generated by running the experiment.
What is cormas.oms?โ
The cormas.oms file provides the bridge between OpenMOLE and Cormas.
It defines a reusable task called CormasTask that:
- loads a
.cmxmodel, - initializes the simulation,
- sets parameter values,
- runs the model,
- collects probe values,
- returns the results to OpenMOLE.
In most cases you will never need to modify this file. It can be reused for all Cormas models.
Step 3. Create a Workflowโ
Next, create a new OpenMOLE script for your model.
In this example, we will create firefighters.oms with the following contents to explore how the number of firefighters impacts the number of steps that are needed to extinguish all fires:
import _file_.cormas._
val numberOfFirefighters = Val[Int]
val mySeed = Val[Int]
val stepsToExtinguish = Val[Double]
val runCormas = CormasTask(
image = "oleks42/cormas-openmole:latest",
modelFile = workDirectory / "Firefighters.cmx",
initSelector = "basicCreation",
stepSelector = "basicStep",
maxSteps = 50000,
stopCondition = "areAllExtinguished",
seed = mySeed,
parameters = Seq(
numberOfFirefighters -> "numberOfFirefighters",
),
probes = Seq(
stepsToExtinguish -> "currentTimeStep"
)
)
val exploration =
DirectSampling(
evaluation = runCormas,
sampling =
(mySeed in (1 to 20)) x
(numberOfFirefighters in (1 to 20 by 1))
)
exploration hook (workDirectory / "summary")
Understanding the Workflowโ
The workflow describes the experiment that OpenMOLE will execute. It is divided into three parts:
- Variable declarations
- Simulation configuration
- Parameter exploration
Declaring Variablesโ
OpenMOLE stores all simulation inputs and outputs in variables. Input variables provide values for model parameters before initializing the simulation. Output variables store the results collected from the simulation (probe values).
// Input variables
val numberOfFirefighters = Val[Int]
val mySeed = Val[Int]
// Output variables
val stepsToExtinguish = Val[Double]
Configuring the Simulationโ
The CormasTask describes how a single simulation should be executed.
val runCormas = CormasTask(...)
The Docker image contains Pharo, Cormas, and the code required to execute a simulation. OpenMOLE automatically downloads it if necessary:
image = "oleks42/cormas-openmole:latest"
Model file specifies which model should be executed:
modelFile = workDirectory / "Firefighters.cmx"
Init and step (control) selectors used to initialize the simulation:
initSelector = "basicCreation",
stepSelector = "basicStep"
Maximum number of steps - a safety limit preventing infinite simulations:
maxSteps = 50000
Stop condition is an optional argument that specifies a boolean method executed by a model. The simulation stops when the stop condition returns true, OR when the maximum number of steps is reached:
stopCondition = "areAllExtinguished"
If your model does not have a stop condition, use
stopCondition = ""
Finally, the seed allows OpenMOLE to repeat the simulation with different random seeds:
seed = mySeed
Defining Parametersโ
Parameters define which model settings can be modified by OpenMOLE. The left side is an OpenMOLE variable. The right side is the corresponding Cormas parameter name.
parameters = Seq(
numberOfFirefighters -> "numberOfFirefighters"
)
By default, parameters are defined on the model itself. If you want to set the parameters defined on entity classes, write them in a form ClassName.parameterName. In the following example, numberOfFirefighters and forestRatio are model parameters while the perceptionRange is a parameter of class FFFirefighter:
parameters = Seq(
numberOfFirefighters -> "numberOfFirefighters",
forestRatio -> "forestRatio",
perceptionRange -> "FFFirefighter.perceptionRange"
)
Remember that if you add more parameters, you must define the variables for them in the top part of your workflow file:
val perceptionRange = Val[Int]
Defining probesโ
Probes define which values should be collected when the simulation finishes. The left side is an OpenMOLE variable. The right side is a selector executed on the model. The selector is executed once the simulation finishes.
probes = Seq(
stepsToExtinguish -> "currentTimeStep"
)
Each probe will be executed on a model and must return a number.
All probe variables must be of type Double.
Defining the Explorationโ
The final section tells OpenMOLE which parameter combinations should be explored. You can read more about different sampling techniques on the Official OpenMOLE Website.
val exploration =
DirectSampling(
evaluation = runCormas,
sampling =
(mySeed in (1 to 20)) x
(numberOfFirefighters in (1 to 20 by 1))
)
Be careful because sampling can quickly make the exploration space very big and if you sample many variables at once, your experiment may take a very long time to complete. For example, if you sample 20 different values for 4 different variables, that would give you 20 * 20 * 20 * 20 = 160,000 simulation runs.
In the example above, we are running 400 simulations and they take about 10 min to complete on my machine (Mac M4 Pro).
Saving the Resultsโ
The last line of our workflow specifies that the results must be saved in the summary file of our work directory:
exploration hook (workDirectory / "summary")
Step 4. Run the Workflowโ
Click the Run button and wait for the simulations to finish.
Depending on the number of parameter combinations and repetitions, this may take anywhere from a few seconds to several hours.

Step 5. Download the Dataโ
Once the execution is complete, OpenMOLE will create a new file named summary.omr in your project directory.
Click on this file to explore the results. OpenMOLE will display them as a table where each row corresponds to a single simulation run and contains:
- parameter values,
- random seed,
- probe values.

You can then export the results as a CSV file and analyze them using R, Python, Excel, LibreOffice Calc, or any other statistical software.
The exported dataset can be used to create plots, compute summary statistics, perform sensitivity analyses, compare scenarios, or calibrate model parameters.
Step 6. Visualize the Resultsโ
You can now visualize your data with any statistical software.
For example, the figure below shows a scatter plot of the Firefighters experiment results. Each point represents a single simulation run. The x-axis corresponds to the number of firefighters, while the y-axis shows the number of simulation steps required to extinguish all fires.

This visualization makes it easy to identify the overall trend: increasing the number of firefighters generally reduces the time needed to extinguish the fire, although individual runs may still exhibit significant variability due to randomness.
The next figure presents the same results using box plots.

In this visualization, we only consider runs with at least three firefighters. Including the cases with one or two firefighters stretches the scale considerably and makes the differences between the remaining configurations more difficult to observe.
Each box summarizes the distribution of the time to extinguish for a given number of firefighters. The central line represents the median, the box contains the middle 50% of observations, and the individual points correspond to the raw simulation runs.
Compared to the scatter plot, box plots make it easier to compare the variability and distribution of outcomes across different parameter values.
Conclusionโ
At this point you have completed a full OpenMOLE workflow: exporting a Cormas model, defining an experiment, running hundreds of simulations, and analyzing the results. You can now extend the workflow with additional parameters, probes, sampling strategies, sensitivity analyses, calibration methods, or distributed execution on remote machines.