| name | sim-results |
| description | Work with Ionworks simulation results: fetch time series and step data, understand the response shape, plot signals. Use when the user wants to analyse, plot, or extract numbers from a simulation result. Triggers: "simulation result", "sim output", "plot simulation", "time series", "simulation data". |
Simulation Results
Reference for fetching and working with Ionworks simulation output.
Fetching results
from ionworks import Ionworks
client = Ionworks()
result = client.simulation.get_result(simulation_id)
result is a SimulationResult dataclass with three fields:
| Field | Type | Description |
|---|
result.time_series | DataFrame | One row per time point; columns are signal names |
result.steps | DataFrame | One row per protocol step |
result.metrics | dict[str, Any] | Scalar metrics; not tabular |
DataFrame is polars by default. Use set_dataframe_backend("pandas") to
get pandas DataFrames instead:
from ionworks import set_dataframe_backend
set_dataframe_backend("pandas")
result = client.simulation.get_result(simulation_id)
Time-series columns
| Column | Resets per step? | Notes |
|---|
Time [s] | No | Cumulative across the whole run |
Voltage [V] | No | Cell terminal voltage |
Current [A] | No | Positive = discharge, negative = charge |
Power [W] | No | |
Temperature [degC] | No | |
Step count | No | Cumulative step index, 0-based |
Cycle count | No | Cumulative cycle index |
Discharge capacity [A.h] | Yes | Resets to 0 at each step boundary |
Charge capacity [A.h] | Yes | Resets to 0 at each step boundary |
Step capacity [A.h] | Yes | Resets to 0 at each step boundary |
The capacity-reset caveat
Discharge capacity [A.h] and Charge capacity [A.h] reset to 0 at
every step boundary. Do not plot them directly — you will get a sawtooth.
To get a continuous cumulative capacity trace, sum the last value of each
step and carry an offset forward:
import polars as pl
ts = result.time_series
step_ends = (
ts.group_by("Step count")
.agg(
pl.last("Discharge capacity [A.h]").alias("step_disch"),
pl.last("Charge capacity [A.h]").alias("step_chg"),
)
.sort("Step count")
.with_columns(
(pl.col("step_disch") - pl.col("step_chg"))
.cum_sum()
.shift(1)
.fill_null(0)
.alias("offset")
)
)
ts = ts.join(step_ends.select(["Step count", "offset"]), on="Step count", how="left")
ts = ts.with_columns(
(pl.col("Discharge capacity [A.h]") - pl.col("Charge capacity [A.h]") + pl.col("offset"))
.alias("Cumulative capacity [A.h]")
)
Steps DataFrame
result.steps has one row per protocol step. Typical columns:
| Column | Description |
|---|
Step count | Step index (matches time_series["Step count"]) |
Step type | "Constant current discharge", "Constant current charge", "Rest", etc. |
Duration [s] | Step duration |
Use Step count to join steps back to the time series:
seg = result.time_series.filter(pl.col("Step count") == step_id)