Skip to main content
Stacked and multi-series plots, and pipelines that record the data they ran against

Stacked and multi-series plots

Measurement time-series plots gain stacked rows, the way a cycler’s own software lays them out. Add row puts a new band under the plot on the same x axis, each with its own left and optional right axis, and a single hover box reads every band at the cursor. Every line on an axis shares that axis’s colour and differs by dash, so matching a line to its scale never depends on colour alone. The right axis of the first row is now drawn dotted.Analysis plots draw more than one series. Split a table by a text column (charge vs discharge pulses, for example) to get one line per value instead of a zig-zag joining them, overlay several columns, put one on a right axis, and stack rows as on the measurement plot. Analyses can carry named views — OCV and resistance against SOC, pulse power against SOC, capacity against C-rate — and the view on screen can be linked directly.

Pipelines record exactly which data they ran against

Every pipeline element now records the measurements and time windows it read. A new panel on the pipeline page shows each pinned span next to the measurement’s current span, so you can see at a glance when a measurement has grown since a fit was run, or is no longer available. Existing pipelines have been backfilled.
Improvements
  • The Validation Report compares temperature as well as voltage when the model is thermal and the measurement has a temperature channel. A pair whose measurement was never instrumented says so in one line rather than drawing empty axes.
  • Simulation time-series plots take a step filter in the same syntax as the measurement filters (1:3,5), can use any loaded column as the x axis (voltage against capacity, for example), and show cycle and step on hover.
  • Validation sections load in a single request, and returning to the full view after zooming no longer refetches.
  • Simulation results load faster, as compact files the page can zoom within without going back to the server.
  • Parameterized-model lists are lighter for projects with uploaded custom models, which were sending the full model with every row.
  • The in-app assistant starts answering within a few seconds. It now says what it is looking up before it looks, and finds a record you name by searching for it rather than walking the whole project.
  • Fit progress is tracked per array element and per start, so a multistart or array fit reports each run separately.
  • Global search opens a cell instance at its own page, rather than its specification’s list of instances.
  • No white flash when loading the app in dark mode.
  • Name columns keep a usable width on narrow screens; the parameterized-model ID column is shorter and copies the full ID on click.
Fixes
  • Pulse sections find every pulse. Short pulses were rejected whenever the same record also held much longer steps, so a pulse test could report under half of its resistance values. A pulse section now also spans the discharges and rests between its pulses, a rate ladder run in duplicate is one ladder, and cycling whose cut-off drifts is counted rather than dropped. Existing analyses do not recompute on their own; new and re-run records carry the corrected numbers.
  • Maccor sub-procedures are read as siblings. Three sub-procedures called in turn were read as nested four levels deep, with every boundary one call late.
  • Variables evaluated later on a stored simulation now match the solve. On a simulation started from a set initial SOC, electrode and electrolyte potentials computed after the fact were offset (by up to ~0.7 V on a DFN). Affected stored results have been corrected.
  • Design optimizations honour the model’s options, including its degradation mechanisms. Previously a design objective ran against a model that could not degrade, so every degradation mode reported zero while the job completed normally. Models saved in the current configuration format were also rejected outright.
  • A pinned time window combined with a first/last step selects the right data. It used to either fail with an unexpected error or fit a slice offset from the intended one. A window that excludes the chosen steps is now a clear error naming the span those steps cover.
  • Organization Admins can choose a project role when adding members. The role dropdown was empty for them; a failure to load roles now shows an error with Retry.
  • Creating a study opens it, so the next simulation goes into the new study rather than the one you were on.
  • The Protocol column filter is back on a study’s simulation list.
  • The simulation form clears a stale cell or model remembered from another project instead of showing a red “not found” error.
  • Pickers say they are loading while loading instead of “No options”, which read as “none exist” — in the channel picker, protocol groups and template pickers among others.
  • A zoomed plot frames a newly added axis on the visible window, not on data just off screen, and zooming back out is instant.
  • The Raw Data page no longer flickers on background refreshes.
  • Table cells no longer show through the scrollbar beside the row-actions column.
  • Older pipelines open reliably. Pipelines that ran before late August could fail to load.
Improvements
  • CycleAgeing scores a target only where it has values. A NaN in a target column now means “not measured here”, so a resistance measured on alternate check-ups can be fitted directly instead of being interpolated first.
  • A fit can target a measurement’s stored analysis. Point a CycleAgeing objective at one measurement — its steps give the experiment and its analysis the targets — with ionworksdata.AnalysisLoader.
  • The fit trace is always recorded, whatever progress sink is in use, so plot_trace() works alongside printed or hosted progress. TraceLoggerSink is deprecated.
Fixes
  • Objective-level penalties and constraints are applied. They were accepted and echoed back but had no effect on the fit, and a submitted config using a symbolic penalty was rejected by validation.
  • A CycleAgeing fit whose experiment comes from a stored measurement can now be built with ionworks_schema and submitted.
  • Fixed a rare failure of multistart half-cell OCP fits when a capacity sweep flattened against a voltage limit.
Improvements
  • Simulation results download as parquet. get_result() still returns a SimulationResult, fetched faster; the new /simulations/{id}/time_series/download and /simulations/{id}/steps/download endpoints redirect to the files directly.
  • Large uploads are more robust. Files from 32 MiB use a multipart transfer, and an upload that hits a gateway timeout is retried once that way.
  • An explicit null in a PATCH clears a nullable field — for example a cell specification’s form_factor, manufacturer or notes, or a model’s description. Omitting a field still leaves it unchanged.
Fixes
  • A refused write returns 403. Updating or deleting a record your key cannot change used to return 500 or 204, even though nothing was changed.
  • Fit results are available the moment a job completes. Reading plots straight after completion could intermittently fail with “No plots are stored”.
Improvements
  • AnalysisLoader loads a measurement’s stored analysis as fit targets.
Fixes
  • DataLoader.generate_experiment keeps cycles and cut-offs. It returned one cycle per step and dropped every termination condition. It now returns one cycle per cycle count with the recorded cut-offs. This changes the shape of a generated experiment, and existing CycleAgeing fits using experiment="from data" will produce different (correct) numbers.
Improvements
  • manage-cells lists the fixed columns of the steps, cycles and time-series tables, so an agent can use them without a discovery call.
  • run-simple-pipelines documents using stored measurements as inputs, with pinned time windows.