import_op has two classes:

Tube – represents a tube in a flow cytometry experiment – an FCS file name and a dictionary of experimental conditions.

ImportOp – the operation that actually creates a new Experiment from a list of Tube.

There are a few utility functions as well:

class cytoflow.operations.import_op.Tube[source]

Bases: traits.has_traits.HasTraits

Represents a tube or plate well we want to import.


The file name of the FCS file to import




A dictionary containing this tube’s experimental conditions. Keys are condition names, values are condition values.


Dict(Str, Any)


>>> tube1 = flow.Tube(file = 'RFP_Well_A3.fcs', conditions = {"Dox" : 10.0})
>>> tube2 = flow.Tube(file='CFP_Well_A4.fcs', conditions = {"Dox" : 1.0})
class cytoflow.operations.import_op.ImportOp[source]

Bases: traits.has_traits.HasStrictTraits

An operation for importing data and making an Experiment.

To use, set the conditions dict to a mapping between condition name and NumPy dtype. Useful dtypes include category, float, int, bool.

Next, set tubes to a list of Tube containing FCS filenames and the corresponding conditions.

If you would rather not analyze every single event in every FCS file, set events to the number of events from each FCS file you want to load.

Call apply to load the data. The usual experiment parameter can be None.


A dictionary mapping condition names (keys) to NumPy dtype``s (values). Useful ``dtype``s include ``category, float, int, and bool.


Dict(Str, Str)


A list of Tube instances, which map FCS files to their corresponding experimental conditions. Each Tube must have a Tube.conditions dict whose keys match those of conditions.




If you only need a subset of the channels available in the data set, specify them here. Each (key, value) pair specifies a channel to include in the output experiment. The key is the channel name in the FCS file, and the value is the name of the channel in the Experiment. You can use this to rename channels as you import data (because flow channel names are frequently not terribly informative.) New channel names must be valid Python identifiers: start with a letter or _, and all characters must be letters, numbers or _. If channels is empty, load all channels in the FCS files.


Dict(Str, Str)


If not None, import only a random subset of events of size events. Presumably the analysis will go faster but less precisely; good for interactive data exploration. Then, unset events and re-run the analysis non-interactively.




Which FCS metadata is the channel name? If None, attempt to autodetect.


{None, “$PnN”, “$PnS”} (default = None)


The FCS standard allows you to encode multiple data sets in a single FCS file. Some software (such as the Beckman-Coulter software) also encode the same data in two different formats – for example, FCS2.0 and FCS3.0. To access a data set other than the first one, set data_set to the 0-based index of the data set you would like to use. This will be used for all FCS files imported by this operation.


Int (default = 0)


cytoflow is designed to operate on an Experiment containing tubes that were all collected under the same instrument settings. In particular, the same PMT voltages ensure that data can be compared across samples.

Very rarely, you may need to set up an Experiment with different voltage settings on different Tube instances. This is likely only to be the case when you are trying to figure out which voltages should be used in future experiments. If so, set ignore_v to a list of channel names to ignore particular channels.






>>> tube1 = flow.Tube(file = 'RFP_Well_A3.fcs', conditions = {"Dox" : 10.0})
>>> tube2 = flow.Tube(file='CFP_Well_A4.fcs', conditions = {"Dox" : 1.0})
>>> import_op = flow.ImportOp(conditions = {"Dox" : "float"},
...                           tubes = [tube1, tube2])
>>> ex = import_op.apply()
apply(experiment=None, metadata_only=False)[source]

Load a new Experiment.

  • experiment (Experiment) – Ignored

  • metadata_only (bool (default = False)) – Only “import” the metadata, creating an Experiment with all the expected metadata and structure but 0 events.


The new Experiment. New channels have the following metadata:

  • voltage - int

    The voltage that this channel was collected at. Determined by the $PnV field from the first FCS file.

  • range - int

    The maximum range of this channel. Determined by the $PnR field from the first FCS file.

New experimental conditions do not have voltage or range metadata, obviously. Instead, they have experiment set to True, to distinguish the experimental variables from the conditions that were added by gates, etc.

If ignore_v is set, it is added as a key to the Experiment-wide metadata.

Return type


cytoflow.operations.import_op.check_tube(filename, experiment, data_set=0)[source]

Check to see if an FCS file can be parsed, and that the tube’s parameters are the same as those already in the Experiment. If not, raises CytoflowError. At the moment, only checks $PnV, the detector voltages.

  • filename (string) – An FCS filename

  • experiment (Experiment) – The Experiment to check filename against.

  • data_set (int (optional, default = 0)) – The FCS standard allows for multiple data sets; data_set specifies which one to check.


CytoflowError – If the FCS file can’t be read, or if the voltages in filename are different than those in experiment.

cytoflow.operations.import_op.autodetect_name_metadata(filename, data_set=0)[source]

Tries to determine whether the channel names should come from $PnN or $PnS.

  • filename (string) – The name of the FCS file to operate on

  • data_set (int (optional, default = 0)) – Which data set in the FCS file to operate on


  • The name of the parameter to parse channel names from,

  • either “$PnN” or “$PnS”

cytoflow.operations.import_op.parse_tube(filename, experiment=None, data_set=0, metadata_only=False)[source]

Parses an FCS file. A thin wrapper over fcsparser.parse.

  • filename (string) – The file to parse.

  • experiment (Experiment (optional, default: None)) – If provided, check the tube’s parameters against this experiment first.

  • data_set (int (optional, default: 0)) – Which data set in the FCS file to parse?

  • metadata_only (bool (optional, default: False)) – If True, only parse the metadata. Because this is at the beginning of the FCS file, this happens much faster than parsing the entire file.


  • tube_metadata (dict) – The metadata from the FCS file

  • tube_data (pandas.DataFrame) – The actual tabular data from the FCS file. Each row is an event, and each column is a channel.