FCS (Flow Cytometry Standard) is the file format for conventional, spectral, and mass cytometry (CyTOF) data. This skill covers reading and writing FCS files, mapping detector channels to antibodies, understanding the FCS 2.0/3.0/3.1/3.2 keyword internals that determine how the data should be read, and choosing between the R (flowCore/flowWorkspace/CytoML) and Python (FlowKit/readfcs) ecosystems. The load step's defaults (silent log-linearization, range truncation) materially change downstream numbers, so they are treated as deliberate decisions, not boilerplate.
# R/Bioconductor
BiocManager::install(c('flowCore', 'flowWorkspace', 'CytoML'))
# Python (optional - for FlowKit workflows or the scanpy/AnnData bridge)
pip install flowkit readfcs
Tell your AI agent what you want to do: - "Read my FCS files into R without any transformation" - "Map the detector channels in this FCS file to my antibody panel" - "Load this FCS file into Python as an AnnData object" - "Import my FlowJo workspace into R"
"Load all FCS files from this directory into a flowSet, read them truly raw (no linearization, no range truncation), and show me the channel-to-antibody mapping." "This is a CyTOF file with metal channels - read it and tell me which channels are markers vs Time/Event_length/beads."
"Pull the recorded spillover matrix out of this FCS file's keywords - it may be stored as $SPILLOVER, SPILL, or $COMP." "I want to do the rest of my analysis in scanpy - load these FCS files into AnnData with readfcs."
"Import my FlowJo .wsp workspace and its gated populations into a GatingSet." "Rename the channels to the antibody names, attach my sample metadata table, and write out the result."
transformation=FALSE, truncate_max_range=FALSE) so values are genuinely raw.pData(parameters()) (or pnn/pns labels in FlowKit).read.FCS() defaults to transformation="linearize" - this silently applies $PnE scaling. Use transformation=FALSE for raw values that match other tools.truncate_max_range=FALSE preserves out-of-range events (common on CyTOF and digital instruments).alter.names=TRUE if channel names with hyphens/spaces break formulas or gating.flowjo_to_gatingset), not flowWorkspace; only .wsp (FlowJo 10+), not legacy .jo.flowFrame = single file; flowSet = collection with shared pData. CATALYST/diffcyt require a pData/metadata table keyed by sample name.