Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Read, inspect, and write Flow Cytometry Standard (FCS) 2.0, 3.0, and 3.1 files with FlowIO. Use for low-level FCS metadata and channel inspection, NumPy event extraction, multi-dataset files, table export, and FCS 3.1 creation; use FlowKit for compensation, cytometry transforms, gating, or FlowJo workspaces.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 12% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 94% | 0% |
Use FlowIO as a lightweight, low-level reader and writer for Flow Cytometry Standard files. Examples in this skill target FlowIO 1.4.0, the current stable release verified on 2026-07-23.
FlowIO is appropriate for:
FlowIO does not perform compensation, logicle/biexponential transforms, gating, clustering, or FlowJo workspace processing. Use FlowKit or another analysis package for those tasks.
Create or activate a Python environment, then install the verified release:
bashuv pip install "flowio==1.4.0"
Confirm the runtime version:
bashuv run python -c "import flowio; print(flowio.__version__)"
FlowIO 1.4.0 supports Python 3.9 through 3.13 and depends on NumPy.
file repair, conversion, and downstream biological analysis.
only_text=True for metadata-onlywork, especially with large or unfamiliar files.
as_array(preprocess=True) forgain/log/time scaling from FCS metadata, or preprocess=False for values as encoded in the DATA segment. Record the choice.
errors. Relax checks only for a known vendor-format defect, and review the resulting event data.
sample, subject, operator, and instrument identifiers. Export only fields needed for the task.
metadata, and representative values after any FCS export.
FlowData.text stores keys in lowercase and strips the leading $ from standard FCS keywords:
pythonfrom flowio import FlowData flow = FlowData("sample.fcs", only_text=True) acquisition_date = flow.text.get("date") instrument = flow.text.get("cyt") next_dataset = int(flow.text.get("nextdata", "0"))
Do not look up "$DATE", "$CYT", or other uppercase dollar-prefixed keys. TEXT values remain strings. FlowIO 1.4.0 also removes every $ character from the decoded TEXT segment, including $ characters inside values; preserve the original file when exact metadata fidelity matters.
flow.events is the unprocessed, flattened one-dimensional event array.flow.as_array() returns shape (event_count, channel_count) as a NumPyfloat64 array.
flow.as_array(preprocess=True) applies FCS gain, logarithmic, and timescaling. It does not apply compensation or logicle/biexponential display transforms.
flow.as_array(preprocess=False) reshapes the encoded event values withoutthose scaling steps.
as_array() creates another in-memory array. FlowIO does not provide chunked or memory-mapped event access.
fluoro_indices, scatter_indices, and time_index usezero-based indices.
flow.channels uses FCS parameter numbers beginning at 1.null_channels contains the PnN label strings supplied throughnull_channel_list, including supplied labels that were not found.
pns_labels always matches pnn_labels in length; missing optional PnSlabels appear as empty strings.
create_fcs() requires:
metadata_dictIt writes FCS 3.1 list-mode ($MODE=L) single-precision float ($DATATYPE=F) data. Required interpretation keywords are generated by FlowIO and cannot be overridden through metadata.
pythonfrom pathlib import Path from flowio import FlowData flow = FlowData(Path("sample.fcs")) events = flow.as_array(preprocess=True) print( { "version": flow.version, "events": flow.event_count, "channels": flow.channel_count, "shape": events.shape, "pnn": flow.pnn_labels, "pns": flow.pns_labels, "date": flow.text.get("date"), "instrument": flow.text.get("cyt"), } )
For metadata only:
pythonfrom flowio import FlowData flow = FlowData("sample.fcs", only_text=True) print(flow.version, flow.event_count, flow.pnn_labels)
Do not call as_array() on a metadata-only instance because its event data was not loaded.
Prefer a path or Path over a caller-owned file handle. FlowData closes a provided handle after parsing. In FlowIO 1.4.0, read_multiple_data_sets(handle) can fail after the first dataset because the handle has been closed; pass a filesystem path for multi-dataset files.
Use the standalone helper rather than manually interpreting $NEXTDATA offsets:
pythonfrom flowio import read_multiple_data_sets datasets = read_multiple_data_sets("legacy-multi-dataset.fcs") for index, dataset in enumerate(datasets): values = dataset.as_array(preprocess=True) print(index, dataset.event_count, dataset.pnn_labels, values.shape)
The FCS 3.1 specification deprecated multiple datasets in one file, but FlowIO can read legacy files that use them.
pythonfrom pathlib import Path import numpy as np from flowio import FlowData, create_fcs values = np.asarray( [[100.0, 200.0, 50.0], [150.0, 180.0, 60.0]], dtype=np.float32, ) pnn_labels = ["FSC-A", "SSC-A", "FITC-A"] pns_labels = ["Forward scatter", "Side scatter", "CD3"] output = Path("output.fcs") with output.open("xb") as handle: create_fcs( handle, values.ravel(order="C"), pnn_labels, opt_channel_names=pns_labels, metadata_dict={ "date": "23-JUL-2026", "cyt": "Example instrument", "src": "Validated NumPy array", }, ) roundtrip = FlowData(output) assert roundtrip.event_count == values.shape[0] assert roundtrip.pnn_labels == pnn_labels np.testing.assert_allclose( roundtrip.as_array(preprocess=False), values, rtol=1e-6, atol=1e-6, )
Metadata keys may be supplied in mixed case or with $, but lowercase keys without $ match FlowIO's normalized representation and are less error-prone. Metadata values must be strings.
Use write_fcs() when the event data does not need to change:
pythonfrom flowio import FlowData flow = FlowData("source.fcs") # Preserve selected source metadata (cyt, date, and spill/spillover when present). flow.write_fcs("copy.fcs") # Write only required metadata plus the custom fields supplied here. flow.write_fcs("deidentified.fcs", metadata={"src": "Deidentified export"})
Passing metadata=None preserves FlowIO's selected defaults. Passing any dictionary, including {}, replaces those defaults rather than merging with them. write_fcs() always produces FCS 3.1 floating-point output; non-float source events are preprocessed before writing. It opens the destination for overwrite, so reject an existing output path before calling it unless replacement is intentional. For floating-point sources it can preserve encoded events while dropping PnG or timestep, changing later as_array(preprocess=True) results. Validate both raw and preprocessed round-trips.
Use create_fcs() instead when event values, event count, or channel layout changes.
scripts/inspect_fcs.py inventories one or more datasets without network access. By default it reads metadata only, emits structural fields and channel labels without full TEXT/ANALYSIS values, and refuses files above a configurable size limit.
Set FLOWIO_SKILL_DIR to the installed skill directory. From this repository's root, use skills/flowio:
bashFLOWIO_SKILL_DIR="skills/flowio" # Metadata and channel inventory uv run --no-project --with "flowio==1.4.0" \ python "$FLOWIO_SKILL_DIR/scripts/inspect_fcs.py" sample.fcs # Include all normalized TEXT metadata; review output for identifiers uv run --no-project --with "flowio==1.4.0" \ python "$FLOWIO_SKILL_DIR/scripts/inspect_fcs.py" sample.fcs --include-text # Load events and compute finite-value statistics using FlowIO preprocessing uv run --no-project --with "flowio==1.4.0" \ python "$FLOWIO_SKILL_DIR/scripts/inspect_fcs.py" sample.fcs --stats # Compute statistics from encoded values instead uv run --no-project --with "flowio==1.4.0" \ python "$FLOWIO_SKILL_DIR/scripts/inspect_fcs.py" sample.fcs --stats --raw
Use --help for output files, input/array memory limits, null-channel labels, and controlled offset-recovery options.
Read only the reference needed for the current task:
references/api_reference.md — exact FlowIO 1.4.0 public API and signaturesreferences/workflows.md — inventory, DataFrame/CSV, batch, write, andround-trip patterns
references/fcs_semantics.md — FCS structure, metadata normalization,preprocessing equations, indexing, and writer behavior
references/troubleshooting.md — offset failures, multi-dataset files,memory limits, validation, security, and privacy
references/sources.md — authoritative upstream docs, release notes, source,and FCS 3.1 publications used for this refresh
as_array(preprocess=True) as raw acquisition values.create_fcs().$ or uppercase spelling.Other measured skills in the registry, with their headline benchmark lift.