How It Works
The process is simple: upload your protocol, configure your cell, and run the simulation.- Upload: Upload your protocol file in the raw format (e.g. XML or JSON). The system automatically detects the format and parses it.
- Configure: Set the parameters for the cell you want to simulate.
- Simulate: Run the simulation and analyze the results.
Step 1: Upload Your Protocol File
You can start by uploading a protocol file from your computer. We currently support files from:- Arbin
- BioLogic (.mps, .bttest)
- Maccor (.xml, .csv)
- Neware
- Novonix (.pro2)
- PyBaMM experiment strings (.txt)
Gamry
.dta files are not protocol files and cannot be uploaded here. To
import EIS measurement data from Gamry instruments, use the
ionworksdata library — see
Data format for details.Required Additional Files
Some protocols reference external files for complex steps, such as custom drive cycle waveforms or reusable subroutines. If your protocol requires such files, the simulator will detect this and prompt you to upload them.Step 2: Review and Configure
After parsing, you can review the protocol and set up the simulation.Protocol Steps
The simulator displays the parsed protocol in three different formats, accessible via tabs:- Human-Readable: A simplified, easy-to-read summary of the steps in your protocol.
- UCP (YAML): The full protocol translated into our Universal Cycler Protocol format. This shows the detailed underlying structure that will be executed.
- Raw: The raw text content of the file you uploaded.
Cell Configuration
To run a meaningful simulation, you need to provide some basic information about the battery cell you want to test. This configures the underlying Equivalent Circuit Model (ECM) with one RC pair, using OCV and resistance parameters matched to your cell.- Chemistry: Select the cell chemistry from a list of pre-configured options. Full-cell chemistries (e.g.,
NMC/Graphite,LFP/Graphite) and Li-metal half cells (e.g.,NMC/Li metal,Graphite/Li metal,LFP/Li metal) are available. This determines the OCV curve, anode/cathode open-circuit potentials, and resistance values used by the model. - Cell capacity (Ah): The nominal capacity of your cell. The ECM parameters are scaled to match this capacity.
- Resistance scale (%): Adjusts the model’s internal resistance relative to the default value for the selected chemistry. The default is
100%(no change). For example, set this to200to double the resistance or50to halve it. Useful for approximating cells with higher or lower impedance than the chemistry default. - Initial SOC (%): The State of Charge of the cell at the beginning of the simulation.
- Temperature (°C): The ambient temperature for the simulation.
Advanced configuration
Under the Advanced section, you can configure optional rules that modify simulation behavior at runtime.Termination conditions
Termination conditions let you stop a simulation early when a variable reaches a target value. This is useful for long cycling protocols where you only need to simulate a limited number of cycles or a specific amount of time. Each condition specifies a variable, a comparison operator (==, !=, >, <, >=, <=), and a value. The simulation stops as soon as any condition is met.
The variable dropdown is organized into two groups:
- Built-in — variables automatically provided by the simulation engine regardless of the protocol
- Protocol variables — variables defined in and extracted from the parsed protocol
Total time
Total time is a built-in variable that tracks the cumulative elapsed simulation time in seconds. Use it to cap how long a simulation runs, independent of the protocol’s own step logic. When you select Total time, a unit picker appears next to the value field so you can enter the threshold in seconds, minutes, hours, or days. The value is automatically converted to seconds for the simulation engine. For example, to stop a long cycling protocol after 2 hours, add a termination condition where Total time >= 2 hours.If the protocol defines its own variable named
total_time, the protocol’s variable takes precedence and the built-in value is not injected.Protocol variables
Protocol variables are extracted from your uploaded protocol file. For example, to stop an Arbin protocol after 3 cycles, you can add a condition wherePV_CHAN_Cycle_Index >= 4. Arbin increments PV_CHAN_Cycle_Index at the start of each cycle, so the index reaches 4 only when the 4th cycle begins — meaning 3 full cycles have already completed.
When a termination condition triggers, the reason is displayed in the simulation metrics using the human-readable form (e.g., “Early termination reason: Total time >= 2 hours”).
Variable callback rules
Variable callback rules let you dynamically update protocol variables during the simulation based on conditions. Each rule specifies a condition (variable, operator, value) and a set of variable updates to apply when the condition is met. For example, you could create a rule that increases the C-rate after a certain number of cycles: whenPV_CHAN_Cycle_Index >= 3, update Current(A) to a higher value. This lets you simulate multi-phase protocols where charging or discharging parameters change at specific points during cycling.
Step 3: Run Simulation & Analyze Results
Once everything is configured, click Run Simulation. The simulator will execute the protocol against the configured cell model. You can cancel a running simulation at any time by clicking the Cancel button on the simulation page. This is useful for long-running protocols where you can already see the results you need.Simulation results
Plots
The primary output is an interactive plot of your simulation data over time. By default, Voltage and Current are shown, but you can configure exactly which variables appear. Click Configure Plot to open the plot settings drawer. Under Time Series, toggle any of the available variables on or off:| Variable | Unit | Description |
|---|---|---|
| Voltage | V | Cell terminal voltage |
| Current | A | Applied current |
| Temperature | °C | Cell temperature (when available) |
| Charge capacity | Ah | Cumulative charge capacity |
| Discharge capacity | Ah | Cumulative discharge capacity |
| State of charge | % | Cell state of charge (when available) |
| Step count | Overall step index | |
| Cycle count | Current cycle number | |
| Step count (within cycle) | Step number within the current cycle |
Key metrics
Below the plot, you will find key performance indicators calculated from the simulation, including:- Total Time
- Charge Throughput (Ah)
- Energy Throughput (Wh)
- Early termination reason (if a termination condition was triggered)
Fullscreen mode
Click the fullscreen icon in the top-right corner of the plot to expand it to fill the screen. The fullscreen view includes the same Configure Plot button, so you can adjust which variables are shown without leaving fullscreen.Download CSV
Click Download CSV next to Configure Plot to export the full simulation time series as a CSV file (simulation_data.csv). The download always contains the complete simulation, even when you’ve zoomed into a window on the plot.
The file includes every time-series variable produced by the simulation (Voltage, Current, Temperature, capacities, Step count, Cycle count, and any additional protocol variables), plus step-level columns expanded to match each time point. Use it to bring results into Excel, pandas, MATLAB, or your own analysis tooling without re-running the simulation.
By simulating your protocols, you can catch errors, validate your experimental design, and gain confidence before committing time and resources to a real test.
Exporting UCP to a vendor protocol file
The conversion also runs in reverse: you can take a protocol authored in UCP and export it as a native file for Maccor, Neware, Arbin, BioLogic, or Novonix. This is useful when you’ve designed and validated a protocol in Ionworks and want to run it on physical hardware. Use theclient.protocol.convert method in the Python API to perform the conversion programmatically.
Because vendor formats vary in expressiveness, not every UCP construct round-trips perfectly. See Differences between commercial protocols below for the major gotchas, and Export-time validation for the specific UCP features each target format rejects upfront. We recommend re-importing the converted file using the upload flow above to confirm it parses back into the steps you expect before running it on a cycler.
Export-time validation
When you convert a UCP protocol to Arbin or Maccor, the converter walks the protocol first and rejects features that can’t be faithfully represented in the target format. You get aValueError naming the offending step rather than a file that silently misbehaves on the cycler.
Arbin rejects:
EISsteps — Arbin schedules have no impedance-sweep step type.Subroutinesteps — there’s no equivalent step type.- Compound
And/Orend conditions — Arbin step limits accept a single equation per limit. - Maccor user variables (
VAR1,VAR2, …) referenced in step values orVariableEndexpressions — Arbin has no runtime variable namespace for them.
- Zero-duration
Reststeps — Maccor requires every step to have at least one nonzero termination. (This is most commonly hit when round-tripping an Arbin “Internal Resistance” step through UCP.)
Cross-cycler variable translation
When a UCP protocol was originally parsed from one vendor and is exported to another, the converter rewrites variable names and cycle-index comparisons so the semantics survive translation:PV_CHAN_Cycle_Index,PV_CHAN_Voltage,PV_CHAN_Current,PV_CHAN_Charge_Capacity/PV_CHAN_Discharge_Capacity,PV_CHAN_Step_Time(Arbin) ↔CYCLE,VOLTAGE,CURRENT,CAPACITY,STIME(Maccor). Both Arbin capacity variants map to Maccor’s singleCAPACITYtoken; the reverse path (Maccor → Arbin) emitsPV_CHAN_Capacity.- Arbin’s
PV_CHAN_Cycle_Indexis 1-indexed while Maccor’sCYCLEis 0-indexed. Numeric cycle-index comparisons are shifted by 1 in either direction so the same set of cycles is matched. For example, an Arbin endPV_CHAN_Cycle_Index <= 2becomes a Maccor User Def endCYCLE <= 1. - UCP-canonical short names (
Capacity,Voltage,Current,Duration,Energy) used inset_variableexpressions are expanded back to Arbin’sPV_CHAN_*tokens on Arbin export so the round-trip parser resolves them correctly.
And / Or ends and VariableEnd expressions exported to Maccor are emitted as a single User Def end with & / | operators.
Differences between Commercial Protocols
Much of the challenge in converting between the different protocols is not the syntax, but the fundamental differences in how the cyclers define the logic to follow the same sequence of steps. In this section, we’ll cover some implementation differences between the Ionworks Universal Cycler Protocol, and the protocols from the cyclers we support.CCCV steps
Most cyclers define CCCV steps as one step with voltage as a “limit” field:- Maccor: Uses a constant current step, with voltage as a “limit”. Maccor also supports a native single-step
Chg Func CCCV/Dis Func CCCVstep type that combines the CC and CV phases (with the CV cutoff specified as a current limit). - Neware: Specifies both current and voltage as a “limit”
- Novonix: Specifies both current and voltage as fields, and uses step type to differentiate between CC (voltage is a cutoff) and CCCV (transition to voltage and hold until a current cutoff)
Chg Func CCCV / Dis Func CCCV step, the parser expands it into the equivalent two-step UCP block automatically.
Header metadata
Some formats (e.g., Novonix.pro2) include top-level header data (Version, LastUpdated, Charger). This metadata is preserved in UCP under header and is used for round-trips when converting back to the original format.
Functional expressions
Maccor supports functional expressions (e.g.,VAR1*0.5) for step values and end conditions. These are carried through UCP as strings and round-tripped using vendor-specific constructs (e.g., Maccor “User Def” end entries), so the meaning is preserved even if another format lacks an exact equivalent.
Nested loops
For formats that use Do/Loop constructs (Maccor), nested loops are numbered (Do 1/Loop 1, Do 2/Loop 2, …) to reflect structure. UCP expresses loops withrepeat on a block; when converting back to Maccor, Do/Loop numbering is generated from the block nesting depth.
Report/Record/Save data/Resolution
This is the field that defines how often the cycler will save data to the output time series.- Maccor uses the “Report” field and allows time, current, voltage, and temperature
- Neware uses the “Record” field and allows time, current, and voltage
- Novonix uses
StepConditionsentries withConditionType: "Save data"and allowsΔt,ΔV, andΔI. - UCP uses the “Resolution” field, which can be set globally and overridden for each step, and currently only supports time
Loops
For loops, there are two fundamental approaches:- Nested Steps: Define the loop as a step block with a nested step, with a
repeatparameter specifying the number of times to repeat the loop. This is the more modern approach, similar to how loops are defined in modern programming languages such as Python.
- UCP (using step blocks)
- Novonix (using
ChildProtocolStepListwithTimesToLoop).
Increment cycle number
- Novonix uses
StepType = 6to increment the cycle counter. In UCP this maps to an auxiliaryIncrement cycle numberstep. - Arbin uses the built-in
PV_CHAN_Cycle_Indexvariable to track the current cycle. When this variable is incremented via aSet Variable(s)step, it maps to both aset_variableaction and anIncrement cycle numberauxiliary step in UCP.
- Goto/State machine: Define special steps like “start loop” and “end loop”. This is the more legacy approach, similar to older programming languages such as Fortran.
- Maccor (using a
Dostep to start the loop, and aLoopstep to end the loop) - Neware (using a special step type to loop back to a specified previous step a certain number of times)
- Arbin (using limit conditions with goto targets to jump between steps, and
Set Variable(s)steps to manage counters)
Cycle-index branching (Arbin)
Arbin protocols commonly usePV_CHAN_Cycle_Index to implement cycle-dependent branching, where different parameters are applied on different cycles. When parsed into UCP, this pattern is represented using control steps with set_variable actions and goto targets.
Drive cycles (BioLogic)
BioLogic.mps protocols use User Profile steps to apply drive cycles (for example, a driving current profile). The waveform is embedded directly in the .mps file as an Urban Profile Table appended after the technique block, so no additional upload is required. When parsed into UCP, a User Profile step maps to a Drive step: the table’s time column defines the step duration, and the value column drives the cell in the corresponding control mode (e.g., Current).
PyBaMM experiment strings
You can upload a plain text file containing PyBaMM experiment strings directly into the Battery Cycler Simulator. The system auto-detects the format and converts the steps into UCP, with list repetition blocks mapping to step blocks with arepeat count.
Basic syntax
For plain steps, each line in the file is a single PyBaMM step string. The supported step types are:Charge at <value> <unit>— constant current, C-rate, or power chargeDischarge at <value> <unit>— constant current, C-rate, or power dischargeHold at <value> V— constant voltage holdRest for <duration>— open-circuit rest period
until and duration constraints with for:
List repetition
To repeat a sequence of steps multiple times, wrap them in square brackets and multiply with* N. This is equivalent to Python’s list repetition syntax.
repeat: 100, rather than duplicating the steps 100 times. You can mix repeated blocks with plain steps:
Nested repetition
Repeated blocks can be nested for more complex protocols:Cycle groups
Use parentheses inside a list to mark a group of steps as a cycle. This automatically inserts an “Increment cycle number” step at the end of each repetition, so cycle-level metrics are tracked correctly:Tuple cycle groups must always be inside a list. Use
[(...)] * N — not (...) * N.