Two easy ways to perform simulations in atoti

One of the key strengths of atoti is that it was built to natively propose effortless ways to perform simulations on your data. In this article, we will detail two ways of building simulations in atoti.

#1 Data Simulations

This type of simulation is particularly powerful in data models where multiple tables are joined together.

It simply consists in creating a new scenario where the content of a data table (or part of it) has been replaced by new data. This is done with a one-liner in atoti:

name_of_table_to_replace.scenarios["Name of new scenario"].load_pandas(new_table_data)

And that is it. A new scenario has been created in which all the previously defined metrics will be re-computed using the new data for this particular table. No need to duplicate datasets, redefine measures or restart the cube, every metric will be re-computed on the fly in the new scenario when needed. The “Simulation” hierarchy natively lets you compare the metrics across scenarios, be it with a query or from atoti’s UI.

Note that the new table data can be loaded from a pandas DataFrame as in the example above, but also from a CSV with load_csv, a spark DataFrame with load_spark or parquet files (see available data sources in the documentation).


In this example we have a CSV file containing sales forecasts and the corresponding  amounts in a specific currency:

We load the CSV file into a sales_forecast_store:

sales_forecast_store = session.read_csv("sales_forecast.csv", sep=";")

We also have a CSV file with conversion rates:

Then, we load the rates into a conversion_rates_store:

conversion_rates_store = session.read_csv("conversion_rates.csv", keys=["currency"])

Next, we can join these two tables, and create a cube and a “Total amount” measure that will compute the total amount in EUR.

sales_store.join(conversion_rates_store, mapping={"currency":"currency"}))
cube = session.create_cube(sales_store)
m["Conversion Rate"] = conversion_rates_store["conversion_rate_to_eur"]
m["Total amount in EUR"] = atoti.agg.sum(
    m["amount.SUM"] * m["Conversion Rate"],

A quick cube.visualize() enables us to visualize the result:

Then if we have a new sales forecast, for example, if we want to test the impact of a new forecast method:

sale_id amount currency
1 400 EUR
2 330 EUR
3 190 EUR
4 100 USD
5 520 USD
6 150 USD
7 8000 JPY
8 15000 JPY

We can simply create a new scenario where everything is identical except this new sales forecast:

sales_forecast_store.scenarios["New Forecast"].load_csv("sales_with_new_forecast.csv")

A cube.visualize() enables us to immediately compare the total amount across the different scenarios using the standard “source simulation” hierarchy:

#2 Measure simulations

Another way to create simulations in atoti is to create a scenario where one or more measures are calculated differently.

In its most simple form, this type of simulation enables you to create a new scenario where some of the measures are either:

  • Replaced: The value of certain measures are replaced by a value you specify
  • Multiplied: Some measures are multiplied by a factor you specify
  • Incremented: A value you specify is added to certain measures

Additionally from that, you can specify a cube level at which you want to perform the changes using the per parameter.

First, you need to setup the simulation:

simulation = cube.setup_simulation(
    "Simulation hierarchy name",

Then you can create as many new scenarios as you want where measures are replaced/multiplied/incremented by the values you want in one line for each scenario:

simulation.scenarios["Scenario 1"] += (replace_value,multiply_factor,increment)    

simulation.scenarios["Scenario 2"] += (replace_value2,multiply_factor2,increment2)

That is all you need to do. Similar to data simulations, new scenarios have been created and all metrics will be re-computed in real-time when you query or view them in the UI. A new simulation hierarchy, with the name provided, has been created to let you compare scenarios easily.

This type of simulation can be used for many forecasting scenarios where you modify the forecasts and see the impact on all other metrics.

It is particularly powerful when the value of some measures depends on those you replace: the downstream measures also get cascaded and updated in real time.

In our soccer premier league notebook, we use it to simulate various scoring systems using points for match wins/ties/losses and compare the impact on the standings.


Continuing with the previous sales and currencies example, we will setup a simulation on conversion rates to measure the impact on the total amount under different currency conversion assumptions:

convserion_rates_simulation = cube.setup_simulation(
    "Conversion rates simulations",
    replace=[m["Conversion Rate"]],

Then we can easily simulate a scenario where the euro drops 10% in value compared to the dollar (rate from 0.92 to 1.02)  and compared to the Japanese yen (rate from 0.0086 to 0.0096):

euro_drops_10_per = convserion_rates_simulation.scenarios["Euro drops 10%"]
euro_drops_10_per += ("USD", 1.02)
euro_drops_10_per += ("JPY", 0.0096)

Scenario comparisons can be performed in the “Conversion rate simulations” hierarchy that we created on the simulation setup. We will, as usual, use a cube.visualize() for that:

#3 Bonus: creating simulations from atoti’s UI

Do you want to explore your data interactively and create simulations at the same time? This is actually possible in atoti’s UI.

Once you have set up a simulation as in the previous section, instead of creating the new scenarios with Python code, you can directly do it in atoti’s UI with the measures simulation widget. Here is an example, starting from the simulation of the previous section:

You can get a link to atoti’s UI of your notebook using session.url.

If you want to perform more advanced atoti simulations or find additional details have a look at the corresponding documentation page.

Latest posts

Understanding Logs in Atoti
From the default log to how to configure additional logging Application logs are extremely important in any system! Most commonly, they are used to troubleshoot any issue that users may encounter while using an application. For instance, developers use them for debugging and the production support crew uses them to investigate outages. Not just that, in production, they are used to monitor an application’s performance and health. For instance, monitoring tools can pick up certain keywords to identify events such as “server down” or “system out of memory”. It can also serve as an audit trail to track user activity...
Atoti: Working with dates in Python
What is the most problematic data type you have ever dealt with when working with data? I would say dates! Depending on the locale, dates come in different formats such as YYYY-mm-dd, d/m/YYYY, d-mmm-yy etc. Not to mention, sometimes it comes with timestamps and time zones! We can let programs infer the date format or explicitly cast the data to date with a specific format e.g. in Python with Pandas DataFrame: What if we open the CSV file in Microsoft Excel, update it, and try to read it again? The above code snippet will throw out exceptions such as this:...
Understanding conditional statements in Atoti
When do we use filter, where and switch statements? We know that we can perform aggregations and multi-dimensional analysis with Atoti. Aggregation is not always as simple as 1 + 2. Sometimes we end up in an “if…else” situation, and that is where conditional statements come in. Let’s explore some examples with the XVA use case from the Atoti CE Notebook Gallery. Some definitions before moving on: Measures – we refer to metrics or quantifiable data that measure certain aspects of our goals. In the code snippets below, they are represented by measure[<name of metrics>]. Members of a level –...

Join our Community

    Like this post ? Please share

    Follow Us

    atoti Free Community Edition is developed and brought to you by ActiveViam. Learn more about ActiveViam at