Know how much longer a running test has left
A test already on a channel can now report how much of it is left. The platform reads the steps the cycler has actually measured, works out exactly where the cell has reached in its protocol — which branch it took, how many loops it has been through, what its variables hold — and simulates only the remainder. Because it starts from where the cell really is rather than where a model would have gone, the estimate tracks the physical run instead of an idealised one. Duration estimates also now work from the cell specification alone, so a request that hasn’t been assigned a specific cell yet can still be estimated.See what’s happening inside the cell
Simulation results now include spatial profile plots. Where a result carries a field that varies through the cell rather than a single number per timestep, it’s rendered as an interactive profile with fixed axes, a proportional time control, typed time overlays and marked domain boundaries. You don’t pick a plot type — whether a variable is scalar or spatial is inferred from the variable itself.Webhooks for your project’s events
Projects can now register HTTPS webhooks that fire when something finishes or changes. Pipelines and simple pipelines notify you when they reach a terminal state — completed, failed or canceled — and nine new cell events cover specifications, instances and measurements being created, updated or deleted. Webhooks are managed from Project Settings, each delivery is signed so you can verify it came from us, retried on failure, and viewable in a delivery log.Cyclers as real instruments
A cycler in the Lab now records the details a real instrument has: version, serial number, firmware version, and the hostname, IP address and port of its control host. On top of that, calibration and service are tracked — record when a cycler was last calibrated and how often it needs to be, and its next due date is derived for you. A cycler that isn’t on a calibration schedule reads as unknown rather than overdue. Scheduled service windows can be recorded ahead of time so the channels are accounted for before the engineer arrives.Studio
Studio
- The sidebar gained an Operate section holding the Channel Wall and the Test Scheduler. The Test Scheduler was previously reachable only by URL.
- Plain-English protocol authoring is now available everywhere a protocol is created — the New Protocol page, the new-simulation flow and the interactive builder, not just the test scheduler.
- The Agent now collapses code and printed output by default, showing the answer rather than the transcript. Plots and errors always stay visible.
- Activity log entries can now be filtered to a single project.
- Fixed live results going missing or stale on some jobs — result metadata could silently fail to upload while the job still reported success.
- Quick-model simulations now create their model inside the project you ran them from, so it appears in the project’s model lists instead of being invisible everywhere.
- Fixed a crash on the pipeline detail page when a parameter had no value.
- Deleting a measurement that a channel booking or an active plan depends on now explains which record is blocking it, and stored files are only removed once the deletion itself succeeds.
- Fixed the “learn more” link on the Protocol Simulator upload screen, which 404ed.
- Render failures are now reported to our error tracking, so crashes get fixed rather than going unnoticed.
Pipeline
Pipeline
- Fits now report per-objective timing and the cost of a parameter sweep, so the work a fit represents can be measured before it is scheduled.
- Breaking:
MultiCostnow takes one input form across both the schema and pipeline packages. The previously documented{cost: weight}mapping never worked in the schema package — a list of cost/weight records is now the single supported form on both sides.
- Invalid
DataFitoptions are now rejected when you submit, with a message naming the unrecognised option, instead of failing minutes into the run with an unexplained internal error.
Python API
Python API
- New
client.searchsub-client for global search across projects, models, cell specifications, instances, measurements, materials, studies, optimizations and pipelines. client.protocolnow covers the whole protocol lifecycle — listing, fetching, finding by name, creating, updating and deleting saved protocols — instead of only validation and conversion.- New clients for project webhooks and for cycler hardware, calibration and scheduled service.
- Fixed
get_plot_datareturning a 404 for every request — the client was calling an address that did not exist. - An API URL configured with a trailing slash no longer produces a doubled slash and a 404.
Protocol Simulator
Protocol Simulator
- A protocol’s position can now be recovered from a real cell’s measured steps — which step it is on, its loop counters, subroutine stack, variables and cycle number. Combined with the existing resume support, a simulation can pick up exactly where a physical test has got to.
Skills
Skills
- New Search skill covering global search across the platform from the SDK.
- New Manage protocols skill covering the full saved-protocol lifecycle, authoring and conversion.
- Manage equipment covers cycler hardware details, calibration tracking and scheduled service.
A home page for every project
Opening a project used to drop you straight onto its studies list. Projects now open on a proper home page: an assistant prompt front and centre, a Running now panel showing pipelines still in flight, a Pick up where you left off row of your most recently touched studies, pipelines, measurements and conversations, and browse tiles with counts for each area of the project. Ask a question from the home page and it opens a fresh Agent conversation with your question already sent.Describe a test in plain English
The Lab test scheduler can now author a protocol from a description. Type something like “1C/1C cycling for 100 cycles between 4.2 V and 2.5 V with 10-minute rests” and you get back a validated protocol, ready to request. If the description leaves out something that would change what physically runs on the channel, you’re asked about it rather than having a value guessed; common conventions (25 °C ambient, CC-CV taper, rest lengths) are assumed and reported back to you. If one of your saved protocols already does the job, it’s offered instead of a new one. Anything the generator returns is a protocol the platform accepts — it’s validated before you ever see it.Test requests get their own page, and export to your cycler
Planned tests now open on a detail page instead of jumping straight into the edit form, with the request, its scheduling, and its actions laid out separately — so an unscheduled request reads as “not booked yet” rather than a half-empty form. From that page you can export the request’s protocol in a cycler’s native format — Maccor, Arbin, Neware, BioLogic (BT-Lab) or Novonix — preview it, and download it, with no need to re-author the test in vendor software. Exports that need more than one file arrive as a single zip.Charge-transfer kinetics in the ECM
The Equivalent Circuit Model gained an optional Butler-Volmer charge-transfer element. Enabling it adds a symmetric charge-transfer overpotential driven by a new Exchange current [A] parameter, which captures rate-dependent losses that a linear series resistance cannot — nearly linear at low current, logarithmic at high current. It’s off by default, so existing models and simulations are completely unchanged, and the new Charge-transfer overpotential [V] output is available when it’s on.Studio
Studio
- ECM simulation results now show a real voltage components plot — open-circuit voltage, the series-resistance drop, and one band per RC pair, stacked down to the terminal voltage.
- Measurement views gained a Filter by Steps or Cycles selector. Measurements with no cycle data — OCV sequences, pulse and DCIR tests, single-pass characterisations — now get the full step filter instead of no filter controls at all, and open on Steps.
- Channel incident history — taking a channel out of service now records the outage with its cause, category, who reported it and when. A down channel shows a callout with the cause, start time and running duration plus a Return to service action, and the channel page lists its past incidents.
- Organization admins can manage the Programs catalog from a new Programs tab in Organization settings — create, rename and delete the programs used to tag planned tests.
- Protocols are now scoped to a project. Every project starts with its own editable copy of the standard protocols instead of sharing a read-only library, so edits in one project can’t affect another. Existing projects have been seeded with theirs.
- Uploading measurement time series now returns immediately and processes in the background, with progress and any processing error visible in the measurement list, so large uploads no longer block the request.
- Revoking an API key now takes effect immediately rather than after a delay.
- The Agent widget’s New chat button now actually starts a blank conversation instead of re-opening the last one.
- Reloading the page mid-reply no longer blanks the earlier messages in an Agent conversation — history and the streaming reply are merged rather than one replacing the other.
- Failed API-key authentication no longer echoes the submitted key back in the error response; only the key’s short prefix is returned.
- Sorting or filtering cell specifications by last-updated no longer errors —
the field is now stored and returned alongside
created_at. - Transient failures in authentication and membership lookups now report a retryable error with a real cause instead of an opaque failure.
- Program names consisting only of whitespace are now rejected, and program-related text meets WCAG contrast requirements.
Pipeline
Pipeline
- Pipeline elements now return typed result objects — parameter-estimation,
optimization, posterior, ensemble, regression and validation results each have
their own type, reachable from
Pipeline.results. A newiwp.analysisnamespace collects post-fit analyses, includingLinearConfidenceIntervalandSobolSensitivity. - Interpolant-valued parameters (for example a measured ambient-temperature profile
supplied per objective) now serialise from a plain dictionary, not just from a
pybamm.ParameterValues. Array-valued parameters round-trip correctly instead of being misread as indexed parameters.
- Fixed a memory leak where every fit result held a reference to itself, keeping results alive longer than necessary. A parent result whose child happened to hold equal parameter values also no longer silently loses that child when copied.
Python API
Python API
- New clients for channel incidents and for the background measurement upload flow, so an upload can be started and its processing state polled from the SDK.
- Protocol clients are now project-scoped, matching the per-project protocol change above.
- Breaking (direct
ionworkspipelineusers only):result.optimizer_result,iwp.OptimizerResultandiwp.SamplerResultare removed in favour of the typed result objects above (OptimizationResult.x/.fun/.success,PosteriorResult, …), andRegressionResult.resultis now.results.
Data Processing
Data Processing
- Power [W] is now computed when a measurement is processed and stored with the time series, rather than derived on every read. It also stays correct when the current sign is auto-corrected during processing.
Protocol Simulator
Protocol Simulator
- A protocol can now be resumed exactly from a captured point — its position, loop counts, variables, cycle number and full physical state — so a run can be checkpointed and continued with no rest step and no loss of accuracy.
- New protocol authoring warnings flag common mistakes before you run anything: mistyped or cross-scope jumps, missing subroutines, loop conditions that can never be satisfied, unreachable steps, voltage limits that contradict the step direction, targets outside the safety window, and rests with a current-based end condition. These are advisory — nothing that runs today stops running — and can be made blocking if you’d rather catch them as errors.
- Protocols now report their derived voltage and current limits — the minimum and maximum voltage and the peak charge and discharge currents implied by the steps, safety limits and drive cycles.
- Maccor and Novonix exports now use the earliest duration end condition rather than the last, so a step no longer runs for longer than requested.
- Fixed a Novonix export writing a structured safety-limit value where a plain number was expected.
- Fixed Arbin loop detection and Neware template handling cases where two divergent code paths disagreed.
Skills
Skills
- Manage equipment covers recording and reading a channel’s incident history.
- Upload data covers the background upload flow and how to poll a measurement’s processing state.
Agent chat, built into the app
A new in-app Agent puts a conversational assistant right inside Studio. Ask it questions about your data and models, hand it files, and follow along as it works — replies stream in as they’re generated, and each conversation is saved so you can pick it back up later. The Agent runs in an isolated sandbox per organization. It’s rolling out to a limited set of organizations first and will become more widely available over the coming weeks.Battery Cycler Simulator, now in your projects
The protocol simulator has moved out of a standalone page and into your projects, so simulations live alongside the cells, studies, and models they belong to. A new Quick model option lets you simulate straight away without first saving a parameterized model — just pick a chemistry and set a capacity and resistance scale inline. Prefer a fitted model? The From library toggle still runs against any of your saved cell → parameterized-model selections.Plan and track lab tests
The Lab view gained a full test scheduler. Request a test on a channel and the platform validates the protocol up front — an invalid protocol is rejected before the request is saved, with a clear message about what’s wrong. The scheduling dialog shows each channel’s live availability and electrical ratings as you pick, and you can copy an existing request to seed a new one or delete one you no longer need. An optional organization Programs catalog lets you tag each test with the program it belongs to, visible on the Lab wall and planning table.Engineers can also watch a channel to keep an eye on the test they care about and filter the Lab wall down to just those — and because a watch is tied to the run currently on the channel, it clears itself automatically the moment that test finishes.Studio
Studio
- Battery Cycler Simulator moved into projects, with a new Quick model option to simulate without a saved parameterized model.
- Lab test scheduler — request, copy, and delete tests on a channel; invalid protocols are rejected on submit with an actionable error.
- Programs — an optional organization catalog for tagging planned tests, surfaced on the Lab wall and planning table.
- Watch a channel to follow its live test and filter the Lab wall to your watched channels; watches clear automatically when the test completes.
- A cell specification can now designate a default parameterized model; the first model created for a spec becomes its default automatically.
- Measurement details gained a derived Power [W] column (voltage × current) selectable in the Time Series tab.
- The measurement Differential Analysis tab now plots dQ/dV in addition to dV/dQ, switchable from a plot-type dropdown.
- Material property datasets and analyses now track their source — when a dataset or analysis was computed from a pipeline or another analysis, you can see and click through to where its data came from.
- Organization admins can resend an invite or send a password reset to a member directly from the Members tab, and adding a member by email now distinguishes newly invited from already-registered users.
- Lab can now be shown or hidden per organization from the admin Navigation settings, like the other feature areas.
- A stale browser tab left open across a deploy now reloads itself to pick up the new version instead of showing a maintenance page.
- Plot axes, tick labels, and titles are now legible in dark mode on validation and other charts.
- Adding a member by email is now case-insensitive, so a differently-cased address no longer creates a mismatch.
- Cycler and channel detail pages no longer error on load for equipment with linked child records.
Pipeline
Pipeline
- MSMR half-cell OCP fits now constrain the fitted host-site occupancy fractions (Xⱼ) to sum to 1, so the values exported and reused downstream are self-consistent.
- A DataFit whose every evaluation is non-finite now fails with a clear error instead of silently returning the initial guesses as if the fit had succeeded.
Python API
Python API
- Fitted models now persist their simulation settings (mesh and solver
configuration), so a model simulates the same way wherever it’s used. The
ModelandParameterizedModelclients expose the setting and document how to build it from live PyBaMM objects viaiws.models.SimulationSettings(...). SimplePipeline.createnow accepts a schema object directly (matchingPipeline.create), so you no longer need to call.to_config()yourself; dicts still work unchanged.- New
JobClient.get_plot_data(job_id, objective_name, …)returns a DataFit’s model-vs-data overlay directly from a completed job.
Protocol Simulator
Protocol Simulator
- Impedance (EIS) simulations for the Equivalent Circuit Model now run through the same standard PyBaMM machinery as every other model.
- Arbin protocols whose step end conditions aggregate per-channel temperatures
(e.g.
max(Temperature, …) > 55) now parse correctly instead of failing with an invalid-end-condition error.
Lab view — see every cycler and channel at a glance
A new project-scoped Lab dashboard shows all of your test equipment organized as sites → cyclers → channels, so you can tell at a glance what’s running where. The Lab wall lists every cycler with a utilization bar and per-state channel counts, filterable by site and by amp/volt rating range. Drill into a cycler to see its full channel grid, or into a single channel to see exactly which cell is on test, its measurement history, and an editable out-of-service toggle with notes.Each channel’s state — occupied, stale (a run that stopped updating and likely needs attention), free, or out of commission — is derived from the measurements linked to it, so the view stays accurate without any live telemetry hookup. Channel cards also show an estimated end time for still-running tests when one is available. A set of scheduling rules keeps the data honest: two runs can’t overlap on the same channel, and a channel can’t be taken out of commission while a test is active.The same equipment picture is available programmatically through the newclient.lab sub-client in the Python SDK — ask for overall utilization, list
free channels (optionally filtered by required ratings), find stale channels
that need attention, or look up what’s on a specific channel, all from a single
call.Measurement analyses
You can now attach analyses to a measurement — a named table of extracted features (e.g. ECM parameters from EIS, or LLI/LAM degradation points from RPT data) stored alongside the raw measurement. The measurement detail page lists a measurement’s analyses, and each analysis has its own detail page with a data preview, downloadable parquet, and a link back to its source measurement. Analyses are fully supported in the Python SDK via the newclient.analysis
client (create from a polars/pandas DataFrame, list, fetch data, update,
delete).Throughput-based degradation in the ECM
The Equivalent Circuit Model (iwp.models.ECM) gained an opt-in degradation
capability: capacity and internal resistance can now evolve as user-supplied
functions of capacity throughput (the running integral of |current|), so a
single simulation can capture fade over the course of a run. Both options
default to constant, so existing ECM configs are unaffected.Studio
Studio
- Global search now covers cyclers and channels alongside projects, studies, and cells — search from anywhere and jump straight to a channel’s detail page.
- The cell specification detail page is now organized into three tabs — Measurements, Instances, and Parameterized models — each with server-side pagination, filtering, and sorting.
- Organization admins can now deactivate a member to suspend their access while preserving their membership and role, then reactivate them later. A deactivated user sees a dedicated screen with an option to switch to another organization.
- Materials and components are now scoped to the project of the cell specification that references them, keeping each project’s parameter data within its own boundary.
- Sorting the project measurements grid by the measurement id column no longer makes every row disappear.
Pipeline
Pipeline
- DataFit runs with a Bayesian sampler now return the full posterior sample chain (per-parameter samples and per-sample costs), not just the point estimate, retrievable from the job result.
Python API
Python API
- New
client.labsub-client for point-in-time equipment questions: overall utilization, free channels (optionally filtered by required amp/volt ratings), stale channels needing attention, and what’s on a given channel. - New
client.analysissub-client for creating, listing, fetching, updating, and deleting measurement analyses, serializing DataFrames to and from parquet transparently. - Submitted pipelines can now reference local data with
file:andfolder:refs; their contents are read and inlined at submit time, and the same inline row cap that applies to raw DataFrames is now correctly enforced for these refs (afile:pointing at a very large CSV no longer slips through). - Raw-data upload now uses the same fast signed-URL flow as regular measurement uploads.
Protocol Simulator
Protocol Simulator
- Arbin Power Simulation drive cycles are now supported — they parse into a drive-cycle step that can apply a power (W) waveform rather than current, and Arbin cumulative capacity/energy counters are modelled correctly across steps.
- Arbin
SetValuesteps that read a last-step quantity (e.g.MV_UD1 = LS_CHAN_Discharge_Capacity, the “measure C/20 capacity then log it” idiom) now resolve correctly at simulation time instead of failing with an unresolved-variable error, so the downstream steps that depend on that value run. - Arbin subschedule steps that happen to share a step index and label with a
step in the parent schedule no longer collide with a duplicate-step-name
error; each subschedule’s steps are kept distinct while still resolving
gototargets correctly.
EIS upload validation
cell_measurement.create(...) now accepts a data_type="eis" hint on the
measurement dict. When set, validate_measurement_data runs a structural
columns check (always on, requires Frequency [Hz], Z_Re [Ohm],
Z_Im [Ohm]) plus two strict-only, individually-skippable heuristic checks.
eis_zim_sign flags a spectrum whose capacitive band is predominantly
positive — i.e. the raw Im(Z) sign is flipped, with the fix hint
Z_Im = -Z_Im. eis_impedance_magnitude catches order-of-magnitude unit
errors by comparing min(Z_Re) against a wide 100× band around a capacity-
derived estimate — no data fetch, just a sanity check against the supplied
rated_capacity. Both fire only on order-of-magnitude issues (a 1000× unit
error, a fully flipped sign) so a plausible spectrum is never touched. The
BioLogic reader now stores the raw imaginary part directly as Z_Im [Ohm]
(negative across the capacitive arc), matching the validator’s convention.Faster pipeline detail page and ECM fits
The pipeline detail page now loads noticeably faster: large per-element data is now loaded lazily on expand instead of upfront, and a slow client-side recalculation on every 5s poll tick has been optimized away. Separately, pipeline ECM fits got faster and more accurate through several internal fit-strategy improvements, with fit quality fully preserved.Studio
Studio
- Protocol detail pages now show a Simulations section listing every simulation that uses the protocol, with the same bulk actions (add to study, rerun, delete) available on the parameterized-model simulation list.
- Pipeline bulk cancel is now instant. The UI flips immediately with optimistic updates, and the slower job-termination work is offloaded to run in the background. A single bulk-cancel endpoint replaces the per-pipeline loop the frontend was previously doing.
- The Cycle Filter now clamps
First N,Last N, andRangevalues that exceed the number of available cycles: it returns all available cycles and showsShowing all N cyclesin neutral text. Explicit single-cycle typos (e.g.0,50,200on a 100-cycle measurement) still error, with a short, actionable message instead of the previous thousands-of-numbers wall of text. - Compute hours are now a first-class usage dimension alongside simulation hours, driven by each org’s contract. The account drawer renders one meter per configured usage type, gated on a combined loading signal with placeholder cards sized to the last-known meter count, so the list no longer briefly collapses to zero at load.
- Deleting an organization as a regular Admin (non-super-admin) now returns a proper 403 Forbidden. Previously the delete was silently blocked but the endpoint returned 204, giving a false success while the org remained in the database.
- Current sign-convention documentation corrected across backend field descriptions, the API discovery endpoint, and the data-upload docs: positive = discharge, negative = charge (matching the platform’s actual data and validators). Descriptions of external cycler conventions that legitimately differ (e.g. BioLogic / Arbin native positive = charge) are unchanged.
Pipeline
Pipeline
- Default population size for the DE and PSO optimizers is now
capped at 40. Explicit
population_sizevalues still bypass the cap; only the auto-scaled default changed, and only above the cap.
- Local pipeline runs now match server behavior in three places where they
had drifted. An OCP interpolant input with only a
datakey is no longer rejected as missing metadata. Schema-provided transforms (Log10,Log,Inverse, …) are no longer silently dropped. And the vacuous multistart guard (Multiple multistarts are being used, but all initial guesses are identical) that fired as a downstream symptom of those drops is gone as a consequence.
Python API
Python API
GET /organizations/current/usageis now public and returns per- dimension usage (simulation,compute) with limits, so SDK clients can read their own quotas without an admin token.
Data Processing
Data Processing
- Neware BTSDA
.xlsxfiles with no explicitsheetsoption now auto-select therecordsheet — where the time series actually lives — instead of defaulting to the metadata-only first sheet and failing with a missingTimestamperror. The previous “you must passsheets={type: 'name', value: 'record'}” gotcha is now automatic; files without arecordsheet still fall back to the first-sheet default.
- The Maccor reader now maps
Cycle C— the cumulative cycle counter, the true cycle number — toCycle from cycler. Previously it mappedCycle P, a program/loop counter that is often0and can reset within a procedure, so any file containing both columns reported meaningless zeros for the cycle number.
Protocol Simulator
Protocol Simulator
- Arbin schedules that reference a subschedule (
SubSchedulestep) no longer fail parsing withDuplicate step name found: 'End Test'. The reservedEnd Testterminal is exempted from the duplicate-name check — each subschedule keeps its own copy, so anygoto: "End Test"from any scope still resolves at simulation time. Genuinely-named block collisions (e.g. a userLoop_Xappearing in two scopes) still error as they should.
ECM fitting: regularization and per-cell capacities
Studio’s ECM fit adds two options. A regularization setting smooths the fitted parameters, and a per-measurement capacity lets you set a known nominal capacity for each measurement in a fit that spans several measurements of the same cell. Capacity fitting is now opt-in, and each fitted measurement reports its own capacity.ArrayDataFit through the JSON config path
iws.ArrayDataFit — fitting the same model independently at each value
of an independent variable (e.g. diffusivity vs. stoichiometry from
GITT / pulse data, or a parameter vs. temperature) — is now a
first-class element_type: "array_data_fit" end to end. The library
and schema already supported it, but the config path (the only surface
the production API sees) previously collapsed it into a plain
DataFit. Array fits now round-trip through config, schema, parser,
executor, and results serialization, and Studio renders the array-
valued fitted parameters with a per-parameter scatter view reachable
from the parameter editor.Studio
Studio
- Cell measurement deletion is now near-instant. The per-measurement storage layout is deterministic, so the file set to remove is now derived from the database record and removed in a single batched call, rather than a slow recursive folder listing.
- Missing or empty step data on a measurement now surface as a clear “data missing” error with a re-upload prompt in the UI, distinct from transient storage failures (which get a Retry button). Upload validation also rejects empty step sets, and the upload rollback cleans up orphaned storage files.
Pipeline
Pipeline
initial_guess_sampleroniws.DataFitacceptsLatinHypercubeorUniformexplicitly, and unknown sampler / distribution / prior names and stray keys are now rejected at submission time with a clear validation error instead of a later runtime crash.
- Configuring an
ArrayDataFitwith a non-number-likeobjectiveskey now surfaces as a clear, actionable configuration error — the message is shown, no internal alert — instead of the opaque “An unexpected error occurred” path. The same improved error handling was applied broadly across data-fit, optimizer, sampler, metrics, and transform configuration, so user-correctable mistakes surface with an actionable message instead of a generic failure.
Python API
Python API
client.ecm.fit(...)now accepts aregularizationoption and a per-measurementcapacityonFitMeasurementRequest(set on all measurements or none);FitResults.capacity_Ahreports one value per fitted measurement.- Submitting an
array_data_fitelement via the JSON config path now round-trips end to end (schema → parser → pipeline → results), so API clients get the same first-class support the library object path already had.
- Documentation examples fixed against the real API surface: the
resubmit endpoint is
POST /jobs/{pipeline_id}/resubmit(the documented/pipelines/{pipeline_id}/resubmitdoes not exist and would 404); theModellist response has nomodel_type/configfield (onlyclient.model.get(id)returns it);model.createconfig usestype, notmodel_type; simulate protocol examples use named steps + string end conditions;CellMeasurementBundleResponseis flat (bundle.name, notbundle.measurement.name).
Skills
Skills
run-simple-pipelinesdocuments thearray_data_fitelement type alongside the standarddata_fit.manage-cells:cell_spec.createandcreate_or_getexamples now matchCreateCellSpecificationNested— aratingsobject (capacity,voltage_min,voltage_maxas{value, unit}Quantities) and per-slotcathode/anodekeys each holding aNestedComponentInputwith a singularmaterialdict. The previous body usedrated_capacity/voltage_range_dc/components: [...]fields that do not exist on the model and would have failed server-side validation.
Faster, more reliable parallel data fitting
Parallel data fitting has been rebuilt on a dedicated execution engine that drives optimizers, point evaluation, multistart coordination, and progress reporting more efficiently and reliably, with clearer error reporting when a fit fails.Name-based measurement lookup
client.resolve_measurement(cell_specification, cell_instance, measurement) resolves a measurement_id from human-readable names,
walking the spec → instance → measurement hierarchy with server-side
filtering at each level. Scripts no longer need to hand-walk three
list endpoints and repeat name-matching boilerplate just to get an id.
parameterized_model.create_or_get also lands, giving parameterized
models the re-runnable create-or-resolve behaviour the other cell
resources already had.Clearer errors for model failures and duplicates
Two opaque “An unexpected error occurred” cases — a fit whose model setup needs geometry the user didn’t supply, and a custom model with no discretisation recipe — now surface as a clearModelError naming
what failed. Separately, attempting to create a resource that already
exists now returns a 409 CONFLICT (with the existing id) instead of
a 500, so duplicate-creation attempts fail clearly instead of
erroring unexpectedly.Studio
Studio
- “Save as template” for an optimization now builds the template server-side, copying an optimization’s saved config directly into the template.
- Completed validation/datafit results no longer sporadically show “Failed to load plot data.” for one of a pair of plots.
- Cycle-ageing experiments driven directly from stored measurement
data (
experiment="from data") now resolve their measurement references correctly, instead of failing later in the run.
Pipeline
Pipeline
- A bare element-wise cost (
SSE/MSE/RMSE/MAE/Max) applied to a multi-variable objective now warns when variable lengths mismatch — e.g. a model-axis dQ/dV variable against a data-axis voltage variable — instead of silently broadcasting to a meaningless residual. - All 1-D interpolant calculations now accept a
"pchip"interpolator (monotone cubic), the right choice for sparse, order-of-magnitudeD(sto)tables such as half-cell GITT per-pulse diffusivity.
- The MSMR half-cell logistic value and derivative are now evaluated more robustly, so it can never overflow.
- Model configuration now rebuilds consistently across execution paths, so results agree regardless of how a run was launched.
- A custom model with serialised geometry/mesh now survives multistart runs reliably, fixing cases that previously failed to serialize.
Python API
Python API
client.resolve_measurementandparameterized_model.create_or_get(both introduced above), plusModel.configfor inspecting a model’s stored configuration.- Passing a bare pandas/polars DataFrame to a schema
datafield (objectivedata_input,OCPDataInterpolant.data, the Arrhenius calculations’data) is now auto-wrapped correctly on serialization, instead of failing server-side validation with the opaque “Required field ‘data’ missing”.
Protocol Simulator
Protocol Simulator
- Arbin protocols now support subschedules, counter loops, and temperature add-ins, so schedules that previously crashed on upload with “Unsupported step type: SubSchedule” now parse and simulate end-to-end.
- BioLogic
.mpssimulation fixes: the loop counter is off by one no longer (EC-Lab’sctrl_repeatdoes not count the first pass, so a loop now runsctrl_repeat + 1times), plus BCD/EIS support and drive-cycle fixes, each reproduced against the reported setting files before fixing. - User-correctable protocol and configuration errors across the Protocol Simulator and pipeline libraries now raise specific, actionable error messages instead of generic failures, so they surface clearly to the user.
Data Processing
Data Processing
- The
process-datareader gotchas are now documented: selecting therecordsheet for multi-sheet Neware BTSDA.xlsxfiles, and current-unit handling — alongside the one-callread.time_series_and_stepsentry point.
GITTModel — a first-class diffusion-only model
GITTModel and HalfCellGITTModel are now first-class models in
ionworkspipeline (with matching ionworks_schema siblings). GITT
fits overwhelmingly use the same lightweight model rather than SPMe:
x-averaged particle diffusion per electrode, a single lumped ohmic
resistance, fixed OCPs, and no Butler-Volmer kinetics, electrolyte
dynamics, or thermal effects. Shipping it as a built-in model unblocks
server-side GITT fits and backs the new half-cell GITT fit template.Download ionworks-defined models for plain pybamm
Users who have onlyionworks-schema / ionworks-api — and not the
licensed ionworkspipeline package — can now obtain ionworks-defined
models (ECM, LumpedSPMR, the MSMR models, GITTModel) in a form
they can load and run with plain pybamm. A new endpoint builds the
model server-side (where the license lives) and returns a loadable
serialisation, exposed through the Python SDK.App-URL helpers for every routed resource
The SDK’sclient.urls grew from a single .measurement() method to
a full set of web-app link builders — project, model,
parameterized_model, optimization, pipeline, study,
simulation, cell_specification, cell_instance, and more — so
callers never hand-construct app.ionworks.com URLs from IDs. The
helpers are environment-aware, deriving the right host for whichever
API environment the client is configured against.Stricter, clearer pipeline configuration
Most user-driven errors inionworkspipeline now raise a clear
configuration error instead of a generic one, so configuration
mistakes — wrong field types, out-of-range values, missing keys — are
routed to a clear Configuration error for the user instead of
being treated as an internal error. Optimizer configuration is now
also validated up front: passing options meant for a different
optimizer now hard-errors at submission time instead of being silently
ignored.Pipeline
Pipeline
- Objective- and variable-level cost scoping is now driven by a single source of truth mapping each objective to the variables it should compute. This lets a weighted Wasserstein cost (position-shifting dQ/dV) and a per-variable SSE cost be combined over one objective, with each cost explicitly scoped to the variables it should consume. Electrode balancing gained an option to emit dQ/dV on the model’s own full-window voltage axis so a weighted Wasserstein comparison can align peaks in voltage rather than on the data grid.
- Strict optimizer-option validation: unknown optimizer option keys (and method/option mismatches) are rejected at submission time, and unknown constructor options are rejected at runtime with an actionable message — the previous behaviour silently ignored them. The typed option wrappers for each supported optimizer (CMA-ES, PSO, Differential Evolution, XNES, Bayesian Optimization, SOBER, TuRBO) remain the recommended way to pass options.
- Failure handling across the fitting and design-optimization paths is now unified onto a single constant, so the two paths can no longer drift apart and failures are better-conditioned for surrogate-based fits.
- ECM coulomb-count capacity reference is now computed per segment. Multi-measurement fits previously accumulated the cumulative integral across concatenated segment boundaries, inflating the capacity estimate to roughly the sum of per-segment throughputs and triggering spurious capacity-sanity-check warnings.
- A custom
geometrywith symbolic bounds is now correctly restored before the simulation is built, instead of arriving in a form that choked the solver. - Custom models now correctly honour their serialised mesh and geometry settings, instead of having them silently rebuilt from defaults.
Python API
Python API
client.model.download/serialize(introduced above) return ionworks-defined models in a plain-pybamm-loadable form.client.urls(introduced above) now builds links for every routed resource, environment-aware.
Global search across the platform
A⌘K dialog now searches across projects, cell specifications,
cell instances, cell measurements, pipelines, datafits, simulations,
optimizations, and parameterized models — with grouped, deep-linked
results and per-entity-type chip filters. Cell measurements and
instances are indexed via server-side full-text search, so a partial
name or id from any of these surfaces lands on the right detail page
in one keystroke. The search dialog supports filtering and paging
results server-side.Bayesian Optimization, TuRBO, and SOBER for parameter estimation
Three surrogate-based optimizers ship inionworkspipeline:BayesianOptimization— sequential or batch BO with (log-)Expected Improvement and a feasibility-weighted acquisition for constrained problems.TuRBO— trust-region BO with Thompson sampling and constraint handling.SOBER— batch BO via Bayesian quadrature with prior-aware importance sampling.
BayesianOptimizationOptions,
TuRBOOptions, SOBEROptions schema, and a new method-selection guide
in the docs explains when to reach for them over Nelder–Mead, CMA-ES,
or differential evolution.ECM parameterization runs as a background job
Authenticated ECM fits now run as background jobs instead of blocking on a synchronous request for 10–60 s.POST /ecm/fit-from-file and
POST /ecm/fit-from-measurements return 202 {job_id, status}; the
public demo POST /ecm/fit stays synchronous so unauthenticated
example fits still complete in one round-trip. The new client.ecm
Python SDK sub-client covers all three input modes — fit_from_example
(sync), fit_from_file and fit_from_measurements (returning an
EcmFitJob with wait_for_completion(...) polling), plus
save_to_project and detect_and_read — and a new ecm-fitting agent
skill walks an agent through picking a mode, running the fit, and
persisting it as a parameterized model. Solver errors from user data
now surface as clear, actionable API errors instead of generic
failures.Inline image previews for file measurements
File-type cell measurements used to render a “Visualization not yet supported” placeholder; the measurement detail page now fetches every attached file, renders images inline (filling the column with a click-to-expand lightbox, Esc or click-out to dismiss), and offers a download link for any file type. The detail page also no longer fails to load forfile and properties-type measurements that don’t have
time series data.Studio
Studio
- Optimizations get a lighter-weight
/optimizationsREST surface (list, get, config, metadata, runs, statuses, cancel, resubmit, delete), and the optimization list page now polls a lightweight status projection every 5 s for faster, more efficient updates. The parameterized-model selector also fetches by id rather than scanning a larger cache. - A project-scoped parameterized model listing lets the parameterized-model picker filter to models that belong to the current project.
- Internal indexing helper fields are hidden in the object-fields panels so detail views no longer surface implementation details.
- Datafit results now surface “Validation not supported” as an inline alert when applicable, instead of leaving the validation tab blank or failing the page.
- Protocol files that pause or end on a non-error stop condition now render a user-correctable inline message; previously the route returned a generic error.
- Errors raised internally are now consistently converted into structured error responses across simulation and datafit result endpoints.
- The Universal Cycler Protocol simulator pages now list Arbin and Novonix alongside Maccor, Bitrode, and BioLogic as supported cycler protocol formats, and the supported-protocols copy is shared between both UCP pages so the two stay in sync.
- Data grid cards now claim an intrinsic width, fixing collapsed-grid layout issues when the parent container had no explicit width.
- Measurement-file uploads to storage now retry on transient errors with capped exponential backoff and a clear error once attempts are exhausted.
- Pipeline list and detail views are more robust to out-of-order responses, so navigating between pipelines during a slow request no longer reverts the view to a stale pipeline. Pipeline-elements caching and background polling were also hardened against stale-data races.
- The measurements list resets to page 1 at render time when the parent entity changes, removing the flash of stale rows that appeared while a new request was in flight.
- Org-context resolution on hard refresh is now deterministic — the active project no longer briefly reverts to the first project in the list before the persisted selection loads.
- Dark mode now derives selection, focus, and hover colors from the Ionworks brand pink so the focused row, selected nav item, and hovered button no longer look muddy against the dark background.
- Validation plot axis titles render correctly with the latest charting library version.
- The cell card on the cell detail page no longer shows redundant metadata fields that duplicated the breadcrumb.
- The all-measurements page now loads cell specs on cold/direct navigation so the spec-name and spec-anode/cathode columns populate on first paint instead of only after navigating in from elsewhere.
Pipeline
Pipeline
CycleAgeingdefaults to a unified experiment model when an experiment is supplied, and compiles by default in that mode. Cycling experiments repeat the same handful of steps many times, so this collapses build and solve cost, giving a substantial speedup for cycle-ageing fits. Pinned to PyBaMM 26.6.1.0.CycleAgeingacceptsexperiment="from data", which builds the cycling experiment from the loaded dataset instead of requiring the user to restate it.CycleAgeingautomatically skips storing intermediate-cycle data when every requested metric only needs first/last-cycle quantities.save_at_cyclesonCycleAgeingis now auto-derived from the requested metric tree when the caller does not pass one explicitly — only the cycles that downstream metrics actually consume are saved.ElectrodeBalancingemitsdQ/dVcurves alongside the existing capacity outputs, so weighted costs can be computed directly against the dQ/dV peak structure.- The
Timemetric accepts a vector of times and reports the metric at each one, replacing the previous one-scalar-at-a-time loop in callers that needed a few sample points. - Solver options can now be passed through to every objective, complementing last week’s solver options on the constructor side.
SimplePipelineis a new pipeline mode with a client-side validator that rejects configs containing more than one expensive element (DataFit,ArrayDataFit,Validation), mirroring the server-side guardrail.
- An unsupported preprocessing option is now rejected at config time when passed in objective options, matching the runtime ban and giving a clearer config-time error.
Python API
Python API
client.electrolyte.transport_from_dataset(dataset_id, forms=, columns=)turns a material property dataset into apybamm.ParameterValuesof concentration-dependent transport functions ready to hand toiws.direct_entries.DirectEntry(parameters=...). Two function forms are supported per property: tabulated interpolation (default) and a Landesfeind–Gasteiger isothermal exponential fit, which stays positive and finite below the lowest measured concentration so high-rate DFN solves don’t fail when the electrolyte depletes.Quantityconstructors accept PyBaMM-style unit strings and normalize them on input, so values copied from a PyBaMM parameter set round-trip into and out of cell schemas without a manual unit rewrite.JobClient.get_parameter_trace(job_id)returns the parameter- evaluation trace from an optimization job as a DataFrame for inspection or downstream plotting.client.ecm(introduced above) is the new ECM sub-client.
- POST and PATCH calls retry on transient connection drops with the same capped-backoff policy already used for GETs, removing spurious connection errors during long-running uploads against a flaky link.
Data Processing
Data Processing
- A constant-current discharge segment with the unsigned mixed-mode sign convention no longer mislabels the step direction, and the matching CC-discharge classifier no longer reverses the sign on file round-trip.
Protocol Simulator
Protocol Simulator
- Arbin protocols with a
SIGN(...)or step-time piecewise-current formula now parse correctly and emit the expected step plan; the previous parser failed on the conditional with a generic syntax error. human_readable_protocol(...)renders drive-cycle steps in the same shorthand notation the simulator uses elsewhere, instead of expanding them inline.
- Pause and end stop reasons now surface as user-correctable inline errors instead of being treated as solver failures.
Skills
Skills
- The
parameterizeskill gains a current-driven fit template and a full-cell OCV template, each with an objective / cost decision tree so an agent can route an incoming dataset to the right starting configuration without re-deriving the choice every time. - A new
electrolyte-transportSDK skill documents theclient.electrolyte.transport_from_dataset(...)workflow, including the interpolant vs. Landesfeind-exponential trade-off and theDirectEntryintegration pattern. - A new
ecm-fittingSDK skill walks through the three ECM input modes (example, file, measurements) and the save-to-project flow. - The
parameterizeskill explains the component/material model and the material → cells reverse lookup so an agent can find which cell specs reference a given material before editing it.
Brand-aligned theme refresh
Studio now follows the Ionworks brand guide. Pink (#FF87B7) drives primary
CTAs, selection, focus, and active nav/tabs; green-black (#020E0D)
anchors text and neutrals; blue (#0C68E9) is reserved for
hyperlinks so links stay obviously clickable. Corners are sharpened
to 4px, typography is updated, and JSON viewers, plots, tables, and
ID chips have been re-skinned to match. All changes are
theme-level — no underlying behavior changes — so every screen
lifts at once.Semantic zoom on pipeline validation plots
Validation plots now fetch their data on demand and decimate server-side based on the visible x-range. Box-zoom into a region re-requests denser data for that window; a step-back zoom and a full-reset control are stacked in a zoom history.Tunable solver options with PyBaMM 26.6 support
ionworkspipeline simulations accept new solver options that merge
over the tuned defaults — e.g. enabling compilation for long
unified-experiment runs without restating the rest of the solver
configuration. It threads through every simulation-backed objective.
The workspace also upgrades to PyBaMM 26.6, with a compatibility layer
so historical and freshly-generated payloads both decode correctly.New data agent skills
Two new agent skills land this release:build-data-report
(multi-section markdown + PDF analysis covering rate capability,
DCIR, OCV, GITT, entropic, aging, and gap analysis) and
validate-data (a pre-upload gate covering header audit, schema,
and strict measurement validation).Studio
Studio
- Cell-measurements list endpoints have been consolidated and now use server-side pagination across project, spec, and instance scopes, keeping the main list view fast even for large datasets.
- Deleting a project no longer shows a misleading “The project you are trying to access does not exist…” toast. The delete confirmation dialog also now requires typing the exact project name to enable the Delete project button, matching the destructive-action pattern used elsewhere.
- Signed-URL generation for measurement files now retries automatically on transient network timeouts, and file listing uses a single batched request instead of many parallel calls. File downloads also retry when the storage service returns an unexpected response under load, and surface exhausted attempts as a clear error instead of a generic failure.
- Cell-instance measurements grid no longer renders the previous spec’s rows after navigating between specs; the cell selector shows a loading skeleton and no longer stalls when an unrelated fetch is in flight; the ECM measurement selector switched to true server-side pagination instead of loading every project measurement into memory.
- The drive-cycles template list endpoint no longer errors at runtime, and now supports standard pagination.
- Fixed an autocomplete component bug where custom dropdown styling options were silently ignored.
Pipeline
Pipeline
- A new fit option skips extra pre- and post-fit result-capture simulations that aren’t surfaced to the user, speeding up server-side fits by default; local users keep the previous behavior unless they opt in.
- Configuration errors are now classified more reliably, so the Configuration error UI path lights up correctly instead of being reported as a generic solver error.
Python API
Python API
client.simulation.get_result()returns a typedSimulationResultobject withtime_seriesandstepsas DataFrames (polars by default, pandas whenset_dataframe_backend("pandas")is active) andmetricsas a plain dict, replacing the previous raw-dict response. Callers use attribute access and.columnsmembership checks instead of dict-key lookups.
Skills
Skills
- New
sim-resultsSDK skill: fetching time-series and step data from a completed simulation, computing SOC via step-boundary cumulation, identifying step types by mean current, deriving DCIR from pulse steps using an OCV baseline plus onset current, and polars-aware plotting conventions. - The
parameterizeskill now documents electrode geometry (thickness, porosity, particle radius, AM fraction, maximum concentration) as a hard build requirement for DFN/SPMe — a physics-based model cannot be assembled without these structural parameters. Geometry lives on the cell spec’s components (not on a measurement), can come from teardown / metrology / vendor datasheet / literature, and FPBM is no longer offered as “available” for Tier-2 cells that lack it.