> ## 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.

# 2026 08 31

<Update label="August 31, 2026" description="Reads 25 of 28 files in the Battery Data Alliance corpus, a new Digatron reader, Arbin EIS sweeps, protocol-name checking, and plots that only fetch what they can show">
  ## Cycler reading, measured against a public adversarial corpus

  We ran every reader against the [Battery Data Alliance parser test-fixture
  corpus](https://doi.org/10.5281/zenodo.21631502) — a published record that exists
  to test battery data pipelines and deliberately includes broken exports. **25 of
  its 28 files now read, up from 3**, all with monotonic time axes. The three that
  still refuse are correct refusals rather than silent damage.

  The fixes matter beyond that corpus, because most of them were failures that
  produced *plausible* data rather than an error:

  * **Arbin workbooks** read their metadata sheet instead of the channel data
    sheet, making most workbooks unreadable, and one header dialect dropped the
    time axis itself while keeping voltage and current.
  * **Maccor** exports using bracketed units (`Test Time [s]`, `Current [A]`) lost
    most of their columns, which surfaced much later as an unrelated-looking error
    from a fitting routine. A header carrying its own units also silently ate the
    first measurement.
  * **BioLogic** exports written in a European locale (decimal comma) failed before
    a single row was read.

  Multi-sheet workbooks now also pick their data sheet the same way across every
  reader, so a vendor whose sheet is named something unexpected no longer depends
  on which reader happens to be handling it.

  ## A Digatron CSV reader

  Digatron CSV exports now read directly. The file's header declares its duration
  columns in seconds while writing milliseconds — trusting the label would give a
  time axis a thousand times too long — so the time axis is derived from the
  timestamp instead, and a duration column whose span disagrees with the wall clock
  is reported rather than swallowed.

  ## Arbin EIS sweeps are no longer dropped

  Arbin writes impedance spectroscopy to a separate sheet, and nothing read it — a
  workbook could report as read while losing every EIS row, with no warning.
  Sweeps now come back spliced into the cycling data in test-time order as their
  own step, with time, voltage and current left null because a sweep is measured
  against frequency rather than the clock. Pass `include_eis=False` to read the
  cycling data alone.

  ## A protocol's name is now checked against the protocol

  `1C/1C, 500 cycles` over a 100-cycle protocol is a perfectly valid protocol with
  a misleading name, and the name is the only thing most readers ever see — it
  travels to the channel assignment, the lab report and the result set. Protocols
  now get a check that reads the name against the protocol and flags which claims
  are contradicted, with a suggested rename, surfaced while you are still typing.

  It deliberately says nothing when there is nothing to contradict: a codename like
  `ETR874` or `RPT` claims nothing, so it draws no warning.

  ## Plots fetch what they can actually show

  Every plot surface now asks the server for the rows its pixels can represent, and
  hands its zoom back to the same route — so opening a chart over a large
  measurement no longer pulls down far more data than the screen can draw, and
  zooming in fetches the detail for the window you are looking at. Validation plots
  read from stored series the same way, so large fits stay responsive.

  A new **Zero x-axis at view start** checkbox on the measurement time-series tab
  relabels the axis from 0 at the left edge of the current view — zoomed into a
  pulse, the axis answers how long it lasted rather than where it sits in the file.
  It re-zeroes on every pan and zoom.

  ## Protocol detail shows the lab work it drives

  A protocol's detail page listed the simulations it produced but not whether it
  had actually been run. It now shows **Simulations**, **Planned measurements** and
  **Measurements** as one tabbed region with counts, each searchable, so "has this
  been run, and is anything queued against it?" is answered on the page.

  Measurements can also record the protocol they were run under, which is what
  links the two together — including as a filter when listing measurements.

  <AccordionGroup>
    <Accordion title="Studio">
      **Improvements**

      * Planned measurements can record a **required temperature and thermal chamber**,
        so a test that must run hot or cold carries that with it. No chamber means
        ambient. Scheduling itself is unchanged for now — a temperature can be set and
        read, but nothing schedules around it yet.
      * The Test Scheduler's search box now **searches the whole backlog on the
        server**, not just the rows already on screen, and matches the protocol, cell
        spec, program and channel **names** shown in the columns rather than only the
        underlying ids.
      * Raw uploaded cycler files are now **detected, parsed and validated
        automatically**, with anything needing a human parked in a review queue with
        actionable choices rather than failing quietly.
      * A still-running measurement's time series can be **extended with new data**
        rather than re-uploaded whole, via `client.cell_measurement.extend()`.
      * Record links across the app now render consistently, with the external-link
        icon marking what is clickable.

      **Fixes**

      * Plot traces, gridlines and links now follow **dark mode**. Some traces
        previously drew in a near-invisible colour against a dark background.
      * The **Cycles tab** offered only two metrics on production — every capacity,
        energy, voltage and duration metric had silently disappeared because of a
        units-spelling mismatch. The picker now derives from the data itself, so it
        cannot drift again.
      * **Re-running a simulation** briefly showed the previous run's error, then
        eventually the new result. A job could also be marked complete when its result
        had not actually been stored, surfacing as a failure to fetch results on an
        apparently successful job.
      * The pan tool now stays selected after a pan.
      * A tab left open across a deploy detects the new version reliably again.
    </Accordion>

    <Accordion title="Python API">
      **Improvements**

      * `client.pipeline` now has the same lifecycle methods as
        `client.simple_pipeline` — `update()`, `cancel()` and `delete()`. Previously a
        pipeline submitted from Python could not be cancelled from Python.
      * `client.pipeline.list()` accepts the full set of filters the API supports and
        returns the total count alongside the page.
    </Accordion>

    <Accordion title="Data Processing">
      **Improvements**

      * New **Digatron CSV** reader.
      * Arbin **EIS sweeps** are read and returned with the cycling data;
        `include_eis=False` opts out.
      * Data-sheet selection in multi-sheet workbooks is now consistent across the
        Arbin, Maccor and Neware readers.

      **Fixes**

      * Eight cycler-reader bugs across Arbin, Maccor, BioLogic and BaSyTec — see the
        headline above.
    </Accordion>
  </AccordionGroup>
</Update>
