The Universal Cycler Protocol (UCP) is a flexible YAML-based language for defining battery cycling experiments. It allows you to create complex experimental sequences with programmatic control.Documentation Index
Fetch the complete documentation index at: https://docs.ionworks.com/llms.txt
Use this file to discover all available pages before exploring further.
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.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
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.
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.
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(),ifelse(), etc.
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.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.).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.
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:
| Column | Description |
|---|---|
Frequency [Hz] | Excitation frequency |
Z_Re [Ohm] | Real part of impedance |
Z_Im [Ohm] | Imaginary part of impedance (negative for capacitive behavior) |
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.