openreadout
OfficialOpenReadout MCP server lets an agent inspect, validate, convert, visualize and analyze raw lab-instrument files across microscopy, mass spec, flow cytometry, plates/qPCR, NMR, electrophysiology and more, offline and without vendor software.
Inspect file metadata, contents, tables, traces, spectra, images, structure and embedded attachments; ask plain-language questions about a file.
Check files for truncation/corruption, see validation/assurance status, and audit storage health of indexed folders.
Export/convert to open formats (OME-TIFF/Zarr, mzML, CSV/Parquet/Arrow, NWB, JCAMP-DX, ASM, RDML, NIfTI, MRC, FASTQ) and extract attachments.
Preview images, plates, traces, spectra and chromatograms; draw annotated plots and multi-panel figures.
Analyze pixels/ROIs/objects/gels, plate-reader assays (wells, curves, dose-response, kinetics, growth, QC), qPCR, flow gating, MS scans/spectra/chromatograms/peaks, NMR peaks/integrals, patch-clamp features and spikes.
Read tables and traces, summarize groups with statistics/tests, batch-measure many files, join sample sheets/plate maps, index/search/link datasets, compare files, and watch live acquisitions with QC events.
Reads Nikon ND2 microscopy files, extracting images, metadata, and allowing inspection, preview, integrity checks, and conversion to open formats such as OME-TIFF and OME-Zarr.
OpenReadout
OpenReadout lets AI agents read and analyze raw files from lab instruments like microscopes, mass specs, flow cytometers, plate readers and NMR. It reads 120+ formats without vendor software, and runs as an MCP server, a CLI, or a Python or R package.
Gallery
Related MCP server: file-analyzer-mcp
Get Started
Install it, then connect it to your agent:
brew install openreadout/tap/openreadout # other ways under Installation below
openreadout mcp --install claude-desktop # or claude, codex, cursor, vscode, geminiThen ask your agent about a file, like "What's in cells.czi?" In Claude Code you can install it as a plugin instead (see AI Integration).
Or try the browser demo with no install. Your files never leave your computer.
With an Agent
Claude finds the cerebellum in a 3.7 GB slide scan and labels its layers.
https://github.com/user-attachments/assets/7ee0f9fe-e6e0-4378-a46d-5cdc04d57151
Claude checks a gene knockout with files from five instruments.
https://github.com/user-attachments/assets/658d300b-dc9d-4164-af84-bb48261fd33f
What It Does
Inspect images, channels, traces, spectra, tables, and metadata, in plain text or structured JSON
Check files for truncation, missing planes, and damaged structure, with exit code 4 when a file is corrupt
Export to OME-TIFF, OME-Zarr, mzML, NWB, CSV, Parquet, Arrow, JCAMP-DX, Allotrope ASM, and RDML, reading every export back to verify it
Preview image planes, traces, spectra, and plate heat maps as PNG
Analyze chromatographic peaks, plate assays (IC50, standard curves), qPCR (Cq, ΔΔCq), NMR peaks, patch-clamp features, spikes, and flow-cytometry gates, with documented methods
Batch over whole directories, index lab shares, and watch running acquisitions
On the Command Line
# Install (macOS / Linux; other ways under Installation)
curl -fsSL https://raw.githubusercontent.com/openreadout/openreadout/main/scripts/install.sh | sh
# What is in the file?
openreadout info cells.lif
# → format: Leica LIF (lif) v2 size: 16.0 MiB images: 1 planes: 2
# → [0] PEI_laminin_35k 2048x2048 z=1 c=2 t=1 uint16 px=0.3250 µm
# → objective: HC PL FLUOTAR L 20x/0.40 DRY
# Is it complete?
openreadout check partial-copy.lif
# → error truncated block chain runs past end of file
# → error missing_planes geometry needs 16777216 bytes but only 8969789 are stored
# Integrate the peaks of a chromatogram
openreadout analyze peaks gc-run.ch --min-height 1
# → 4 peaks, area in pA·min
# → 1 4.852 min area 0.2779 25.08 %
# → ...
# Structured JSON for scripts and agents
openreadout info cells.lif --json{
"ok": true,
"schema_version": "2",
"data": {
"format": { "id": "lif", "name": "Leica LIF", "vendor": "Leica Microsystems" },
"images": [
{
"size_x": 2048, "size_y": 2048, "size_c": 2,
"pixel_type": "uint16",
"physical_size": { "x": 0.325, "y": 0.325, "unit": "µm" }
}
]
}
}Formats
Area | Formats | Export to |
Light microscopy | Zeiss CZI, Nikon ND2, Leica LIF, Olympus OIR/VSI/OIB, Imaris, OME-TIFF and other TIFF variants, OME-Zarr, whole-slide images (including Philips iSyntax, Hamamatsu VMS and MIRAX) | OME-TIFF, OME-Zarr |
High-content screening | Harmony (Opera Phenix, Operetta), ImageXpress, CellVoyager | OME-Zarr plate, OME-TIFF |
Electron microscopy | MRC, Gatan DM3/DM4, FEI SER/EMI, Velox EMD, EER movies, SerialEM mdoc | OME-TIFF, OME-Zarr, MRC |
Structural biology | CBF/miniCBF, SMV, EIGER NeXus (NXmx) diffraction images | MRC, OME-TIFF |
Medical imaging | DICOM (files, series, studies, DICOMDIR), NIfTI, Analyze, Bruker ParaVision | NIfTI, OME-TIFF |
Mass spectrometry | Thermo RAW, Bruker timsTOF and BAF, Agilent MassHunter, Waters MassLynx, Sciex WIFF, mzML | mzML, Parquet, Arrow |
Chromatography | Agilent ChemStation and OpenLab, Shimadzu, Chromeleon, AIA/ANDI | CSV, JCAMP-DX, Parquet |
Electrophysiology | Axon ABF, Intan, SpikeGLX, Open Ephys, Neuralynx, Blackrock, Plexon, HEKA, Spike2, TDT, Axona, NWB | NWB, CSV, Parquet |
NMR and spectroscopy | Bruker TopSpin and OPUS, Varian, JEOL, Thermo OMNIC, Renishaw, JCAMP-DX, SPC | JCAMP-DX, CSV |
Flow cytometry | FCS, FlowJo workspaces, Gating-ML | CSV, Parquet, Arrow |
Plate readers and qPCR | Plate-reader exports, RDML, Applied Biosystems, LightCycler, Rotor-Gene | Allotrope ASM, RDML, CSV |
DNA sequencing and electrophoresis | Illumina run folders, Oxford Nanopore POD5 and FAST5, FASTQ, BAM, ABIF Sanger and fragment-analysis files, Agilent Bioanalyzer and TapeStation | FASTQ, CSV, Parquet |
Other | NanoDrop, Qubit, Incucyte, gel and blot imagers, ÄKTA, ITC, Biacore, Seahorse, Octet, Zetasizer, XRD, EPR, electrochemistry, thermal analysis | CSV, Parquet |
The format list lists every format OpenReadout reads, with its known gaps.
Installation
Ships as a single self-contained binary. No Java, no Python, no vendor DLLs -- nothing else to install.
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/openreadout/openreadout/main/scripts/install.sh | sh
# Windows (PowerShell)
irm https://raw.githubusercontent.com/openreadout/openreadout/main/scripts/install.ps1 | iex
# Homebrew (macOS / Linux)
brew install openreadout/tap/openreadout
# npm (all platforms; installs the native binary for your platform as a dependency)
npm install -g openreadout
# Rust toolchain
cargo install openreadout --lockedDocker, Nix, cargo-binstall, and the other channels are on the install page.
Verify installation: openreadout --version
AI Integration
MCP Server
Built-in MCP server — register with one command:
openreadout mcp --install claude # Claude Code
openreadout mcp --install claude-desktop # Claude Desktop
openreadout mcp --install codex # OpenAI Codex
openreadout mcp --install cursor # Cursor
openreadout mcp --install vscode # VS Code / Copilot
openreadout mcp --install gemini # Gemini CLIWindsurf, Zed, Continue, and Cline are supported too. The server exposes 28 tools (openreadout_info, openreadout_check, openreadout_preview, openreadout_export, openreadout_peaks, ...) over JSON-RPC, so the client doesn't need shell access.
Claude Code Plugin
Installs the MCP server and the skill together:
/plugin marketplace add openreadout/agent-plugins
/plugin install openreadout@openreadoutGemini CLI Extension
gemini extensions install https://github.com/openreadout/agent-pluginsCodex Plugin
codex plugin marketplace add openreadout/agent-plugins
codex plugin add openreadout@openreadoutEach of these adds the skill and the MCP server from the openreadout/agent-plugins repository. The server runs the openreadout binary from your PATH, so install it first.
Agent Skill
openreadout self skill --install claude # ~/.claude/skills/openreadout
openreadout self skill --install agents # ~/.agents/skills/openreadout (Codex, Cursor, Copilot, Gemini CLI)The skill source is in skills/openreadout.
Built for Agents
JSON output for every command, with published schemas.
Fixed exit codes:
0ok,1error,2usage,3unknown format,4corrupt,5I/O,6unsupported.Errors with a hint about what to try next.
Assurance on every result: whether that kind of file was checked against another reader.
--strictrefuses anything that wasn't.Previews the agent can look at, as PNG.
Figures from
plot: plate grids, dose-response fits, gated dot plots and more, as PNG, SVG or PDF.Fast metadata:
inforeads headers only, so a 100 GB file is as quick as a small one.Read-only and offline.
Python and R
Python — pip install openreadout returns metadata as dicts and pixels as NumPy, dask, or xarray arrays, with plugins for bioio and napari. See the Python guide.
import openreadout
with openreadout.File("cells.lif") as f:
f.images[0]["channels"] # same keys as `info --json`
stack = f.to_xarray(0) # labelled with channel names and µm
f.preview(composite=True) # shows itself in Jupyter
openreadout.plot(data={"file": "growth.pda"}, facet="plate").save("plate.pdf")R — the R package returns arrays and data frames, and draws the same previews and figures. See the R guide.
Comparison
OpenReadout | Bio-Formats | bioio | czifile / nd2 / liffile | msconvert | |
Open source & free | ✓ (MIT / Apache-2.0) | ✓ (GPL) | ✓ (plugins vary) | ✓ (BSD) | ✓ (vendor DLLs are not) |
AI-native CLI + JSON + MCP | ✓ | ✗ | ✗ | ✗ | ✗ |
Zero install (single binary) | ✓ | ✗ (JVM) | ✗ (Python) | ✗ (Python) | ✗ |
No vendor DLLs | ✓ | ✓ | ✓ | ✓ | ✗ |
Integrity check | ✓ | ✗ | ✗ | ✗ | ✗ |
Microscopy | ✓ | ✓ | ✓ | ✓ (one format each) | ✗ |
Mass spectrometry | ✓ | ✗ | ✗ | ✗ | ✓ |
Ephys, flow, NMR, chromatography, plates, qPCR | ✓ | ✗ | ✗ | ✗ | ✗ |
Cross-platform | ✓ | ✓ | ✓ | ✓ | Windows (or Wine) |
Validation
Each reader is tested against other readers on public instrument files. See how we validate.
The readers were written from public files, published specifications and permissively licensed readers (credited in NOTICE), without vendor SDKs or DLLs. GPL readers such as Bio-Formats are only run as black boxes in tests. See the clean-room policy and the per-format provenance logs.
Documentation
The documentation has guides for every command and format:
Getting started: Install | Your first file | Reading the JSON output
Guides: AI agents | Python | R | Recipes | Batch tables
A file that does not work: run
openreadout report FILEand attach the bundle to a new-variant issue. The bundle contains no data values, sample names, or paths.
Privacy
OpenReadout runs on your computer, makes no network connections and sends no telemetry. See PRIVACY.md.
License
Licensed under either the Apache License 2.0 or the MIT license, at your option. OpenReadout is not affiliated with any instrument vendor; see TRADEMARKS.md.
Bug reports and contributions are welcome on GitHub Issues. See CONTRIBUTING.md, and read the clean-room policy before working on a reader.
Demo files and README images come from the public test corpus (corpus/manifest.toml), used under their licences, and are credited in .github/assets/gallery/CREDITS.md. demo.tape regenerates the terminal demo.
If you find OpenReadout useful, please give it a star on GitHub — it helps others discover the project.
Available Tools
28 toolsopenreadout_assayBRead-onlyIdempotent
Plate-reader exports, with the layout the file stores or layout. analysis: wells (per-well values, blank subtraction, replicate mean/SD/CV, outliers), curve (standard curve, back-calculated concentrations, LLOQ/ULOQ), dose-response (IC50/EC50 per compound with CI and Hill slope), kinetics (Vmax, lag, AUC per well), growth (growth rate, doubling time, lag, logistic fit, and whether each well grew, crashed or regrew, with times), qc (Z′, S/B, S/N, SSMD). An argument that names analyses applies to those only.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the file or data-set directory. | |
| lloq | No | curve: lower limit of quantification (overrides the recovery rule). | |
| plot | No | curve, dose-response: also return a PNG of the points and the fitted curve. | |
| uloq | No | curve: upper limit of quantification (overrides the recovery rule). | |
| model | No | curve, dose-response: the model. Default `4pl`. `linear` = y = slope · x + intercept; `4pl` = Four-parameter logistic: y = d + (a − d) / (1 + (x/c)^b); `5pl` = Five-parameter logistic: y = d + (a − d) / (1 + (x/c)^b)^g. | |
| wells | No | Only these wells (`A1:H6`); the layout's blanks and controls are still used. | |
| fields | No | Rows show their main fields to 4 significant digits (growth: pattern, growth_rate_per_h, doubling_time_h, lag_time_s, max_value, time_to_max_s, crash_s, trough_s, regrowth_s). fields adds others, e.g. `["auc_h", "logistic_k"]`; `["all"]`: every field, full precision. | |
| fit_on | No | curve: fit every standard replicate or the level means. Default `replicates`. `replicates` = Every standard well (replicates as separate points); `means` = The mean of each standard level. | |
| layout | No | Plate-layout file: CSV/TSV, a plate-map grid (blocks whose corner cell names the field: role, sample, compound, concentration, dilution) or a long table with a `well` column. | |
| reduce | No | wells, curve, dose-response, qc on a kinetic read: how each well's time course becomes one value. `first` = first time point; `last` = last time point; `max` = largest value; `min` = smallest value; `mean` = mean over all time points; `max-slope` = largest slope over `window` points, per minute; `mean-slope` = least-squares slope over all time points, per minute; `auc` = area under the curve (value × s). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| window | No | Points per sliding window (reduce=max-slope, kinetics, growth). Default: 5 or a tenth of the time points, whichever is larger. | |
| analysis | Yes | What to compute. `wells` = Per-well and per-replicate-group values: roles, blank subtraction, mean, SD, CV %, outliers; `curve` = Standard curve (linear, 4PL, 5PL) and back-calculated concentrations of every well; `dose-response` = Dose-response per compound: IC50/EC50 with confidence interval, Hill slope, top, bottom; `kinetics` = Per-well kinetic metrics: max slope (Vmax), lag time, time to max, AUC; `growth` = Per-well growth curves: growth rate, doubling time, lag, logistic fit; which wells grew, crashed or regrew and when (growth_summary); `qc` = Assay quality from control wells: Z′, signal/background, signal/noise, CVs. | |
| normalize | No | wells, dose-response, qc: percent effect from the controls. Default `none`. `none` = the (blank-subtracted) signal; `controls` = percent effect: 0 % = the negative control (vehicle) mean, 100 % = the positive control mean. | |
| standards | No | curve: standards as `WELLS=CONCENTRATION` items separated by `;` (`A1,A2=100;B1:B2=50`). Default: the layout's. | |
| weighting | No | curve, dose-response: fit weighting. Default `none`. `none` = Every point weight 1 (ordinary least squares); `1/y` = w = 1/|y|; `1/y2` = w = 1/y²; `1/x` = w = 1/x (x > 0); `1/x2` = w = 1/x² (x > 0). | |
| confidence | No | curve, dose-response: confidence level of intervals. Default 0.95. | |
| blank_wells | No | Wells to mark as blanks (`H1,H2`, `H1:H12`). | |
| plate_options | No | Rarely needed plate options. | |
| negative_wells | No | Wells to mark as negative controls (no effect / vehicle). | |
| positive_wells | No | Wells to mark as positive controls (full effect / maximum signal). | |
| growth_threshold | No | growth: values at or below this are left out of the log-scale fit. Default 5 % of each well's maximum. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | The input file. |
| read | Yes | The read analysed. |
| blank | No | Blank subtraction applied. |
| curve | No | Standard-curve fit report (`curve`). |
| notes | No | What was assumed or left out. |
| plate | No | Plate (table) name. |
| table | Yes | Table (plate) index. |
| wells | No | One row per well. |
| format | Yes | Format id of the input (`plate`, or `long-csv`). |
| growth | No | One row per well (`growth`). |
| layout | Yes | Where the layout came from and what it assigns. |
| reduce | No | How kinetic time courses were reduced to one value per well (endpoint analyses). |
| quality | No | Assay quality from control wells (whenever positive and negative controls exist). |
| samples | No | One row per replicate group (sample, standard level, control, dose). |
| written | No | Files written (`--csv`, `--plot`). |
| analysis | Yes | The analysis run (`wells`, `curve`, `dose-response`, `kinetics`, `growth`, `qc`). |
| kinetics | No | One row per well (`kinetics`). |
| outliers | Yes | Outlier rule and flagged wells. |
| warnings | No | What may be wrong with the layout: role names read as samples, controls of unknown sign, role-map entries that matched no well. |
| compounds | No | One row per compound (`dose-response`). |
| growth_summary | No | Wells by growth pattern, with the range of crash and regrowth times (`growth`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered without the description. The description adds the analysis-scoping rule but says nothing about error behavior, layout-resolution conflicts, or what happens when required layout/standards are missing — context the schema only partially carries (e.g. strict/exit_code 6).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The analysis taxonomy is dense and useful, and the scoping sentence earns its place. But the opening fragment is confusingly terse (it states no action), and the whole enumeration duplicates the `analysis` parameter's enum description, so a meaningful portion is redundant for an agent that has the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present the description need not explain return values, and annotations cover safety, so what remains — orienting the agent on the six analysis families and the argument-scoping rule — is largely delivered. It falls short only on modality routing versus siblings and on failure/precondition behavior for a 22-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 22 parameters with enums, defaults and formulas. The description's analysis enumeration largely restates the `analysis` enum text (LLOQ/ULOQ, IC50/EC50, Z′/S/B/S/N/SSMD) rather than adding new meaning, so the baseline of 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (plate-reader exports) and enumerates the six analysis modes the tool computes, so an agent can tell it is the plate-reader assay analysis tool rather than the qPCR, chromatogram, or ephys siblings. However, the opening 'Plate-reader exports, with the layout the file stores or `layout`' is a verbless fragment that never states the action ('analyse/compute') outright, and no sibling is named for contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'An argument that names analyses applies to those only' gives real applicability guidance, telling the agent that e.g. `curve` or `plot` are scoped to the analyses named in `analysis`, and the analysis enumeration implies which mode to pick. But there is no when-to-use/when-not guidance and no naming of alternatives like `openreadout_stats`, `openreadout_extract` or `openreadout_summarize` that an agent might otherwise reach for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_batchADestructiveIdempotent
One measure over many files as one tidy table, optionally joined to sample sheets or plate maps (the join key is chosen from the data and reported in joins[] with unmatched rows) and summarized by group (by; test against a control). Analyses (peaks, chromatogram, nmr-peaks, ephys-features, spikes, qpcr, gate, assay) take the arguments of their tools as options. Inputs (paths): files, directories, globs or an index query. Returns at most limit rows (page with offset; output writes them all to a file); a failing file is a row with error. openreadout_summarize regroups a table written by an earlier output.
| Name | Required | Description | Default |
|---|---|---|---|
| by | No | Summarize by these columns (e.g. `["condition"]`): n, mean, sd, sem, median, min, max, cv_percent per group; channels/parameters/populations stay apart automatically. | |
| keys | No | Fixed join keys `SHEET_COLUMN=FIELD` (path, file, stem, sample_id, sample_name, barcode, well, position, run_order, column:NAME). | |
| test | No | `welch` or `mann-whitney` against `control` (a value of the first `by` column). | |
| limit | No | Rows to return (default 20, max 500; 0 with `output`: the rows are in the file). | |
| paths | No | Files, directories or glob patterns. | |
| query | No | … and the query (search syntax, e.g. "format=fcs channel~CD4"). | |
| where | No | Row filters `COLUMN=VALUE` / `COLUMN!=VALUE` (e.g. "parameter=FITC-A"). | |
| fields | No | Columns to keep (info: index field names, or `["all"]`). | |
| offset | No | First row returned. | |
| output | No | Write the full table (or the summary, with `by`) to this .csv/.tsv/.jsonl/.json/.parquet file (verified; never overwrites without `overwrite`). | |
| values | No | Value columns to summarize (default: the measure's main values). | |
| control | No | The control group. | |
| formats | No | Only these format ids (e.g. `["fcs"]`). | |
| measure | Yes | What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `scans` = one row per MS scan header (options: the openreadout_scans filters); `peaks` = openreadout_peaks (its arguments as options); `chromatogram` = openreadout_chromatogram (its arguments as options); `assay` = a plate-reader assay: options `analysis` (wells, curve, dose-response, kinetics, growth, qc) and the other openreadout_assay arguments; `nmr-peaks` = openreadout_nmr_peaks (its arguments as options); `ephys-features` = openreadout_ephys_features (its arguments as options); `spikes` = openreadout_spikes (its arguments as options); `qpcr` = openreadout_qpcr (its arguments as options); `gate` = population counts, percentages and medians (workspace or gatingml). | |
| options | No | The measure's options. Analyses: the arguments of that analysis's tool (openreadout_peaks, openreadout_nmr_peaks, openreadout_assay with its `analysis`, ...), plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. scans: the openreadout_scans filters. | |
| exact_by | No | Group by exactly `by` (do not add the measurement columns that vary). | |
| overwrite | No | Replace an existing output file. | |
| recursive | No | Walk sub-directories. | |
| replicate | No | Average rows within each replicate first. | |
| worksheet | No | Worksheet of an XLSX sheet. | |
| from_index | No | Also take the data sets an index query selects: the index directory … | |
| sample_sheets | No | Sample sheets (CSV/TSV/XLSX) or plate layouts (plate-map grids) to join; the key is chosen from the data (file name, path, sample id recorded in the file, well, barcode, vial, run order) and reported under joins[]. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | Rows as arrays in column order. |
| grain | Yes | Columns that identify a row within its data set. |
| joins | No | Sample sheets and layouts joined, in order. |
| inputs | Yes | How the inputs became data sets. |
| offset | Yes | Index of the first row in `rows`. |
| output | No | The file the full table was written to (`-o`). |
| columns | Yes | Columns of `rows`, with type, unit and role (`id`, `key`, `metadata`, `annotation`, `value`, `error`). |
| measure | Yes | Measure (`stats`, `trace`, `table`, `gate`, `info`, …). |
| summary | No | The group summary (`--by`). |
| warnings | No | Things to check: skipped inputs, grouping, join results. |
| truncated | Yes | True when the table has rows after the last one returned (page with `offset`, or read the full table from `output`). |
| total_rows | Yes | Rows in the whole table. |
| returned_rows | Yes | Rows returned here. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare the safety profile (destructiveHint=true, idempotentHint=true), and the description adds real behavior beyond that: a failing file becomes a row with error rather than aborting, limit defaults to 20/max 500 with offset paging, output writes all rows and never overwrites without overwrite, and the join key is chosen from the data and reported in joins[] with unmatched rows.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense and front-loaded: the core purpose, then joins/summarization, then inputs, then paging/output semantics. Every clause carries information, though the heavy parenthetical stacking (measure lists, option lists) makes it read as one long run-on rather than clearly separable statements.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the description still covers the non-obvious output contract (rows written to file vs returned, per-file errors as rows, joins[] reporting). For a 22-parameter tool with nested `options` this is nearly complete, missing only explicit prerequisites/permissions for writing output files.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 22 parameters in detail, including the per-measure semantics of `measure`. The description reinforces how `options` maps to sibling tools and how joins are keyed, but adds little syntax beyond what the schema provides — the baseline 3 for full coverage applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource+scope: 'One measure over many files as one tidy table', then names the optional join and group-summarization behaviors. It explicitly distinguishes itself from the sibling openreadout_summarize, which only regroups a previously written table, so an agent can route without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear input-mode guidance ('files, directories, globs or an index query') and explains that analyses (peaks, chromatogram, nmr-peaks, ...) are invoked by passing their tool arguments as options. It also names openreadout_summarize as the follow-up alternative, but never states the when-not condition versus the singular openreadout_stats/table/trace tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_checkARead-onlyIdempotent
Integrity check: ok plus findings (severity, code, message) for truncation, missing planes or parts, bad blocks; a plate folder reports missing files per well; a file still being written reports acquisition_in_progress.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the file or data-set directory. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| headers_only | No | Check headers and structure only (offsets, declared sizes and counts, missing parts): no decompression, decoding or checksums over the data. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | True when no finding has severity `error`. |
| path | Yes | The input file. |
| format | Yes | Format id of the input file. |
| findings | Yes | Everything found, in the order checked. |
| assurance | No | Whether the file lies inside what its reader has been validated on (the same block as `info` → `assurance`). `ok` says the file is intact; `assurance` says whether its values can be trusted. Filled by the `check` command when the header can be read. |
| acquisition | No | Present when the file is not finished: still being written (`in_progress`: findings about the unfinished tail are warnings and `ok` covers the complete part) or stopped before the end (`interrupted`). See `book/src/guides/lab-shares.md`. |
| checks_performed | Yes | What was verified, in plain words, so the caller knows what "ok" covers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the bar is lower, and the description adds real behavioral detail: the shape of findings (severity, code, message), the plate-folder per-well reporting mode, and the acquisition_in_progress special case. It does not explain the strict/exit_code 6 behavior that only the schema hints at.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence that front-loads the outcome (ok plus findings) before enumerating detection categories. No filler, though the semicolon-chained clauses make it slightly harder to parse than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, yet the description still usefully summarizes the finding structure and the folder-mode behavior. Complete enough to call correctly; the only gap is sibling differentiation and strict-mode behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all three parameters are already documented, making 3 the baseline. The description adds only slight context (a directory argument triggers per-well reporting) and does not elaborate on strict or headers_only semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (integrity check) on a specific resource (file/data-set directory) and enumerates what it detects: truncation, missing planes or parts, bad blocks. An agent can tell it is a damage check, but the description never distinguishes it from the similarly-scoped sibling openreadout_health.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the content: the tool is for verifying file/folder integrity. There is no explicit when-to-use statement, no when-not-to, and no routing to alternatives such as openreadout_info or openreadout_health.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_chromatogramARead-onlyIdempotent
Chromatograms from mass spectra and detector signals: TIC, BPC, extracted-ion (mz with ppm or da), SRM/MRM transitions, stored chromatograms and UV/DAD/FID/TCD traces (traces). Per chromatogram: apex time and intensity, integral, and thinned arrays. Answers 'when does m/z X elute'.
| Name | Required | Description | Default |
|---|---|---|---|
| da | No | XIC tolerance in m/z units instead of ppm. | |
| mz | No | Extracted-ion chromatograms at these m/z values (one streaming pass for all). | |
| bpc | No | Base-peak chromatogram. | |
| ppm | No | XIC tolerance (half-width) in ppm. Default 10. | |
| run | No | Spectra run. Default 0. | |
| tic | No | Total-ion chromatogram (the default for mass-spectrometry files when nothing else is chosen). | |
| file | Yes | Path to the file or data-set directory. | |
| sweep | No | Sweep of the traces (one spectrum of a map or series, one injection). Default 0. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| traces | No | Stored chromatograms or detector signals (UV/DAD, FID, TCD, stored TIC/SRM): trace indices from openreadout_info → traces[]. | |
| channel | No | Channel of the traces (e.g. one DAD wavelength). Default: the first signal channel. | |
| profile | No | Use profile data where scans store both profile and centroids. Default false (the instrument's centroids). | |
| ms_level | No | MS level of the scans. Default 1 (2 with `precursor`). | |
| mz_range | No | TIC/BPC over this m/z range only, `[low, high]`. | |
| polarity | No | `positive` or `negative`: only scans of this polarity. | |
| rt_range | No | Retention-time range `[start, end]`, minutes. | |
| aggregate | No | `sum` (default) or `max` of the points inside an XIC window. | |
| precursor | No | Only MS/MS scans of this precursor m/z (product-ion XIC). | |
| max_points | No | Points returned per chromatogram (the most intense point of each of N equal slices). Default 500, max 20000; the summary (apex, integral) always covers every point. | |
| scan_filter | No | Only scans whose scan filter/description contains this text (case-insensitive). | |
| transitions | No | SRM/MRM transitions as `"Q1>Q3"` strings, e.g. `"279.2>179.2"`. | |
| precursor_tol | No | Precursor tolerance, m/z units. Default 0.5. | |
| transition_tol | No | Q1/Q3 tolerance of transitions, m/z units. Default 0.5. |
Output Schema
| Name | Required | Description |
|---|---|---|
| run | No | Spectra run used, when any chromatogram was computed from spectra. |
| path | Yes | The input file. |
| notes | No | Anything the caller should know. |
| format | Yes | Format id of the input file. |
| output | No | File written (`-o`), when any. |
| spectra_read | Yes | Spectra decoded. |
| chromatograms | Yes | One entry per requested chromatogram. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and a closed world, so the safety profile is fully covered. The description adds that output arrays are thinned while the apex/integral summary covers every point, which is useful behavioral context, but it discloses nothing about cost, streaming, or parameter interaction beyond what the schema's own parameter text already states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with the supported chromatogram modes before the per-chromatogram output and the use-case question. Nothing is padded, though the mode enumeration and output summary run long for a single sentence, which keeps it just under a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a 23-parameter tool with an output schema and full annotation coverage, the description supplies the missing high-level framing: which chromatogram types exist and what each result contains. It does not explain how the many mode selectors (tic/bpc/mz/transitions/traces) interact or which combinations are mutually exclusive, which is the main residual gap for a tool this complex.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every one of the 23 parameters is already documented in the schema, including tolerances, defaults, and the max_points thinning rule. The description only restates a handful of these (mz with ppm or da, transitions, traces) at a conceptual level without adding syntax or interaction semantics, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (chromatograms) and enumerates the specific modes it extracts — TIC, BPC, extracted-ion with ppm/da tolerance, SRM/MRM transitions, stored/detector traces — which lets an agent recognize the tool against siblings like openreadout_spectrum or openreadout_trace. The verb is only implied in the text (it lives in the annotation title 'Extract chromatograms'), and no sibling is named for contrast, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through one concrete question it answers, "when does m/z X elute," which points at extracted-ion work, and through the mode list that hints which parameters select which behavior. There is no explicit when-to-use versus openreadout_spectrum/openreadout_trace/openreadout_peaks, and no stated exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_compareARead-onlyIdempotent
Compare two files, e.g. a raw file and its export: metadata differences, geometry, channel names, physical sizes, and per-plane hashes or the largest difference within tolerance. identical says whether they hold the same data.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | The first file (e.g. the raw file). | |
| image | No | Only this image index (in both files). | |
| level | No | Pyramid level (0 = full resolution, the default). | |
| ignore | No | JSON pointers (into openreadout_info output) to leave out of the metadata diff; `*` matches one segment. | |
| select | No | Plane selection strings such as `c=0`, `z=2-5`, `t=0,3`. A second file holding only the selected planes (an export with the same selection) is matched to them in order. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| against | Yes | The second file (e.g. an OME-TIFF export of `file`). | |
| no_pixels | No | Metadata and geometry only, no pixels. | |
| tolerance | No | Largest absolute sample difference that still counts as equal. Default: bit-identical planes (same xxh3-128). |
Output Schema
| Name | Required | Description |
|---|---|---|
| ours | Yes | The first file. |
| notes | No | Caveats (e.g. formats that store different metadata for the same acquisition). |
| images | Yes | Geometry, channel-name and physical-size comparison per image index. |
| planes | Yes | The plane-by-plane comparison. |
| theirs | Yes | The second file. |
| metadata | Yes | The normalized-metadata diff. |
| identical | Yes | Nothing compared differs: metadata (unless skipped), geometry, channel names, physical sizes and planes (within the tolerance). The exit code is 0 when true, 1 when false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds behavior beyond that: it discloses the default equality rule (bit-identical xxh3-128 planes unless tolerance is set), that strict mode refuses unvalidated values with exit_code 6, and what the 'identical' flag reports. It does not describe output shape or performance characteristics, but the output schema exists to carry that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence with the core action front-loaded and the compared aspects following. Every clause carries information, though the enumerated list plus the trailing 'identical says...' sentence makes it slightly cramped rather than maximally scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter comparison tool, the definition plus a 100%-covered schema, an output schema, and safe-read annotations leave nothing an agent needs missing: purpose, what is compared, the equality default, and the return signal ('identical') are all present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every one of the 9 parameters is already documented in the schema, including tolerance's xxh3-128 default and the ignore JSON-pointer syntax. The description only echoes these at a high level ('per-plane hashes or the largest difference within tolerance') without adding format or interaction details, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Compare two files') and enumerates exactly what dimensions are compared: metadata, geometry, channel names, physical sizes, per-plane hashes. That is far more specific than the title alone. It stops short of naming a sibling, so an agent cannot infer from the text alone why it would pick this over openreadout_check or openreadout_info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical 'e.g. a raw file and its export' gives a concrete usage scenario and the required params reinforce it ('an OME-TIFF export of `file`'). There is no explicit when-not guidance and no naming of the alternative tools (openreadout_check, openreadout_info) whose output feeds the `ignore` pointers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_ephys_featuresCRead-onlyIdempotent
Patch-clamp features: action potentials per sweep, rheobase, f-I slope, input resistance, membrane time constant, capacitance, sag; in voltage clamp, holding current and access resistance.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the file or data-set directory. | |
| trace | No | Trace index (default 0). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| sweeps | No | Sweeps to analyse (default all). | |
| channel | No | Channel (default: the first voltage channel, else the first current channel). | |
| max_spikes | No | Per-spike rows returned (default 25, the first spikes in sweep order; counts stay complete). | |
| min_rise_mv | No | A spike's peak must rise this far above the lowest voltage since the previous spike, mV (default 15; 0 counts every crossing, as eFEL does). | |
| dvdt_threshold | No | dV/dt onset criterion, V/s (default 10). | |
| peak_threshold_mv | No | Spike voltage threshold, mV (default −20). |
Output Schema
| Name | Required | Description |
|---|---|---|
| cell | Yes | Per-cell features. |
| path | Yes | Input path. |
| notes | No | Remarks. |
| trace | Yes | Trace analysed. |
| format | Yes | Format id. |
| spikes | Yes | One row per spike (at most `max_spikes`). |
| sweeps | Yes | One row per sweep. |
| channel | Yes | Channel analysed. |
| settings | Yes | Spike detection settings. |
| stimulus | No | Stimulus from the protocol, when there is one. |
| clamp_mode | Yes | `current_clamp`, `voltage_clamp` or `unknown` (from the channel and command units). |
| sample_rate_hz | Yes | Sampling rate, Hz. |
| spikes_truncated | Yes | True when `spikes` was cut at `max_spikes`. |
| spike_count_total | Yes | Total spikes detected. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and non-destructive, so the safety profile is covered. The description adds no behavioral context beyond the domain split of current vs voltage clamp: nothing about required file/assurance preconditions, what happens when features cannot be computed, or how strict mode affects results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the topic leads and the clamp-mode distinction follows. It is efficient, though the semicolon-heavy feature list reads more like an output inventory than guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained — yet the description spends its length restating those outputs instead of covering the gaps: required input format, the meaning of strict/exit_code 6, and how it relates to openreadout_spikes. Adequate but with clear omissions for a 9-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter carries its own default and semantics, so the baseline of 3 applies. The description's enumerated quantities describe outputs rather than clarifying any parameter, adding no interpretive value for inputs like sweeps, channel or the spike-detection thresholds.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (patch-clamp features) and enumerates the specific quantities computed, so an agent can tell this is an ephys feature-extraction tool. However, there is no explicit verb and no differentiation from neighbours like openreadout_spikes or openreadout_trace, which also operate on traces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisite statement (e.g. what file kinds qualify), and no mention of alternatives such as openreadout_spikes for raw spike events. The agent must infer selection context entirely from the feature list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_exportADestructiveIdempotent
Convert to an open format, or save a figure, as a new file read back and verified; the source is never touched. format: ome-tiff (images, default; pyramidal when the source is), ome-zarr (multiscale; plates as OME-NGFF HCS), mzml (mass spectra, default), csv (one table or one sweep of a trace, default for tables and traces), parquet or arrow (tables, traces with every sweep, spectra=true for MS points), nwb (electrophysiology), jcamp (NMR, IR/Raman, chromatograms), asm (plate readers), rdml (qPCR), nifti (volumes: CT, MRI). Figures: plot or preview = the arguments of that call, output .png, .jpg, .tiff, .svg or .pdf (scale, dpi for print); the picture comes back too. Sends progress with a progressToken.
| Name | Required | Description | Default |
|---|---|---|---|
| dpi | No | Figures: print resolution (e.g. 300), recorded in .png, .jpg and .tiff files; .svg and .pdf pages get the size the raster would print at. | |
| run | No | mzML, Parquet, Arrow: spectra run index (default 0). | |
| file | No | Path to the file (not with plot or preview). | |
| plot | No | Save a figure: the arguments of an openreadout_plot call. `output` names the file. | |
| rows | No | CSV, Parquet, Arrow, NWB, JCAMP-DX: rows (samples of each sweep for traces) `A-B`, `A-` or `A`, zero-based and inclusive. | |
| image | No | Images: only this image index. | |
| level | No | Images: export this source pyramid level as the full resolution (default 0). | |
| scale | No | Figures: pixels per figure pixel in .png, .jpg and .tiff files (default 2, up to 8); image previews are read again at max_size × scale. | |
| sweep | No | CSV, Parquet, Arrow, NWB, JCAMP-DX: only this sweep (CSV default 0; the others: every sweep). | |
| table | No | CSV, Parquet, Arrow: this table index (FCS data set, plate read, event or peak table). | |
| trace | No | CSV, Parquet, Arrow, NWB, JCAMP-DX: this trace index (NWB default: every trace). | |
| wells | No | OME-Zarr of a multi-well plate: only the fields of these wells (`C05`). | |
| format | No | `ome-tiff` (one BigTIFF file; the default for images), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0; the default for mass spectra), `csv` (one table, or one sweep of a trace; the default for tables and traces), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces), `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms), `asm` (Allotrope Simple Model plate-reader JSON), `rdml` (RDML 1.3; qPCR files), `fastq` (base calls: a Sanger read, its default, gives one file; an Illumina run folder gives a directory of gzip FASTQ, one file per lane and read, and rows `0-N` writes the first N+1 clusters of each lane), `nifti` (NIfTI-1 `.nii.gz`; one volume with voxel size and scanner orientation) or `mrc` (MRC2014; EM movies, stacks and diffraction images). Without it, the extension of `output` decides; it must not contradict `output`. | |
| labels | No | CSV: add a second header line with column labels (FCS `$PnS`). | |
| output | No | Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.csv`, `.asm.json`, `.rdml`, `.fastq`, `.parquet`, `.arrow`, `.nwb`, `.jdx`, `.nii.gz` or `.mrc`. Its extension sets the format when `format` is not given. Figures: .png, .jpg, .tiff, .svg or .pdf (default `<data file stem>.figure.png` or `.preview.png` next to the data). | |
| region | No | Images: export only this rectangle `{x, y, width, height}` (pixels of `level`) of every plane, read tile by tile (cut a field out of a whole-slide image). | |
| select | No | Images: plane selection strings such as `c=0`, `z=2-5`, `t=0,3`. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| preview | No | Save a picture: the arguments of an openreadout_preview call (file, region, annotations, marks, dark, …); max_size up to 8192. Images are saved with a scale bar and no rulers (axes scale-bar; add title, caption) unless axes says otherwise. | |
| spectra | No | Parquet, Arrow: export the mass spectra of `run` (one row per point, plus a `<name>.scans.parquet` per-scan summary) instead of a table or trace. | |
| centroid | No | mzML, Parquet, Arrow: write the instrument's centroid lists instead of profiles where a scan has both. | |
| overwrite | No | Replace an existing output file or directory. | |
| group_frames | No | MRC: sum every N time points into one section (dose fractions of a movie). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag a non-read-only, destructive, idempotent write confined to the local world. The description adds real value on top: the source is never touched, output is read back and verified, overwrite replaces an existing file or directory, strict mode can fail with exit_code 6, and progress is reported via progressToken. Minor gap: no mention of permissions or what is returned on success.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first clause, which is good. But the remainder is a single dense run-on that dumps the entire format list already present in the schema's format parameter, so a large fraction of the text duplicates structured data instead of earning its place. Structure suffers from being one unbroken block.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 23-parameter, no-required, nested-object tool with no output schema, the description covers conversion targets, figure saving, verification, overwrite and progress well. The main gap is the return value for the data-export path (only figures are said to come back), which with no output schema is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every one of the 23 parameters is already documented inline, including the format enum-like list. The description largely restates the format options rather than adding interpretation, and the default-selection rule (extension of output decides unless format is given) is already in the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause gives a specific verb and resource: convert data to an open format or save a figure, written as a new file that is read back and verified, leaving the source untouched. This is clearly distinguishable from display-oriented siblings like openreadout_plot and openreadout_preview, whose arguments this tool reuses. An agent knows exactly what this tool produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: it lists per-source default formats and notes that plot/preview arguments are reused for figures, which hints at the boundary with those siblings. However, it never explicitly says when to choose export over plot/preview, nor states any prerequisites or exclusions. Guidance is present but left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_extractADestructiveIdempotent
Write one attachment a file embeds (a slide label or thumbnail, a preview image, time stamps) to a new file as stored, verified. openreadout_info view=structure lists them.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Absolute or working-directory-relative path to the file that holds the attachment. | |
| output | No | Output path. Default: `<input stem>.<attachment name>.<ext>` next to the input. | |
| overwrite | No | Replace an existing output file. | |
| attachment | Yes | The attachment: a name as openreadout_info view=structure lists it (a CZI's `Thumbnail`, `Label` or `SlidePreview` image, `TimeStamps`), or `#<index>`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | The input file. |
| xxh3 | Yes | xxh3-128 of the written bytes, 32 hex chars. |
| format | Yes | Format id of the input file. |
| output | Yes | Where the bytes were written. |
| verified | Yes | True once the output was read back and matched. |
| attachment | Yes | The attachment that was extracted. |
| bytes_written | Yes | Number of bytes written. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, readOnlyHint=false and openWorldHint=false, so the safety profile is covered structurally. The description adds a genuine behavioral note with 'as stored, verified' (bytes are written unmodified and checked), but says nothing about what overwriting destroys, permissions, or failure behavior when the attachment is absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no padding; the action and its scope are front-loaded and the pointer to openreadout_info view=structure comes second as a discovery hint. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering the destructive/idempotent profile and an output schema present, the description need not explain return values; it correctly focuses on which attachment to pull and where listing lives. It is slightly thin on interaction between `output` and `overwrite` (what happens when the target already exists), which keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (file, output, overwrite, attachment) are already documented, including the `#<index>` form. The description only echoes the attachment concept and adds no syntax, default, or interaction detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (extract/write) and resource (an embedded attachment such as a slide label, thumbnail, preview image, or time stamps) and gives concrete examples of the attachment types, which separates it from generic siblings like openreadout_export. It lacks explicit verb+resource naming tied to other tools' scopes, but the purpose is clear without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Points the agent at openreadout_info view=structure as the way to discover valid attachment values, which is useful context, but never states when to use this tool versus alternatives like openreadout_export or openreadout_preview, nor any prerequisites or exclusions. Usage is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_gateARead-onlyIdempotent
Flow-cytometry gating from a FlowJo workspace (workspace) or Gating-ML 2.0 file (gatingml): the event count, percentage and medians of every population of the FCS file. Without workspace or gatingml, file is the gating file and the answer describes its samples and gate tree.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the file or data-set directory. | |
| table | No | FCS data set index. Default 0. | |
| sample | No | Workspace sample name or id (default: matched by file name, then $FIL, then the only one). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| medians | No | Parameters whose median over each population's events is reported under populations[].medians (`$PnN` or `$PnS`; `Comp-NAME` for compensated values), or `["all"]`: every parameter a gate uses, compensated as the gate reads it. | |
| gatingml | No | Gating-ML 2.0 document (instead of workspace). | |
| workspace | No | FlowJo workspace (.wsp); `file` is then the FCS file to count events in. | |
| populations | No | Report only these populations (paths or unique names) and their descendants. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | No | The FCS file gated; absent when only the gating file was described. |
| tree | Yes | The same populations as a tree (quadrant gates appear as grouping nodes without a count). |
| notes | No | Caveats: skipped populations, disagreements with counts stored in the workspace, scaling. |
| table | No | FCS data set (table) gated. |
| sample | No | The workspace sample whose gates were used (FlowJo only). |
| workspace | No | Workspace-level facts (FlowJo only). |
| transforms | Yes | Transforms by id (FlowJo: by parameter name). |
| event_count | No | Events in the data set. |
| gating_file | Yes | The gating file (FlowJo workspace or Gating-ML document). |
| populations | Yes | One row per population, parents before children. |
| compensation | Yes | Compensation matrices the gating file defines (and whether any gate used them). |
| gating_format | Yes | `flowjo-wsp` or `gating-ml`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: the fallback interpretation of `file` when both gating inputs are omitted, and the specific report contents per population. It does not mention failure modes such as the strict/exit_code 6 path (that only appears in the schema).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the core action and outputs. The second sentence's fallback rule is a little packed with clauses, but every clause carries actionable information and nothing is repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 8 parameters, an output schema present, and full schema coverage, the description supplies what the structured fields cannot: the operating-mode logic and the fallback behaviour. Minor gaps remain around error/strict handling and how `populations` and `medians` interact, but nothing essential for a correct call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further by describing cross-parameter coupling: `workspace` makes `file` the FCS file to count in, `gatingml` is an alternative to `workspace`, and the absence of both redefines `file`. That role-switching is not obvious from the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — flow-cytometry gating — and names the two input modes (FlowJo workspace, Gating-ML 2.0) plus the exact outputs (event count, percentage, medians per population). No sibling tool overlaps this domain, so an agent can select it unambiguously.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear mode-selection guidance: pass `workspace` or `gatingml` to compute gated counts, and if neither is supplied, `file` acts as the gating file and the answer degrades to a sample/gate-tree description. It does not point to any alternative tool for other flow-cytometry tasks, so exclusions are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_healthARead-onlyIdempotent
Storage health of a share indexed by openreadout_index: truncated or corrupt files, unreadable formats, duplicates (confirmed by content hash unless no_hash), the same experiment stored twice, files at risk, totals and personal-data findings.
| Name | Required | Description | Default |
|---|---|---|---|
| no_hash | No | Do not confirm duplicate candidates by hashing their content (no file is read). | |
| max_list | No | Most entries listed per section (default 50; counts are complete). | |
| index_dir | Yes | Index directory (from openreadout_index or `openreadout index`). |
Output Schema
| Name | Required | Description |
|---|---|---|
| pii | Yes | Personal data. |
| roots | Yes | The roots of the index. |
| totals | Yes | Totals. |
| at_risk | Yes | Vendor-only formats with no open export. |
| by_year | Yes | Per acquisition year. |
| by_family | Yes | Per family. |
| by_format | Yes | Data sets and bytes per format. |
| index_dir | Yes | The index directory. |
| integrity | Yes | Truncated and corrupt data sets. |
| duplicates | Yes | Byte-identical copies. |
| unreadable | Yes | Unreadable formats and unrecognised files. |
| generated_at | Yes | When this report was made. |
| index_complete | Yes | Whether the index covers every root to the end. |
| near_duplicates | Yes | The same experiment stored more than once. |
| index_updated_at | Yes | When the index was last written. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds that duplicate confirmation reads file content unless no_hash is set, hinting at I/O cost, but it does not state how expensive a full hash pass is, whether progress is reported, or how sections behave on a partially indexed share.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that leads with the resource ('Storage health of a share indexed by openreadout_index') and then lists findings; the enumeration is dense but every item conveys a distinct output category. Slightly list-heavy but free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full output schema and complete annotation coverage, the description only needs to convey purpose and scope, and it does so, including the results categories. The only gap is workflow guidance relative to sibling diagnostics, which is minor given the rich structured metadata.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter already carries a description, so the schema does the heavy lifting. The description only gestures at no_hash via 'unless no_hash' and says nothing extra about max_list or index_dir beyond the schema, which is an appropriate baseline-3 case.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific resource and scope — storage health of a share produced by openreadout_index — and enumerates the concrete findings it reports (truncated/corrupt files, duplicates, files at risk, totals). This separates it from openreadout_stats, openreadout_info and openreadout_check well enough for selection, though the phrasing is a noun phrase rather than an explicit verb.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The tie to openreadout_index implies 'run after indexing', but there is no explicit when-to-use, when-not-to-use, or named alternative (e.g. openreadout_check vs openreadout_stats). The agent must infer the workflow position and the choice between this and sibling inspection tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_indexAIdempotent
Catalog every data set under roots into index_dir (Parquet: one row per data set with format, size, sample, instrument, technique, method, operator, start, dimensions, channels, objective, events, scans, integrity status, personal-data flags). Headers only and resumable: a call stops after max_files/max_seconds with complete=false, and the same call again continues. openreadout_search queries the result. For one folder of files, openreadout_batch with measure info lists what each file is in one call.
| Name | Required | Description | Default |
|---|---|---|---|
| pii | No | Look for personal data (default true). | |
| check | No | Integrity check per data set: `headers` (default; structure only), `full` or `none`. | |
| roots | Yes | Directories (or files) to crawl. | |
| exclude | No | Glob patterns of names or root-relative paths to skip. | |
| restart | No | Discard an interrupted crawl instead of resuming it. | |
| threads | No | Worker threads (default: the number of CPUs). | |
| index_dir | Yes | Index directory to create or update (never inside a root). | |
| max_files | No | Stop after this many files in this call (default 20000); call again to continue. | |
| full_rescan | No | Read every file again instead of reusing unchanged records. | |
| max_seconds | No | Stop after this many seconds in this call (default 45); call again to continue. | |
| follow_symlinks | No | Crawl directories behind symbolic links too (links to files are always read). |
Output Schema
| Name | Required | Description |
|---|---|---|
| pii | Yes | Personal-data totals. |
| next | No | What to do next, when the crawl is not complete. |
| tool | Yes | The tool and version that wrote it. |
| bytes | Yes | Bytes of every file seen. |
| crawl | Yes | Crawl counters, cumulative over resumed sessions. |
| files | Yes | Rows of `files.parquet`. |
| roots | Yes | The directories (or files) crawled, absolute. |
| years | Yes | Data sets per acquisition year (`unknown` when the file records no date). |
| tables | Yes | The tables. |
| changes | Yes | Data sets per change (`new`, `changed`, `unchanged`, `moved`) and `removed`. |
| formats | Yes | Data sets and bytes per format id. |
| complete | Yes | True when the crawl walked every root to the end. False after a cap (`--max-files`, `--max-seconds`) or an interruption: the tables then hold what was read so far plus the previous run's records for the rest, and rerunning the same command continues. |
| datasets | Yes | Data sets (rows of `experiments.parquet`) after multi-file grouping. |
| families | Yes | Data sets and bytes per family. |
| problems | Yes | Problems per category (`integrity`, `readability`, `walk`, `pii`). |
| settings | Yes | Options of the crawl. |
| index_dir | Yes | Absolute path of the index directory. |
| started_at | Yes | When this run started (ISO-8601 UTC). |
| updated_at | Yes | When the tables were written. |
| files_per_s | Yes | Items per second over the crawl's wall time. |
| check_status | Yes | Data sets per check status. |
| schema_version | Yes | [`INDEX_SCHEMA_VERSION`]. |
| unknown_extensions | Yes | Files no reader recognises, per lower-case extension (`(none)` for no extension). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations it discloses the substantive behavioral traits: headers-only scanning, resumability via max_files/max_seconds with complete=false, and the same call resuming an interrupted crawl. This resumption contract is not derivable from the annotations or schema and is exactly what the agent needs. It is consistent with idempotentHint=true and readOnlyHint=false (it writes an index).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then mechanics, then sibling routing; every sentence carries weight. The parenthetical column list is dense but informative. Slightly long, but no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, yet the description still outlines the index contents. Combined with annotations covering safety and idempotency, an agent has everything needed to invoke this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning: it enumerates the per-row fields produced and clarifies the stop-and-continue semantics of max_files/max_seconds. It also implies the roots/index_dir distinction ('never inside a root' contrast). Modest extra value over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Catalog every data set under roots into index_dir') and details the output shape (Parquet, one row per data set). It distinguishes itself from siblings by naming openreadout_search as the query path and openreadout_batch as the alternative for single folders.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It routes the agent explicitly: openreadout_search queries the index, and openreadout_batch should be used for one folder of files instead. It does not state when *not* to index or prerequisites (e.g. permission to write index_dir), but the alternative-tool guidance is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_infoARead-onlyIdempotent
What an instrument file or data-set directory holds, from its headers (fast on huge files): format, images[] (sizes, pixel type, µm/px, channels and dyes, objective), tables[], traces[], spectra[] (MS runs), plate, experiment (sample, instrument, method, operator, start) and assurance. view=summary attaches a ~384 px thumbnail of image 0 with full-resolution pixel rulers. ask answers a question in words, naming the fields it used.
| Name | Required | Description | Default |
|---|---|---|---|
| ask | No | A question in plain words ("what was the gradient?", "which channel is DAPI?", "how many MS/MS scans?"): answered under answers[] with the fields each came from. Implies view=explain. | |
| file | Yes | Path to the file or data-set directory. | |
| kind | No | view=structure: list only elements of this kind (as entries_total names them), e.g. "attachment" or "subblock". | |
| view | No | What to return. `summary` = the header summary (default); `full` = the summary with per-frame records (time stamps, stage positions, exposure) and per-field provenance; vendor=true adds the vendor's raw metadata tree; `structure` = the container: images, blocks/segments/chunks, attachments (label, thumbnail, previews), pyramid levels, with offsets and sizes; `explain` = a plain-English account with caveats and suggested next steps (ask answers questions); `format` = the format only, from the file's signature (cheapest; works on damaged files). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| vendor | No | view=full: include the vendor's raw metadata tree (can be megabytes). Default false. | |
| thumbnail | No | view=summary: attach a small picture of image 0 (~384 px, with full-resolution pixel rulers) as image content. Default true; skipped (with a note) when it would decode too much. | |
| max_frames | No | view=full: per-frame records per image under images[].extra.frames. Default 100; 0 omits them; -1 embeds all. | |
| max_images | No | List at most this many images (0 = all). Default: all, except screening plates (16; their field images are all alike and plate.wells[].images indexes every field). | |
| first_entry | No | view=structure with kind: skip this many elements of that kind first (paging). | |
| max_entries | No | view=structure: list at most this many elements of each kind (0 = all). Default 50. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, idempotentHint, non-destructive), so the bar is lower, and the description still adds real behavior: header-only reads are fast on huge files, view=summary attaches a ~384 px thumbnail with pixel rulers, and it reports the 'assurance' field. It could go further on rate limits or how the server behaves on unsupported formats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first clause, but the rest is a dense, parenthetical run-on enumerating return fields (images[], tables[], traces[], spectra[], plate, experiment) that partly duplicates the output schema. Given 11 parameters and 5 view modes, some length is justified, but it is not tightly structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, multi-view inspection tool with full schema coverage, annotations, and an output schema, the description supplies the core mental model: header-derived content, view modes, thumbnail behavior, and cheap format detection. Nothing essential for calling it correctly is missing, though the relationship to sibling inspection tools is unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and an output schema exists, so the schema carries the parameter burden and 3 is the baseline. The description only lightly adds meaning — roughly that view=summary governs the thumbnail and that ask returns answers with the fields used — while most of the parameter detail lives in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause names a specific resource and action: reading what an instrument file or data-set directory holds from its headers. It conveys the 'inspect metadata' role clearly, but it never distinguishes itself from close siblings such as openreadout_check, openreadout_summarize, or openreadout_preview, which an agent must route between.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied rather than stated: 'fast on huge files' and 'works on damaged files' hint at when this tool is the right choice, and the view list implies mode selection. However, there is no explicit when-to-use vs when-not, and no routing to any of the many sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_linkBRead-onlyIdempotent
Groups files that measured the same sample across instruments and formats (sample id, barcode, plate well + plate, a conversion naming its source, the same acquisition or the same spectra), from headers; every link has its evidence and a confidence (high/medium/low; links below min_confidence are listed in weak_links).
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Directories (walked recursively), files or glob patterns. | |
| query | No | … and the query. | |
| formats | No | Only these format ids. | |
| from_index | No | Also take the data sets an index query selects: the index directory … | |
| no_recursive | No | Only the top level of directories. | |
| min_confidence | No | `low`, `medium` (default) or `high`: weaker links are listed in weak_links, not grouped. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | No | Things to know. |
| groups | Yes | Groups of two or more data sets. |
| inputs | Yes | How the inputs became data sets. |
| unlinked | Yes | Data sets in no group. |
| weak_links | No | Links below `min_confidence` (not grouped), strongest first (first 50). |
| min_confidence | Yes | Minimum confidence of links that form groups. |
| unlinked_examples | No | Some of them. |
| shared_identifiers | No | Identifiers treated as weak evidence. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish the safe-read profile (readOnlyHint, idempotentHint, non-destructive), so the bar is lower, and the description still adds real behavior: each link carries evidence and a confidence rating, and below-threshold links are diverted into a weak_links list rather than grouped. That threshold-diversion behavior is not derivable from the annotations and is exactly the kind of operational detail an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded, but the whole definition is a single semicolon-joined run-on sentence with a long parenthetical of matching criteria, which is dense and slows parsing. Every clause is substantive, so nothing is padding, but the structure could be cleaner and shorter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the description does cover the grouping logic and confidence handling adequately. However, for a six-parameter cross-file correlation tool with no required parameters and no stated usage context, the absence of any when-to-use or scoping guidance leaves a real gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all six parameters are already documented in the schema, and several of those descriptions are themselves truncated ('… and the query', 'the index directory …'). The description only reinforces min_confidence's weak_links consequence, which the schema already states, so it adds little beyond the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb ('groups') and resource ('files that measured the same sample'), then enumerates the actual matching heuristics (sample id, barcode, plate well + plate, conversion source, shared acquisition/spectra). This makes the tool's function unmistakable and hard to confuse with the many read/plot/query siblings, though no sibling is named explicitly for contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to choose this tool over alternatives such as openreadout_search, openreadout_index, or openreadout_compare, despite a crowded sibling set. The description explains what the tool computes but never states the scenario that should trigger it or any exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_nmr_peaksARead-onlyIdempotent
NMR peak list (ppm, height, width, S/N) and integrals of given regions or of every multiplet (auto_integrate), from the vendor's processed spectrum or a spectrum processed from the FID (from=fid: group delay, apodization, zero filling, FT, phase, baseline).
| Name | Required | Description | Default |
|---|---|---|---|
| lb | No | Exponential line broadening in Hz (0 = none; default stored, else 0.3 Hz 1H / 1 Hz other). | |
| file | Yes | Path to the file or data-set directory. | |
| from | No | `auto` (default: the vendor's processed spectrum if present, else process the FID), `fid` (always process the FID), `processed` (stored spectrum only). | |
| size | No | Transform size in complex points (power of two). | |
| phase | No | `default` (stored phases, else automatic), `stored`, `auto`, `magnitude`, `none`, or `"P0,P1"` in degrees. | |
| sweep | No | Row of a ser/arrayed FID (default 0). | |
| trace | No | Trace index (default: chosen by `from`). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| min_snr | No | Minimum peak height in noise SDs (default 10). | |
| baseline | No | Baseline: `default` (order-1 polynomial), `none`, `poly:N`. Stored spectra are used as stored unless this is given. | |
| negative | No | Also report negative peaks (DEPT/APT). | |
| integrate | No | Regions to integrate, `[[a, b], …]` in ppm. | |
| max_peaks | No | Keep at most this many peaks (tallest; default 200). | |
| range_ppm | No | Only pick between two shifts, `[a, b]` ppm. | |
| auto_integrate | No | Without integrate: integrate every multiplet (peaks closer than 15 Hz, ±10 Hz). | |
| min_prominence | No | Minimum prominence in noise SDs (default 5). | |
| integral_reference | No | Normalise integrals so region `[index, value]` has that value (default `[0, 1]`). | |
| min_height_fraction | No | Minimum height as a fraction of the tallest point (default 0; e.g. 0.01). |
Output Schema
| Name | Required | Description |
|---|---|---|
| axis | Yes | The chemical-shift axis of the spectrum. |
| path | Yes | The input path. |
| notes | No | Remarks. |
| peaks | Yes | Peaks, high shift first. |
| sweep | Yes | Sweep (row) used. |
| trace | Yes | Trace used (see `info` → `traces[]`). |
| format | Yes | Format id. |
| source | Yes | `processed` (a spectrum the vendor software stored) or `fid` (processed here). |
| nucleus | No | Observed nucleus, when known. |
| noise_sd | Yes | Robust noise standard deviation (same units as `height`). |
| integrals | No | Integrals of the requested regions. |
| main_peak | No | The tallest positive peak (named like `analyze peaks` → `main_peak` for chromatograms). |
| peak_count | Yes | Number of peaks found. |
| processing | No | How the FID was processed (`source` = `fid` only). |
| trace_name | No | Its name. |
| peak_options | Yes | Thresholds used. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: the FID processing chain it will apply (group delay, apodization, zero filling, FT, phase, baseline) and the fact that a stored spectrum is used as-is unless processing is requested. It stops short of stating permissions or failure behavior, but this is solid added context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence with the primary output (peak list) front-loaded and the processing options parenthesized after. No wasted words, though the nested parentheses make it harder to parse at a glance than a two-sentence split would.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and 100% schema coverage, the description need not explain return values or parameter details; it correctly focuses on scope and the processing modes. The one gap is the absence of any differentiation from the sibling openreadout_peaks, which an agent needs for correct tool selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 18 parameters, including defaults and enumerated string values. The description echoes only two of them (from=fid, auto_integrate) without adding syntax or constraints beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (NMR peak list plus integrals) and enumerates the returned quantities (ppm, height, width, S/N), so an agent knows exactly what it gets. However, it never distinguishes itself from the closely named sibling openreadout_peaks (or openreadout_spectrum), leaving ambiguity about which tool to pick for generic vs NMR-specific peak extraction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage contexts via 'from the vendor's processed spectrum or a spectrum processed from the FID (from=fid ...)' and 'integrals of given regions or of every multiplet (auto_integrate)', which hints at the two operating modes. But it gives no explicit when-to-use/when-not guidance and never names an alternative tool, so the agent must infer the routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_peaksBRead-onlyIdempotent
Detect and integrate peaks: chromatograms (detector traces, TIC, XIC, SRM) with retention time, area, height, widths, tailing, plates, resolution, S/N and area % (purity); one peak near rt; a compound list; bands and regions of IR, Raman, UV-Vis and NMR spectra and peaks of sized electropherograms in bp (x_range, integrate). Takes the openreadout_chromatogram arguments to choose the signal.
| Name | Required | Description | Default |
|---|---|---|---|
| da | No | XIC tolerance in m/z units instead of ppm. | |
| mz | No | Extracted-ion chromatograms at these m/z values (one streaming pass for all). | |
| rt | No | Expected retention time (minutes): also report the peak there as `picked`. | |
| bpc | No | Base-peak chromatogram. | |
| ppm | No | XIC tolerance (half-width) in ppm. Default 10. | |
| run | No | Spectra run. Default 0. | |
| tic | No | Total-ion chromatogram (the default for mass-spectrometry files when nothing else is chosen). | |
| file | Yes | Path to the file or data-set directory. | |
| pick | No | `largest` (default) or `nearest` peak in the window. | |
| sweep | No | Sweep of the traces (one spectrum of a map or series, one injection). Default 0. | |
| smooth | No | Savitzky–Golay window in points (below 5: none). Default automatic. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| traces | No | Stored chromatograms or detector signals (UV/DAD, FID, TCD, stored TIC/SRM): trace indices from openreadout_info → traces[]. | |
| window | No | Half-width of the `rt` window (and of compounds without one), minutes. Default 0.5. | |
| channel | No | Channel of the traces (e.g. one DAD wavelength). Default: the first signal channel. | |
| min_snr | No | Detection threshold, height / noise σ. Default 3. | |
| profile | No | Use profile data where scans store both profile and centroids. Default false (the instrument's centroids). | |
| x_range | No | Axis windows `[[a, b], ...]` to integrate, in the axis's own units (either order): on a spectrum (IR/Raman cm⁻¹, UV nm, NMR ppm) each is a region under `spectra[].regions` (area with the `baseline`, area without it, maximum, centroid, the bands inside); on a chromatogram a manual integration in minutes. | |
| baseline | No | Baseline under detected peaks: `auto` (default), `drop`, `valley` or `tangent`; or the baseline under `x_range` windows and manual integrations: `linear` (default: a straight line between the window's ends) or `none` (area of the signal itself). | |
| ms_level | No | MS level of the scans. Default 1 (2 with `precursor`). | |
| mz_range | No | TIC/BPC over this m/z range only, `[low, high]`. | |
| polarity | No | `positive` or `negative`: only scans of this polarity. | |
| rt_range | No | Retention-time range `[start, end]`, minutes. | |
| aggregate | No | `sum` (default) or `max` of the points inside an XIC window. | |
| compounds | No | Targeted compounds: `[{name, mz? | q1+q3? | trace?, rt?, window?, ppm?, polarity?, ms_level?, precursor?}]`; one result row each under `compounds`. | |
| integrate | No | Manual integrations `[[start, end], ...]` in minutes. | |
| min_width | No | Smallest width at half height, minutes. | |
| precursor | No | Only MS/MS scans of this precursor m/z (product-ion XIC). | |
| min_height | No | Detection threshold in signal units. | |
| scan_filter | No | Only scans whose scan filter/description contains this text (case-insensitive). | |
| transitions | No | SRM/MRM transitions as `"Q1>Q3"` strings, e.g. `"279.2>179.2"`. | |
| area_seconds | No | Areas in signal × seconds instead of signal × minutes. Default false. | |
| summary_only | No | Leave out the full peak tables (keep compounds, picked and manual results). Default false. | |
| precursor_tol | No | Precursor tolerance, m/z units. Default 0.5. | |
| transition_tol | No | Q1/Q3 tolerance of transitions, m/z units. Default 0.5. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | The input file. |
| notes | No | Anything the caller should know. |
| format | Yes | Format id of the input file. |
| outputs | No | Files written (`-o`, `--plot`). |
| spectra | No | Spectra (traces whose axis is not time: wavenumber, wavelength, ppm, …): bands and integrated regions, one entry per analysed spectrum. |
| compounds | No | One row per compound of the compound list. |
| chromatograms | Yes | One entry per analysed chromatogram. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description adds genuine scope context (which instruments/domains it applies to and that signal selection mirrors openreadout_chromatogram), but much of the rest is a recitation of returned quantities that the output schema already carries, and it says nothing about errors, caveats, or cost for a 35-parameter call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Appropriately sized for a 35-parameter tool and front-loaded with the core verb phrase, but it is a single run-on sentence stitched together with semicolons and nested parentheses, which makes the modality-by-modality enumeration hard to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema documenting returns, 100% schema coverage, and annotations carrying the safety profile, the description is nearly sufficient: it establishes scope across chromatography, spectroscopy and electrophoresis. The main remaining gap is sibling disambiguation (openreadout_nmr_peaks, openreadout_chromatogram) that an agent needs in order to pick the right tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% across 35 parameters, so the baseline is 3 and the schema does the heavy lifting. The description only names a handful of parameters (x_range, integrate, rt) and cross-references openreadout_chromatogram for signal selection; it adds no tolerance, unit, or default semantics beyond what is already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Detect and integrate peaks') and then enumerates the exact data types handled (detector traces, TIC, XIC, SRM, IR/Raman/UV-Vis/NMR bands, electropherogram peaks in bp) plus the reported quantities. This is well beyond a tautology. It does not, however, differentiate itself from the close sibling openreadout_nmr_peaks, which plausibly overlaps the NMR/spectral case.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the enumeration of applicable modalities tells the agent what kinds of inputs qualify, and 'Takes the openreadout_chromatogram arguments to choose the signal' links it to a sibling for signal selection. There is no explicit when-to-use / when-not-to-use statement and no routing away from openreadout_nmr_peaks or openreadout_chromatogram.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_plotARead-onlyIdempotent
A finished figure from lab files in one call, as image content plus what was drawn (series, data read, ranges, units, marked peaks). Name data by file and selector, never by pasting numbers: traces and sweeps, chromatograms (TIC, XIC) and the spectrum at an rt or the TIC apex, plate wells by range or layout group (curves per well, or mean ± spread per group), FCS dot plots coloured by gate population and histograms, f–I curves, dose-response and standard-curve fits, a table file's columns (openreadout_batch output); small inline values are allowed. Several files overlay; facet=series gives small multiples, facet=plate plate positions; panels side by side; annotate with bands, lines, labelled points, arrows. Draws only; openreadout_export saves the figure.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | The x axis. | |
| y | No | The y axis. | |
| data | No | What to draw: one series spec or a list of them, drawn in order (first at the back). | |
| file | No | The file of every series here that names no file, table or values. Alone, without `data`, it draws the file's default view. | |
| facet | No | Small multiples: `series` = one small plot per series (sweeps, files, groups, wells); `plate` = plate wells in their plate positions. | |
| share | No | Panels that share an axis range. Default none. | |
| stack | No | Offset each series upward by this fraction of the tallest one (stacked spectra). | |
| theme | No | Colour scheme. Default light. | |
| title | No | Title over the figure. | |
| width | No | Width in px (default 1200, at most 3000). | |
| height | No | Height in px (default from the content, at most 3000). | |
| legend | No | How series are named: `direct` labels at the line ends, a `key` row, or `none`. Default direct when it fits, else key. | |
| panels | No | Several panels, side by side (see columns); instead of a top-level `data`. | |
| strict | No | true: refuse values this file's assurance does not validate (exit_code 6, with a hint). | |
| caption | No | Small print under the figure (a source credit, a method note). | |
| columns | No | Panels (or facets of a single panel) per row. Default: all panels in one row; facets in a near-square grid. | |
| annotate | No | Bands, lines, labelled points, arrows, boxes and notes, in the units the axes show: the same annotations as openreadout_preview (`facet` picks one small plot). | |
| row_labels | No | Row headings of a plate facet, top to bottom. Default: the layout group of each block of rows, else the row letters. | |
| column_labels | No | Column headings of a plate facet (e.g. doses), left to right. |
Output Schema
| Name | Required | Description |
|---|---|---|
| save | No | How to save this figure to a file (MCP: the openreadout_export call). |
| files | Yes | Files the data came from. |
| notes | No | What was done to the data (subtractions, fits, transforms). |
| theme | Yes | `light` or `dark`. |
| title | No | Figure title. |
| width | Yes | Picture size in px. |
| height | Yes | Picture size in px. |
| panels | Yes | One entry per panel. |
| warnings | No | Data that could not be drawn as asked, or values to double-check. |
| inline_series | Yes | Series drawn from inline values (numbers the caller supplied, not read from a file). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered; the description adds real workflow context: the tool returns image content plus a record of what was drawn, and it will not persist anything (export is needed to save). The 'never paste numbers' rule is extra behavioral guidance beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is well front-loaded, but the middle is one very long run-on sentence listing every drawable data type with semicolons, which is hard to scan. Each clause carries information, yet the structure could be split or bulletted for the same content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 19-parameter tool with full schema coverage, annotations, and an output schema, the description covers the capability envelope, the draw-vs-save boundary, faceting/panels, and annotation support. Minor schema-level details (size caps, strict mode) are left entirely to the schema, which is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds a conceptual map of the selector space (file+selector by data family) and the important rule that values must be referenced by file/selector rather than pasted, which is semantic guidance the schema does not state outright.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('a finished figure from lab files in one call') and enumerates exactly the data families it can draw (traces, chromatograms, plates, FCS, dose-response, tables). It explicitly routes the agent apart from siblings by naming what it does not do ('Draws only; openreadout_export saves the figure') and by relating itself to openreadout_preview.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete selection rule ('Name data by file and selector, never by pasting numbers' with inline values as the exception) and names the alternative tool for a related task (openreadout_export for saving). It does not, however, explicitly state when to choose this over openreadout_preview, which also draws.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_previewARead-onlyIdempotent
A picture of the data as image content plus what was drawn: an image plane (default channel 0, middle z), a composite, a max projection (mip=z), a region (only the tiles needed are read), a trace or spectrum plot (largest peaks labelled; marks=spikes marks action potentials; x_range zooms), a Sanger chromatogram with base calls and quality or a sized electropherogram with the ladder, a plate heat map or, for kinetic reads, per-well growth curves coloured by layout group, or a flow-cytometry density plot. Image pictures carry rulers in full-resolution pixels and a µm scale bar, so a region read off the rulers zooms in. annotations draw your own labelled points, boxes, outlines, arrows, lines and bands in the picture's coordinates, to show the user what you found. Draws only; openreadout_export saves the picture.
| Name | Required | Description | Default |
|---|---|---|---|
| fft | No | Images: a power-spectrum (FFT) inset in the top-right corner: Thon rings of a cryo-EM micrograph, the spots of a lattice. | |
| lut | No | Colour lookup. Default: gray for one channel (inverted on diffraction images), channel colours for composites. `gray` = black to white; `channel-color` = black to the channel's colour; `inverted` = white to black: dark marks on a light ground (diffraction images). | |
| mip | No | Maximum-intensity projection, over the selected range if any. `z` = along z (focal planes); `t` = along t (time points). | |
| run | No | Spectrum preview: run index. | |
| sum | No | Sum projection, over the selected range if any: a movie's frames added up (e.g. sum t, select t=0-39). `z` = along z (focal planes); `t` = along t (time points). | |
| axes | No | Image previews: what frames the picture. `rulers` = coordinate rulers in full-resolution pixels and a scale bar around the picture (default); `grid` = rulers, plus faint grid lines over the data at the ruler ticks; `scale-bar` = a figure for people: the picture with a scale bar, the title and the caption; no rulers; `none` = the bare downsampled plane. | |
| dark | No | Draw in the dark theme. | |
| file | Yes | Path to the file. | |
| scan | No | Spectrum preview: instrument scan number instead of an index. | |
| view | No | Volumes: the plane to show. `axial`, `coronal`, `sagittal` (radiological orientation), `orthogonal` (all three, crossing at the middle or the selected z), `xz`, `yz`, or `native` (as stored). Default: medical images in their acquisition plane, others native. With a view, `z` and `mip: z` count slices of that view. `native` = the planes as stored; `axial` = head-foot slices, patient's left on the right, anterior up; `coronal` = front-back slices, patient's left on the right, head up; `sagittal` = left-right slices, anterior on the left, head up; `orthogonal` = axial, coronal and sagittal planes through the volume's centre (or the selected z); `xz` = columns against z: a cut along the stack; `yz` = rows against z: a cut along the stack. | |
| image | No | Image index (default 0). | |
| lanes | No | Gels and blots: how lanes are found for `marks: lanes` (as `openreadout_stats` lanes). | |
| level | No | Pyramid level to read (default: the level nearest max_size, or the level at which `region` renders at about max_size). | |
| marks | No | Marks from the data. Default auto: the prominent peaks of spectra and chromatograms are labelled; diffraction images get resolution rings. `auto` = label the largest peaks of spectra and chromatograms (default); `peaks` = label the largest peaks of any trace; `spikes` = mark the action potentials of current-clamp sweeps; `objects` = images: outline and number the nuclei, cells or spots found (`stats` objects); `lanes` = gels and blots: box and number the lanes, draw their profiles and bands (`stats` lanes); `rings` = diffraction images: resolution rings and the beam centre (auto draws them when the geometry is known); `none` = no marks. | |
| sweep | No | Trace preview: sweep index. | |
| table | No | Plate or flow-cytometry preview: table index. | |
| title | No | Image previews with axes scale-bar: a title above the picture. | |
| trace | No | Trace preview: trace index (see openreadout_info traces[]). | |
| format | No | Encoding. Default png (sent as JPEG when a PNG would be too large); svg also returns the vector drawing as text. `png` = lossless (default); `jpeg` = lossy and smaller; `svg` = vector: text stays text, image data is embedded as PNG. | |
| region | No | Zoom: only this rectangle, `{x, y, width, height}` in full-resolution pixels (or in the pixels of `level` when a level is given). Whole-slide images: look at the overview first, then at regions of it. | |
| select | No | Plane selection such as `c=1`, `z=4`, `t=0` or combined `c=0,1,z=2`. Default: c=0, the middle z, t=0. Several channels imply a composite. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| caption | No | Image previews with axes scale-bar: a caption under the picture (what it shows, the stain, the sample). | |
| columns | No | Table columns: a plate's value column, or the x and y parameters of a flow-cytometry density plot (one gives a histogram; default FSC-A, SSC-A). | |
| objects | No | Images: how objects are found for `marks: objects` (as `openreadout_stats` objects). | |
| x_range | No | Trace preview: only this window of the x axis, `[a, b]` in its units (bp of a sized electropherogram, base positions of a Sanger read, minutes, ppm, …). | |
| centroid | No | Spectrum preview: the instrument's centroid list instead of the profile. | |
| channels | No | Trace preview: channel indices (default: the first 8). | |
| contrast | No | `auto` (default; the file's display window when it has one, `log:90,99.95` on diffraction images), `min-max`, `percentile:LO,HI` (e.g. `percentile:1,99`), `log` (`log:50,99.9`) or `log:LO,HI`, `raw`, or a display window `window:CENTER,WIDTH` (`window:40,400`), `window:file`, or a CT preset `window:soft-tissue`, `brain`, `subdural`, `stroke`, `bone`, `lung`, `mediastinum`, `liver`. | |
| max_size | No | Longest side in pixels, rulers included (MCP: default 768, at most 2048). | |
| spectrum | No | Spectrum preview: zero-based spectrum index. | |
| composite | No | Blend all (or the selected) channels additively in their colours. | |
| annotations | No | Your own marks, drawn on top and reported back with their pixel positions. Coordinates as the picture shows them: full-resolution pixels on images (the ruler numbers), axis units on plots, wells on plates. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | What to do next with the picture (look at it; zoom with a region read off the rulers). |
| kind | Yes | `image`, `trace`, `chromatogram`, `spectrum`, `plate` or `events`. |
| path | Yes | The input file. |
| save | No | How to save this picture to a file (MCP: the openreadout_export call). |
| xxh3 | Yes | xxh3-128 of the encoded bytes, 32 hex chars (identical across runs for the same request). |
| bytes | Yes | Size of the encoded image. |
| image | No | Present for image previews. |
| lanes | No | `marks: lanes`: the lanes and bands found in the area shown, as `stats` lanes. |
| marks | No | Marks drawn from the data (labelled peaks, action potentials). |
| notes | No | Anything the caller should know (fallbacks, caps, implied options). |
| plate | No | Present for plate previews. |
| trace | No | Present for trace previews. |
| width | Yes | Image width in pixels. |
| events | No | Present for event previews. |
| format | Yes | Format id of the input file. |
| height | Yes | Image height in pixels. |
| output | No | The written file (CLI); absent when the preview is returned inline (MCP image content). |
| panels | No | Plot panels (traces, spectra, plate curves, events): where each sits in the picture and the data range it shows. |
| objects | No | `marks: objects`: the objects counted in the area shown, as `stats` objects (the first 20 listed). |
| encoding | Yes | `png`, `jpeg` or `svg`. |
| spectrum | No | Present for spectrum previews. |
| verified | Yes | True once a written file was read back and matched. |
| annotations | No | The caller's annotations as drawn: each as given, plus where it landed in PNG pixels. |
| chromatogram | No | Present for chromatogram previews (a mass-spectrometry run's total-ion chromatogram). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/destructive=false, so the safety profile is covered. The description adds real behavioral context beyond that: images carry rulers in full-resolution pixels plus a µm scale bar, a region read off the rulers zooms in, and annotations are 'drawn on top and reported back with their pixel positions.' That the tool only draws (never writes files) is also usefully disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is buried in a single enormous run-on sentence that enumerates every picture modality; nothing is front-loaded, and several clauses ('region ... only the tiles needed are read', 'x_range zooms') simply repeat structured schema content. It is information-dense but structurally weak, so it is neither wasteful enough for a 2 nor clean enough for a 4.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 33-parameter, multi-modal tool with an output schema and annotations already present, the description covers the modality space, the drawing-only scope, and coordinate conventions well. Return-value detail is rightly left to the output schema, so the remaining gap is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description still adds cross-parameter meaning beyond the schema — the default plane ('channel 0, middle z'), that mip=z is a max projection, that marks=spikes marks action potentials, that x_range zooms the axis, and that a region taken from the rulers zooms in. Much of this is restated from the schema, keeping it out of the top band.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource (draws a picture of the data as image content) and enumerates the exact picture types it produces across modalities. It also explicitly distinguishes itself from a sibling: 'Draws only; openreadout_export saves the picture,' so an agent can tell preview from export without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the alternative that matters most (openreadout_export for saving) and gives the selecting condition ('Draws only'). It also frames the use case ('annotations ... to show the user what you found'), but never differentiates itself from other rendering-adjacent siblings such as openreadout_plot or openreadout_chromatogram, so guidance is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_qpcrARead-onlyIdempotent
Real-time PCR (RDML, .eds, .rex, ...): one record per well and target with sample, task, Cq and Tm; compute_cq recomputes Cq, ddcq gives 2^-ΔΔCq fold changes, standard_curve fits efficiency per target.
| Name | Required | Description | Default |
|---|---|---|---|
| run | No | Only this run. | |
| ddcq | No | ΔΔCq relative quantification (rows: one per sample × target). | |
| file | Yes | Path to the file or data-set directory. | |
| well | No | Only this well (`A1`). | |
| fields | No | Rows show their main fields to 4 significant digits (records: well, sample, target, cq, tm; relative_quantities: cq means, delta_cq, delta_delta_cq, rq with rq_min and rq_max). fields adds others, e.g. `["threshold"]`; `["all"]`: every field, full precision. | |
| sample | No | Only this sample, case-insensitive. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| target | No | Only this target, case-insensitive. | |
| cq_method | No | How `compute_cq` computes Cq; default: `second-derivative` for LightCycler 480 `.ixo` files without a threshold or baseline window, else `threshold`. `threshold` = Where the baseline-corrected curve crosses a threshold; `stored-threshold` = A threshold crossing with only the threshold and baseline the file stores; `second-derivative` = The maximum of the second derivative, as the LightCycler 480 places its Cp. | |
| threshold | No | Threshold for `compute_cq`. | |
| compute_cq | No | Also compute our own Cq. | |
| max_records | No | At most this many records (default 500). | |
| baseline_end | No | Baseline window for `compute_cq`, last cycle. | |
| baseline_start | No | Baseline window for `compute_cq`, first cycle. | |
| control_sample | No | ΔΔCq control (calibrator) sample; default: the file's. | |
| standard_curve | No | Standard curve per target (rows: one per target). | |
| undetermined_cq | No | Cq for undetermined results in means and ΔΔCq; default: left out and counted. | |
| reference_targets | No | ΔΔCq reference targets; default: the file's. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | The input file. |
| notes | Yes | What to keep in mind. |
| cycles | No | Number of PCR cycles in the program. |
| format | Yes | Format id. |
| dialect | Yes | Dialect (`rdml`, `eds-sds`, `eds-7500`, `eds-json`, `rex`). |
| records | Yes | The records. |
| targets | Yes | Per target: counts by Cq status and the mean Cq without the undetermined results. |
| cq_counts | Yes | Cq statuses over every record that matches the filters (not cut by `max_records`). |
| truncated | Yes | True when `max_records` cut the list. |
| experiment | No | Experiment or run name. |
| instrument | No | Instrument model. |
| record_count | Yes | Records matching the filters. |
| cq_comparison | No | Our Cq against the vendor's (with `compute_cq`). |
| control_sample | No | Control (calibrator) sample used or recorded. |
| standard_curves | No | Standard curves (with `standard_curve`). |
| undetermined_cq | No | Cq used for undetermined results in the aggregates, when the request gave one. |
| reference_targets | Yes | Reference targets used or recorded (endogenous controls). |
| relative_quantities | No | ΔΔCq results (with `relative`). |
| acquisition_temperature_c | No | Temperature of the step that reads fluorescence during cycling (the annealing / extension temperature of a two-step PCR), °C. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and a closed world, so the safety profile is fully covered without the description. The description adds output-format context (one record per well and target; 2^-ΔΔCq; per-target efficiency) but says nothing about permissions, rate limits, or failure behavior beyond what annotations give.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence, front-loaded with the assay type and file formats, then the record structure and the three mode flags. Nothing is wasted, though the mode list is crammed into one clause that would read better as a short enumeration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and annotations carry the safety profile. For an 18-parameter tool the description still conveys the core analysis modes and record shape; the only real gap is that it does not say when to prefer ddcq versus standard_curve or when compute_cq should be enabled.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 18 parameters (including the cq_method enum values and every analysis flag). The description restates compute_cq, ddcq and standard_curve at a high level but adds no syntax or semantics beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific domain (real-time PCR), the supported file formats (RDML, .eds, .rex), and the output granularity (one record per well and target with sample, task, Cq and Tm). That is clear enough to distinguish it from the other domain-specific siblings, but it never explicitly names an alternative or positions itself relative to them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the three analysis modes do (compute_cq recomputes Cq, ddcq gives 2^-ΔΔCq fold changes, standard_curve fits efficiency), which implicitly tells the agent when each flag is relevant. However it gives no explicit when-to-use guidance, no prerequisites, and no routing away from sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_reportBIdempotent
A privacy-reviewed diagnostic bundle for a file that is refused, fails or is not validated, for a new-variant issue: no data values, free text only with include_text, and the issue_url to file it at. Nothing is sent; the user files it.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | The file (or data-set directory) that is refused, fails or is not validated. | |
| output | No | Also write the bundle to this new local file. Default: only return it. | |
| include_text | No | Keep free text from the file (sample, image and channel names, comments); the path and personal data are still replaced. Default false: only with the user's consent. |
Output Schema
| Name | Required | Description |
|---|---|---|
| bytes | No | Size of the written bundle. |
| output | No | Where the bundle was written; `None` with `--dry-run` (or from MCP without `output`). |
| report | Yes | The bundle, exactly as written. |
| issue_url | Yes | Where to file it (never contacted by the program). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, openWorldHint=false, idempotentHint=true, destructiveHint=false), the description discloses meaningful behavior: 'Nothing is sent; the user files it' confirms no network transmission, 'privacy-reviewed' signals a sanitization step, 'no data values' states the data-minimization posture, and the include_text mention ties free-text retention to consent. These add real context an agent would not infer from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single compact sentence, which is good, but the structure is a run-on with multiple colons and an ambiguous clause ('for a new-variant issue: no data values, free text only with include_text') that forces re-reading. Front-loading the bundle concept is fine; the rest is dense rather than efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and the description covers the operative context for this tool: the trigger condition, the privacy/consent behavior, and the fact that nothing is transmitted. An agent could call it correctly; only the missing verb and confusing 'new-variant issue' phrasing leave minor ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents file, output and include_text with descriptions, making the baseline 3. The description only restates the include_text consent rule and references 'the issue_url to file it at' (an output field, not a parameter), adding no parameter syntax or format detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the deliverable (a 'privacy-reviewed diagnostic bundle') and its trigger ('a file that is refused, fails or is not validated'), so the resource is identifiable, but it never states a verb like 'produce' or 'write' and the colon-laden phrasing ('for a new-variant issue: no data values, free text only...') muddies what the tool actually does. No sibling is named or differentiated, though the purpose is distinctive enough to stand apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a usable trigger condition — use it when a file is refused, fails validation, or is a 'new-variant issue' — which is better than nothing. However, it names no alternative sibling (e.g. openreadout_check or openreadout_info) and gives no when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_scansARead-onlyIdempotent
The scans of a mass-spectrometry run, without decoding peaks: scan number, MS level, retention time, polarity, precursor m/z and charge, isolation window, activation, collision energy, filter, stored TIC; filtered and paged, and every match counted (matched, ms_level_counts). IR, Raman, UV-Vis and NMR spectra are traces: openreadout_trace.
| Name | Required | Description | Default |
|---|---|---|---|
| run | No | Run index for files with several runs (Sciex samples; default 0). | |
| file | Yes | Path to the mass-spectrometry file. | |
| count | No | Only count the matching scans (matched, ms_level_counts); list none. | |
| limit | No | List at most this many matching scans (default 100, at most 5000); all are counted. | |
| charge | No | Only precursors of this charge state. | |
| offset | No | Skip this many matching scans (paging; default 0). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| ms_level | No | Only scans of this MS level (1 = full scans, 2 = MS/MS). | |
| polarity | No | Only `positive` or `negative` scans. | |
| rt_range | No | Retention-time window `[start, end]` in minutes. | |
| precursor | No | Only MS/MS scans whose precursor m/z is within the tolerance of this. | |
| activation | No | Only this activation: HCD, CID, ETD, ... (case-insensitive). | |
| scan_filter | No | Only scans whose filter string contains this text (case-insensitive). | |
| precursor_ppm | No | Precursor tolerance in ppm instead. | |
| precursor_tol | No | Precursor tolerance in m/z units (default 0.01). |
Output Schema
| Name | Required | Description |
|---|---|---|
| run | Yes | Run index. |
| path | Yes | The input file. |
| scans | Yes | The listed scans, in spectrum-index order. |
| filter | No | The conditions applied (omitted when every scan is listed). |
| format | Yes | Format id of the input file. |
| offset | Yes | Position of the first listed scan among the matching ones (0-based; `--offset`). |
| source | Yes | `headers` when the reader listed scan headers without decoding peaks, `spectra` when every spectrum had to be decoded to list it. |
| matched | Yes | Scans matching the conditions (all of them are counted, not only the page listed). |
| returned | Yes | Number of scans listed. |
| truncated | Yes | True when more matching scans follow the page (`offset + returned < matched`). |
| rt_range_s | No | Retention-time range of the matching scans in seconds. |
| scan_count | Yes | Spectra in the run. |
| ms_level_counts | Yes | Counts of the matching scans per MS level (`"1"`, `"2"`, ...). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds useful behavior beyond that: it lists the exact fields returned, notes that results are filtered/paged, and discloses that every match is counted (matched, ms_level_counts) even when paging. No auth or rate-limit context, hence not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence with semicolons, front-loaded with the resource and field list before the routing note. Every clause carries information (fields, filtering/paging, counting, sibling routing), though the field enumeration makes it heavier than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is not required, and the annotations carry the safety profile. For a 15-parameter filtered-list tool, the description supplies the resource scope, the returned fields, and sibling routing, leaving only minor gaps like prerequisites or run semantics that the schema covers.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 15 parameters thoroughly (rt_range, precursor_tol, strict, count, limit, etc.). The description only summarizes 'filtered and paged' and the counting behavior; it adds no parameter syntax or format detail beyond the schema. Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('scans of a mass-spectrometry run') and immediately scopes it with 'without decoding peaks', enumerating the fields it returns. It also distinguishes itself from openreadout_trace by naming the modalities (IR, Raman, UV-Vis, NMR) that belong to the sibling, so an agent can tell the two apart without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear routing: this tool is for MS scans, and the final sentence directs the agent to openreadout_trace for IR/Raman/UV-Vis/NMR. 'Without decoding peaks' implies openreadout_peaks is the alternative for peak data. There is no explicit when-not statement, but the alternative is named, which is strong guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_searchARead-onlyIdempotent
Query an index from openreadout_index: 'format=nd2 objective=60x', 'channel~CD4', 'events>100000', 'rate>=20kHz', 'acquired<2015', 'status=truncated|corrupt'. Returns {total, returned, results[]}: total counts every match, results is capped by limit (default 50); fields=['all'] returns every column.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort field (`size`, `-acquired` for descending). Default: path order. | |
| limit | No | Most results (default 50, max 1000). | |
| query | No | Query: space-separated terms, all must match; `OR` between alternatives. `field=value`, `!=`, `~` (contains), `<`/`<=`/`>`/`>=` with units (`size>1GB`, `rate>=20kHz`) or dates (`acquired<2020`), `field:TERM` (`technique:FBbi_00000246`), `-term` negates, `a|b` alternatives, bare words search paths, samples, channels and descriptions. Fields: format, family, sample, instrument, model, operator, method, technique, acquired, year, objective (`63x`), channel, pixel, x/y/z/c/t, size, rows, scans, rate, status, pii, risk, `param.<name>`, or any column of experiments.parquet. Empty: everything. | |
| fields | No | Columns to return (aliases allowed); default: path, format, size, acquired, sample, instrument model, technique, channels, objective, check status, what. `["all"]`: every column. | |
| index_dir | Yes | Index directory (from openreadout_index or `openreadout index`). |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | The query as given. |
| total | Yes | Data sets matching. |
| fields | Yes | The columns of each result. |
| results | Yes | One object per matching data set, with the requested columns. |
| returned | Yes | Results returned. |
| index_dir | Yes | The index directory searched. |
| truncated | Yes | True when `total` > `returned`. |
| index_complete | Yes | Whether the index covers every root to the end (see `index.json`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, non-destructive, and openWorldHint=false, so the safety profile is covered. The description adds that total is the full match count while results is capped by limit (default 50) — real behavioral value — but an output schema already exists, so this partially duplicates structured data rather than breaking new ground.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded paragraph: purpose first, then concrete query exemplars, then the return envelope. It is dense and every clause is relevant, though the query examples overlap heavily with the already-complete schema and slightly dilute the opening.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only search tool with full schema coverage, an output schema, and a rich annotation set, the definition covers the essentials. It omits only secondary concerns — index_dir validity requirements and how sort interacts with the limit cap — which are minor given the structured fields carry them.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the query grammar, sort semantics, limit bounds, and field aliases are all documented in the schema. The description's query exemplars ('rate>=20kHz', 'status=truncated|corrupt') restate that syntax rather than adding units or edge cases the schema omits, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Query an index from openreadout_index'), naming the sibling that produces the input and thereby signaling the precondition. However, it never contrasts itself with search-adjacent siblings like openreadout_table, openreadout_info, or openreadout_scans, so an agent must infer the boundary from names alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'an index from openreadout_index' implies the index must exist first, which is useful routing context. But there is no explicit when-to-use/when-not, no statement of what to do when the index is missing, and no pointer to a sibling for viewing or exporting the results.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_spectrumARead-onlyIdempotent
One mass spectrum, picked by retention time (rt, minutes: the scan nearest it), scan number or zero-based spectrum index: metadata, peaks[] (the most intense, with charge from the isotope spacing and neutral mass) and mz[]/intensity[].
| Name | Required | Description | Default |
|---|---|---|---|
| rt | No | The MS scan (of ms_level, default 1) nearest this retention time, minutes: the spectrum at a chromatogram's apex. | |
| run | No | Run index for files with several runs (Sciex samples; default 0). | |
| file | Yes | Path to the mass-spectrometry file. | |
| scan | No | The scan number as the instrument counts it (1-based in Thermo files; mzML `scan=N` native ids, mzXML `num`, timsTOF spectrum position + 1). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| centroid | No | The stored centroid list instead of the profile when a scan has both. | |
| ms_level | No | Count spectrum among the spectra of this MS level only (1 = full scans, 2 = MS/MS). MS1 and MS/MS scans interleave, and ms_level=2 with spectrum=0 is the first MS/MS scan. | |
| spectrum | No | The zero-based spectrum index, counted within ms_level when it is given. | |
| lock_mass | No | Waters .raw: correct m/z with the lock-spray reference scans, given the lock compound's m/z (e.g. 556.2771), or "auto" for the Lock Mass the file records. Default: m/z as stored. | |
| top_peaks | No | Most intense peaks listed under peaks[] with charge and neutral mass (default 20). | |
| max_points | No | At most this many points, the most intense kept (default 1000; point_count reports the full size). |
Output Schema
| Name | Required | Description |
|---|---|---|
| run | Yes | Run index the spectrum belongs to. |
| path | Yes | The input file. |
| view | Yes | `primary` (profile when recorded) or `centroid` (the instrument's centroid list). |
| peaks | No | The most intense peaks of the whole spectrum, with charges from their isotope patterns. |
| format | Yes | Format id of the input file. |
| spectrum | Yes | The spectrum, with its arrays. |
| truncated | Yes | True when `mz`/`intensity` were shortened to `max_points` (the most intense points are kept, in m/z order). |
| point_count | Yes | Number of points in the full spectrum (the arrays may be shortened by `max_points`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=false and destructiveHint=false, so the safety profile is fully covered. The description adds little beyond structured fields: the 'nearest scan' rt behavior and the peak/charge/neutral-mass output details are already in the schema and output schema respectively. No mention of errors, cost, or the strict/exit_code 6 refusal behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence, front-loaded with the resource and the selection keys before listing outputs. It is run-on and packs three selectors plus output shape into one clause, but every element earns its place and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return values, and with 100% schema coverage the parameters are covered. It adequately frames the selection keys and the shape of the result for a read-only single-record tool; only alternative-routing guidance is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 11 parameters in detail (rt, run, scan, spectrum, ms_level, top_peaks, max_points, etc.). The description restates only rt, scan and spectrum and adds no format or default semantics beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource ('One mass spectrum') and the three mutually exclusive selectors (retention time, scan number, zero-based spectrum index), which is enough to distinguish it from siblings like openreadout_chromatogram, openreadout_scans and openreadout_peaks. An agent can tell what it retrieves and how to address the target without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: read a single spectrum when you can name it by rt, scan or index. There is no explicit when-to-use / when-not-to-use guidance and no routing to alternatives such as openreadout_scans (enumerate scans) or openreadout_peaks (peak lists), so the agent must infer the boundaries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_spikesARead-onlyIdempotent
Extracellular spike detection per channel: band-pass, threshold at K x MAD noise, spike counts, rates and times.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the file or data-set directory. | |
| sign | No | `neg` (default), `pos` or `both`. | |
| trace | No | Trace index (default 0; pick the broadband stream). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| sweeps | No | Sweeps/segments (default all). | |
| band_hz | No | Band-pass `[low, high]` Hz (default [300, 6000]). | |
| channels | No | Channels (default all). | |
| max_times | No | Spike times per channel returned (default 200). | |
| threshold | No | Threshold in MAD noise units (default 5). | |
| max_seconds | No | Only the first N seconds of each sweep. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | Input path. |
| notes | No | Remarks. |
| trace | Yes | Trace analysed. |
| format | Yes | Format id. |
| sweeps | Yes | Sweeps analysed. |
| channels | Yes | One entry per channel. |
| settings | Yes | Settings used (the high edge after clamping to 0.45 × the sampling rate). |
| sample_rate_hz | Yes | Sampling rate, Hz. |
| spike_count_total | Yes | Spikes on all channels. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-destructive behavior, so the bar is low; the description still adds real value by disclosing the processing pipeline (band-pass, K x MAD thresholding) and the outputs produced (counts, rates, times). It does not mention cost, data-size limits, or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that names the domain first and then enumerates the pipeline stages and outputs. No filler, no restatement of the title or name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full output schema and complete annotation set, the description only needs to frame the computation, which it does. The main residual gap is the absence of any statement about prerequisites (e.g. broadband trace selection, assurance/strict validation) that an agent would need before calling it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with 10 well-documented parameters, so the schema already carries parameter meaning. The description echoes band-pass, threshold and time outputs but adds no syntax, units or default information beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Extracellular spike detection per channel') plus the algorithm used, so an agent knows exactly what computation is performed. It contrasts implicitly with generic siblings like openreadout_peaks by naming the extracellular-spike domain, but never names an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the domain phrase 'extracellular spike detection per channel' plus the mention of picking a broadband stream, which tells the agent the expected input. There is no explicit when-to-use/when-not guidance and no routing to sibling tools such as openreadout_peaks or openreadout_ephys_features.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_statsARead-onlyIdempotent
Pixel statistics per channel and image: count, min, max, mean, std, percentiles p1–p99, zero and saturated fractions (at the detector's 2^bits−1 when recorded), histogram; RGB images also per component. per=plane adds every plane; per=well or field gives rows per well of a screening plate. mip='z' measures the maximum-intensity projection; whole slides: a coarser level and/or a region. Measurements on one plane: line (intensity profile, FWHM), polygon (statistics inside), objects (count nuclei, cells or spots; preview marks=objects shows them), lanes (gel and blot lanes, band volumes and sizes; preview marks=lanes).
| Name | Required | Description | Default |
|---|---|---|---|
| mip | No | Maximum-intensity projection first: `z` (per image, channel and time point: the largest value of each pixel over the selected z planes) or `t`; the statistics are of the projections. `z` = Along z: one projected plane per image, channel and time point; `t` = Along t: one projected plane per image, channel and z. | |
| per | No | Rows. `channel` = channel and image aggregates (default); `plane` = also one entry per plane (image, c, z, t); `well` = a screening plate (pass the plate folder or index, never one TIFF): one row per well × channel over the well's fields; `field` = a screening plate: one row per well × field × channel. | |
| bins | No | Histogram bins (0 = none). Default 32, at most 65536. | |
| file | Yes | Absolute or working-directory-relative path to the instrument file, or a plate's index file or folder (Harmony `Index.idx.xml`, ImageXpress `.HTD`, CellVoyager `MeasurementData.mlf`, OME-Zarr plate). | |
| line | No | Intensity profile along the line `[x0, y0, x1, y1]` (pixels of `level`, as on the preview rulers): values per channel, peak position and FWHM in px and µm. | |
| image | No | Only this image index. | |
| lanes | No | Lanes and bands of a gel or blot in `region` or the whole plane: each lane's total and each band's row and background-subtracted volume (with `ladder`, its size). `{}` finds the lanes; preview marks=lanes draws them. | |
| level | No | Pyramid level: 0 = full resolution (default). | |
| scale | No | Histogram spacing: `linear` (default) or `log`. `linear` = Equal-width bins from `min` to `max` (integer data: to `max + 1`, so each bin holds whole values); `log` = Geometrically spaced bins from the smallest positive value to `max`; values ≤ 0 are counted in `nonpositive`. Suited to data spanning decades (photon counts, spectra). | linear |
| wells | No | per=well|field: only these wells (`C05`, `c5`). | |
| region | No | Only this rectangle of each plane, `{x, y, width, height}` in the pixel coordinates of `level` (e.g. the 512 x 512 centre of a whole-slide image). | |
| select | No | Plane selection strings such as `c=0`, `z=2-5`, `t=0,3`. The aggregates cover exactly the selection. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| objects | No | Count objects in `region`, `polygon` or the whole plane: count, density, sizes, centroids, each object's mean in every channel and how many are positive per channel. `{}` counts nuclei with settings taken from the image (size, threshold, H&E colour deconvolution). Found in a DNA-stain channel unless `select` names one. | |
| polygon | No | Statistics inside this polygon `[[x, y], ...]` (pixels of `level`): area, mean, std, median, sum per channel. | |
| line_width | No | Profile width in pixels, averaged across the line. Default 1. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the read-only/idempotent/non-destructive profile, so the bar is lower, and the description still adds real behavior: 'strict ... refuses values the file's assurance does not validate (exit_code 6)', that 'the counts cover all' objects while only max_objects are listed, and that with a ladder 'bands then get sizes'. No rate limits, cost, or failure modes beyond exit_code 6 are described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single very long run-on passage with semicolon-separated clauses and no structure, so the key 'what it computes' idea competes with a dense feature dump. Nothing is truly wasted, but it is not front-loaded by importance and is hard to scan, which weakens selection speed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 16-parameter tool this is a thorough description: it covers the output statistics, every measurement mode, projection and pyramid handling, plate/slide scoping, and selection semantics. With annotations and an existing output schema carrying the safety and return-shape burden, almost nothing an agent needs in order to call it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 16 parameters, and the description largely mirrors that content (mip, per, line, polygon, objects, lanes are all restated rather than extended). It does tie modes together usefully ('preview marks=objects shows them'), but adds little semantic detail the schema lacks, so the baseline 3 is right.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource (pixel statistics per channel/image) and immediately enumerates the measurement families it covers (count, min/max/mean/std, percentiles, histogram), so an agent knows exactly what the tool produces. It does not, however, name or contrast itself with any sibling such as openreadout_preview or openreadout_extract, leaving the boundary to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Embedded conditional guidance is present: 'per=plane adds every plane; per=well or field gives rows per well of a screening plate', 'mip=z measures the maximum-intensity projection', and 'Measurements on one plane: line..., polygon..., objects..., lanes...'. This tells the agent when each mode applies, but there are no explicit exclusions or pointer to an alternative tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_summarizeADestructiveIdempotent
Group statistics of a table written by an earlier openreadout_batch output (or any CSV, TSV, JSON Lines, JSON or Parquet table): n, mean, sd, sem, median, min, max and CV % per group of by, optionally averaging replicates first and testing every group against a control.
| Name | Required | Description | Default |
|---|---|---|---|
| by | Yes | Group by these columns. | |
| test | No | `welch` or `mann-whitney` against `control`. | |
| table | Yes | A table file written by an openreadout_batch `output` (or any CSV, TSV, JSON Lines, JSON or Parquet table). | |
| where | No | Row filters `COLUMN=VALUE` / `COLUMN!=VALUE`. | |
| output | No | Write the summary to this file. | |
| values | No | Value columns (default: the measure's main values). | |
| control | No | The control group (a value of the first `by` column). | |
| exact_by | No | Group by exactly `by`. | |
| overwrite | No | Replace an existing output file. | |
| replicate | No | Average rows within each replicate first. |
Output Schema
| Name | Required | Description |
|---|---|---|
| input | Yes | The table summarized. |
| output | No | Where it was written. |
| summary | Yes | The summary. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a non-read-only, destructive, idempotent operation, and the description is consistent with that by noting the `output` write target and the ability to overwrite an existing output file. It also adds genuinely useful context beyond the annotations, such as accepted input formats and that replicates can be averaged before summarization. It does not discuss failure modes or what happens to prior results beyond the overwrite flag.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action (group statistics of a table) and the enumerated outputs, followed by the optional behaviors. It is a single dense sentence with nested parentheticals, which makes it slightly run-on but still economical with no wasted clauses.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a ten-parameter statistical tool with an output schema (so return values need no explanation) and annotations covering the safety profile, the description supplies enough to call it correctly: input formats, the grouping key, and the optional replicate/control behaviors. It is close to complete, with only minor gaps around filtering and value-column selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all ten parameters are already documented in the schema and this is the baseline case. The description reinforces `by` grouping, replicate averaging, and control testing, but says nothing about `where`, `exact_by`, or `values`, adding little meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource (group summary statistics of a table) and enumerates exactly what is computed (n, mean, sd, sem, median, min, max, CV%), plus the accepted input sources. It does not explicitly differentiate itself from potentially overlapping siblings such as openreadout_stats or openreadout_compare, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer it should call this when it wants per-group descriptive statistics, optionally with replicate averaging or a control comparison. No when-not-to-use conditions, prerequisites, or alternative tools are named, and the relationship to openreadout_stats is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_tableARead-onlyIdempotent
Rows of a table {columns, labels, rows, total_rows, truncated}: FCS events ($PnN columns), plate reads (well, row, col, read, wavelength_nm, time_s, value), event, spike or peak tables (including the vendor's own integration results). Values are raw; FCS can be compensated, transformed and given 0/1 population columns from a workspace or Gating-ML file. filter with count=true counts the events meeting conditions.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the file. | |
| count | No | Return only the count (`filter.matched_rows`, `total_rows`, `percent`), no rows. | |
| table | No | Table index (FCS data set or plate read; see openreadout_info → tables[]). Default 0. | |
| filter | No | Row conditions `COLUMN OP NUMBER` (OP: > >= < <= == !=; COLUMN: $PnN, $PnS or `gate:<path>`), all of which must hold, e.g. `["FITC-A > 1000"]`. Tested on the values returned (after compensate/transform when given) over the whole table; `filter.matched_rows` counts every match and first_row/max_rows page through them. | |
| sample | No | Workspace sample name or id (default: matched by file name or $FIL). | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| gatingml | No | FCS only: Gating-ML 2.0 file (same uses as workspace). | |
| max_rows | No | Maximum rows to return. Default 100 (fewer for wide tables: about 5000 values), capped at 10000. | |
| first_row | No | Zero-based first row. Default 0. | |
| transform | No | FCS only: transform after compensation: `logicle`, `arcsinh`, `hyperlog`, `log`, `linear`, `biex`, `flowjo-log`, `arcsinh-cofactor`, with parameters as `NAME:K=V,…` (`logicle:T=262144,W=0.5,M=4.5,A=0`, `arcsinh-cofactor:5`), or `workspace` for the FlowJo sample's per-parameter transforms. | |
| workspace | No | FCS only: FlowJo workspace (.wsp) for compensate=gating, transform=workspace and populations. | |
| compensate | No | FCS only: compensate the values: `auto` (the gating file's matrix when one is given, else the file's $SPILLOVER/$SPILL/SPILL), `fcs` or `gating`. Values become FCS scale values first ($PnE, $PnG, $TIMESTEP). | |
| parameters | No | FCS only: parameters ($PnN) to transform; default every fluorescence parameter. | |
| populations | No | FCS only: populations (paths like `/Lymphocytes/Singlets` or unique names) whose 0/1 membership is appended as `gate:<path>` columns. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | The input file. |
| rows | Yes | Row-major values; `rows[r][c]`. Non-finite values serialize as `null`. A text column holds codes here; `texts` has its text. |
| table | Yes | Table index (see `info` → `tables[]`). |
| texts | No | Text columns (`info` → `tables[].columns[].extra.categories`) by column name: the text of each returned row, so `texts[name][r]` is what `rows[r][c]` codes. Absent when the table has no text column. |
| filter | No | Present with `--where`/`--count`: the row conditions and how many rows of the whole table meet them. `rows`, `first_row` and `truncated` then page through the matching rows. |
| format | Yes | Format id of the input file. |
| labels | Yes | Column labels (FCS `$PnS`), `null` where absent. |
| columns | Yes | Column names (FCS `$PnN`). |
| first_row | Yes | Zero-based index of the first row returned. |
| truncated | Yes | True when more rows follow the returned slice. |
| processing | No | Present when the values were processed (FCS scale values, compensation, transforms, population membership columns); absent for raw values. |
| total_rows | Yes | Rows in the whole table. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnly/idempotent/no-destructive, but the description adds real behavior: values are raw unless compensate/transform/workspace/populations are applied, FCS scaling ($PnE, $PnG, $TIMESTEP) is applied first, and strict can refuse values (exit_code 6). Those are substantive traits beyond the annotation set.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences that front-load the return shape and table kinds, with no filler. The colon-separated noun lists are terse to the point of being hard to parse, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 14-parameter tool the description covers the important axes — table selection, raw vs compensated/transformed values, workspace/Gating-ML population columns, and filter/count behavior — and an output schema exists so return format need not be repeated. Only the interaction between first_row/max_rows paging and filtering is left to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description restates the filter semantics ('tested on the values returned after compensate/transform', matched_rows counting) that the schema already documents, and adds little independent meaning for the other 13 parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource precisely (rows of a table) and enumerates the concrete table kinds it returns — FCS events, plate reads, event/spike/peak tables — plus the return shape {columns, labels, rows, total_rows, truncated}. That is a clear specific operation, though it never explicitly contrasts itself with preview/export/extract siblings, only deferring to openreadout_info for table indices.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: it points to openreadout_info → tables[] for choosing a table index and notes that filter+count=true yields counts. There is no explicit 'use this when you need actual row values, use openreadout_preview/summarize otherwise' routing, so an agent must infer the boundary from siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_traceBRead-onlyIdempotent
One window of one sweep of a sampled signal or 1-D spectrum in physical units: electrophysiology sweeps, chromatography detector traces, ÄKTA curves, ITC thermograms, SPR sensorgrams, NMR FIDs and spectra (process=true turns an FID into a spectrum), IR/Raman/UV-Vis/CD spectra (each spectrum of a map is a sweep), qPCR curves, EPR, XRD, electrochemistry, thermal analysis. Per channel: min, max, mean, std and argmax_axis_value (the maximum's position on the axis: retention time, ppm, cm⁻¹, °2θ) over the window, plus the first max_samples values.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the file. | |
| count | No | Window length in samples (statistics cover the whole window). Default: to the end of the sweep. | |
| sweep | No | Sweep (episode or segment) index. Default 0. | |
| trace | No | Trace index (see openreadout_info → traces[]). Default 0. | |
| strict | No | Refuse values the file's assurance does not validate (exit_code 6). Default: the server's. | |
| process | No | NMR: return FID traces as spectra processed by OpenReadout (group delay, apodization, zero filling, FT, stored or automatic phase, baseline, ppm axis). | |
| x_range | No | Window on the trace's own axis instead of first_sample/count, `[a, b]` either order: cm⁻¹, nm, ppm, a chromatogram's retention time in its axis unit; seconds for signals without an axis. | |
| channels | No | Channel indices to return. Default: all channels. | |
| max_samples | No | Samples returned per channel. Default 200, capped at 10000. | |
| first_sample | No | First sample of the window, zero-based within the sweep. Default 0. |
Output Schema
| Name | Required | Description |
|---|---|---|
| axis | No | The trace's abscissa (`info` → `traces[].extra.axis`: `{quantity, unit, first, step, …}`), e.g. the ppm axis of an NMR spectrum or a chromatogram's retention time in minutes; sample `i` of the sweep is at `first + i * step`. For a time axis this agrees with `start_s` and `sample_rate_hz` (`first` = `start_s` at `first_sample` 0, `step` = 1 / `sample_rate_hz`, in `unit`). Irregular axes (`irregular: true`) name the channel holding each sample's abscissa instead. |
| path | Yes | The input file. |
| sweep | Yes | Sweep index. |
| trace | Yes | Trace index (see `info` → `traces[]`). |
| format | Yes | Format id of the input file. |
| start_s | Yes | Time of the first window sample in seconds. Single-sweep traces use the trace's own clock: `info.traces[].start_s + first_sample / sample_rate_hz` (a chromatogram's retention time, negative when acquisition began before injection; an electrophysiology recording's clock). Multi-sweep traces are timed from the start of the sweep (`first_sample / sample_rate_hz`; `sweep_start_s` places the sweep in the recording). Irregularly sampled traces (`sample_rate_hz` 0 with a `time` channel) report that channel's first window value; traces without a time base (spectra) report 0. |
| x_range | No | The axis window asked for (`x_range`, low to high): axis units, or seconds for signals without an axis. `first_sample`/`sample_count` are the samples inside it. |
| channels | Yes | One entry per requested channel. |
| truncated | Yes | True when fewer samples are returned than the window holds. |
| sweep_count | Yes | Sweeps in the trace. |
| first_sample | Yes | First sample of the window (zero-based, within the sweep). |
| sample_count | Yes | Samples in the window (statistics cover all of them). |
| sweep_start_s | No | Time of the sweep's first sample on the recording clock, seconds, when the file records it (`info.traces[].start_s` for a single sweep, `extra.sweep_starts_s[sweep]` for multi-sweep traces). |
| sample_rate_hz | Yes | Samples per second. |
| sweep_sample_count | Yes | Samples in this sweep. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered by structured data. The description's remaining behavioral contribution is the NMR process=true transform, which is notable, but the return contents it lists (min/max/mean/std/argmax) are already covered by the output schema. Error behavior (strict/exit_code 6) is left entirely to the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is front-loaded, but the first sentence is a very long catalogue of ~14 instrument domains whose tail entries add little for an agent that already knows its data type. The second sentence stacks output fields and axis-unit clarifications into a single run-on. Information-dense, but not tightly edited.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and 100% parameter description coverage, the description does not need to explain return values; it still usefully frames what a window/sweep/spectrum means, which the schema alone would not convey. The main gap is the absence of any when-to-use or alternative-tool guidance given 27 sibling tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces the units used by argmax_axis_value and by x_range (retention time, ppm, cm⁻¹, °2θ) and clarifies that a map's each spectrum counts as a sweep, but it adds no syntax or default information beyond what the parameter descriptions already state.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a precise definition of the resource: 'one window of one sweep of a sampled signal or 1-D spectrum in physical units', and enumerates the data domains it covers (electrophysiology, chromatography, NMR, ITC, SPR, qPCR, etc.). It is clear the tool reads a sub-window of a series, but it never explicitly names the sibling it replaces or differs from (e.g. openreadout_spectrum, openreadout_scans, openreadout_stats), so sibling differentiation must be inferred.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the domain enumeration — the agent can infer this is the general-purpose trace/sweep reader for any sampled signal. There is no explicit when-to-use statement, no exclusions, and no routing to alternatives such as openreadout_spectrum or openreadout_scans. The 'process=true turns an FID into a spectrum' note is the closest thing to a mode-selection hint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openreadout_watchARead-only
Follow directories an instrument writes to: each call looks once and returns events since cursor (dataset_new, plane_new, scan_new, frame_new, dataset_complete, dataset_stalled, qc with qc=true: saturation, focus drift, dropped frames, TIC drop, error). Poll with the returned cursor; files are never locked.
| Name | Required | Description | Default |
|---|---|---|---|
| qc | No | First call only: evaluate the built-in live QC rules on each new plane or scan. | |
| dirs | Yes | Directories (or files) to watch. The same list (in any order) continues the same watcher across calls. | |
| limit | No | Most events returned (default 200, max 5000); call again with the new cursor for more. | |
| since | No | First call only: report data sets modified since then (`10m`, `2h`, `1d`, an ISO-8601 time, or `all`). Default: the live window (5 minutes) back from now. | |
| cursor | No | Return events with a sequence number greater than this (the `cursor` of the previous call); 0 or absent on the first call. | |
| stall_after | No | First call only: seconds without growth before `dataset_stalled` (default 120). | |
| follow_symlinks | No | First call only: walk into directories behind symbolic links too (links to files are always followed). |
Output Schema
| Name | Required | Description |
|---|---|---|
| more | Yes | True when more events are waiting (raise `limit` or call again). |
| notes | No | What the watcher left out and how to include it. |
| cursor | Yes | Pass back as `cursor` to get only newer events. |
| events | Yes | Events after the given cursor, oldest first (the same objects `openreadout watch` prints under `data`). |
| dropped | Yes | True when events after the cursor were dropped (the server keeps the last 10000). |
| tracked | Yes | Data sets the watcher remembers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, non-destructive, not idempotent), and the description adds genuinely useful behavior beyond that: each call is a single non-blocking look, continuation is by cursor, and watching never locks files. It does not explain backpressure or what happens when a watched directory disappears.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, with the core purpose front-loaded before the event-type parenthetical. The embedded enumeration of event names is dense but earns its place by telling the agent what to expect to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value detail is not required, yet the description still names the event vocabulary the agent will need for routing. Combined with the polling/cursor guidance, an agent has enough to invoke and loop correctly; only edge behavior (missing dirs, error recovery) is unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all seven parameters including the first-call-only nature of qc/since/stall_after/follow_symlinks. The description adds only the cursor/polling linkage, which the schema's cursor description already carries, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Follow directories an instrument writes to') plus the operational model ('each call looks once and returns events since cursor'), and enumerates the returned event types. It is clearly distinguishable from read-once siblings like openreadout_scans or openreadout_check.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational context: poll repeatedly using the returned cursor, and 'files are never locked' signals it is safe to call alongside a running acquisition. It does not name an alternative sibling or state an explicit when-not-to-use, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
34 tool updates
v0.4.0- Added
openreadout_assay - Removed
openreadout_assay_curve - Removed
openreadout_assay_qc - Removed
openreadout_assay_wells - Changed
openreadout_batch17 fields changed- removed
Input schema / properties / by / defaultRemoved value: -[] - removed
Input schema / properties / exact_by / defaultRemoved value: -false - removed
Input schema / properties / fields / defaultRemoved value: -[] - removed
Input schema / properties / formats / defaultRemoved value: -[] - removed
Input schema / properties / keys / defaultRemoved value: -[] - removed
Input schema / properties / limit / minimumRemoved value: -0 - changed
Input schema / properties / measure / descriptionPrevious value: -"What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `scans` = one row per MS scan header (options: the openreadout_scans filters); `peaks` = openreadout_peaks (its arguments as options); `chromatogram` = openreadout_chromatogram (its arguments as options); `assay` = a plate-reader assay: options `analysis` (wells, curve, dose-response, kinetics, growth, qc) and the arguments of that openreadout_assay_* tool; `nmr-peaks` = openreadout_nmr_peaks (its arguments as options); `ephys-features` = openreadout_ephys_features (its arguments as options); `spikes` = openreadout_spikes (its arguments as options); `qpcr` = openreadout_qpcr (its arguments as options); `gate` = population counts, percentages and medians (workspace or gatingml)."New value: +"What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `scans` = one row per MS scan header (options: the openreadout_scans filters); `peaks` = openreadout_peaks (its arguments as options); `chromatogram` = openreadout_chromatogram (its arguments as options); `assay` = a plate-reader assay: options `analysis` (wells, curve, dose-response, kinetics, growth, qc) and the other openreadout_assay arguments; `nmr-peaks` = openreadout_nmr_peaks (its arguments as options); `ephys-features` = openreadout_ephys_features (its arguments as options); `spikes` = openreadout_spikes (its arguments as options); `qpcr` = openreadout_qpcr (its arguments as options); `gate` = population counts, percentages and medians (workspace or gatingml)." - removed
Input schema / properties / offset / defaultRemoved value: -0 - removed
Input schema / properties / offset / minimumRemoved value: -0 - changed
Input schema / properties / options / descriptionPrevious value: -"The measure's options. Analyses: the arguments of that analysis's tool (openreadout_peaks, openreadout_nmr_peaks, ...; assay: `analysis` = wells, curve, dose-response, kinetics, growth or qc, plus the arguments of that openreadout_assay_* tool), plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. scans: the openreadout_scans filters."New value: +"The measure's options. Analyses: the arguments of that analysis's tool (openreadout_peaks, openreadout_nmr_peaks, openreadout_assay with its `analysis`, ...), plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. scans: the openreadout_scans filters." - removed
Input schema / properties / overwrite / defaultRemoved value: -false - removed
Input schema / properties / paths / defaultRemoved value: -[] - removed
Input schema / properties / recursive / defaultRemoved value: -false - removed
Input schema / properties / sample_sheets / defaultRemoved value: -[] - removed
Input schema / properties / values / defaultRemoved value: -[] - removed
Input schema / properties / where / defaultRemoved value: -[] - changed
Output schema / $defs / Value / anyOfPrevious value: -[ - { - "description": "No value (JSON `null`, an empty CSV field).", - "type": "null" - }, - { - "description": "`true` / `false`.", - "type": "boolean" - }, - { - "description": "A whole number.", - "format": "int64", - "type": "integer" - }, - { - "description": "A real number (NaN and infinities are written as `null`).", - "format": "double", - "type": "number" - }, - { - "description": "Text.", - "type": "string" - } -]New value: +[ + { + "description": "No value (JSON `null`, an empty CSV field).", + "type": "null" + }, + { + "description": "`true` / `false`.", + "type": "boolean" + }, + { + "description": "A whole number.", + "format": "int64", + "type": "integer" + }, + { + "description": "A real number (NaN and infinities are written as `null`).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + { + "description": "Text.", + "type": "string" + } +]
- Changed
openreadout_check5 fields changed- changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the file or data-set directory."New value: +"Path to the file or data-set directory." - removed
Input schema / properties / headers_only / defaultRemoved value: -false - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - changed
Output schema / $defs / Acquisition / properties / modified_ago_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Acquisition / properties / window_s / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Changed
openreadout_chromatogram20 fields changed- removed
Input schema / properties / bpc / defaultRemoved value: -false - removed
Input schema / properties / channel / minimumRemoved value: -0 - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory." - removed
Input schema / properties / max_points / minimumRemoved value: -0 - removed
Input schema / properties / ms_level / minimumRemoved value: -0 - removed
Input schema / properties / mz / defaultRemoved value: -[] - removed
Input schema / properties / profile / defaultRemoved value: -false - removed
Input schema / properties / run / defaultRemoved value: -0 - removed
Input schema / properties / run / minimumRemoved value: -0 - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / sweep / minimumRemoved value: -0 - removed
Input schema / properties / tic / defaultRemoved value: -false - removed
Input schema / properties / traces / defaultRemoved value: -[] - removed
Input schema / properties / traces / items / minimumRemoved value: -0 - removed
Input schema / properties / transitions / defaultRemoved value: -[] - changed
Output schema / $defs / Chromatogram / properties / intensity / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Chromatogram / properties / mz_range / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Chromatogram / properties / mz_window / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Chromatogram / properties / rt_min / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Chromatogram / requiredPrevious value: -[ - "label", - "kind", - "source", - "points", - "rt_min", - "intensity" -]New value: +[ + "label", + "kind", + "source", + "points", + "rt_min", + "intensity", + "decimated" +]
- Changed
openreadout_compare10 fields changed- removed
Input schema / properties / ignore / defaultRemoved value: -[] - removed
Input schema / properties / image / minimumRemoved value: -0 - removed
Input schema / properties / level / defaultRemoved value: -0 - removed
Input schema / properties / level / minimumRemoved value: -0 - removed
Input schema / properties / no_pixels / defaultRemoved value: -false - removed
Input schema / properties / select / defaultRemoved value: -[] - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - changed
Output schema / $defs / ImageComparison / requiredPrevious value: -[ - "image", - "geometry_equal", - "channel_names_equal", - "ours_channels", - "theirs_channels", - "physical_size_equal" -]New value: +[ + "image", + "geometry_equal", + "channel_names_equal", + "physical_size_equal" +] - changed
Output schema / $defs / PlaneComparison / requiredPrevious value: -[ - "compared", - "planes", - "identical", - "within_tolerance", - "mismatched", - "skipped_images", - "mismatches" -]New value: +[ + "compared", + "planes", + "identical", + "within_tolerance", + "mismatched", + "mismatches" +] - changed
Output schema / requiredPrevious value: -[ - "identical", - "ours", - "theirs", - "metadata", - "images", - "planes", - "notes" -]New value: +[ + "identical", + "ours", + "theirs", + "metadata", + "images", + "planes" +]
- Removed
openreadout_dose_response - Changed
openreadout_ephys_features35 fields changed- removed
Input schema / properties / channel / minimumRemoved value: -0 - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory." - removed
Input schema / properties / max_spikes / minimumRemoved value: -0 - added
Input schema / properties / min_rise_mvAdded value: +{ + "description": "A spike's peak must rise this far above the lowest voltage since the previous spike, mV (default 15; 0 counts every crossing, as eFEL does).", + "type": "number" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / sweeps / items / minimumRemoved value: -0 - removed
Input schema / properties / trace / defaultRemoved value: -0 - removed
Input schema / properties / trace / minimumRemoved value: -0 - changed
Output schema / $defs / ApSettings / properties / dvdt_threshold_v_per_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / $defs / ApSettings / properties / min_rise_mvAdded value: +{ + "description": "Rise of a spike's peak above the lowest voltage since the previous spike's peak, mV.", + "format": "double", + "type": [ + "number", + "null" + ] +} - changed
Output schema / $defs / ApSettings / properties / peak_threshold_mv / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ApSettings / requiredPrevious value: -[ - "peak_threshold_mv", - "dvdt_threshold_v_per_s", - "dvdt_window_samples" -]New value: +[ + "peak_threshold_mv", + "dvdt_threshold_v_per_s", + "dvdt_window_samples", + "min_rise_mv" +] - changed
Output schema / $defs / CellFeatures / properties / fi_slope_hz_per_pa / descriptionPrevious value: -"Least-squares slope of rate vs current over steps that fire, Hz/pA."New value: +"Least-squares slope of rate vs current from the rheobase to the step with the highest\nrate (steps past it, where firing fails, are left out), Hz/pA." - changed
Output schema / $defs / CellFeatures / properties / rheobase_pa / descriptionPrevious value: -"Smallest depolarising step that evokes at least one spike during the stimulus, pA."New value: +"Smallest depolarising step that evokes at least one spike during the stimulus, pA.\nAbsent when the cell also fires during a step of 0 pA or less (it fires without\ndepolarising current, so a rheobase is not defined; `notes` says so)." - added
Output schema / $defs / CellFeatures / properties / spontaneous_rate_hzAdded value: +{ + "description": "Firing rate before the stimulus, over every sweep, Hz: above 0 the cell fires on its own.", + "format": "double", + "type": [ + "number", + "null" + ] +} - changed
Output schema / $defs / CellFeatures / requiredPrevious value: -[ - "fi_curve" -]New value: +[ + "resting_mv", + "rheobase_pa", + "rheobase_sweep", + "fi_curve", + "fi_slope_hz_per_pa", + "max_firing_rate_hz", + "input_resistance_mohm", + "tau_ms", + "capacitance_pf", + "sag_ratio", + "holding_current_pa", + "access_resistance_mohm", + "membrane_resistance_mohm", + "membrane_capacitance_pf" +] - changed
Output schema / $defs / ChannelRef / requiredPrevious value: -[ - "index", - "name" -]New value: +[ + "index", + "name", + "unit" +] - changed
Output schema / $defs / FiPoint / properties / current_pa / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / FiPoint / properties / rate_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spike / properties / amplitude_mv / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spike / properties / peak_mv / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spike / properties / peak_time_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spike / properties / rise_time_ms / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spike / properties / threshold_mv / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spike / properties / threshold_time_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spike / properties / upstroke_v_per_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spike / requiredPrevious value: -[ - "sweep", - "index", - "peak_sample", - "peak_time_s", - "peak_mv", - "threshold_time_s", - "threshold_mv", - "threshold_from_dvdt", - "amplitude_mv", - "rise_time_ms", - "upstroke_v_per_s" -]New value: +[ + "sweep", + "index", + "peak_sample", + "peak_time_s", + "peak_mv", + "threshold_time_s", + "threshold_mv", + "threshold_from_dvdt", + "amplitude_mv", + "half_width_ms", + "rise_time_ms", + "decay_time_ms", + "ahp_mv", + "ahp_depth_mv", + "upstroke_v_per_s", + "downstroke_v_per_s", + "isi_ms" +] - added
Output schema / $defs / StepResponse / requiredAdded value: +[ + "baseline_mv", + "steady_state_mv", + "extreme_mv", + "input_resistance_mohm", + "tau_ms", + "sag_ratio", + "steady_fraction" +] - changed
Output schema / $defs / StimulusInfo / properties / holding / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / StimulusInfo / requiredPrevious value: -[ - "output", - "holding" -]New value: +[ + "output", + "unit", + "holding", + "epoch" +] - added
Output schema / $defs / SweepFeatures / properties / spike_count_beforeAdded value: +{ + "description": "Spikes whose peak comes before the stimulus starts.", + "format": "uint", + "minimum": 0, + "type": [ + "integer", + "null" + ] +} - changed
Output schema / $defs / SweepFeatures / requiredPrevious value: -[ - "sweep", - "spike_count" -]New value: +[ + "sweep", + "stimulus_start_s", + "stimulus_end_s", + "stimulus_pa", + "stimulus_mv", + "spike_count", + "spike_count_stimulus", + "firing_rate_hz", + "first_spike_latency_ms", + "isi_mean_ms", + "isi_cv", + "adaptation_index", + "half_width_mean_ms", + "amplitude_mean_mv" +] - changed
Output schema / $defs / TestPulse / properties / delta_mv / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / TestPulse / requiredPrevious value: -[ - "delta_mv" -]New value: +[ + "delta_mv", + "holding_current_pa", + "peak_current_pa", + "steady_current_pa", + "access_resistance_mohm", + "membrane_resistance_mohm", + "total_resistance_mohm", + "tau_ms", + "capacitance_pf" +] - changed
Output schema / properties / sample_rate_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Changed
openreadout_export28 fields changed- removed
Input schema / $defs / Region / properties / height / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / width / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / x / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / y / minimumRemoved value: -0 - removed
Input schema / properties / centroid / defaultRemoved value: -false - added
Input schema / properties / dpiAdded value: +{ + "description": "Figures: print resolution (e.g. 300), recorded in .png, .jpg and .tiff files; .svg and .pdf pages get the size the raster would print at.", + "type": "integer" +} - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file."New value: +"Path to the file (not with plot or preview)." - changed
Input schema / properties / format / descriptionPrevious value: -"`ome-tiff` (one BigTIFF file; the default for images), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0; the default for mass spectra), `csv` (one table, or one sweep of a trace; the default for tables and traces), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces), `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms), `asm` (Allotrope Simple Model plate-reader JSON) or `rdml` (RDML 1.3; qPCR files). Without it, the extension of `output` decides; it must not contradict `output`."New value: +"`ome-tiff` (one BigTIFF file; the default for images), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0; the default for mass spectra), `csv` (one table, or one sweep of a trace; the default for tables and traces), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces), `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms), `asm` (Allotrope Simple Model plate-reader JSON), `rdml` (RDML 1.3; qPCR files), `fastq` (base calls: a Sanger read, its default, gives one file; an Illumina run folder gives a directory of gzip FASTQ, one file per lane and read, and rows `0-N` writes the first N+1 clusters of each lane), `nifti` (NIfTI-1 `.nii.gz`; one volume with voxel size and scanner orientation) or `mrc` (MRC2014; EM movies, stacks and diffraction images). Without it, the extension of `output` decides; it must not contradict `output`." - added
Input schema / properties / group_framesAdded value: +{ + "description": "MRC: sum every N time points into one section (dose fractions of a movie).", + "type": "integer" +} - removed
Input schema / properties / image / minimumRemoved value: -0 - removed
Input schema / properties / labels / defaultRemoved value: -false - removed
Input schema / properties / level / defaultRemoved value: -0 - removed
Input schema / properties / level / minimumRemoved value: -0 - changed
Input schema / properties / output / descriptionPrevious value: -"Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.csv`, `.asm.json`, `.rdml`, `.parquet`, `.arrow`, `.nwb` or `.jdx`. Its extension sets the format when `format` is not given."New value: +"Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.csv`, `.asm.json`, `.rdml`, `.fastq`, `.parquet`, `.arrow`, `.nwb`, `.jdx`, `.nii.gz` or `.mrc`. Its extension sets the format when `format` is not given. Figures: .png, .jpg, .tiff, .svg or .pdf (default `<data file stem>.figure.png` or `.preview.png` next to the data)." - removed
Input schema / properties / overwrite / defaultRemoved value: -false - added
Input schema / properties / plotAdded value: +{ + "additionalProperties": true, + "description": "Save a figure: the arguments of an openreadout_plot call. `output` names the file.", + "type": "object" +} - added
Input schema / properties / previewAdded value: +{ + "additionalProperties": true, + "description": "Save a picture: the arguments of an openreadout_preview call (file, region, annotations, marks, dark, …); max_size up to 8192. Images are saved with a scale bar and no rulers (axes scale-bar; add title, caption) unless axes says otherwise.", + "type": "object" +} - removed
Input schema / properties / run / defaultRemoved value: -0 - removed
Input schema / properties / run / minimumRemoved value: -0 - added
Input schema / properties / scaleAdded value: +{ + "description": "Figures: pixels per figure pixel in .png, .jpg and .tiff files (default 2, up to 8); image previews are read again at max_size × scale.", + "type": "number" +} - removed
Input schema / properties / select / defaultRemoved value: -[] - removed
Input schema / properties / spectra / defaultRemoved value: -false - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / sweep / minimumRemoved value: -0 - removed
Input schema / properties / table / minimumRemoved value: -0 - removed
Input schema / properties / trace / minimumRemoved value: -0 - removed
Input schema / properties / wells / defaultRemoved value: -[] - removed
Input schema / requiredRemoved value: -[ - "file" -]
- Changed
openreadout_extract1 field changed- removed
Input schema / properties / overwrite / defaultRemoved value: -false
- Changed
openreadout_gate10 fields changed- changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory." - removed
Input schema / properties / medians / defaultRemoved value: -[] - changed
Input schema / properties / medians / descriptionPrevious value: -"Parameters whose median over each population's events is reported under populations[].medians (`$PnN` or `$PnS`; `Comp-NAME` for compensated values)."New value: +"Parameters whose median over each population's events is reported under populations[].medians (`$PnN` or `$PnS`; `Comp-NAME` for compensated values), or `[\"all\"]`: every parameter a gate uses, compensated as the gate reads it." - removed
Input schema / properties / populations / defaultRemoved value: -[] - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / table / defaultRemoved value: -0 - removed
Input schema / properties / table / minimumRemoved value: -0 - changed
Output schema / $defs / CompensationSummary / properties / matrix / items / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PopulationRow / properties / medians / additionalProperties / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / TransformSummary / properties / parameters / additionalProperties / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Removed
openreadout_growth - Changed
openreadout_health4 fields changed- removed
Input schema / properties / max_list / minimumRemoved value: -0 - removed
Input schema / properties / no_hash / defaultRemoved value: -false - changed
Output schema / $defs / DuplicateGroup / requiredPrevious value: -[ - "size_bytes", - "paths" -]New value: +[ + "size_bytes", + "sha256", + "paths" +] - changed
Output schema / $defs / IntegrityEntry / requiredPrevious value: -[ - "path", - "status", - "codes" -]New value: +[ + "path", + "format", + "status", + "codes" +]
- Changed
openreadout_index11 fields changed- removed
Input schema / properties / exclude / defaultRemoved value: -[] - added
Input schema / properties / follow_symlinksAdded value: +{ + "description": "Crawl directories behind symbolic links too (links to files are always read).", + "type": "boolean" +} - removed
Input schema / properties / full_rescan / defaultRemoved value: -false - removed
Input schema / properties / max_files / minimumRemoved value: -0 - removed
Input schema / properties / restart / defaultRemoved value: -false - removed
Input schema / properties / threads / minimumRemoved value: -0 - changed
Output schema / $defs / CrawlStats / properties / elapsed_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / IndexSettings / requiredPrevious value: -[ - "check", - "follow_symlinks", - "pii" -]New value: +[ + "check", + "follow_symlinks", + "exclude", + "pii" +] - added
Output schema / $defs / TableManifest / properties / columnsAdded value: +{ + "description": "Columns (name, type, unit class, description). Always in `index.json`; left out of the\nMCP tool's answer (listed in `index.json` and `book/src/guides/lab-shares.md`).", + "items": true, + "readOnly": true, + "type": "array" +} - changed
Output schema / $defs / WalkStats / properties / symlinks_skipped / descriptionPrevious value: -"Symbolic links skipped (not followed)."New value: +"Symbolic links to directories skipped (not followed)." - changed
Output schema / properties / files_per_s / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Changed
openreadout_info21 fields changed- changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory." - added
Input schema / properties / first_entryAdded value: +{ + "description": "view=structure with kind: skip this many elements of that kind first (paging).", + "type": "integer" +} - added
Input schema / properties / kindAdded value: +{ + "description": "view=structure: list only elements of this kind (as entries_total names them), e.g. \"attachment\" or \"subblock\".", + "type": "string" +} - added
Input schema / properties / max_entriesAdded value: +{ + "description": "view=structure: list at most this many elements of each kind (0 = all). Default 50.", + "type": "integer" +} - removed
Input schema / properties / max_images / minimumRemoved value: -0 - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate (assurance.strict_refuses). Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / vendor / defaultRemoved value: -false - changed
Output schema / $defs / Acquisition2 / properties / modified_ago_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Acquisition2 / properties / window_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ChannelInfo / properties / emission_range_nm / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ColumnInfo / properties / range / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / $defs / Listing / properties / entries_totalAdded value: +{ + "additionalProperties": { + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "description": "How many elements of each kind the container holds, when `entries` lists only some.", + "type": "object" +} - added
Output schema / $defs / Listing / properties / notesAdded value: +{ + "description": "What was left out of `entries` and how to list it.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / $defs / PlateSummary / requiredPrevious value: -[ - "rows", - "columns", - "wells", - "field_count", - "planes_expected", - "complete" -]New value: +[ + "rows", + "columns", + "wells", + "field_count", + "planes_expected", + "planes_absent", + "planes_missing", + "complete" +] - changed
Output schema / $defs / PlateWell / requiredPrevious value: -[ - "well", - "row", - "column", - "row_index", - "column_index", - "images" -]New value: +[ + "well", + "row", + "column", + "row_index", + "column_index", + "images", + "planes_missing" +] - changed
Output schema / $defs / ResolutionLevel / properties / downsample_x / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ResolutionLevel / properties / downsample_y / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SignalChannelInfo / properties / offset / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SignalChannelInfo / properties / scale / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SpectraInfo / properties / rt_range_s / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / TraceInfo / properties / sample_rate_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Removed
openreadout_kinetics - Changed
openreadout_link4 fields changed- removed
Input schema / properties / formats / defaultRemoved value: -[] - removed
Input schema / properties / no_recursive / defaultRemoved value: -false - removed
Input schema / properties / paths / defaultRemoved value: -[] - changed
Output schema / $defs / LinkMember / requiredPrevious value: -[ - "path" -]New value: +[ + "path", + "format" +]
- Changed
openreadout_nmr_peaks37 fields changed- added
Input schema / properties / auto_integrateAdded value: +{ + "description": "Without integrate: integrate every multiplet (peaks closer than 15 Hz, ±10 Hz).", + "type": "boolean" +} - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory." - changed
Input schema / properties / integral_reference / prefixItemsPrevious value: -[ - { - "minimum": 0, - "type": "integer" - }, - { - "type": "number" - } -]New value: +[ + { + "type": "integer" + }, + { + "type": "number" + } +] - removed
Input schema / properties / integrate / defaultRemoved value: -[] - removed
Input schema / properties / max_peaks / minimumRemoved value: -0 - removed
Input schema / properties / negative / defaultRemoved value: -false - removed
Input schema / properties / size / minimumRemoved value: -0 - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / sweep / defaultRemoved value: -0 - removed
Input schema / properties / sweep / minimumRemoved value: -0 - removed
Input schema / properties / trace / minimumRemoved value: -0 - changed
Output schema / $defs / Apodization / oneOfPrevious value: -[ - { - "description": "No window.", - "properties": { - "kind": { - "const": "none", - "type": "string" - } - }, - "required": [ - "kind" - ], - "type": "object" - }, - { - "description": "`e^{−π·LB·t}`: Lorentzian lines broadened by `line_broadening_hz`.", - "properties": { - "kind": { - "const": "exponential", - "type": "string" - }, - "line_broadening_hz": { - "description": "Added Lorentzian full width at half height, Hz.", - "format": "double", - "type": "number" - } - }, - "required": [ - "kind", - "line_broadening_hz" - ], - "type": "object" - }, - { - "description": "`e^{−(π·GB·t)²/(4 ln 2)}`: multiplies each line by a Gaussian of `line_broadening_hz`\nfull width at half height.", - "properties": { - "kind": { - "const": "gaussian", - "type": "string" - }, - "line_broadening_hz": { - "description": "Gaussian full width at half height, Hz.", - "format": "double", - "type": "number" - } - }, - "required": [ - "kind", - "line_broadening_hz" - ], - "type": "object" - } -]New value: +[ + { + "description": "No window.", + "properties": { + "kind": { + "const": "none", + "type": "string" + } + }, + "required": [ + "kind" + ], + "type": "object" + }, + { + "description": "`e^{−π·LB·t}`: Lorentzian lines broadened by `line_broadening_hz`.", + "properties": { + "kind": { + "const": "exponential", + "type": "string" + }, + "line_broadening_hz": { + "description": "Added Lorentzian full width at half height, Hz.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "kind", + "line_broadening_hz" + ], + "type": "object" + }, + { + "description": "`e^{−(π·GB·t)²/(4 ln 2)}`: multiplies each line by a Gaussian of `line_broadening_hz`\nfull width at half height.", + "properties": { + "kind": { + "const": "gaussian", + "type": "string" + }, + "line_broadening_hz": { + "description": "Gaussian full width at half height, Hz.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "kind", + "line_broadening_hz" + ], + "type": "object" + } +] - changed
Output schema / $defs / FidParameters / properties / carrier_frequency_mhz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / FidParameters / properties / group_delay_points / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / FidParameters / properties / reference_frequency_mhz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / FidParameters / properties / spectral_width_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Integral / properties / from_ppm / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Integral / properties / to_ppm / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Integral / properties / value / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Integral / requiredPrevious value: -[ - "from_ppm", - "to_ppm", - "value", - "points" -]New value: +[ + "from_ppm", + "to_ppm", + "value", + "normalized", + "points" +] - changed
Output schema / $defs / Peak / properties / height / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / hz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / ppm / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / requiredPrevious value: -[ - "ppm", - "hz", - "index", - "height" -]New value: +[ + "ppm", + "hz", + "index", + "height", + "width_hz", + "width_ppm", + "snr" +] - changed
Output schema / $defs / PeakOptions / properties / min_height_fraction / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PeakOptions / properties / min_prominence_snr / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PeakOptions / properties / min_snr / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PeakOptions / properties / range_ppm / prefixItemsPrevious value: -[ - { - "format": "double", - "type": "number" - }, - { - "format": "double", - "type": "number" - } -]New value: +[ + { + "format": "double", + "type": [ + "number", + "null" + ] + }, + { + "format": "double", + "type": [ + "number", + "null" + ] + } +] - changed
Output schema / $defs / PpmAxis / properties / first_ppm / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PpmAxis / properties / reference_frequency_mhz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PpmAxis / properties / step_ppm / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ProcessingRecord / properties / group_delay_points / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ProcessingRecord / properties / phase0_deg / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ProcessingRecord / properties / phase1_deg / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ProcessingRecord / requiredPrevious value: -[ - "steps", - "fid_points", - "size", - "apodization_source", - "group_delay_points", - "phase_mode", - "phase0_deg", - "phase1_deg", - "baseline", - "parameters", - "stored" -]New value: +[ + "steps", + "fid_points", + "size", + "apodization", + "apodization_source", + "group_delay_points", + "phase_mode", + "phase0_deg", + "phase1_deg", + "baseline", + "parameters", + "stored" +] - added
Output schema / $defs / StoredProcessing / requiredAdded value: +[ + "spectrum_stored" +] - changed
Output schema / properties / noise_sd / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Changed
openreadout_peaks64 fields changed- removed
Input schema / $defs / Compound / properties / channel / minimumRemoved value: -0 - removed
Input schema / $defs / Compound / properties / ms_level / minimumRemoved value: -0 - changed
Input schema / $defs / Compound / properties / polarity / descriptionPrevious value: -"Scan polarity. Polarity filter. `positive` = Positive-ion scans; `negative` = Negative-ion scans."New value: +"Scan polarity. `positive` = Positive-ion scans; `negative` = Negative-ion scans." - removed
Input schema / $defs / Compound / properties / trace / minimumRemoved value: -0 - removed
Input schema / properties / area_seconds / defaultRemoved value: -false - removed
Input schema / properties / bpc / defaultRemoved value: -false - removed
Input schema / properties / channel / minimumRemoved value: -0 - removed
Input schema / properties / compounds / defaultRemoved value: -[] - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory." - removed
Input schema / properties / integrate / defaultRemoved value: -[] - removed
Input schema / properties / ms_level / minimumRemoved value: -0 - removed
Input schema / properties / mz / defaultRemoved value: -[] - removed
Input schema / properties / profile / defaultRemoved value: -false - removed
Input schema / properties / run / defaultRemoved value: -0 - removed
Input schema / properties / run / minimumRemoved value: -0 - removed
Input schema / properties / smooth / minimumRemoved value: -0 - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / summary_only / defaultRemoved value: -false - removed
Input schema / properties / sweep / minimumRemoved value: -0 - removed
Input schema / properties / tic / defaultRemoved value: -false - removed
Input schema / properties / traces / defaultRemoved value: -[] - removed
Input schema / properties / traces / items / minimumRemoved value: -0 - removed
Input schema / properties / transitions / defaultRemoved value: -[] - removed
Input schema / properties / x_range / defaultRemoved value: -[] - changed
Output schema / $defs / Band / properties / area / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Band / properties / area_percent / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Band / properties / baseline_end / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Band / properties / baseline_start / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Band / properties / end / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Band / properties / height / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Band / properties / start / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Band / properties / x / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / BandMethod / properties / min_snr / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / BandMethod / properties / noise / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ChromatogramPeaks / properties / mz_window / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ChromatogramPeaks / properties / total_area / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / area / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / area_percent / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / baseline_end / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / baseline_start / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / end_min / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / height / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / rt_min / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / start_min / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Peak / properties / width_base_min / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PeakMethod / properties / min_snr / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PeakMethod / properties / noise / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PeakMethod / properties / rt_range_min / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PickedPeak / properties / expected_rt_min / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PickedPeak / properties / rt_window_min / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / area / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / area_no_baseline / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / baseline_end / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / baseline_start / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / from / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / max_height / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / max_value / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / max_x / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / peaks_area / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / to / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / x_first / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Region / properties / x_last / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SpectrumBands / properties / x_max / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SpectrumBands / properties / x_min / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Added
openreadout_plot - Changed
openreadout_preview101 fields changed- added
Input schema / $defs / AnnotationAdded value: +{ + "additionalProperties": false, + "description": "One annotation, in the coordinates the picture shows: full-resolution pixels on images (as on the rulers), axis units on plots (as on the tick labels), and on plate curve grids the time and value axes every card shares.", + "properties": { + "channel": { + "description": "Trace previews with several panels: the channel whose panel it goes in (default: the first panel).", + "type": "integer" + }, + "color": { + "description": "`accent` (default, warm red), `ink`, `muted`, `white`, another colour name or `#RRGGBB`.", + "type": "string" + }, + "facet": { + "description": "Plots with small multiples: the one small plot it goes in, by its title (e.g. `B3` or `sweep 6`; default: every one).", + "type": "string" + }, + "height": { + "description": "box: height.", + "type": "number" + }, + "label": { + "description": "Text drawn with the mark (the text itself for type text).", + "type": "string" + }, + "points": { + "description": "polygon, line: the vertices, `[[x, y], ...]`.", + "items": { + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "description": "What to draw. `point` = a dot at x, y (with its label beside it); `box` = a rectangle: corner x, y and width, height; `polygon` = a closed outline through points; `line` = an open line through points; `arrow` = an arrow from x, y (where the label goes) to x2, y2; `text` = the label alone, at x, y; `vline` = a vertical line at x; `hline` = a horizontal line at y; `vband` = a vertical band from x to x2; `hband` = a horizontal band from y to y2; `well` = a ring around a plate well (well; previews of plates only).", + "enum": [ + "point", + "box", + "polygon", + "line", + "arrow", + "text", + "vline", + "hline", + "vband", + "hband", + "well" + ], + "type": "string" + }, + "well": { + "description": "Plate previews: the well (e.g. `B3`) for type well, or the one card a mark goes in on a curve grid (default: every card).", + "type": "string" + }, + "width": { + "description": "box: width.", + "type": "number" + }, + "x": { + "description": "point, text: position; box: corner; arrow: tail; vline, vband: x (vband from x to x2).", + "type": "number" + }, + "x2": { + "description": "arrow: head; vband: other edge.", + "type": "number" + }, + "y": { + "description": "point, text: position; box: corner; arrow: tail; hline, hband: y (hband from y to y2).", + "type": "number" + }, + "y2": { + "description": "arrow: head; hband: other edge.", + "type": "number" + } + }, + "required": [ + "type" + ], + "type": "object" +} - added
Input schema / $defs / LadderRequestAdded value: +{ + "additionalProperties": false, + "description": "The marker lane and its sizes.", + "properties": { + "lane": { + "description": "Lane number of the marker (1 = leftmost).", + "type": "integer" + }, + "sizes": { + "description": "Marker sizes from the top of the lane down (largest first), e.g. kDa or bp.", + "items": { + "type": "number" + }, + "type": "array" + }, + "unit": { + "description": "Unit of the sizes, e.g. `kDa` or `bp`.", + "type": "string" + } + }, + "required": [ + "lane", + "sizes" + ], + "type": "object" +} - added
Input schema / $defs / LanesRequestAdded value: +{ + "additionalProperties": false, + "description": "How lanes and bands are found. Everything is optional.", + "properties": { + "count": { + "description": "Number of lanes. Default: found from the image.", + "type": "integer" + }, + "ladder": { + "$ref": "#/$defs/LadderRequest", + "description": "The marker lane and its sizes; bands then get sizes." + }, + "min_share": { + "description": "Bands lower than this share of the lane's highest band are dropped. Default 0.05.", + "type": "number" + }, + "polarity": { + "default": "auto", + "description": "Bright bands (fluorescence, chemiluminescence) or dark ones (stains). Default auto. `auto` = from the image: dark objects on a bright background (brightfield) or bright ones; `bright` = objects brighter than the background (fluorescence); `dark` = objects darker than the background (brightfield).", + "enum": [ + "auto", + "bright", + "dark" + ], + "type": "string" + }, + "profiles": { + "description": "Return each lane's profile (200 values from the top down). Default false.", + "type": "boolean" + }, + "width_px": { + "description": "Lane width in pixels. Default 0.7 lane pitches.", + "type": "number" + } + }, + "type": "object" +} - added
Input schema / $defs / ObjectsRequestAdded value: +{ + "additionalProperties": false, + "description": "How objects are found. Everything is optional; the defaults suit nuclei.", + "properties": { + "diameter_px": { + "description": "The same in pixels, for images without a pixel size.", + "type": "number" + }, + "diameter_um": { + "description": "Expected object diameter in µm. Default: measured from the image (spots: 0.5 µm).", + "type": "number" + }, + "kind": { + "default": "nuclei", + "description": "Default nuclei. `nuclei` = nuclei (default): touching nuclei are split; `cells` = whole cells stained throughout (larger; touching cells are split); `spots` = small bright spots (puncta, foci, single molecules), found by a Laplacian of Gaussian.", + "enum": [ + "nuclei", + "cells", + "spots" + ], + "type": "string" + }, + "max_area_um2": { + "description": "Largest object kept in µm². Default: no limit.", + "type": "number" + }, + "max_objects": { + "description": "Objects listed (in reading order). Default 100; the counts cover all.", + "type": "integer" + }, + "method": { + "default": "auto", + "description": "Default auto. `auto` = Otsu's, or the triangle method when objects are sparse; `otsu` = Otsu's (two classes of similar spread); `triangle` = the triangle method (a big background peak, few objects); `local` = each pixel against its neighbourhood (uneven staining).", + "enum": [ + "auto", + "otsu", + "triangle", + "local" + ], + "type": "string" + }, + "min_area_um2": { + "description": "Smallest object kept in µm². Default: a fifth of the expected area.", + "type": "number" + }, + "polarity": { + "default": "auto", + "description": "Default auto. `auto` = from the image: dark objects on a bright background (brightfield) or bright ones; `bright` = objects brighter than the background (fluorescence); `dark` = objects darker than the background (brightfield).", + "enum": [ + "auto", + "bright", + "dark" + ], + "type": "string" + }, + "split": { + "description": "Cut touching objects apart (seeded watershed). Default true.", + "type": "boolean" + }, + "stain": { + "default": "auto", + "description": "RGB images. Default auto. `auto` = hematoxylin for brightfield (stained tissue); for fluorescence, blue for nuclei when the blue component holds signal, else the brightest component; `hematoxylin` = the nuclear stain of H&E and IHC, by colour deconvolution; `eosin` = eosin, by colour deconvolution; `dab` = the brown IHC chromogen, by colour deconvolution; `red` = one component; `green` = one component; `blue` = one component; `luminance` = the mean of the components.", + "enum": [ + "auto", + "hematoxylin", + "eosin", + "dab", + "red", + "green", + "blue", + "luminance" + ], + "type": "string" + }, + "threshold": { + "description": "Threshold in raw units of what is measured (spots: the height above the local background). Default: chosen by `method`.", + "type": "number" + } + }, + "type": "object" +} - removed
Input schema / $defs / Region / properties / height / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / width / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / x / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / y / minimumRemoved value: -0 - added
Input schema / properties / annotationsAdded value: +{ + "description": "Your own marks, drawn on top and reported back with their pixel positions. Coordinates as the picture shows them: full-resolution pixels on images (the ruler numbers), axis units on plots, wells on plates.", + "items": { + "$ref": "#/$defs/Annotation" + }, + "type": "array" +} - changed
Input schema / properties / axes / descriptionPrevious value: -"Image previews: what frames the picture. What frames an image preview. `rulers` = coordinate rulers in full-resolution pixels and a scale bar around the picture (default); `grid` = rulers, plus faint grid lines over the data at the ruler ticks; `none` = the bare downsampled plane."New value: +"Image previews: what frames the picture. `rulers` = coordinate rulers in full-resolution pixels and a scale bar around the picture (default); `grid` = rulers, plus faint grid lines over the data at the ruler ticks; `scale-bar` = a figure for people: the picture with a scale bar, the title and the caption; no rulers; `none` = the bare downsampled plane." - changed
Input schema / properties / axes / enumPrevious value: -[ - "rulers", - "grid", - "none" -]New value: +[ + "rulers", + "grid", + "scale-bar", + "none" +] - added
Input schema / properties / captionAdded value: +{ + "description": "Image previews with axes scale-bar: a caption under the picture (what it shows, the stain, the sample).", + "type": "string" +} - removed
Input schema / properties / centroid / defaultRemoved value: -false - removed
Input schema / properties / channels / defaultRemoved value: -[] - removed
Input schema / properties / channels / items / minimumRemoved value: -0 - removed
Input schema / properties / columnRemoved value: -{ - "description": "Plate preview (long layout): value column name.", - "type": "string" -} - added
Input schema / properties / columnsAdded value: +{ + "description": "Table columns: a plate's value column, or the x and y parameters of a flow-cytometry density plot (one gives a histogram; default FSC-A, SSC-A).", + "items": { + "type": "string" + }, + "type": "array" +} - removed
Input schema / properties / composite / defaultRemoved value: -false - changed
Input schema / properties / contrast / descriptionPrevious value: -"`auto` (default), `min-max`, `percentile:LO,HI` (e.g. `percentile:1,99`) or `raw`."New value: +"`auto` (default; the file's display window when it has one, `log:90,99.95` on diffraction images), `min-max`, `percentile:LO,HI` (e.g. `percentile:1,99`), `log` (`log:50,99.9`) or `log:LO,HI`, `raw`, or a display window `window:CENTER,WIDTH` (`window:40,400`), `window:file`, or a CT preset `window:soft-tissue`, `brain`, `subdural`, `stroke`, `bone`, `lung`, `mediastinum`, `liver`." - added
Input schema / properties / darkAdded value: +{ + "description": "Draw in the dark theme.", + "type": "boolean" +} - added
Input schema / properties / fftAdded value: +{ + "description": "Images: a power-spectrum (FFT) inset in the top-right corner: Thon rings of a cryo-EM micrograph, the spots of a lattice.", + "type": "boolean" +} - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file."New value: +"Path to the file." - changed
Input schema / properties / format / descriptionPrevious value: -"Encoding. Default png (sent as JPEG when a PNG would be too large). Output encoding. `png` = lossless (default); `jpeg` = lossy and smaller."New value: +"Encoding. Default png (sent as JPEG when a PNG would be too large); svg also returns the vector drawing as text. `png` = lossless (default); `jpeg` = lossy and smaller; `svg` = vector: text stays text, image data is embedded as PNG." - changed
Input schema / properties / format / enumPrevious value: -[ - "png", - "jpeg" -]New value: +[ + "png", + "jpeg", + "svg" +] - removed
Input schema / properties / image / minimumRemoved value: -0 - added
Input schema / properties / lanesAdded value: +{ + "$ref": "#/$defs/LanesRequest", + "description": "Gels and blots: how lanes are found for `marks: lanes` (as `openreadout_stats` lanes)." +} - removed
Input schema / properties / level / minimumRemoved value: -0 - changed
Input schema / properties / lut / descriptionPrevious value: -"Colour lookup. Default: gray for one channel, channel colours for composites. Colour lookup for a single channel. `gray` = black to white; `channel-color` = black to the channel's colour."New value: +"Colour lookup. Default: gray for one channel (inverted on diffraction images), channel colours for composites. `gray` = black to white; `channel-color` = black to the channel's colour; `inverted` = white to black: dark marks on a light ground (diffraction images)." - changed
Input schema / properties / lut / enumPrevious value: -[ - "gray", - "channel-color" -]New value: +[ + "gray", + "channel-color", + "inverted" +] - added
Input schema / properties / marksAdded value: +{ + "description": "Marks from the data. Default auto: the prominent peaks of spectra and chromatograms are labelled; diffraction images get resolution rings. `auto` = label the largest peaks of spectra and chromatograms (default); `peaks` = label the largest peaks of any trace; `spikes` = mark the action potentials of current-clamp sweeps; `objects` = images: outline and number the nuclei, cells or spots found (`stats` objects); `lanes` = gels and blots: box and number the lanes, draw their profiles and bands (`stats` lanes); `rings` = diffraction images: resolution rings and the beam centre (auto draws them when the geometry is known); `none` = no marks.", + "enum": [ + "auto", + "peaks", + "spikes", + "objects", + "lanes", + "rings", + "none" + ], + "type": "string" +} - changed
Input schema / properties / max_size / descriptionPrevious value: -"Longest side in pixels, rulers included (default 768, max 2048)."New value: +"Longest side in pixels, rulers included (MCP: default 768, at most 2048)." - removed
Input schema / properties / max_size / minimumRemoved value: -0 - changed
Input schema / properties / mip / descriptionPrevious value: -"Maximum-intensity projection, over the selected range if any. Axis of a maximum-intensity projection. `z` = along z (focal planes); `t` = along t (time points)."New value: +"Maximum-intensity projection, over the selected range if any. `z` = along z (focal planes); `t` = along t (time points)." - added
Input schema / properties / objectsAdded value: +{ + "$ref": "#/$defs/ObjectsRequest", + "description": "Images: how objects are found for `marks: objects` (as `openreadout_stats` objects)." +} - removed
Input schema / properties / run / minimumRemoved value: -0 - removed
Input schema / properties / scan / minimumRemoved value: -0 - removed
Input schema / properties / select / defaultRemoved value: -[] - removed
Input schema / properties / spectrum / minimumRemoved value: -0 - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - added
Input schema / properties / sumAdded value: +{ + "description": "Sum projection, over the selected range if any: a movie's frames added up (e.g. sum t, select t=0-39). `z` = along z (focal planes); `t` = along t (time points).", + "enum": [ + "z", + "t" + ], + "type": "string" +} - removed
Input schema / properties / sweep / minimumRemoved value: -0 - changed
Input schema / properties / table / descriptionPrevious value: -"Plate preview: table index."New value: +"Plate or flow-cytometry preview: table index." - removed
Input schema / properties / table / minimumRemoved value: -0 - added
Input schema / properties / titleAdded value: +{ + "description": "Image previews with axes scale-bar: a title above the picture.", + "type": "string" +} - removed
Input schema / properties / trace / minimumRemoved value: -0 - added
Input schema / properties / viewAdded value: +{ + "description": "Volumes: the plane to show. `axial`, `coronal`, `sagittal` (radiological orientation), `orthogonal` (all three, crossing at the middle or the selected z), `xz`, `yz`, or `native` (as stored). Default: medical images in their acquisition plane, others native. With a view, `z` and `mip: z` count slices of that view. `native` = the planes as stored; `axial` = head-foot slices, patient's left on the right, anterior up; `coronal` = front-back slices, patient's left on the right, head up; `sagittal` = left-right slices, anterior on the left, head up; `orthogonal` = axial, coronal and sagittal planes through the volume's centre (or the selected z); `xz` = columns against z: a cut along the stack; `yz` = rows against z: a cut along the stack.", + "enum": [ + "native", + "axial", + "coronal", + "sagittal", + "orthogonal", + "xz", + "yz" + ], + "type": "string" +} - added
Input schema / properties / x_rangeAdded value: +{ + "description": "Trace preview: only this window of the x axis, `[a, b]` in its units (bp of a sized electropherogram, base positions of a Sanger read, minutes, ppm, …).", + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" +} - added
Output schema / $defs / AnnotationTypeAdded value: +{ + "description": "What an annotation draws.", + "oneOf": [ + { + "const": "point", + "description": "a dot at x, y (with its label beside it)", + "type": "string" + }, + { + "const": "box", + "description": "a rectangle: corner x, y and width, height", + "type": "string" + }, + { + "const": "polygon", + "description": "a closed outline through points", + "type": "string" + }, + { + "const": "line", + "description": "an open line through points", + "type": "string" + }, + { + "const": "arrow", + "description": "an arrow from x, y (where the label goes) to x2, y2", + "type": "string" + }, + { + "const": "text", + "description": "the label alone, at x, y", + "type": "string" + }, + { + "const": "vline", + "description": "a vertical line at x", + "type": "string" + }, + { + "const": "hline", + "description": "a horizontal line at y", + "type": "string" + }, + { + "const": "vband", + "description": "a vertical band from x to x2", + "type": "string" + }, + { + "const": "hband", + "description": "a horizontal band from y to y2", + "type": "string" + }, + { + "const": "well", + "description": "a ring around a plate well (well; previews of plates only)", + "type": "string" + } + ] +} - added
Output schema / $defs / ChromatogramPreviewAdded value: +{ + "description": "Details of a chromatogram preview of a mass-spectrometry run (its first look).", + "properties": { + "apex_intensity": { + "description": "Its intensity.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "apex_rt_min": { + "description": "Retention time of the tallest point, minutes.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "ms1_scans": { + "description": "MS1 scans drawn.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "run": { + "description": "Run index.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "scans": { + "description": "Scans in the run (all MS levels).", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "signal": { + "description": "`tic` (the total ion current each scan header records) or `bpc` (base-peak intensity).", + "type": "string" + } + }, + "required": [ + "run", + "signal", + "ms1_scans", + "scans", + "apex_rt_min", + "apex_intensity" + ], + "type": "object" +} - added
Output schema / $defs / DataMarkAdded value: +{ + "description": "A mark drawn from the data: a labelled peak or a detected action potential.", + "properties": { + "channel": { + "description": "Trace previews: the channel.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "kind": { + "description": "`peak`, `spike`, `resolution_ring` (x: resolution in Å, y: radius in full-resolution\npixels) or `beam_center` (x, y: full-resolution pixels).", + "type": "string" + }, + "label": { + "description": "The label drawn (e.g. the m/z or ppm), if any.", + "type": [ + "string", + "null" + ] + }, + "x": { + "description": "Position along the x axis, in its unit.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "y": { + "description": "Value there, in the panel's unit.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "kind", + "x", + "y" + ], + "type": "object" +} - added
Output schema / $defs / DrawnAnnotationAdded value: +{ + "description": "An annotation as drawn: the request, plus where it landed in PNG pixels.", + "properties": { + "channel": { + "description": "Trace previews with several panels: the channel whose panel it goes in (default: the\nfirst panel).", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "color": { + "description": "`accent` (default, warm red), `ink`, `muted`, `white`, another colour name or `#RRGGBB`.", + "type": [ + "string", + "null" + ] + }, + "drawn_color": { + "description": "The colour drawn, `#RRGGBB`.", + "type": "string" + }, + "facet": { + "description": "Plots with small multiples: the one small plot it goes in, by its title (e.g. `B3` or\n`sweep 6`; default: every one).", + "type": [ + "string", + "null" + ] + }, + "height": { + "description": "box: height.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "label": { + "description": "Text drawn with the mark (the text itself for type text).", + "type": [ + "string", + "null" + ] + }, + "label_px": { + "anyOf": [ + { + "$ref": "#/$defs/PxRect" + }, + { + "type": "null" + } + ], + "description": "Where the label went, in PNG pixels." + }, + "outside": { + "description": "True when part of the mark lies outside what the picture shows (it is clipped).", + "type": "boolean" + }, + "points": { + "description": "polygon, line: the vertices, `[[x, y], ...]`.", + "items": { + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "px": { + "description": "The mark's key points in PNG pixels: the point, the box corners, the vertices, the\narrow's tail and head, a line's or band's ends (one pair per card on a curve grid).", + "items": { + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "$ref": "#/$defs/AnnotationType", + "description": "What to draw." + }, + "well": { + "description": "Plate previews: the well (e.g. `B3`) for type well, or the one card a mark goes in on a\ncurve grid (default: every card).", + "type": [ + "string", + "null" + ] + }, + "width": { + "description": "box: width.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "x": { + "description": "point, text: position; box: corner; arrow: tail; vline, vband: x (vband from x to x2).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "x2": { + "description": "arrow: head; vband: other edge.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "y": { + "description": "point, text: position; box: corner; arrow: tail; hline, hband: y (hband from y to y2).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "y2": { + "description": "arrow: head; hband: other edge.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "type", + "drawn_color", + "px" + ], + "type": "object" +} - added
Output schema / $defs / EventsPreviewAdded value: +{ + "description": "Details of an event (flow cytometry) preview.", + "properties": { + "events": { + "description": "Events drawn.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "scales": { + "description": "`linear` or `asinh` (each axis, x first).", + "items": { + "type": "string" + }, + "type": "array" + }, + "table": { + "description": "Table index.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "total_events": { + "description": "Events in the table.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "x": { + "description": "Parameter on the x axis.", + "type": "string" + }, + "y": { + "description": "Parameter on the y axis (absent for a histogram).", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "table", + "x", + "events", + "total_events", + "scales" + ], + "type": "object" +} - added
Output schema / $defs / ImagePreview / properties / crosshairAdded value: +{ + "description": "Orthogonal views: the voxel (x, y, z of the stored planes) the three planes cross at.", + "items": { + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "maxItems": 3, + "minItems": 3, + "type": [ + "array", + "null" + ] +} - changed
Output schema / $defs / ImagePreview / properties / downsample / descriptionPrevious value: -"Block size of the averaging downsample (1 = none)."New value: +"Pixels of the plane at `level` per drawn pixel, horizontally: above 1 when the plane was\nmade smaller (an area average), below 1 when it was enlarged (each source pixel drawn as\na square), 1 when drawn as is." - changed
Output schema / $defs / ImagePreview / properties / downsample / formatPrevious value: -"uint32"New value: +"double" - removed
Output schema / $defs / ImagePreview / properties / downsample / minimumRemoved value: -0 - changed
Output schema / $defs / ImagePreview / properties / downsample / typePrevious value: -"integer"New value: +[ + "number", + "null" +] - added
Output schema / $defs / ImagePreview / properties / fft_insetAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/Region" + }, + { + "type": "null" + } + ], + "description": "Where the power-spectrum inset is drawn (`fft`), in PNG pixels." +} - changed
Output schema / $defs / ImagePreview / properties / lut / descriptionPrevious value: -"`gray`, `channel-color` or `rgb`."New value: +"`gray`, `inverted`, `channel-color` or `rgb`." - changed
Output schema / $defs / ImagePreview / properties / projection / descriptionPrevious value: -"`max-z` or `max-t` for a maximum-intensity projection."New value: +"`max-z` or `max-t` for a maximum-intensity projection, `sum-z` or `sum-t` for a sum." - changed
Output schema / $defs / ImagePreview / properties / source_per_pixel / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ImagePreview / properties / source_per_pixel_y / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / $defs / ImagePreview / properties / viewAdded value: +{ + "description": "The plane of the volume shown, when it is not the stored planes: `axial`, `coronal`,\n`sagittal`, `orthogonal`, `xz` or `yz`. Rulers, regions and annotations then count the\npixels of that view.", + "type": [ + "string", + "null" + ] +} - added
Output schema / $defs / ImagePreview / properties / view_slicesAdded value: +{ + "description": "With a view: how many slices it has (the range of `z`).", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] +} - changed
Output schema / $defs / ImagePreview / requiredPrevious value: -[ - "image", - "level", - "source_width", - "source_height", - "downsample", - "c", - "z", - "t", - "composite", - "rgb", - "contrast", - "lut", - "channels" -]New value: +[ + "image", + "level", + "source_width", + "source_height", + "downsample", + "c", + "z", + "t", + "composite", + "rgb", + "contrast", + "lut", + "channels", + "axes", + "plot_area", + "source_origin", + "source_per_pixel", + "source_per_pixel_y", + "full_res_region" +] - added
Output schema / $defs / PlateGroupAdded value: +{ + "description": "One layout group of a plate preview (a SoftMax Pro group, a sample name, …).", + "properties": { + "blank": { + "description": "True for blank wells (drawn faint).", + "type": "boolean" + }, + "color": { + "description": "Colour it is drawn in, `#RRGGBB`.", + "type": "string" + }, + "name": { + "description": "Group name as the file records it.", + "type": "string" + }, + "wells": { + "description": "Wells in the group.", + "format": "uint32", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "name", + "color", + "wells" + ], + "type": "object" +} - changed
Output schema / $defs / PlatePreview / descriptionPrevious value: -"Details of a plate heat map."New value: +"Details of a plate preview." - added
Output schema / $defs / PlatePreview / properties / grouped_byAdded value: +{ + "description": "The layout field the colours follow (e.g. `SoftMax group`).", + "type": [ + "string", + "null" + ] +} - added
Output schema / $defs / PlatePreview / properties / groupsAdded value: +{ + "description": "The groups, in the order of the key.", + "items": { + "$ref": "#/$defs/PlateGroup" + }, + "type": "array" +} - changed
Output schema / $defs / PlatePreview / properties / max / descriptionPrevious value: -"Value shown at the yellow end of the scale."New value: +"Heat map: value at the dark end of the colour scale; curves: top of every card's y axis." - changed
Output schema / $defs / PlatePreview / properties / min / descriptionPrevious value: -"Colour-scale ends (dark = min, yellow = max)."New value: +"Heat map: value at the light end of the colour scale; curves: bottom of every card's y\naxis." - added
Output schema / $defs / PlatePreview / properties / timeAdded value: +{ + "description": "Curves: the time axis every card shares, in `time_unit`.", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": [ + "array", + "null" + ] +} - added
Output schema / $defs / PlatePreview / properties / time_unitAdded value: +{ + "description": "Curves: `s`, `min` or `h`.", + "type": [ + "string", + "null" + ] +} - added
Output schema / $defs / PlatePreview / properties / viewAdded value: +{ + "description": "`heatmap` (one value per well) or `curves` (a kinetic read, one small plot per well).", + "type": "string" +} - changed
Output schema / $defs / PlatePreview / requiredPrevious value: -[ - "table", - "layout", - "rows", - "columns", - "wells", - "value" -]New value: +[ + "table", + "layout", + "view", + "rows", + "columns", + "wells", + "value" +] - added
Output schema / $defs / PlotPanelAdded value: +{ + "description": "One plot panel inside the picture, for mapping PNG pixels to data values and back: the\nvalue at the panel's left edge is `x[0]`, at its right edge `x[1]`, at its bottom `y[0]`\nand at its top `y[1]`, along the scale named in `x_scale` / `y_scale`.", + "properties": { + "channel": { + "description": "Trace previews: the channel drawn in this panel.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "plot_area": { + "$ref": "#/$defs/PxRect", + "description": "The panel's rectangle in PNG pixels." + }, + "well": { + "description": "Plate curve previews: the well of this card.", + "type": [ + "string", + "null" + ] + }, + "x": { + "description": "Values at the left and right edges.", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "x_scale": { + "description": "`linear`, `log` or `asinh`.", + "type": "string" + }, + "y": { + "description": "Values at the bottom and top edges.", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "y_scale": { + "description": "`linear`, `log` or `asinh`.", + "type": "string" + } + }, + "required": [ + "plot_area", + "x", + "y", + "x_scale", + "y_scale" + ], + "type": "object" +} - changed
Output schema / $defs / PreviewChannel / properties / display_max / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / PreviewChannel / properties / display_min / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / $defs / PxRectAdded value: +{ + "description": "A rectangle in PNG pixels (fractional).", + "properties": { + "height": { + "description": "Height.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "width": { + "description": "Width.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "x": { + "description": "Left edge.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "y": { + "description": "Top edge.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "x", + "y", + "width", + "height" + ], + "type": "object" +} - changed
Output schema / $defs / ScaleBar / properties / length / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ScaleBar / properties / length_um / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SourcePoint / properties / x / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SourcePoint / properties / y / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SpectrumPreview / properties / max_intensity / descriptionPrevious value: -"Largest intensity (the top of the plot)."New value: +"Largest intensity." - changed
Output schema / $defs / SpectrumPreview / requiredPrevious value: -[ - "run", - "index", - "scan_number", - "ms_level", - "style", - "point_count", - "x_axis" -]New value: +[ + "run", + "index", + "scan_number", + "ms_level", + "rt_s", + "style", + "point_count", + "x_axis" +] - changed
Output schema / $defs / TracePreview / properties / channels / descriptionPrevious value: -"One panel per channel, top to bottom."New value: +"One panel per channel, top to bottom (one shared panel for overlays)." - changed
Output schema / $defs / TracePreview / properties / sample_rate_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / TracePreviewChannel / properties / min / descriptionPrevious value: -"Bottom and top of the panel's y axis (the channel's finite range, padded by 5 %)."New value: +"Bottom of the panel's y axis." - changed
Output schema / $defs / XAxis / descriptionPrevious value: -"The horizontal axis of a trace or spectrum preview (the labels at its two ends)."New value: +"The horizontal axis of a trace or spectrum preview." - changed
Output schema / $defs / XAxis / properties / first / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / XAxis / properties / last / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / annotationsAdded value: +{ + "description": "The caller's annotations as drawn: each as given, plus where it landed in PNG pixels.", + "items": { + "$ref": "#/$defs/DrawnAnnotation" + }, + "type": "array" +} - added
Output schema / properties / chromatogramAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/ChromatogramPreview" + }, + { + "type": "null" + } + ], + "description": "Present for chromatogram previews (a mass-spectrometry run's total-ion chromatogram)." +} - changed
Output schema / properties / encoding / descriptionPrevious value: -"`png` or `jpeg`."New value: +"`png`, `jpeg` or `svg`." - added
Output schema / properties / eventsAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/EventsPreview" + }, + { + "type": "null" + } + ], + "description": "Present for event previews." +} - changed
Output schema / properties / kind / descriptionPrevious value: -"`image`, `trace`, `spectrum` or `plate`."New value: +"`image`, `trace`, `chromatogram`, `spectrum`, `plate` or `events`." - added
Output schema / properties / lanesAdded value: +{ + "additionalProperties": true, + "description": "`marks: lanes`: the lanes and bands found in the area shown, as `stats` lanes.", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / marksAdded value: +{ + "description": "Marks drawn from the data (labelled peaks, action potentials).", + "items": { + "$ref": "#/$defs/DataMark" + }, + "type": "array" +} - added
Output schema / properties / objectsAdded value: +{ + "additionalProperties": true, + "description": "`marks: objects`: the objects counted in the area shown, as `stats` objects (the first\n20 listed).", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / panelsAdded value: +{ + "description": "Plot panels (traces, spectra, plate curves, events): where each sits in the picture and\nthe data range it shows.", + "items": { + "$ref": "#/$defs/PlotPanel" + }, + "type": "array" +} - added
Output schema / properties / saveAdded value: +{ + "description": "How to save this picture to a file (MCP: the openreadout_export call).", + "type": [ + "string", + "null" + ] +}
- Changed
openreadout_qpcr25 fields changed- removed
Input schema / properties / baseline_end / minimumRemoved value: -0 - removed
Input schema / properties / baseline_start / minimumRemoved value: -0 - removed
Input schema / properties / compute_cq / defaultRemoved value: -false - changed
Input schema / properties / cq_method / descriptionPrevious value: -"How `compute_cq` computes Cq; default: `second-derivative` for LightCycler 480 `.ixo` files without a threshold or baseline window, else `threshold`. How our Cq is computed (none of the methods reads the vendor's Cq or call). `threshold` = Where the baseline-corrected curve crosses a threshold; `stored-threshold` = A threshold crossing with only the threshold and baseline the file stores; `second-derivative` = The maximum of the second derivative, as the LightCycler 480 places its Cp."New value: +"How `compute_cq` computes Cq; default: `second-derivative` for LightCycler 480 `.ixo` files without a threshold or baseline window, else `threshold`. `threshold` = Where the baseline-corrected curve crosses a threshold; `stored-threshold` = A threshold crossing with only the threshold and baseline the file stores; `second-derivative` = The maximum of the second derivative, as the LightCycler 480 places its Cp." - removed
Input schema / properties / ddcq / defaultRemoved value: -false - added
Input schema / properties / fieldsAdded value: +{ + "description": "Rows show their main fields to 4 significant digits (records: well, sample, target, cq, tm; relative_quantities: cq means, delta_cq, delta_delta_cq, rq with rq_min and rq_max). fields adds others, e.g. `[\"threshold\"]`; `[\"all\"]`: every field, full precision.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory." - removed
Input schema / properties / max_records / minimumRemoved value: -0 - removed
Input schema / properties / reference_targets / defaultRemoved value: -[] - removed
Input schema / properties / standard_curve / defaultRemoved value: -false - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - changed
Output schema / $defs / CqComparison / requiredPrevious value: -[ - "cq_method", - "method", - "curves", - "both_cq", - "both_undetermined", - "only_vendor", - "only_ours", - "vendor_threshold_used" -]New value: +[ + "cq_method", + "method", + "curves", + "both_cq", + "both_undetermined", + "only_vendor", + "only_ours", + "vendor_threshold_used", + "mean_difference", + "mean_abs_difference", + "median_abs_difference", + "max_abs_difference", + "within_0_1", + "within_0_5", + "pearson_r" +] - changed
Output schema / $defs / QpcrAssayRecord / properties / tm / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - removed
Output schema / $defs / QpcrAssayRecord / requiredRemoved value: -[ - "run", - "well", - "row", - "col", - "cq_undetermined", - "cq_status", - "tm", - "flags", - "cycles" -] - changed
Output schema / $defs / RelativeQuantity / properties / cq_mean / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / RelativeQuantity / properties / delta_cq / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / RelativeQuantity / properties / reference_cq_mean / typePrevious value: -"number"New value: +[ + "number", + "null" +] - removed
Output schema / $defs / RelativeQuantity / requiredRemoved value: -[ - "sample", - "target", - "replicates", - "undetermined", - "cq_mean", - "reference_cq_mean", - "delta_cq" -] - changed
Output schema / $defs / StandardCurveFit / properties / efficiency_percent / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / StandardCurveFit / properties / intercept / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / StandardCurveFit / properties / r2 / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / StandardCurveFit / properties / slope / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / StandardCurveFit / requiredPrevious value: -[ - "target", - "points", - "levels", - "slope", - "intercept", - "r2", - "efficiency_percent" -]New value: +[ + "target", + "points", + "levels", + "slope", + "intercept", + "r2", + "efficiency_percent", + "vendor_slope", + "vendor_efficiency_percent", + "vendor_r2" +] - changed
Output schema / $defs / TargetCqSummary / requiredPrevious value: -[ - "target", - "counts", - "averaged" -]New value: +[ + "target", + "counts", + "averaged", + "cq_mean", + "cq_sd", + "cq_min", + "cq_max" +] - changed
Output schema / requiredPrevious value: -[ - "path", - "format", - "dialect", - "reference_targets", - "record_count", - "truncated", - "records", - "cq_counts", - "targets", - "relative_quantities", - "standard_curves", - "notes" -]New value: +[ + "path", + "format", + "dialect", + "reference_targets", + "record_count", + "truncated", + "records", + "cq_counts", + "targets", + "notes" +]
- Changed
openreadout_report1 field changed- removed
Input schema / properties / include_text / defaultRemoved value: -false
- Changed
openreadout_scans13 fields changed- removed
Input schema / properties / count / defaultRemoved value: -false - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the mass-spectrometry file."New value: +"Path to the mass-spectrometry file." - removed
Input schema / properties / limit / minimumRemoved value: -0 - removed
Input schema / properties / ms_level / minimumRemoved value: -0 - removed
Input schema / properties / offset / defaultRemoved value: -0 - removed
Input schema / properties / offset / minimumRemoved value: -0 - removed
Input schema / properties / run / defaultRemoved value: -0 - removed
Input schema / properties / run / minimumRemoved value: -0 - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - changed
Output schema / $defs / ScanHeader / properties / isolation_window_mz / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ScanHeader / properties / scan_window_mz / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ScanHeader / requiredPrevious value: -[ - "index", - "scan_number", - "ms_level", - "polarity", - "centroided" -]New value: +[ + "index", + "scan_number", + "ms_level", + "rt_s", + "polarity", + "centroided" +] - changed
Output schema / properties / rt_range_s / items / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Changed
openreadout_search3 fields changed- removed
Input schema / properties / fields / defaultRemoved value: -[] - removed
Input schema / properties / limit / minimumRemoved value: -0 - removed
Input schema / properties / query / defaultRemoved value: -""
- Changed
openreadout_spectrum20 fields changed- removed
Input schema / properties / centroid / defaultRemoved value: -false - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the mass-spectrometry file."New value: +"Path to the mass-spectrometry file." - changed
Input schema / properties / max_points / descriptionPrevious value: -"At most this many points (default 2000; point_count reports the full size)."New value: +"At most this many points, the most intense kept (default 1000; point_count reports the full size)." - removed
Input schema / properties / max_points / minimumRemoved value: -0 - removed
Input schema / properties / ms_level / minimumRemoved value: -0 - added
Input schema / properties / rtAdded value: +{ + "description": "The MS scan (of ms_level, default 1) nearest this retention time, minutes: the spectrum at a chromatogram's apex.", + "type": "number" +} - removed
Input schema / properties / run / defaultRemoved value: -0 - removed
Input schema / properties / run / minimumRemoved value: -0 - removed
Input schema / properties / scan / minimumRemoved value: -0 - removed
Input schema / properties / spectrum / minimumRemoved value: -0 - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - added
Input schema / properties / top_peaksAdded value: +{ + "description": "Most intense peaks listed under peaks[] with charge and neutral mass (default 20).", + "type": "integer" +} - added
Output schema / $defs / MsPeakAdded value: +{ + "description": "One of the most intense peaks of a mass spectrum, with its charge from the isotope pattern.", + "properties": { + "charge": { + "description": "Charge from the spacing of the isotope peaks above it (1.00336/z), when at least one\nis found.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "intensity": { + "description": "Intensity.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "isotopes": { + "description": "Isotope peaks found in a row above this one at that spacing.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "monoisotopic_mz": { + "description": "m/z of the lowest peak of the same isotope pattern (the monoisotopic ion when it is\nseen), when it is below this one.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "mz": { + "description": "m/z.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "neutral_mass_da": { + "description": "Neutral monoisotopic mass (z · (m/z ∓ proton)), Da, when the charge and polarity are\nknown.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "mz", + "intensity" + ], + "type": "object" +} - changed
Output schema / $defs / Spectrum / properties / intensity / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spectrum / properties / isolation_window_mz / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spectrum / properties / mz / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spectrum / properties / scan_window_mz / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Spectrum / requiredPrevious value: -[ - "index", - "scan_number", - "ms_level", - "polarity", - "centroided", - "mz", - "intensity" -]New value: +[ + "index", + "scan_number", + "ms_level", + "rt_s", + "polarity", + "centroided", + "mz", + "intensity" +] - added
Output schema / properties / peaksAdded value: +{ + "description": "The most intense peaks of the whole spectrum, with charges from their isotope patterns.", + "items": { + "$ref": "#/$defs/MsPeak" + }, + "type": "array" +} - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when `mz`/`intensity` were shortened to `max_points`."New value: +"True when `mz`/`intensity` were shortened to `max_points` (the most intense points are\nkept, in m/z order)."
- Changed
openreadout_spikes20 fields changed- removed
Input schema / properties / channels / defaultRemoved value: -[] - removed
Input schema / properties / channels / items / minimumRemoved value: -0 - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory." - removed
Input schema / properties / max_times / minimumRemoved value: -0 - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / sweeps / items / minimumRemoved value: -0 - removed
Input schema / properties / trace / defaultRemoved value: -0 - removed
Input schema / properties / trace / minimumRemoved value: -0 - changed
Output schema / $defs / ChannelSpikes / properties / duration_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ChannelSpikes / properties / noise / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ChannelSpikes / properties / rate_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ChannelSpikes / properties / threshold / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / ChannelSpikes / requiredPrevious value: -[ - "channel", - "name", - "noise", - "threshold", - "spike_count", - "rate_hz", - "duration_s", - "times", - "times_truncated" -]New value: +[ + "channel", + "name", + "unit", + "noise", + "threshold", + "spike_count", + "rate_hz", + "duration_s", + "times", + "times_truncated" +] - changed
Output schema / $defs / DetectSettings / properties / exclude_ms / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / DetectSettings / properties / high_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / DetectSettings / properties / low_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / DetectSettings / properties / threshold / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SpikeTime / properties / amplitude / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SpikeTime / properties / time_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / sample_rate_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Changed
openreadout_stats46 fields changed- added
Input schema / $defs / LadderRequestAdded value: +{ + "additionalProperties": false, + "description": "The marker lane and its sizes.", + "properties": { + "lane": { + "description": "Lane number of the marker (1 = leftmost).", + "type": "integer" + }, + "sizes": { + "description": "Marker sizes from the top of the lane down (largest first), e.g. kDa or bp.", + "items": { + "type": "number" + }, + "type": "array" + }, + "unit": { + "description": "Unit of the sizes, e.g. `kDa` or `bp`.", + "type": "string" + } + }, + "required": [ + "lane", + "sizes" + ], + "type": "object" +} - added
Input schema / $defs / LanesRequestAdded value: +{ + "additionalProperties": false, + "description": "How lanes and bands are found. Everything is optional.", + "properties": { + "count": { + "description": "Number of lanes. Default: found from the image.", + "type": "integer" + }, + "ladder": { + "$ref": "#/$defs/LadderRequest", + "description": "The marker lane and its sizes; bands then get sizes." + }, + "min_share": { + "description": "Bands lower than this share of the lane's highest band are dropped. Default 0.05.", + "type": "number" + }, + "polarity": { + "default": "auto", + "description": "Bright bands (fluorescence, chemiluminescence) or dark ones (stains). Default auto. `auto` = from the image: dark objects on a bright background (brightfield) or bright ones; `bright` = objects brighter than the background (fluorescence); `dark` = objects darker than the background (brightfield).", + "enum": [ + "auto", + "bright", + "dark" + ], + "type": "string" + }, + "profiles": { + "description": "Return each lane's profile (200 values from the top down). Default false.", + "type": "boolean" + }, + "width_px": { + "description": "Lane width in pixels. Default 0.7 lane pitches.", + "type": "number" + } + }, + "type": "object" +} - added
Input schema / $defs / ObjectsRequestAdded value: +{ + "additionalProperties": false, + "description": "How objects are found. Everything is optional; the defaults suit nuclei.", + "properties": { + "diameter_px": { + "description": "The same in pixels, for images without a pixel size.", + "type": "number" + }, + "diameter_um": { + "description": "Expected object diameter in µm. Default: measured from the image (spots: 0.5 µm).", + "type": "number" + }, + "kind": { + "default": "nuclei", + "description": "Default nuclei. `nuclei` = nuclei (default): touching nuclei are split; `cells` = whole cells stained throughout (larger; touching cells are split); `spots` = small bright spots (puncta, foci, single molecules), found by a Laplacian of Gaussian.", + "enum": [ + "nuclei", + "cells", + "spots" + ], + "type": "string" + }, + "max_area_um2": { + "description": "Largest object kept in µm². Default: no limit.", + "type": "number" + }, + "max_objects": { + "description": "Objects listed (in reading order). Default 100; the counts cover all.", + "type": "integer" + }, + "method": { + "default": "auto", + "description": "Default auto. `auto` = Otsu's, or the triangle method when objects are sparse; `otsu` = Otsu's (two classes of similar spread); `triangle` = the triangle method (a big background peak, few objects); `local` = each pixel against its neighbourhood (uneven staining).", + "enum": [ + "auto", + "otsu", + "triangle", + "local" + ], + "type": "string" + }, + "min_area_um2": { + "description": "Smallest object kept in µm². Default: a fifth of the expected area.", + "type": "number" + }, + "polarity": { + "default": "auto", + "description": "Default auto. `auto` = from the image: dark objects on a bright background (brightfield) or bright ones; `bright` = objects brighter than the background (fluorescence); `dark` = objects darker than the background (brightfield).", + "enum": [ + "auto", + "bright", + "dark" + ], + "type": "string" + }, + "split": { + "description": "Cut touching objects apart (seeded watershed). Default true.", + "type": "boolean" + }, + "stain": { + "default": "auto", + "description": "RGB images. Default auto. `auto` = hematoxylin for brightfield (stained tissue); for fluorescence, blue for nuclei when the blue component holds signal, else the brightest component; `hematoxylin` = the nuclear stain of H&E and IHC, by colour deconvolution; `eosin` = eosin, by colour deconvolution; `dab` = the brown IHC chromogen, by colour deconvolution; `red` = one component; `green` = one component; `blue` = one component; `luminance` = the mean of the components.", + "enum": [ + "auto", + "hematoxylin", + "eosin", + "dab", + "red", + "green", + "blue", + "luminance" + ], + "type": "string" + }, + "threshold": { + "description": "Threshold in raw units of what is measured (spots: the height above the local background). Default: chosen by `method`.", + "type": "number" + } + }, + "type": "object" +} - removed
Input schema / $defs / Region / properties / height / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / width / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / x / minimumRemoved value: -0 - removed
Input schema / $defs / Region / properties / y / minimumRemoved value: -0 - removed
Input schema / properties / bins / minimumRemoved value: -0 - removed
Input schema / properties / image / minimumRemoved value: -0 - added
Input schema / properties / lanesAdded value: +{ + "$ref": "#/$defs/LanesRequest", + "description": "Lanes and bands of a gel or blot in `region` or the whole plane: each lane's total and each band's row and background-subtracted volume (with `ladder`, its size). `{}` finds the lanes; preview marks=lanes draws them." +} - removed
Input schema / properties / level / defaultRemoved value: -0 - removed
Input schema / properties / level / minimumRemoved value: -0 - added
Input schema / properties / lineAdded value: +{ + "description": "Intensity profile along the line `[x0, y0, x1, y1]` (pixels of `level`, as on the preview rulers): values per channel, peak position and FWHM in px and µm.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" +} - added
Input schema / properties / line_widthAdded value: +{ + "description": "Profile width in pixels, averaged across the line. Default 1.", + "type": "integer" +} - changed
Input schema / properties / mip / descriptionPrevious value: -"Maximum-intensity projection first: `z` (per image, channel and time point: the largest value of each pixel over the selected z planes) or `t`; the statistics are of the projections. The axis of a maximum-intensity projection (`stats --mip z`). `z` = Along z: one projected plane per image, channel and time point; `t` = Along t: one projected plane per image, channel and z."New value: +"Maximum-intensity projection first: `z` (per image, channel and time point: the largest value of each pixel over the selected z planes) or `t`; the statistics are of the projections. `z` = Along z: one projected plane per image, channel and time point; `t` = Along t: one projected plane per image, channel and z." - added
Input schema / properties / objectsAdded value: +{ + "$ref": "#/$defs/ObjectsRequest", + "description": "Count objects in `region`, `polygon` or the whole plane: count, density, sizes, centroids, each object's mean in every channel and how many are positive per channel. `{}` counts nuclei with settings taken from the image (size, threshold, H&E colour deconvolution). Found in a DNA-stain channel unless `select` names one." +} - added
Input schema / properties / polygonAdded value: +{ + "description": "Statistics inside this polygon `[[x, y], ...]` (pixels of `level`): area, mean, std, median, sum per channel.", + "items": { + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "type": "array" +} - changed
Input schema / properties / scale / descriptionPrevious value: -"Histogram spacing: `linear` (default) or `log`. Spacing of histogram bin edges. `linear` = Equal-width bins from `min` to `max` (integer data: to `max + 1`, so each bin holds whole values); `log` = Geometrically spaced bins from the smallest positive value to `max`; values ≤ 0 are counted in `nonpositive`. Suited to data spanning decades (photon counts, spectra)."New value: +"Histogram spacing: `linear` (default) or `log`. `linear` = Equal-width bins from `min` to `max` (integer data: to `max + 1`, so each bin holds whole values); `log` = Geometrically spaced bins from the smallest positive value to `max`; values ≤ 0 are counted in `nonpositive`. Suited to data spanning decades (photon counts, spectra)." - removed
Input schema / properties / select / defaultRemoved value: -[] - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / wells / defaultRemoved value: -[] - added
Output schema / $defs / BandAdded value: +{ + "description": "One band.", + "properties": { + "fraction_of_lane": { + "description": "Share of the lane's band volume.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "height": { + "description": "Height of the maximum above the background, in stored units.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "number": { + "description": "Band number in its lane, from the top.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "relative": { + "description": "Volume relative to the strongest band of the image (1 = the strongest band).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "saturated_px": { + "description": "Pixels of the band at the saturation level: its volume is a lower bound.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "size": { + "description": "Size from the ladder, in its unit.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "volume": { + "description": "Background-subtracted volume: stored units × pixels.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "y": { + "description": "Row of the band's maximum (full-resolution pixels).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "y_range": { + "description": "First and last row of the band.", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "number", + "y", + "y_range", + "height", + "volume", + "fraction_of_lane", + "relative" + ], + "type": "object" +} - added
Output schema / $defs / CountConfidenceAdded value: +{ + "description": "How far a count can be trusted.", + "oneOf": [ + { + "const": "high", + "description": "the objects look like what was asked for", + "type": "string" + }, + { + "const": "low", + "description": "many objects are irregular or of the wrong size: check a picture before quoting the count", + "type": "string" + } + ] +} - changed
Output schema / $defs / Histogram / properties / edges / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / $defs / KindAdded value: +{ + "description": "What to count.", + "oneOf": [ + { + "const": "nuclei", + "description": "nuclei (default): touching nuclei are split", + "type": "string" + }, + { + "const": "cells", + "description": "whole cells stained throughout (larger; touching cells are split)", + "type": "string" + }, + { + "const": "spots", + "description": "small bright spots (puncta, foci, single molecules), found by a Laplacian of Gaussian", + "type": "string" + } + ] +} - added
Output schema / $defs / LaneAdded value: +{ + "description": "One lane.", + "properties": { + "background": { + "description": "Its background, at the same rows.", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "type": "array" + }, + "band_volume": { + "description": "Sum of the band volumes.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "bands": { + "description": "The bands, top first.", + "items": { + "$ref": "#/$defs/Band" + }, + "type": "array" + }, + "empty": { + "description": "True when no band was found (or the lane was placed in a gap between found lanes).", + "type": "boolean" + }, + "number": { + "description": "Lane number, 1 = leftmost.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "profile": { + "description": "The profile from the top down, `profile_step_px` apart (with `profiles: true`).", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "type": "array" + }, + "total_volume": { + "description": "Background-subtracted volume of the whole lane (stored units × pixels): the total\nsignal, e.g. for normalising to a total-protein stain.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "x": { + "description": "Centre column (full-resolution pixels).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "x_range": { + "description": "Left and right edges.", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "number", + "x", + "x_range", + "total_volume", + "band_volume", + "bands" + ], + "type": "object" +} - added
Output schema / $defs / LanesAdded value: +{ + "description": "Lanes and bands of one plane.", + "properties": { + "band_count": { + "description": "Bands found over all lanes.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "bin": { + "description": "Full-resolution pixels per analysed pixel (1 unless the plane was binned).", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "c": { + "description": "The channel measured.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "count": { + "description": "Lanes found.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "lane_contrast": { + "description": "How far the lanes stand out from the gaps between them: 1 − gap signal / lane signal of\nthe column profile (0 = not at all; below 0.15 the lanes are a guess).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "lanes": { + "description": "The lanes, left to right.", + "items": { + "$ref": "#/$defs/Lane" + }, + "type": "array" + }, + "pitch_px": { + "description": "Distance between neighbouring lane centres, pixels.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "polarity": { + "description": "`bright` or `dark` bands, as measured.", + "type": "string" + }, + "profile_step_px": { + "description": "Distance between profile values, pixels (with `profiles: true`).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "saturation_level": { + "description": "The value counted as saturated, when the pixel type has one.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "size_unit": { + "description": "Unit of band sizes (from the ladder).", + "type": [ + "string", + "null" + ] + }, + "width_px": { + "description": "Lane width, pixels.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "y_range": { + "description": "Rows the lanes span: first and last (full-resolution pixels).", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "count", + "polarity", + "pitch_px", + "width_px", + "y_range", + "c", + "bin", + "band_count", + "lanes" + ], + "type": "object" +} - added
Output schema / $defs / MeasureOutputAdded value: +{ + "description": "Measurements on one plane: a line profile, statistics inside a polygon or an object count.", + "properties": { + "downsample": { + "description": "Level-0 pixels per pixel of this level (1 at level 0).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "format": { + "description": "Format id.", + "type": "string" + }, + "image": { + "description": "Image index.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "lanes": { + "anyOf": [ + { + "$ref": "#/$defs/Lanes" + }, + { + "type": "null" + } + ], + "description": "Lanes and bands." + }, + "level": { + "description": "Pyramid level read; coordinates are its pixels.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "notes": { + "description": "What was assumed.", + "items": { + "type": "string" + }, + "type": "array" + }, + "objects": { + "anyOf": [ + { + "$ref": "#/$defs/Objects" + }, + { + "type": "null" + } + ], + "description": "Objects." + }, + "path": { + "description": "The file.", + "type": "string" + }, + "pixel_size_um": { + "description": "Pixel size at this level in µm, when recorded.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "profile": { + "anyOf": [ + { + "$ref": "#/$defs/Profile" + }, + { + "type": "null" + } + ], + "description": "Profile along `line`." + }, + "roi": { + "anyOf": [ + { + "$ref": "#/$defs/Roi" + }, + { + "type": "null" + } + ], + "description": "Statistics inside `polygon`." + }, + "t": { + "description": "The time point read.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "z": { + "description": "The z plane read.", + "format": "uint32", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "path", + "format", + "image", + "level", + "downsample", + "z", + "t" + ], + "type": "object" +} - added
Output schema / $defs / ObjectAdded value: +{ + "description": "One object.", + "properties": { + "area_px": { + "description": "Pixels.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "area_um2": { + "description": "Area in µm².", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "diameter_um": { + "description": "Diameter of a disc of the same area, in µm.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "edge": { + "description": "True when the object touches the edge of the area searched (it may be cut).", + "type": "boolean" + }, + "height": { + "description": "Spots: height above the local background in what was measured.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "id": { + "description": "Number, in reading order (the label on a picture of the objects).", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "mean": { + "description": "Mean raw value in each channel of `channels`, in that order.", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "type": "array" + }, + "solidity": { + "description": "Area over the area of its convex hull (1 = convex; low values suggest merged objects).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "x": { + "description": "Centroid column, in pixels of the level read.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "y": { + "description": "Centroid row.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "id", + "x", + "y", + "area_px", + "mean" + ], + "type": "object" +} - added
Output schema / $defs / ObjectChannelAdded value: +{ + "description": "One channel measured in every object.", + "properties": { + "background": { + "description": "Median value outside the objects.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "c": { + "description": "Channel index (`c`), or the RGB component or stain index.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "mean": { + "anyOf": [ + { + "$ref": "#/$defs/Spread" + }, + { + "type": "null" + } + ], + "description": "Object means." + }, + "name": { + "description": "Channel, component or stain name.", + "type": [ + "string", + "null" + ] + }, + "positive": { + "anyOf": [ + { + "$ref": "#/$defs/Positive" + }, + { + "type": "null" + } + ], + "description": "Objects clearly brighter than the rest (or than the background)." + } + }, + "required": [ + "c", + "background" + ], + "type": "object" +} - added
Output schema / $defs / ObjectsAdded value: +{ + "description": "Objects found in one plane.", + "properties": { + "area_fraction": { + "description": "Fraction of the area searched covered by objects.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "area_px": { + "anyOf": [ + { + "$ref": "#/$defs/Spread" + }, + { + "type": "null" + } + ], + "description": "Object areas in pixels (objects off the edge, or all when every one touches it)." + }, + "area_um2": { + "anyOf": [ + { + "$ref": "#/$defs/Spread" + }, + { + "type": "null" + } + ], + "description": "Object areas in µm²." + }, + "channels": { + "description": "Every channel measured in the objects, in the order of each object's `mean`.", + "items": { + "$ref": "#/$defs/ObjectChannel" + }, + "type": "array" + }, + "confidence": { + "$ref": "#/$defs/CountConfidence", + "description": "`high`, or `low` when less than half of the objects' area is in compact objects of the\nexpected size (`fit`), when most objects are under a third of the expected area, or\nwhen more objects were found than the area holds: the image may not suit the count, or\nthe threshold cut noise into pieces (see `notes`)." + }, + "count": { + "description": "Objects found, including those touching the edge.", + "format": "uint", + "minimum": 0, + "type": "integer" + }, + "density_per_mm2": { + "description": "Objects per mm² (edge objects count half).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "diameter_um": { + "anyOf": [ + { + "$ref": "#/$defs/Spread" + }, + { + "type": "null" + } + ], + "description": "Diameters (of a disc of the same area) in µm." + }, + "expected_diameter_from": { + "description": "`given`, `measured` (from the image) or `default`.", + "type": "string" + }, + "expected_diameter_px": { + "description": "Object diameter expected, in pixels: it sets the smoothing, the background scale, how\nclose two objects may be and the smallest object kept.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "expected_diameter_um": { + "description": "The same in µm.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "fit": { + "description": "Share of the objects' area in compact objects (solidity at least 0.85) of the expected\nsize (a third to three times the area of its disc), 0 to 1. Not for spots.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "kind": { + "$ref": "#/$defs/Kind", + "description": "What was counted." + }, + "large": { + "description": "Objects more than twice the median area: possibly several objects together.", + "format": "uint", + "minimum": 0, + "type": "integer" + }, + "measured": { + "description": "What objects were found in: a channel (`c=0 DAPI`), an RGB component, `luminance` or a\nstain (`hematoxylin`, `eosin`, `dab`).", + "type": "string" + }, + "objects": { + "description": "The objects in reading order (top to bottom, then left to right).", + "items": { + "$ref": "#/$defs/Object" + }, + "type": "array" + }, + "polarity": { + "$ref": "#/$defs/Polarity", + "description": "`bright` or `dark`." + }, + "region": { + "$ref": "#/$defs/Region", + "description": "The rectangle searched, in pixels of the level read." + }, + "searched_um2": { + "description": "Area searched (the region, or the polygon) in µm².", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "split": { + "description": "Whether touching objects were cut apart.", + "type": "boolean" + }, + "threshold": { + "description": "Threshold, in units of what was measured after background subtraction (spots: height\nabove the local background).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "threshold_method": { + "description": "`otsu`, `otsu-3`, `triangle`, `local`, `sparse` (a few objects on a large background:\nhalf way from the background to the objects), `noise` (spots: five robust standard\ndeviations of the background) or `given`.", + "type": "string" + }, + "touching_edge": { + "description": "Objects touching the edge of the area searched.", + "format": "uint", + "minimum": 0, + "type": "integer" + }, + "truncated": { + "description": "True when `objects` lists fewer than `count`.", + "type": "boolean" + } + }, + "required": [ + "kind", + "measured", + "region", + "expected_diameter_px", + "expected_diameter_from", + "polarity", + "threshold", + "threshold_method", + "split", + "count", + "confidence", + "touching_edge", + "area_fraction", + "large", + "channels", + "objects", + "truncated" + ], + "type": "object" +} - changed
Output schema / $defs / Percentiles / properties / p1 / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Percentiles / properties / p5 / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Percentiles / properties / p50 / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Percentiles / properties / p95 / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / Percentiles / properties / p99 / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / $defs / PolarityAdded value: +{ + "description": "Bright or dark objects.", + "oneOf": [ + { + "const": "auto", + "description": "from the image: dark objects on a bright background (brightfield) or bright ones", + "type": "string" + }, + { + "const": "bright", + "description": "objects brighter than the background (fluorescence)", + "type": "string" + }, + { + "const": "dark", + "description": "objects darker than the background (brightfield)", + "type": "string" + } + ] +} - added
Output schema / $defs / PositiveAdded value: +{ + "description": "Objects above a threshold in one channel.", + "properties": { + "count": { + "description": "Objects whose mean is above it.", + "format": "uint", + "minimum": 0, + "type": "integer" + }, + "fraction": { + "description": "The same as a fraction of all objects.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "method": { + "description": "`otsu` (the object means fall in two groups), `background` (the channel's background\nplus five robust standard deviations) or `none` (no object is clearly brighter).", + "type": "string" + }, + "threshold": { + "description": "Threshold on the object mean.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "threshold", + "method", + "count", + "fraction" + ], + "type": "object" +} - added
Output schema / $defs / ProfileAdded value: +{ + "description": "An intensity profile along a line.", + "properties": { + "channels": { + "description": "One entry per channel.", + "items": { + "$ref": "#/$defs/ProfileChannel" + }, + "type": "array" + }, + "length_px": { + "description": "Line length in pixels.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "length_um": { + "description": "Line length in µm, when the pixel size is recorded.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "line": { + "description": "`[x0, y0, x1, y1]` in pixels of the level read.", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "samples": { + "description": "Samples taken along the line (one per pixel up to 20 000).", + "format": "uint", + "minimum": 0, + "type": "integer" + }, + "step_px": { + "description": "Distance between the returned values in pixels (the first is at the start, the last\nat the end).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "step_um": { + "description": "Distance between the returned values in µm.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "width_px": { + "description": "Pixels averaged across the line.", + "format": "uint32", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "line", + "width_px", + "length_px", + "step_px", + "samples", + "channels" + ], + "type": "object" +} - added
Output schema / $defs / ProfileChannelAdded value: +{ + "description": "One channel of a profile.", + "properties": { + "c": { + "description": "Channel index (`c`), or the RGB component for RGB images.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "fwhm_px": { + "description": "Full width at half maximum of the highest peak above the line's minimum, in pixels.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "fwhm_um": { + "description": "The same in µm.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "max": { + "description": "Largest value along the line.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "max_at_px": { + "description": "Distance of the largest value from the start, in pixels.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "max_at_um": { + "description": "The same in µm, when the pixel size is recorded.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "mean": { + "description": "Mean value along the line.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "min": { + "description": "Smallest value along the line.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "name": { + "description": "Channel or component name.", + "type": [ + "string", + "null" + ] + }, + "values": { + "description": "The profile, one value every `step_px` from the start (at most 200; each the mean of the\nsamples it covers).", + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "type": "array" + } + }, + "required": [ + "c", + "min", + "max", + "mean", + "max_at_px", + "values" + ], + "type": "object" +} - added
Output schema / $defs / RoiAdded value: +{ + "description": "Statistics inside a polygon.", + "properties": { + "area_px": { + "description": "Pixels inside.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "area_um2": { + "description": "Area in µm², when the pixel size is recorded.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "channels": { + "description": "One entry per channel.", + "items": { + "$ref": "#/$defs/RoiChannel" + }, + "type": "array" + }, + "polygon": { + "description": "The vertices, in pixels of the level read.", + "items": { + "items": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "type": "array" + } + }, + "required": [ + "polygon", + "area_px", + "channels" + ], + "type": "object" +} - added
Output schema / $defs / RoiChannelAdded value: +{ + "description": "Statistics of one channel inside a polygon.", + "properties": { + "c": { + "description": "Channel index (`c`), or the RGB component.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "max": { + "description": "Largest value.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "mean": { + "description": "Mean value.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "median": { + "description": "Median value.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "min": { + "description": "Smallest value.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "name": { + "description": "Channel or component name.", + "type": [ + "string", + "null" + ] + }, + "std": { + "description": "Standard deviation.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "sum": { + "description": "Sum of the values (integrated intensity).", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "c", + "min", + "max", + "mean", + "std", + "median", + "sum" + ], + "type": "object" +} - changed
Output schema / $defs / SampleStats / properties / zero_fraction / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / SampleStats / requiredPrevious value: -[ - "count", - "non_finite", - "exact", - "zero_fraction" -]New value: +[ + "count", + "exact", + "zero_fraction" +] - added
Output schema / $defs / SpreadAdded value: +{ + "description": "Minimum, median, mean and maximum.", + "properties": { + "max": { + "description": "Largest.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "mean": { + "description": "Mean.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "median": { + "description": "Median.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "min": { + "description": "Smallest.", + "format": "double", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "min", + "median", + "mean", + "max" + ], + "type": "object" +} - changed
Output schema / anyOfPrevious value: -[ - { - "$ref": "#/$defs/StatsOutput", - "description": "per=channel|plane." - }, - { - "$ref": "#/$defs/WellStatsOutput", - "description": "per=well|field." - } -]New value: +[ + { + "$ref": "#/$defs/StatsOutput", + "description": "per=channel|plane." + }, + { + "$ref": "#/$defs/WellStatsOutput", + "description": "per=well|field." + }, + { + "$ref": "#/$defs/MeasureOutput", + "description": "line, polygon, objects or lanes." + } +]
- Changed
openreadout_summarize5 fields changed- removed
Input schema / properties / exact_by / defaultRemoved value: -false - removed
Input schema / properties / overwrite / defaultRemoved value: -false - removed
Input schema / properties / values / defaultRemoved value: -[] - removed
Input schema / properties / where / defaultRemoved value: -[] - changed
Output schema / $defs / Value / anyOfPrevious value: -[ - { - "description": "No value (JSON `null`, an empty CSV field).", - "type": "null" - }, - { - "description": "`true` / `false`.", - "type": "boolean" - }, - { - "description": "A whole number.", - "format": "int64", - "type": "integer" - }, - { - "description": "A real number (NaN and infinities are written as `null`).", - "format": "double", - "type": "number" - }, - { - "description": "Text.", - "type": "string" - } -]New value: +[ + { + "description": "No value (JSON `null`, an empty CSV field).", + "type": "null" + }, + { + "description": "`true` / `false`.", + "type": "boolean" + }, + { + "description": "A whole number.", + "format": "int64", + "type": "integer" + }, + { + "description": "A real number (NaN and infinities are written as `null`).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + { + "description": "Text.", + "type": "string" + } +]
- Changed
openreadout_table15 fields changed- removed
Input schema / properties / count / defaultRemoved value: -false - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file."New value: +"Path to the file." - removed
Input schema / properties / filter / defaultRemoved value: -[] - removed
Input schema / properties / first_row / defaultRemoved value: -0 - removed
Input schema / properties / first_row / minimumRemoved value: -0 - removed
Input schema / properties / max_rows / minimumRemoved value: -0 - removed
Input schema / properties / parameters / defaultRemoved value: -[] - removed
Input schema / properties / populations / defaultRemoved value: -[] - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / table / defaultRemoved value: -0 - removed
Input schema / properties / table / minimumRemoved value: -0 - changed
Output schema / $defs / AppliedTransform / properties / parameters / additionalProperties / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / CompensationSummary / properties / matrix / items / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / TableFilterSummary / properties / percent / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / rows / items / items / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Changed
openreadout_trace18 fields changed- removed
Input schema / properties / channels / defaultRemoved value: -[] - removed
Input schema / properties / channels / items / minimumRemoved value: -0 - removed
Input schema / properties / count / minimumRemoved value: -0 - changed
Input schema / properties / file / descriptionPrevious value: -"Absolute or working-directory-relative path to the instrument file."New value: +"Path to the file." - removed
Input schema / properties / first_sample / defaultRemoved value: -0 - removed
Input schema / properties / first_sample / minimumRemoved value: -0 - removed
Input schema / properties / max_samples / minimumRemoved value: -0 - removed
Input schema / properties / process / defaultRemoved value: -false - changed
Input schema / properties / strict / descriptionPrevious value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's." - removed
Input schema / properties / sweep / defaultRemoved value: -0 - removed
Input schema / properties / sweep / minimumRemoved value: -0 - removed
Input schema / properties / trace / defaultRemoved value: -0 - removed
Input schema / properties / trace / minimumRemoved value: -0 - changed
Output schema / $defs / TraceChannelSlice / properties / samples / items / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / TraceStats / requiredPrevious value: -[ - "count", - "finite" -]New value: +[ + "count", + "finite", + "min", + "max", + "mean", + "std", + "argmin", + "argmax" +] - changed
Output schema / properties / sample_rate_hz / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / start_s / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / x_range / items / typePrevious value: -"number"New value: +[ + "number", + "null" +]
- Changed
openreadout_watch7 fields changed- removed
Input schema / properties / cursor / minimumRemoved value: -0 - added
Input schema / properties / follow_symlinksAdded value: +{ + "description": "First call only: walk into directories behind symbolic links too (links to files are always followed).", + "type": "boolean" +} - removed
Input schema / properties / limit / minimumRemoved value: -0 - removed
Input schema / properties / qc / defaultRemoved value: -false - changed
Output schema / $defs / QcFinding / properties / threshold / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / $defs / QcFinding / properties / value / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / notesAdded value: +{ + "description": "What the watcher left out and how to include it.", + "items": { + "type": "string" + }, + "type": "array" +}
31 tool updates
v0.3.0- Removed
openreadout_analyze - Added
openreadout_assay_curve - Added
openreadout_assay_qc - Added
openreadout_assay_wells - Changed
openreadout_batch10 fields changed- removed
Input schema / properties / inputsRemoved value: -{ - "default": [], - "description": "Files, directories or glob patterns (summarize: the one table file).", - "items": { - "type": "string" - }, - "type": "array" -} - changed
Input schema / properties / measure / descriptionPrevious value: -"What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `spectra` = one row per MS scan header (options: the openreadout_spectra filters); `peaks` = openreadout_analyze kind peaks (options); `chromatogram` = openreadout_analyze kind chromatogram (options); `assay` = openreadout_analyze kind assay (options); `nmr-peaks` = openreadout_analyze kind nmr-peaks (options); `ephys-features` = openreadout_analyze kind ephys-features (options); `spikes` = openreadout_analyze kind spikes (options); `qpcr` = openreadout_analyze kind qpcr (options); `gate` = population counts, percentages and medians (workspace or gatingml); `summarize` = group statistics (by) of the one table file in inputs, written by an earlier output."New value: +"What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `scans` = one row per MS scan header (options: the openreadout_scans filters); `peaks` = openreadout_peaks (its arguments as options); `chromatogram` = openreadout_chromatogram (its arguments as options); `assay` = a plate-reader assay: options `analysis` (wells, curve, dose-response, kinetics, growth, qc) and the arguments of that openreadout_assay_* tool; `nmr-peaks` = openreadout_nmr_peaks (its arguments as options); `ephys-features` = openreadout_ephys_features (its arguments as options); `spikes` = openreadout_spikes (its arguments as options); `qpcr` = openreadout_qpcr (its arguments as options); `gate` = population counts, percentages and medians (workspace or gatingml)." - changed
Input schema / properties / measure / enumPrevious value: -[ - "stats", - "trace", - "table", - "info", - "spectra", - "peaks", - "chromatogram", - "assay", - "nmr-peaks", - "ephys-features", - "spikes", - "qpcr", - "gate", - "summarize" -]New value: +[ + "stats", + "trace", + "table", + "info", + "scans", + "peaks", + "chromatogram", + "assay", + "nmr-peaks", + "ephys-features", + "spikes", + "qpcr", + "gate" +] - changed
Input schema / properties / options / descriptionPrevious value: -"The measure's options. Analyses: the openreadout_analyze options of that kind, plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. spectra: the openreadout_spectra filters."New value: +"The measure's options. Analyses: the arguments of that analysis's tool (openreadout_peaks, openreadout_nmr_peaks, ...; assay: `analysis` = wells, curve, dose-response, kinetics, growth or qc, plus the arguments of that openreadout_assay_* tool), plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. scans: the openreadout_scans filters." - added
Input schema / properties / pathsAdded value: +{ + "default": [], + "description": "Files, directories or glob patterns.", + "items": { + "type": "string" + }, + "type": "array" +} - removed
Output schema / $defs / BatchOutputRemoved value: -{ - "description": "Output of a batch command in table mode.", - "properties": { - "columns": { - "description": "Columns of `rows`, with type, unit and role (`id`, `key`, `metadata`, `annotation`,\n`value`, `error`).", - "items": { - "$ref": "#/$defs/Column" - }, - "type": "array" - }, - "grain": { - "description": "Columns that identify a row within its data set.", - "items": { - "type": "string" - }, - "type": "array" - }, - "inputs": { - "$ref": "#/$defs/InputReport", - "description": "How the inputs became data sets." - }, - "joins": { - "description": "Sample sheets and layouts joined, in order.", - "items": { - "$ref": "#/$defs/JoinReport" - }, - "type": "array" - }, - "measure": { - "description": "Measure (`stats`, `trace`, `table`, `gate`, `info`, …).", - "type": "string" - }, - "offset": { - "description": "Index of the first row in `rows`.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "output": { - "anyOf": [ - { - "$ref": "#/$defs/WrittenFile" - }, - { - "type": "null" - } - ], - "description": "The file the full table was written to (`-o`)." - }, - "returned_rows": { - "description": "Rows returned here.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "rows": { - "description": "Rows as arrays in column order.", - "items": { - "items": { - "$ref": "#/$defs/Value" - }, - "type": "array" - }, - "type": "array" - }, - "summary": { - "anyOf": [ - { - "$ref": "#/$defs/SummaryOutput" - }, - { - "type": "null" - } - ], - "description": "The group summary (`--by`)." - }, - "total_rows": { - "description": "Rows in the whole table.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "truncated": { - "description": "True when the table has rows after the last one returned (page with `offset`, or read\nthe full table from `output`).", - "type": "boolean" - }, - "warnings": { - "description": "Things to check: skipped inputs, grouping, join results.", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "measure", - "grain", - "inputs", - "columns", - "total_rows", - "offset", - "returned_rows", - "truncated", - "rows" - ], - "type": "object" -} - removed
Output schema / $defs / SummarizeToolOutputRemoved value: -{ - "description": "A summary of a saved table.", - "properties": { - "input": { - "description": "The table summarized.", - "type": "string" - }, - "output": { - "anyOf": [ - { - "$ref": "#/$defs/WrittenFile" - }, - { - "type": "null" - } - ], - "description": "Where it was written." - }, - "summary": { - "$ref": "#/$defs/SummaryOutput", - "description": "The summary." - } - }, - "required": [ - "input", - "summary" - ], - "type": "object" -} - removed
Output schema / anyOfRemoved value: -[ - { - "$ref": "#/$defs/BatchOutput", - "description": "A batch table." - }, - { - "$ref": "#/$defs/SummarizeToolOutput", - "description": "The summary of a saved table." - } -] - added
Output schema / propertiesAdded value: +{ + "columns": { + "description": "Columns of `rows`, with type, unit and role (`id`, `key`, `metadata`, `annotation`,\n`value`, `error`).", + "items": { + "$ref": "#/$defs/Column" + }, + "type": "array" + }, + "grain": { + "description": "Columns that identify a row within its data set.", + "items": { + "type": "string" + }, + "type": "array" + }, + "inputs": { + "$ref": "#/$defs/InputReport", + "description": "How the inputs became data sets." + }, + "joins": { + "description": "Sample sheets and layouts joined, in order.", + "items": { + "$ref": "#/$defs/JoinReport" + }, + "type": "array" + }, + "measure": { + "description": "Measure (`stats`, `trace`, `table`, `gate`, `info`, …).", + "type": "string" + }, + "offset": { + "description": "Index of the first row in `rows`.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "output": { + "anyOf": [ + { + "$ref": "#/$defs/WrittenFile" + }, + { + "type": "null" + } + ], + "description": "The file the full table was written to (`-o`)." + }, + "returned_rows": { + "description": "Rows returned here.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "rows": { + "description": "Rows as arrays in column order.", + "items": { + "items": { + "$ref": "#/$defs/Value" + }, + "type": "array" + }, + "type": "array" + }, + "summary": { + "anyOf": [ + { + "$ref": "#/$defs/SummaryOutput" + }, + { + "type": "null" + } + ], + "description": "The group summary (`--by`)." + }, + "total_rows": { + "description": "Rows in the whole table.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "truncated": { + "description": "True when the table has rows after the last one returned (page with `offset`, or read\nthe full table from `output`).", + "type": "boolean" + }, + "warnings": { + "description": "Things to check: skipped inputs, grouping, join results.", + "items": { + "type": "string" + }, + "type": "array" + } +} - added
Output schema / requiredAdded value: +[ + "measure", + "grain", + "inputs", + "columns", + "total_rows", + "offset", + "returned_rows", + "truncated", + "rows" +]
- Changed
openreadout_check41 fields changed- removed
Input schema / properties / againstRemoved value: -{ - "description": "Compare with this second file instead (e.g. an OME-TIFF export of `file`): metadata differences, geometry, channels, physical sizes and per-plane hashes.", - "type": "string" -} - added
Input schema / properties / headers_onlyAdded value: +{ + "default": false, + "description": "Check headers and structure only (offsets, declared sizes and counts, missing parts): no decompression, decoding or checksums over the data.", + "type": "boolean" +} - removed
Input schema / properties / ignoreRemoved value: -{ - "default": [], - "description": "against: JSON pointers (into openreadout_info output) to leave out of the metadata diff; `*` matches one segment.", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Input schema / properties / imageRemoved value: -{ - "description": "against: only this image index (in both files).", - "minimum": 0, - "type": "integer" -} - removed
Input schema / properties / include_textRemoved value: -{ - "default": false, - "description": "report: keep free text from the file (sample, image and channel names, comments); the path and personal data are still replaced. Default false: only with the user's consent.", - "type": "boolean" -} - removed
Input schema / properties / no_pixelsRemoved value: -{ - "default": false, - "description": "against: metadata and geometry only, no pixels.", - "type": "boolean" -} - removed
Input schema / properties / outputRemoved value: -{ - "description": "report: also write the bundle to this new local file. Default: only return it.", - "type": "string" -} - removed
Input schema / properties / reportRemoved value: -{ - "default": false, - "description": "Build a privacy-reviewed diagnostic bundle for the maintainers instead (for a file that is refused, fails, or is not validated).", - "type": "boolean" -} - removed
Input schema / properties / selectRemoved value: -{ - "default": [], - "description": "against: plane selection strings such as `c=0`, `z=2-5`, `t=0,3`. A second file holding only the selected planes (an export with the same selection) is matched to them in order.", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Input schema / properties / toleranceRemoved value: -{ - "description": "against: largest absolute sample difference that still counts as equal. Default: bit-identical planes (same xxh3-128).", - "type": "number" -} - changed
Output schema / $defs / Acquisition / descriptionPrevious value: -"`acquisition` in `info`, `info --view structure`, `check` and `check --planes`: present only for\nfiles that are not finished. See `book/src/guides/lab-shares.md`."New value: +"`acquisition` in `info`, `info --view structure`, `check` and `planes`: present only for\nfiles that are not finished. See `book/src/guides/lab-shares.md`." - removed
Output schema / $defs / CheckReportRemoved value: -{ - "description": "Output of `check`.", - "properties": { - "acquisition": { - "anyOf": [ - { - "$ref": "#/$defs/Acquisition" - }, - { - "type": "null" - } - ], - "description": "Present when the file is not finished: still being written (`in_progress`: findings\nabout the unfinished tail are warnings and `ok` covers the complete part) or stopped\nbefore the end (`interrupted`). See `book/src/guides/lab-shares.md`." - }, - "assurance": { - "anyOf": [ - { - "$ref": "#/$defs/Assurance" - }, - { - "type": "null" - } - ], - "description": "Whether the file lies inside what its reader has been validated on (the same block as\n`info` → `assurance`). `ok` says the file is intact; `assurance` says whether its values\ncan be trusted. Filled by the `check` command when the header can be read." - }, - "checks_performed": { - "description": "What was verified, in plain words, so the caller knows what \"ok\" covers.", - "items": { - "type": "string" - }, - "type": "array" - }, - "findings": { - "description": "Everything found, in the order checked.", - "items": { - "$ref": "#/$defs/Finding" - }, - "type": "array" - }, - "format": { - "description": "Format id of the input file.", - "type": "string" - }, - "ok": { - "description": "True when no finding has severity `error`.", - "type": "boolean" - }, - "path": { - "description": "The input file.", - "type": "string" - } - }, - "required": [ - "path", - "format", - "ok", - "checks_performed", - "findings" - ], - "type": "object" -} - removed
Output schema / $defs / CompareOutputRemoved value: -{ - "description": "Output of `check --against`.", - "properties": { - "identical": { - "description": "Nothing compared differs: metadata (unless skipped), geometry, channel names,\nphysical sizes and planes (within the tolerance). The exit code is 0 when true, 1\nwhen false.", - "type": "boolean" - }, - "images": { - "description": "Geometry, channel-name and physical-size comparison per image index.", - "items": { - "$ref": "#/$defs/ImageComparison" - }, - "type": "array" - }, - "metadata": { - "$ref": "#/$defs/MetadataComparison", - "description": "The normalized-metadata diff." - }, - "notes": { - "description": "Caveats (e.g. formats that store different metadata for the same acquisition).", - "items": { - "type": "string" - }, - "type": "array" - }, - "ours": { - "$ref": "#/$defs/CompareSide", - "description": "The first file." - }, - "planes": { - "$ref": "#/$defs/PlaneComparison", - "description": "The plane-by-plane comparison." - }, - "theirs": { - "$ref": "#/$defs/CompareSide", - "description": "The second file." - } - }, - "required": [ - "identical", - "ours", - "theirs", - "metadata", - "images", - "planes", - "notes" - ], - "type": "object" -} - removed
Output schema / $defs / CompareSideRemoved value: -{ - "description": "One file of the pair.", - "properties": { - "format": { - "description": "Its format id.", - "type": "string" - }, - "images": { - "description": "Number of images.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "path": { - "description": "The file as given.", - "type": "string" - }, - "tables": { - "description": "Number of tables.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "traces": { - "description": "Number of traces.", - "format": "uint32", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "path", - "format", - "images", - "tables", - "traces" - ], - "type": "object" -} - removed
Output schema / $defs / DetectionSummaryRemoved value: -{ - "description": "The reader that claimed the input.", - "properties": { - "confidence": { - "description": "`definite`, `likely` or `extension_only`.", - "type": "string" - }, - "format": { - "description": "Format id.", - "type": "string" - }, - "note": { - "description": "Why the match is less than definite.", - "type": [ - "string", - "null" - ] - }, - "reader_confidence": { - "description": "The reader's confidence level (`high`, `medium`, `low`).", - "type": "string" - } - }, - "required": [ - "format", - "confidence", - "reader_confidence" - ], - "type": "object" -} - removed
Output schema / $defs / DifferenceRemoved value: -{ - "description": "A value that differs, at an RFC 6901 JSON pointer into `info --json` `data`.", - "properties": { - "ours": { - "description": "Value in the first file; absent when the first file lacks the field." - }, - "pointer": { - "description": "RFC 6901 JSON pointer to the value, e.g. `/images/0/physical_size/x`.", - "type": "string" - }, - "theirs": { - "description": "Value in the second file; absent when the second file lacks the field." - } - }, - "required": [ - "pointer" - ], - "type": "object" -} - removed
Output schema / $defs / GeneratorRemoved value: -{ - "description": "Program name and version.", - "properties": { - "name": { - "description": "`openreadout`.", - "type": "string" - }, - "version": { - "description": "Its version.", - "type": "string" - } - }, - "required": [ - "name", - "version" - ], - "type": "object" -} - removed
Output schema / $defs / GeometryRemoved value: -{ - "description": "Geometry of one image.", - "properties": { - "pixel_type": { - "$ref": "#/$defs/PixelType", - "description": "Sample type." - }, - "samples_per_pixel": { - "description": "1 for grayscale, 3 for interleaved RGB.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "size_c": { - "description": "Number of channels.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "size_t": { - "description": "Number of time points.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "size_x": { - "description": "Width in pixels.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "size_y": { - "description": "Height in pixels.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "size_z": { - "description": "Number of Z planes.", - "format": "uint32", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "size_x", - "size_y", - "size_z", - "size_c", - "size_t", - "pixel_type", - "samples_per_pixel" - ], - "type": "object" -} - removed
Output schema / $defs / HexSampleRemoved value: -{ - "description": "A hex excerpt.", - "properties": { - "at": { - "description": "`head` or the structure entry (`kind name`).", - "type": "string" - }, - "hex": { - "description": "Space-separated bytes; masked text bytes are `__`.", - "type": "string" - }, - "offset": { - "description": "Byte offset.", - "format": "uint64", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "at", - "offset", - "hex" - ], - "type": "object" -} - removed
Output schema / $defs / ImageComparisonRemoved value: -{ - "description": "One image index present in either file.", - "properties": { - "channel_names_equal": { - "description": "Channel names agree.", - "type": "boolean" - }, - "geometry_equal": { - "description": "Both files have the image and their geometries agree (with `selected`, after the\nselection).", - "type": "boolean" - }, - "image": { - "description": "Image index.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "ours": { - "anyOf": [ - { - "$ref": "#/$defs/Geometry" - }, - { - "type": "null" - } - ], - "description": "Absent when the first file has no image with this index." - }, - "ours_channels": { - "description": "Channel names of the first file (listed only when they differ).", - "items": { - "type": [ - "string", - "null" - ] - }, - "type": "array" - }, - "ours_physical_size": { - "anyOf": [ - { - "$ref": "#/$defs/PhysicalSize" - }, - { - "type": "null" - } - ], - "description": "Physical pixel size in the first file (listed only when the sizes differ)." - }, - "physical_size_equal": { - "description": "Physical sizes agree to a relative 1e-6 (both absent counts as equal).", - "type": "boolean" - }, - "selected": { - "description": "The second file holds only the selected planes of this image (an export made with the\nsame selection): planes, channels and the metadata diff were matched in selection\norder, and `ours` is the geometry after the selection.", - "type": "boolean" - }, - "theirs": { - "anyOf": [ - { - "$ref": "#/$defs/Geometry" - }, - { - "type": "null" - } - ], - "description": "Absent when the second file has no image with this index." - }, - "theirs_channels": { - "description": "Channel names of the second file (listed only when they differ).", - "items": { - "type": [ - "string", - "null" - ] - }, - "type": "array" - }, - "theirs_physical_size": { - "anyOf": [ - { - "$ref": "#/$defs/PhysicalSize" - }, - { - "type": "null" - } - ], - "description": "Physical pixel size in the second file (listed only when the sizes differ)." - } - }, - "required": [ - "image", - "geometry_equal", - "channel_names_equal", - "ours_channels", - "theirs_channels", - "physical_size_equal" - ], - "type": "object" -} - removed
Output schema / $defs / InputSummaryRemoved value: -{ - "description": "The input without its name.", - "properties": { - "extension": { - "description": "Lower-case extension without the dot (`nd2`, `raw`, `d`), when there is one.", - "type": [ - "string", - "null" - ] - }, - "kind": { - "description": "`file` or `directory`.", - "type": "string" - }, - "member_extensions": { - "additionalProperties": { - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "description": "Member counts per extension.", - "type": "object" - }, - "members": { - "description": "A directory's members: relative paths with names that are not plain tokens replaced.", - "items": { - "$ref": "#/$defs/Member" - }, - "type": "array" - }, - "members_omitted": { - "description": "Members not listed (more than 2000).", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "sha256": { - "description": "SHA-256 of the whole file (files up to 1 GiB).", - "type": [ - "string", - "null" - ] - }, - "sha256_first_64mib": { - "description": "SHA-256 of the first 64 MiB (larger files).", - "type": [ - "string", - "null" - ] - }, - "signature_hex": { - "description": "The first 16 bytes in hex; printable runs that are not a plain token are masked (`__`).", - "type": [ - "string", - "null" - ] - }, - "signature_text": { - "description": "The same bytes as text where they are a plain token (`ZISRAWFILE`, `ABF2`).", - "type": [ - "string", - "null" - ] - }, - "size_bytes": { - "description": "Bytes (a directory: the sum over its members).", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "text_like": { - "description": "The file looks like text (a delimited export, XML, JSON).", - "type": "boolean" - } - }, - "required": [ - "kind", - "size_bytes" - ], - "type": "object" -} - removed
Output schema / $defs / IntegrityRemoved value: -{ - "description": "Integrity findings.", - "properties": { - "checks_performed": { - "description": "What was verified.", - "items": { - "type": "string" - }, - "type": "array" - }, - "findings": { - "description": "Findings: severity, code, message (scrubbed), offset.", - "items": true, - "type": "array" - }, - "mode": { - "description": "`headers` (`check --headers-only`) or `full`.", - "type": "string" - }, - "ok": { - "description": "No finding of severity error.", - "type": "boolean" - } - }, - "required": [ - "mode", - "ok", - "checks_performed", - "findings" - ], - "type": "object" -} - removed
Output schema / $defs / KindCountRemoved value: -{ - "description": "Count and bytes of one entry kind.", - "properties": { - "bytes": { - "description": "Their total size, where sizes are known.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "count": { - "description": "How many.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "kind": { - "description": "Entry kind.", - "type": "string" - } - }, - "required": [ - "kind", - "count", - "bytes" - ], - "type": "object" -} - removed
Output schema / $defs / MemberRemoved value: -{ - "description": "One member of a directory data set.", - "properties": { - "path": { - "description": "Path relative to the data set, `/`-separated.", - "type": "string" - }, - "size": { - "description": "Bytes.", - "format": "uint64", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "path", - "size" - ], - "type": "object" -} - removed
Output schema / $defs / MetadataComparisonRemoved value: -{ - "description": "The normalized-metadata diff.", - "properties": { - "compared": { - "description": "False with `--no-metadata`.", - "type": "boolean" - }, - "difference_count": { - "description": "Total number of differences (the list holds at most 1000).", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "differences": { - "description": "The differences, at most 1000.", - "items": { - "$ref": "#/$defs/Difference" - }, - "type": "array" - }, - "equal": { - "description": "True when no difference was found.", - "type": "boolean" - }, - "ignored": { - "description": "Pointers left out (defaults plus `--ignore`); `extra` objects are also left out unless\n`include_extra`.", - "items": { - "type": "string" - }, - "type": "array" - }, - "include_extra": { - "description": "Whether `extra` objects were compared.", - "type": "boolean" - } - }, - "required": [ - "compared", - "equal", - "ignored", - "include_extra", - "difference_count", - "differences" - ], - "type": "object" -} - removed
Output schema / $defs / PhysicalSizeRemoved value: -{ - "description": "Physical pixel size in micrometres (the OME default unit). Every present value is > 0.", - "properties": { - "unit": { - "description": "Always `µm` in this schema version.", - "type": "string" - }, - "x": { - "description": "Pixel width in µm (the distance between neighbouring columns).", - "format": "double", - "type": [ - "number", - "null" - ] - }, - "y": { - "description": "Pixel height in µm (the distance between neighbouring rows).", - "format": "double", - "type": [ - "number", - "null" - ] - }, - "z": { - "description": "Spacing between Z planes (focal slices) in µm.", - "format": "double", - "type": [ - "number", - "null" - ] - } - }, - "required": [ - "unit" - ], - "type": "object" -} - removed
Output schema / $defs / PixelTypeRemoved value: -{ - "description": "Sample type of one channel value. Names follow OME-XML `PixelType` values.", - "oneOf": [ - { - "const": "int8", - "description": "Signed 8-bit integer.", - "type": "string" - }, - { - "const": "int16", - "description": "Signed 16-bit integer.", - "type": "string" - }, - { - "const": "int32", - "description": "Signed 32-bit integer.", - "type": "string" - }, - { - "const": "uint8", - "description": "Unsigned 8-bit integer.", - "type": "string" - }, - { - "const": "uint16", - "description": "Unsigned 16-bit integer (the usual microscope camera output).", - "type": "string" - }, - { - "const": "uint32", - "description": "Unsigned 32-bit integer.", - "type": "string" - }, - { - "const": "float", - "description": "32-bit IEEE 754 floating point.", - "type": "string" - }, - { - "const": "double", - "description": "64-bit IEEE 754 floating point.", - "type": "string" - }, - { - "const": "int64", - "description": "Signed 64-bit integer.", - "type": "string" - }, - { - "const": "uint64", - "description": "Unsigned 64-bit integer.", - "type": "string" - }, - { - "const": "complex", - "description": "Complex number of two 32-bit floats (real, then imaginary): OME `complex`.", - "type": "string" - }, - { - "const": "double-complex", - "description": "Complex number of two 64-bit floats (real, then imaginary): OME `double-complex`.", - "type": "string" - } - ] -} - removed
Output schema / $defs / PlaneComparisonRemoved value: -{ - "description": "Plane-by-plane comparison.", - "properties": { - "compared": { - "description": "False with `--no-pixels`.", - "type": "boolean" - }, - "identical": { - "description": "Planes with identical xxh3-128.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "mismatched": { - "description": "Planes that differ beyond the tolerance (or at all, without one).", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "mismatches": { - "description": "At most 1000 entries, in plane order.", - "items": { - "$ref": "#/$defs/PlaneMismatch" - }, - "type": "array" - }, - "planes": { - "description": "Planes read from both files.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "skipped_images": { - "description": "Image indices not compared plane by plane (missing on one side or geometry differs).", - "items": { - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "type": "array" - }, - "tolerance": { - "description": "The `--tolerance` used, if any.", - "format": "double", - "type": [ - "number", - "null" - ] - }, - "within_tolerance": { - "description": "Planes that differ but within the tolerance.", - "format": "uint64", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "compared", - "planes", - "identical", - "within_tolerance", - "mismatched", - "skipped_images", - "mismatches" - ], - "type": "object" -} - removed
Output schema / $defs / PlaneMismatchRemoved value: -{ - "description": "A plane that differs.", - "properties": { - "c": { - "description": "Channel index.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "differing_samples": { - "description": "Samples that differ (absent when the planes' shapes differ).", - "format": "uint64", - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "image": { - "description": "Image index.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "max_abs_diff": { - "description": "Largest absolute difference between corresponding samples.", - "format": "double", - "type": [ - "number", - "null" - ] - }, - "note": { - "description": "Why the samples could not be compared (e.g. the plane shapes differ).", - "type": [ - "string", - "null" - ] - }, - "ours_xxh3": { - "description": "xxh3-128 of the plane in the first file.", - "type": "string" - }, - "t": { - "description": "Time index.", - "format": "uint32", - "minimum": 0, - "type": "integer" - }, - "theirs_xxh3": { - "description": "xxh3-128 of the plane in the second file.", - "type": "string" - }, - "within_tolerance": { - "description": "With a tolerance: whether `max_abs_diff` is within it (then the plane counts as equal).", - "type": "boolean" - }, - "z": { - "description": "Z index.", - "format": "uint32", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "image", - "c", - "z", - "t", - "ours_xxh3", - "theirs_xxh3", - "within_tolerance" - ], - "type": "object" -} - removed
Output schema / $defs / PrivacyRemoved value: -{ - "description": "The privacy statement of a bundle.", - "properties": { - "excluded": { - "description": "What it leaves out.", - "items": { - "type": "string" - }, - "type": "array" - }, - "included": { - "description": "What the bundle contains, in plain words.", - "items": { - "type": "string" - }, - "type": "array" - }, - "mode": { - "description": "`structure_only` (default) or `with_text` (`--include-text`).", - "type": "string" - }, - "personal_data": { - "description": "Personal-data flags (kind and rule, never the value) found in the metadata.", - "items": { - "type": "string" - }, - "type": "array" - }, - "redacted_strings": { - "description": "Distinct strings from the file replaced by `<redacted-N>` or `<text:LEN>` placeholders.", - "format": "uint32", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "mode", - "included", - "excluded", - "redacted_strings" - ], - "type": "object" -} - removed
Output schema / $defs / ReportRemoved value: -{ - "description": "The diagnostic bundle.", - "properties": { - "assurance": { - "anyOf": [ - { - "$ref": "#/$defs/Assurance" - }, - { - "type": "null" - } - ], - "description": "The assurance block (`info` → `assurance`), text scrubbed." - }, - "candidates": { - "description": "Readers registered for the input's extension (what the user probably expected).", - "items": { - "type": "string" - }, - "type": "array" - }, - "detection": { - "anyOf": [ - { - "$ref": "#/$defs/DetectionSummary" - }, - { - "type": "null" - } - ], - "description": "The reader that claimed the input, when one did." - }, - "generator": { - "$ref": "#/$defs/Generator", - "description": "The program that wrote it." - }, - "input": { - "$ref": "#/$defs/InputSummary", - "description": "The input, without its name or path." - }, - "integrity": { - "anyOf": [ - { - "$ref": "#/$defs/Integrity" - }, - { - "type": "null" - } - ], - "description": "Integrity findings (`check`)." - }, - "metadata": { - "description": "The normalized metadata (`info`) with numbers kept and free text replaced." - }, - "privacy": { - "$ref": "#/$defs/Privacy", - "description": "What the bundle contains and leaves out; read before sharing." - }, - "report_version": { - "description": "Bundle layout version ([`REPORT_VERSION`]).", - "type": "string" - }, - "samples": { - "description": "Hex excerpts (only with `hex_bytes`).", - "items": { - "$ref": "#/$defs/HexSample" - }, - "type": "array" - }, - "stages": { - "description": "The decode path: each stage in order with its result.", - "items": { - "$ref": "#/$defs/Stage" - }, - "type": "array" - }, - "structure": { - "anyOf": [ - { - "$ref": "#/$defs/StructureMap" - }, - { - "type": "null" - } - ], - "description": "The container's structure (`info --view structure`)." - }, - "vendor_keys": { - "anyOf": [ - { - "$ref": "#/$defs/VendorKeys" - }, - { - "type": "null" - } - ], - "description": "Key skeleton of the vendor metadata tree (`info --view full` → `vendor`): paths and value\ntypes." - } - }, - "required": [ - "report_version", - "generator", - "privacy", - "input", - "stages" - ], - "type": "object" -} - removed
Output schema / $defs / ReportOutputRemoved value: -{ - "description": "What `openreadout check FILE --report` prints under `--json`.", - "properties": { - "bytes": { - "description": "Size of the written bundle.", - "format": "uint64", - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "issue_url": { - "description": "Where to file it (never contacted by the program).", - "type": "string" - }, - "output": { - "description": "Where the bundle was written; `None` with `--dry-run` (or from MCP without `output`).", - "type": [ - "string", - "null" - ] - }, - "report": { - "$ref": "#/$defs/Report", - "description": "The bundle, exactly as written." - } - }, - "required": [ - "issue_url", - "report" - ], - "type": "object" -} - changed
Output schema / $defs / Scope / oneOfPrevious value: -[ - { - "const": "metadata", - "description": "The normalized metadata (`info`, all its views): sizes, channels, instrument, times.", - "type": "string" - }, - { - "const": "pixels", - "description": "Image planes (`check --planes`, `stats`, `export` of images, `preview`).", - "type": "string" - }, - { - "const": "spectra", - "description": "Mass spectra and scan headers (`spectra`, `analyze chromatogram`, mzML export).", - "type": "string" - }, - { - "const": "traces", - "description": "Sampled signals (`trace`, electrophysiology, chromatograms, NMR and IR/Raman spectra).", - "type": "string" - }, - { - "const": "tables", - "description": "Tables (FCS events, plate reads, qPCR results, event and peak tables).", - "type": "string" - } -]New value: +[ + { + "const": "metadata", + "description": "The normalized metadata (`info`, all its views): sizes, channels, instrument, times.", + "type": "string" + }, + { + "const": "pixels", + "description": "Image planes (`planes`, `stats`, `export` of images, `preview`).", + "type": "string" + }, + { + "const": "spectra", + "description": "Mass spectra and scan headers (`scans`, `spectrum`, `analyze chromatogram`, mzML export).", + "type": "string" + }, + { + "const": "traces", + "description": "Sampled signals (`trace`, electrophysiology, chromatograms, NMR and IR/Raman spectra).", + "type": "string" + }, + { + "const": "tables", + "description": "Tables (FCS events, plate reads, qPCR results, event and peak tables).", + "type": "string" + } +] - removed
Output schema / $defs / StageRemoved value: -{ - "description": "One stage of the decode path.", - "properties": { - "detail": { - "description": "What the stage found, in a few words (`12 entries`, `plane 512x512 uint16`).", - "type": [ - "string", - "null" - ] - }, - "elapsed_ms": { - "description": "Milliseconds the stage took.", - "format": "uint64", - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "error": { - "anyOf": [ - { - "$ref": "#/$defs/StageError" - }, - { - "type": "null" - } - ], - "description": "The error, when the stage failed." - }, - "stage": { - "description": "`detect`, `open`, `info`, `assurance`, `ls`, `check`, `vendor`, `first_read`.", - "type": "string" - }, - "status": { - "description": "`ok`, `error`, `skipped` or `panic` (a bug: the reader crashed in this stage).", - "type": "string" - } - }, - "required": [ - "stage", - "status" - ], - "type": "object" -} - removed
Output schema / $defs / StageErrorRemoved value: -{ - "description": "An error as the CLI would report it, text scrubbed.", - "properties": { - "code": { - "description": "Stable code (`corrupt_file`, `unsupported_feature`, ...).", - "type": "string" - }, - "exit_code": { - "description": "Process exit code the CLI would return.", - "format": "int32", - "type": "integer" - }, - "hint": { - "description": "The hint.", - "type": [ - "string", - "null" - ] - }, - "message": { - "description": "The message.", - "type": "string" - }, - "offset": { - "description": "Byte offset of the problem, when the reader knows it.", - "format": "uint64", - "minimum": 0, - "type": [ - "integer", - "null" - ] - } - }, - "required": [ - "code", - "exit_code", - "message" - ], - "type": "object" -} - removed
Output schema / $defs / StructureMapRemoved value: -{ - "description": "The container's structure.", - "properties": { - "by_kind": { - "description": "Count and bytes per entry kind.", - "items": { - "$ref": "#/$defs/KindCount" - }, - "type": "array" - }, - "entries": { - "description": "The first 400 entries in file order.", - "items": true, - "type": "array" - }, - "entries_total": { - "description": "Entries `info --view structure` lists.", - "format": "uint64", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "entries_total", - "by_kind", - "entries" - ], - "type": "object" -} - removed
Output schema / $defs / VendorKeysRemoved value: -{ - "description": "Key skeleton of the vendor tree.", - "properties": { - "omitted": { - "description": "Paths not listed (beyond 3000).", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "paths": { - "description": "`path`, value `type` (`string`, `number`, `bool`, `null`, `object`, `array`), `count`.", - "items": { - "$ref": "#/$defs/VendorPath" - }, - "type": "array" - }, - "total_paths": { - "description": "Distinct key paths (array indices folded to `[]`).", - "format": "uint64", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "total_paths", - "paths" - ], - "type": "object" -} - removed
Output schema / $defs / VendorPathRemoved value: -{ - "description": "One vendor key path.", - "properties": { - "count": { - "description": "Occurrences.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "path": { - "description": "Dotted key path, arrays as `[]`.", - "type": "string" - }, - "type": { - "description": "JSON type of the values (several joined by `|`).", - "type": "string" - } - }, - "required": [ - "path", - "type", - "count" - ], - "type": "object" -} - removed
Output schema / anyOfRemoved value: -[ - { - "$ref": "#/$defs/CheckReport", - "description": "The integrity check." - }, - { - "$ref": "#/$defs/CompareOutput", - "description": "against: the comparison." - }, - { - "$ref": "#/$defs/ReportOutput", - "description": "report: the diagnostic bundle." - } -] - added
Output schema / propertiesAdded value: +{ + "acquisition": { + "anyOf": [ + { + "$ref": "#/$defs/Acquisition" + }, + { + "type": "null" + } + ], + "description": "Present when the file is not finished: still being written (`in_progress`: findings\nabout the unfinished tail are warnings and `ok` covers the complete part) or stopped\nbefore the end (`interrupted`). See `book/src/guides/lab-shares.md`." + }, + "assurance": { + "anyOf": [ + { + "$ref": "#/$defs/Assurance" + }, + { + "type": "null" + } + ], + "description": "Whether the file lies inside what its reader has been validated on (the same block as\n`info` → `assurance`). `ok` says the file is intact; `assurance` says whether its values\ncan be trusted. Filled by the `check` command when the header can be read." + }, + "checks_performed": { + "description": "What was verified, in plain words, so the caller knows what \"ok\" covers.", + "items": { + "type": "string" + }, + "type": "array" + }, + "findings": { + "description": "Everything found, in the order checked.", + "items": { + "$ref": "#/$defs/Finding" + }, + "type": "array" + }, + "format": { + "description": "Format id of the input file.", + "type": "string" + }, + "ok": { + "description": "True when no finding has severity `error`.", + "type": "boolean" + }, + "path": { + "description": "The input file.", + "type": "string" + } +} - added
Output schema / requiredAdded value: +[ + "path", + "format", + "ok", + "checks_performed", + "findings" +]
- Added
openreadout_chromatogram - Added
openreadout_compare - Added
openreadout_dose_response - Added
openreadout_ephys_features - Changed
openreadout_export8 fields changed- removed
Input schema / properties / attachmentRemoved value: -{ - "description": "Write this embedded attachment instead (a CZI's `Thumbnail`, `Label` or `SlidePreview` image, `TimeStamps`; names from openreadout_info view=structure, kind attachment), or `#<index>`.", - "type": "string" -} - changed
Input schema / properties / format / descriptionPrevious value: -"`ome-tiff` (default for images; one BigTIFF file), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0, for mass-spectrometry files; the default for them), `asm` (Allotrope Simple Model plate-reader JSON; plate-reader exports only), `rdml` (RDML 1.3; qPCR files: RDML, Applied Biosystems .eds, Rotor-Gene .rex), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces) or `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms)."New value: +"`ome-tiff` (one BigTIFF file; the default for images), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0; the default for mass spectra), `csv` (one table, or one sweep of a trace; the default for tables and traces), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces), `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms), `asm` (Allotrope Simple Model plate-reader JSON) or `rdml` (RDML 1.3; qPCR files). Without it, the extension of `output` decides; it must not contradict `output`." - added
Input schema / properties / labelsAdded value: +{ + "default": false, + "description": "CSV: add a second header line with column labels (FCS `$PnS`).", + "type": "boolean" +} - changed
Input schema / properties / output / descriptionPrevious value: -"Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.asm.json`, `.rdml`, `.parquet`, `.arrow`, `.nwb` or `.jdx`."New value: +"Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.csv`, `.asm.json`, `.rdml`, `.parquet`, `.arrow`, `.nwb` or `.jdx`. Its extension sets the format when `format` is not given." - changed
Input schema / properties / rows / descriptionPrevious value: -"Parquet, Arrow, NWB, JCAMP-DX: rows (samples of each sweep for traces) `A-B`, `A-` or `A`, zero-based and inclusive."New value: +"CSV, Parquet, Arrow, NWB, JCAMP-DX: rows (samples of each sweep for traces) `A-B`, `A-` or `A`, zero-based and inclusive." - changed
Input schema / properties / sweep / descriptionPrevious value: -"Parquet, Arrow, NWB, JCAMP-DX: only this sweep (default: every sweep)."New value: +"CSV, Parquet, Arrow, NWB, JCAMP-DX: only this sweep (CSV default 0; the others: every sweep)." - changed
Input schema / properties / table / descriptionPrevious value: -"Parquet, Arrow: this table index (FCS data set, plate read, event or peak table)."New value: +"CSV, Parquet, Arrow: this table index (FCS data set, plate read, event or peak table)." - changed
Input schema / properties / trace / descriptionPrevious value: -"Parquet, Arrow, NWB, JCAMP-DX: this trace index (NWB default: every trace)."New value: +"CSV, Parquet, Arrow, NWB, JCAMP-DX: this trace index (NWB default: every trace)."
- Added
openreadout_extract - Removed
openreadout_formats - Added
openreadout_gate - Added
openreadout_growth - Added
openreadout_health - Changed
openreadout_info2 fields changed- changed
Output schema / $defs / Acquisition2 / descriptionPrevious value: -"`acquisition` in `info`, `info --view structure`, `check` and `check --planes`: present only for\nfiles that are not finished. See `book/src/guides/lab-shares.md`."New value: +"`acquisition` in `info`, `info --view structure`, `check` and `planes`: present only for\nfiles that are not finished. See `book/src/guides/lab-shares.md`." - changed
Output schema / $defs / Scope / oneOfPrevious value: -[ - { - "const": "metadata", - "description": "The normalized metadata (`info`, all its views): sizes, channels, instrument, times.", - "type": "string" - }, - { - "const": "pixels", - "description": "Image planes (`check --planes`, `stats`, `export` of images, `preview`).", - "type": "string" - }, - { - "const": "spectra", - "description": "Mass spectra and scan headers (`spectra`, `analyze chromatogram`, mzML export).", - "type": "string" - }, - { - "const": "traces", - "description": "Sampled signals (`trace`, electrophysiology, chromatograms, NMR and IR/Raman spectra).", - "type": "string" - }, - { - "const": "tables", - "description": "Tables (FCS events, plate reads, qPCR results, event and peak tables).", - "type": "string" - } -]New value: +[ + { + "const": "metadata", + "description": "The normalized metadata (`info`, all its views): sizes, channels, instrument, times.", + "type": "string" + }, + { + "const": "pixels", + "description": "Image planes (`planes`, `stats`, `export` of images, `preview`).", + "type": "string" + }, + { + "const": "spectra", + "description": "Mass spectra and scan headers (`scans`, `spectrum`, `analyze chromatogram`, mzML export).", + "type": "string" + }, + { + "const": "traces", + "description": "Sampled signals (`trace`, electrophysiology, chromatograms, NMR and IR/Raman spectra).", + "type": "string" + }, + { + "const": "tables", + "description": "Tables (FCS events, plate reads, qPCR results, event and peak tables).", + "type": "string" + } +]
- Added
openreadout_kinetics - Added
openreadout_nmr_peaks - Added
openreadout_peaks - Changed
openreadout_preview10 fields changed- changed
Input schema / properties / axes / descriptionPrevious value: -"Image previews: coordinate rulers in full-resolution pixels and a scale bar around the picture (default true); false = the bare plane."New value: +"Image previews: what frames the picture. What frames an image preview. `rulers` = coordinate rulers in full-resolution pixels and a scale bar around the picture (default); `grid` = rulers, plus faint grid lines over the data at the ruler ticks; `none` = the bare downsampled plane." - added
Input schema / properties / axes / enumAdded value: +[ + "rulers", + "grid", + "none" +] - changed
Input schema / properties / axes / typePrevious value: -"boolean"New value: +"string" - changed
Input schema / properties / format / descriptionPrevious value: -"`png` (default) or `jpeg`."New value: +"Encoding. Default png (sent as JPEG when a PNG would be too large). Output encoding. `png` = lossless (default); `jpeg` = lossy and smaller." - added
Input schema / properties / format / enumAdded value: +[ + "png", + "jpeg" +] - removed
Input schema / properties / gridRemoved value: -{ - "default": false, - "description": "Image previews: faint grid lines at the ruler ticks over the data (default false).", - "type": "boolean" -} - changed
Input schema / properties / lut / descriptionPrevious value: -"`gray` or `channel-color` (default: gray for one channel, channel colours for composites)."New value: +"Colour lookup. Default: gray for one channel, channel colours for composites. Colour lookup for a single channel. `gray` = black to white; `channel-color` = black to the channel's colour." - added
Input schema / properties / lut / enumAdded value: +[ + "gray", + "channel-color" +] - changed
Input schema / properties / mip / descriptionPrevious value: -"Maximum-intensity projection axis: `z` (or `t`), over the selected range if any."New value: +"Maximum-intensity projection, over the selected range if any. Axis of a maximum-intensity projection. `z` = along z (focal planes); `t` = along t (time points)." - added
Input schema / properties / mip / enumAdded value: +[ + "z", + "t" +]
- Added
openreadout_qpcr - Added
openreadout_report - Added
openreadout_scans - Removed
openreadout_spectra - Added
openreadout_spectrum - Added
openreadout_spikes - Changed
openreadout_stats2 fields changed- added
Output schema / $defs / StatsOutput / properties / images_skippedAdded value: +{ + "description": "Images left out of a run over every image because the reader refuses their pixel data\n(raw FLIM photon histograms, for one; `info` notes say which). Absent when none were.", + "items": { + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "type": "array" +} - changed
Output schema / $defs / StatsOutput / properties / planes / descriptionPrevious value: -"Per-plane statistics (omitted with `--no-planes`)."New value: +"Per-plane statistics (with `--per plane`)."
- Added
openreadout_summarize - Changed
openreadout_table4 fields changed- added
Input schema / properties / parametersAdded value: +{ + "default": [], + "description": "FCS only: parameters ($PnN) to transform; default every fluorescence parameter.", + "items": { + "type": "string" + }, + "type": "array" +} - removed
Input schema / properties / transform_parametersRemoved value: -{ - "default": [], - "description": "FCS only: parameters ($PnN) to transform; default every fluorescence parameter.", - "items": { - "type": "string" - }, - "type": "array" -} - changed
Output schema / properties / rows / descriptionPrevious value: -"Row-major values; `rows[r][c]`. Non-finite values serialize as `null`."New value: +"Row-major values; `rows[r][c]`. Non-finite values serialize as `null`. A text column\nholds codes here; `texts` has its text." - added
Output schema / properties / textsAdded value: +{ + "additionalProperties": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": "Text columns (`info` → `tables[].columns[].extra.categories`) by column name: the text\nof each returned row, so `texts[name][r]` is what `rows[r][c]` codes. Absent when the\ntable has no text column.", + "type": "object" +}
- Changed
openreadout_watch2 fields changed- added
Input schema / properties / stall_afterAdded value: +{ + "description": "First call only: seconds without growth before `dataset_stalled` (default 120).", + "type": "number" +} - removed
Input schema / properties / stall_after_sRemoved value: -{ - "description": "First call only: seconds without growth before `dataset_stalled` (default 120).", - "type": "number" -}
15 tool updates
v0.1.0- First observed
openreadout_analyze - First observed
openreadout_batch - First observed
openreadout_check - First observed
openreadout_export - First observed
openreadout_formats - First observed
openreadout_index - First observed
openreadout_info - First observed
openreadout_link - First observed
openreadout_preview - First observed
openreadout_search - First observed
openreadout_spectra - First observed
openreadout_stats - First observed
openreadout_table - First observed
openreadout_trace - First observed
openreadout_watch
TDQS
Scored across 28 tools
Most tools target a distinct data type or analysis (e.g. chromatogram vs spectrum vs scans vs trace), and descriptions often cross-reference boundaries like 'Draws only; openreadout_export saves'. However, the visualization cluster (plot, preview, export) and data-inspection cluster (info, stats, table) can still be confused by an agent. Overlap exists but is mostly mitigated by detailed descriptions.
All 28 tools use the openreadout_ prefix followed by lowercase snake_case, with no case mixing or chaotic patterns. Compound names like ephys_features and nmr_peaks are still predictable. The convention is uniform across the entire set.
28 tools is above the 25-tool threshold for 'too many' and risks overwhelming an agent choosing among them. While most tools are specialized and non-redundant, the surface is heavy for a single MCP server. Some grouping or consolidation would improve usability.
The set covers indexing, search, info, preview, plot, export, conversion, integrity checks, batch analysis, summarization, and technique-specific analyses (MS, NMR, qPCR, flow, ephys, plate, imaging). Lifecycle operations for reading, inspecting, analyzing, and exporting lab data are thorough. No obvious dead ends for the apparent scientific data readout domain.
Maintenance
Related MCP Connectors
Convert PDF, Word, Excel and scanned documents to Markdown, tables and RAG chunks. OCR.
Geometry and CAD file metadata extraction for STL, OBJ, PLY, PCD, LAS/LAZ, glTF/GLB.
High-fidelity PDF to structured Markdown conversion and document field extraction.
144 deterministic file tools: PDF, image, media, convert, analyze. Connect in one click (OAuth).
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that extracts clean text, tables, and structured data from documents, images, code, and audio files, supporting 97 formats with OCR, transcription, and code intelligence.MIT
- FlicenseNot gradedqualityCmaintenanceEnables local, read-only extraction of text and structure from PDF, DOCX, PPTX, SVG, and PNG files, including OCR for images, directory tree and metadata reporting, with strict path isolation and audit logging.-
- FlicenseBqualityAmaintenanceEnables local, offline document extraction and manipulation—PDF first but also HTML, DOCX, XLSX, PPTX, EML, EPUB, Markdown, and plain text—through tools for probing, locating, extracting, converting, assembling, OCR, protecting, and redacting documents, with nothing leaving the machine.7-
- AlicenseAqualityCmaintenanceConverts documents among PDF, DOCX, Markdown, plain text, and images while returning fidelity reports that clearly distinguish PASS, FAIL, NOT_CHECKED, and UNSUPPORTED outcomes. Also enables lossless reading, exact search, and structured extraction from long documents without treating unchecked content as passed.16AGPL 3.0