FlowKit
When to use
Use FlowKit to apply or build cytometry gating strategies, analyze batches of FCS samples, or reproduce supported FlowJo workspace analyses. It supports GatingML 2.0 and a subset of FlowJo 10 features. Import success alone does not establish agreement with FlowJo.
The examples and bundled helper target FlowKit 1.3.2 on Python 3.13. Upstream supports additional Python versions; those were not exercised here. The helper and examples were tested on synthetic FCS data, including a public FlowJo 10.6.1 synthetic workspace fixture. They are not biological validation.
Install
Use a separate environment; FlowKit 1.3.2 requires NumPy >2 and pandas <3:
uv venv --python 3.13 .venv-flowkit
uv pip install --python .venv-flowkit/bin/python "flowkit==1.3.2"
.venv-flowkit/bin/python -c "import flowkit; print(flowkit.__version__)"
The scientific package is BSD-3-Clause licensed; this skill is MIT licensed.
工作流程
- Identify the analysis definition. Use
Sessionfor a programmatic or GatingML strategy; useWorkspacefor FlowJo sample-specific gates, compensation, and transforms. Request the actual strategy or controls when biological thresholds have not been supplied. - Inspect samples and channel identities. Match detector/PnN labels to
compensation matrices and gate dimensions; PnS marker names may be empty or
repeated. Verify sample IDs: the default is FCS
$FIL, which can differ from the current filename. Reject ID collisions before loading a batch. - Establish the coordinate system. Determine whether the supplied events are already compensated. Apply compensation before nonlinear transforms; match gate thresholds to the same transformed or untransformed coordinates. See compensation and gating.
- Check the hierarchy. Preserve parent gates and full gate paths, including
root. For a study, review acquisition/time stability, debris exclusion, singlets, viability, and phenotype gates as appropriate to its panel. Use single-stain controls for compensation and suitable negative/FMO controls for positivity; demonstration thresholds are not transferable biology. - Analyze and inspect. Run on all events, then check gate overlays and sample-level QC. A plot's subsample is not the population denominator. Review warnings and compare representative imported results to FlowJo.
- Export counts with denominators and provenance. Keep gate paths, sample IDs, total event counts, input hashes, package versions, and the analysis definition. Keep biological replicates identifiable; events from one specimen are not independent experimental replicates.
Apply an existing strategy
Set FLOWKIT_SKILL_DIR to this skill's installed directory. From the repository
root it is skills/flowkit. Paths below represent the user's local inputs.
FLOWKIT_SKILL_DIR="skills/flowkit"
uv run --no-project --python 3.13 --with "flowkit==1.3.2" \
python "$FLOWKIT_SKILL_DIR/scripts/analyze_gates.py" \
--gatingml gates.xml --fcs sample.fcs --output-dir results-gatingml
For a FlowJo workspace, supply every FCS file in the selected group:
uv run --no-project --python 3.13 --with "flowkit==1.3.2" \
python "$FLOWKIT_SKILL_DIR/scripts/analyze_gates.py" \
--workspace study.wsp --group "Study" \
--fcs sample-a.fcs sample-b.fcs --output-dir results-workspace
The helper writes gate_report.csv and provenance.json to a new directory.
It rejects duplicate sample IDs, missing/extra workspace-group samples,
zero-event samples, and strategies without gates. It uses explicit input files,
does not follow paths embedded in the workspace, and runs without
multiprocessing or transformed-event caching. It still loads each sample into
memory; use manageable batches via the Python API for large studies.
--filename-as-id deliberately switches from $FIL to file basenames. Use it
only when those names match the analysis definition. See
workspace analysis for partial-group
analysis, result interpretation, and fluorescence summaries.
Build a strategy in Python
This runnable example uses sample.fcs with FSC-A, FL1-A, and FL2-A.
The matrix, thresholds, and transform parameters are synthetic teaching
values. Replace them with the study's validated settings.
import flowkit as fk
import numpy as np
sample = fk.Sample("sample.fcs")
strategy = fk.GatingStrategy()
strategy.add_comp_matrix(
"spill", fk.Matrix(
np.array([[1.0, 0.1], [0.2, 1.0]]), ["FL1-A", "FL2-A"],
fluorochromes=["FITC", "PE"],
)
)
logicle = fk.transforms.LogicleTransform(
param_t=262144, param_w=0.5, param_m=4.5, param_a=0
)
strategy.add_transform("logicle", logicle)
strategy.add_gate(
fk.gates.RectangleGate("Cells", [
fk.Dimension("FSC-A", range_min=50, range_max=300)
]),
gate_path=("root",),
)
thresholds = logicle.apply(np.array([50.0, 600.0]))
strategy.add_gate(
fk.gates.RectangleGate("Positive", [
fk.Dimension(
"FL1-A", compensation_ref="spill", transformation_ref="logicle",
range_min=float(thresholds[0]), range_max=float(thresholds[1]),
)
]),
gate_path=("root", "Cells"),
)
session = fk.Session(gating_strategy=strategy, fcs_samples=[sample])
session.analyze_samples(use_mp=False)
report = session.get_analysis_report()
print(report[["sample_id", "gate_path", "gate_name", "count",
"absolute_percent", "relative_percent"]])
with open("gates.xml", "xb") as handle:
session.export_gml(handle)
GatingML exports a template by default. When custom per-sample gates exist,
use session.export_gml(handle, sample_id=sample.id) for that sample's strategy.
A single template export does not preserve every sample-specific override.
Interpretation checks
countis the number of events passing the gate and its ancestors.absolute_percentis percent of all sample events;relative_percentis percent of the immediate parent. These are percentages, not fractions.- Gate names can repeat under different parents. Use
(gate_name, gate_path)as the identifier, not the name alone. The helper serializes paths as JSON arrays inside CSV cells to preserve names containing separators. - A zero-event parent makes a child percentage biologically undefined; FlowKit may report zero. Report the denominator and mark that comparison unavailable rather than interpreting it as absence of a phenotype.
- Compensated negative fluorescence is legitimate. Do not clip it to zero or discard those events merely to permit a logarithmic transform.
- Define whether “MFI” means mean or median and name the event source. A transformed display value is not an intensity on the original scale.
參考資料
- Compensation and gating: event sources, detector order, transform semantics, gate paths, and plotting.
- Workspaces and results: sample matching, missing FCS files, FlowJo limits, and gated fluorescence summaries.
- FlowKit API and versioned source: consult signatures when moving beyond the tested release.
- FlowKit publication: cite the software and version in scientific methods when used for analysis.