Global Configuration
You can define global settings for the entire protocol under the optionalglobal key.
initial_temperature: The starting temperature for the experiment in degrees Celsius. Defaults to25. When used in a design optimization, this value is automatically converted to Kelvin and applied as both the initial and ambient temperature for the simulation.initial_state_type: How to define the initial state of the cell. Allowed values:soc_percentage: Interpretinitial_state_valueas a percentage of state of charge (0–100).voltage: Interpretinitial_state_valueas a starting voltage in Volts.
initial_state_value: The initial value for the selected type.resolution: The time resolution for the simulation output in seconds. Defaults to60.
Safety Limits
You can define optional safety limits for the simulation. If any of these are breached, the simulation jumps to a recovery step (goto) or, if no goto is supplied, ends the test.
Each limit may be given as a bare number or as an object with an explicit goto so that different fault conditions can route to different recovery steps:
- If the triggering limit has its own
goto, jump there. - Otherwise, if
safety_limits.gotois set, jump there. - Otherwise, the test ends.
If a step’s termination condition (see below) has the same value as a global
safety_limit, the safety limit takes precedence.Simulation Steps
Each simulation step is defined as a dictionary with a single key that defines the step’s direction. The value of this key is a dictionary containing the step’s parameters. The primary step directions are:Rest: The cell is at rest.Charge: The cell is being charged.Discharge: The cell is being discharged.Drive: A drive cycle step (see below).EIS: An Electrochemical Impedance Spectroscopy step (see below).
Step Parameters
mode: The control mode for the step (e.g.,C-rate,Current,Power,Voltage). Required unless the step isRest.value: The setpoint for the control mode. This can be a fixed number or a dynamic expression.duration: The maximum duration of the step in seconds.ends: A list of one or more cut-off conditions. A step must have either adurationor at least oneendscondition.temperature: (Optional) The ambient temperature for this specific step in Celsius, overriding the global setting.resolution: (Optional) The time resolution for this specific step, overriding the global setting.set_variable: (Optional) A list of variables to calculate and set after the step completes.note: (Optional) A string for informational purposes.
Parameterized Steps with input['...']
You can use input['...'] syntax in value, duration, and ends fields to create parameterized protocols. When running the protocol, the actual values are provided at runtime.
resolution, global settings, and set_variable expressions. See Experiment Templates for complete examples.
Termination Conditions (ends)
The ends conditions define when a step should terminate.
- Supported Types:
Voltage,Current,C-rate,Capacity,Temperature(case-insensitive). - Supported Operators:
<and>. - Sign Convention: For
Current,C-rate, andCapacityterminations, always provide a positive value. The engine automatically handles the internal sign convention (e.g., negative current for charge). ForVoltageandTemperature, signs are respected as written. - Derivative Terminations: To terminate based on the rate of change of a variable, use the format
"d/dt(Type) operator value".
If a step’s termination condition is met at the very beginning (e.g., trying
to charge a battery that is already at 4.2V), the step will be skipped. Any
goto transitions on that termination condition will not be executed.
The step’s set_variable entries are still evaluated, so accumulators and
reference values you compute at the end of a step remain consistent whether
the step ran or was skipped.Example: Derivative Termination
Derivative-based terminations are useful for ending a step based on the stability of a signal. For example, a constant-voltage charge phase can be terminated when the current stops changing, which indicates the battery is full.Example: CCCV Charge
Ambient Temperature Steps
TheAmbient Temperature step changes the ambient (chamber) temperature mid-protocol. It is an instantaneous step — it sets the chamber setpoint and immediately advances to the next step; the simulation continues at the new ambient temperature until another Ambient Temperature step is reached.
temperature_setpoint: Required. The new ambient temperature in degrees Celsius. Must be greater than absolute zero.temperature_ramp_rate: (Optional) Ramp rate in °C/min. Defaults to2.0.
An
Ambient Temperature step overrides the global.initial_temperature
setting (and any prior step’s temperature override) from that point in the
protocol onward.EIS Steps
TheEIS step performs an Electrochemical Impedance Spectroscopy measurement at the current state of the cell.
lower_frequency: The lower frequency bound for the EIS sweep in Hz.upper_frequency: The upper frequency bound for the EIS sweep in Hz.
EIS steps are not supported in design optimization experiments. Use EIS steps in standalone simulations instead.
pybamm.EISSimulation under the hood) and Equivalent Circuit Models. For an ECM the impedance is computed analytically from the series resistance parameter R0 [Ohm] and each indexed R_rc (i) [Ohm] / C_rc (i) [F] parallel branch — so the Battery Cycler Simulator, which uses an ECM, can run EIS steps from uploaded protocols (e.g. BioLogic PEIS/GEIS techniques) without any extra configuration. Analytic ECM EIS requires the resistance and capacitance parameters to be constants; SOC- or current-dependent ECM parameters are rejected with a clear error.
In the simulation results view, each EIS step is marked with a vertical line on the time-domain plots at the instant the impedance sweep was taken; hovering the marker shows an EIS step N tooltip so you can correlate the Nyquist trace with its position in the cycling history.
Example: Basic EIS
Perform an EIS measurement after a 30-minute rest period.Example: EIS with Dynamic Frequencies
The frequencies can be calculated dynamically using variables.Control Steps
Control steps are used for programmatic logic and do not run a simulation. They are ideal for setting variables or creating loops withgoto.
Control step parameters
set_variable: (Optional) A list of variables to set (see dynamic behavior with variables).goto: (Optional) The name of the step block to jump to after executing this control step. This enables non-sequential control flow, such as branching to different steps based on variable values.
"Increment cycle number": Increments the internal cycle counter."End"or"Pause": Terminates the entire simulation.
Reserved goto targets
In addition to jumping to a named step block, goto accepts the reserved target End Test, which stops the simulation immediately. This works from both step termination conditions (ends) and from Control step goto fields, and is also valid inside subschedules — jumping to End Test from a subschedule ends the entire test, not just the subschedule.
A Control step’s goto runs unconditionally every time the step is
entered, so use it to terminate a branch you have already routed into:
goto to a step termination
condition instead — the jump fires only when that condition is met:
End Test when you want a fault condition or logic branch to terminate the run explicitly rather than falling through to the next step.
Dynamic Behavior with Variables
You can define variables usingset_variable and use them to create dynamic, responsive protocols.
name: The name of the variable. Must start withVAR_.eval: A Python expression to be evaluated. The result must be a number.
eval expression can use:
- User Inputs:
input['...'] - Other Variables: Any
VAR_variable already defined. - Special Variables:
t(step-relative time in seconds),Cycle(0-indexed cycle counter). - Simulation Results:
Voltage,Current, etc. from the previous step. - Helper Functions:
first(),last(),mean(),abs(),sign(),min(),max(),ifelse().
Initialising variables
Expressions are evaluated eagerly —ifelse(condition, A, B) evaluates both branches before picking one — so a variable referenced anywhere in an expression must already exist. Use a Control step at the top of the protocol to seed every variable you’ll write to:
Protocols imported from a Maccor
.000 file automatically gain a leading Initialize Variables Control block that seeds every referenced VARn to 0 — this mirrors the way real Maccor cyclers default user variables in hardware. You’ll see it at the top of the parsed UCP YAML.Example: Time-Varying Control
Linearly ramp the C-rate from 0.1 to 1.1 over one hour.sign() that charges for the first 30 s and then discharges for the next 30 s:
When a step value is an explicit function of
t, the waveform may legitimately drive the cell in both directions during the single step. The usual rule that a Charge step can only carry an upper voltage cut-off (and a Discharge step a lower one) is relaxed for time-varying values, so you can attach safety cut-offs on both sides.Example: Conditional Logic
Use theifelse helper to create conditional logic. This example defines a subsequent step’s direction based on the final voltage of the previous step.
Step Blocks
Steps can be grouped into named blocks. This is essential forgoto targets and for repeating a sequence of steps using the repeat keyword.
A block’s name cannot be one of the reserved step types (
Charge,
Discharge, Rest, Control, etc.). The reserved goto target End Test
is allowed as a jump destination but cannot be used as a block name.Drive Cycles
You can use a drive cycle for complex profiles by passing data to thesolve_protocol function in your Python code and referencing it in the YAML.
- In Python: Pass a
drive_cyclesdictionary where values are 2-column NumPy arrays (time, value). - In YAML: Use the
Drivedirection. Thevalueis the name of the drive cycle from the dictionary. The duration is defined by the time column in the data. mode: Controls how the second data column is interpreted. UseCurrent(default, amps) for a current profile, orPower(watts) for a power profile. Voltage cut-offs can be attached to either mode viaends.
Subroutines
Subroutines are reusable sequences of steps defined in your Python code and called from the YAML protocol. This is useful for standard procedures like a CCCV charge.- In Python: Pass a
subroutinesdictionary tosolve_protocol. The values are lists of steps. - In YAML: Use the
Subroutinestep type with the name of the subroutine to execute.
Output
The protocol solver returns a pandas DataFrame containing the results of the simulation, including time, voltage, current, temperature, cycle number, and any custom variables defined withset_variable.
For EIS steps, the output DataFrame includes frequency-domain impedance data instead of time-domain data:
During EIS steps, time-domain columns (
Time [s], Voltage [V], Current [A]) are present but contain NaN values. The Step count column identifies which step each row belongs to, allowing you to separate EIS data from cycling data.