Skip to main content
July 6, 2026
ECM fitting with regularization and per-cell nominal capacities, ArrayDataFit through the JSON config path, and near-instant measurement deletion

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.
Improvements
  • Cell measurement deletion is now near-instant. Logfire traces showed DELETE /cell_measurements/{id} averaging 10.3s (max 20.2s), with ~100% of the latency in a single recursive list of the measurement’s storage folder. The per-measurement bucket layout is deterministic, so the file set is now derived from the DB record and removed in a single batched call. The recursive list stays for the org-wide sweep, where it’s genuinely needed.
  • Missing or empty steps.parquet files on a measurement now surface as a typed 422 MEASUREMENT_DATA_MISSING 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.
Improvements
  • initial_guess_sampler on iws.DataFit accepts LatinHypercube or Uniform explicitly, and unknown sampler / distribution / prior names and stray keys are now rejected at submission time with a clear ValidationError instead of a later runtime crash.
Fixes
  • Configuring an ArrayDataFit with a non-number-like objectives key (the reported bug) now surfaces as a UserConfigurationError routed to CONFIGURATION_ERROR — the message is shown, no Sentry page — instead of the opaque “An unexpected error occurred” path. Same treatment applied to sibling user-config validation sites reachable during construction / parse: bad Material inputs, non-Transform/Parameter in Transform.__init__, a non-dict Pipeline.elements, and cost-setter type checks on parameter estimators.
  • Continued sweep of ~50 more bare ValueError raises reclassified as UserConfigurationError / ModelError / ProtocolConfigurationError across the data-fit, optimizer, sampler, metrics, and transform code — user-correctable mistakes surface with an actionable message and no on-call page.
Improvements
  • client.ecm.fit(...) now accepts a regularization option and a per-measurement capacity on FitMeasurementRequest (set on all measurements or none); FitResults.capacity_Ah reports one value per fitted measurement.
  • Submitting an array_data_fit element 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.
Fixes
  • Documentation examples fixed against the real API surface: the resubmit endpoint is POST /jobs/{pipeline_id}/resubmit (the documented /pipelines/{pipeline_id}/resubmit does not exist and would 404); the Model list response has no model_type / config field (only client.model.get(id) returns it); model.create config uses type, not model_type; simulate protocol examples use named steps + string end conditions; CellMeasurementBundleResponse is flat (bundle.name, not bundle.measurement.name).
Improvements
  • run-simple-pipelines documents the array_data_fit element type alongside the standard data_fit.
  • manage-cells: cell_spec.create and create_or_get examples now match CreateCellSpecificationNested — a ratings object (capacity, voltage_min, voltage_max as {value, unit} Quantities) and per-slot cathode / anode keys each holding a NestedComponentInput with a singular material dict. The previous body used rated_capacity / voltage_range_dc / components: [...] fields that do not exist on the model and would have failed server-side validation.