Reading Flow Cytometry Data¶
This tutorial focuses on how to open FCS files and manipulate the data therein using FlowCal
.
To start, navigate to the examples
directory included with FlowCal, and open a python
session therein. Then, import FlowCal
as with any other python module.
>>> import FlowCal
FCS files are standard files in which flow cytometry data is stored. Normally, one FCS file corresponds to one sample.
The object FlowCal.io.FCSData
allows a user to open an FCS file. The following instruction opens the file Data001.fcs
from the FCFiles
folder, loads the information into an FCSData
object, and assigns it to a variable s
.
>>> s = FlowCal.io.FCSData('FCFiles/Data001.fcs')
An FCSData
object is a 2D numpy
array with a few additional features. The first dimension indexes the event number, and the second dimension indexes the flow cytometry channel (or “parameter”, as called by the FCS standard). We can see the number of events and channels using the standard numpy
‘s shape
property:
>>> print s.shape
(30000, 8)
As with any numpy
array, we can slice an FCSData
object. For example, let’s obtain the first 100 events.
>>> s_sub = s[:100]
>>> print s_sub.shape
(100, 8)
Note that the product of slicing an FCSData object is also an FCSData object. We can also get all the events in a subset of channels by slicing in the second dimension.
>>> s_sub_ch = s[:, [3, 4, 5]]
>>> print s_sub_ch.shape
(30000, 3)
However, it is not immediately obvious what channels we are getting. Fortunately, the FCSData
object contains some additional information about the acquisition settings. In particular, we can check the name of the channels with the channels
property.
>>> print s.channels
('TIME', 'FSC', 'SSC', 'FL1', 'FL2', 'FL3', 'FL1W', 'FL1A')
>>> print s_sub_ch.channels
('FL1', 'FL2', 'FL3')
It turns out that s_sub_ch
contains the fluorescence channels FL1
, FL2
, and FL3
.
One of the most practical features of an FCSData
object is the ability to slice channels using their name. For example, if we want the fluorescence channels we can use the following.
>>> s_sub_ch_2 = s[:, ['FL1', 'FL2', 'FL3']]
>>> print s_sub_ch_2.channels
('FL1', 'FL2', 'FL3')
This is completely equivalent to indexing with integers.
>>> import numpy as np
>>> np.all(s_sub_ch == s_sub_ch_2)
True
FCSData
contains more acquisition information, such as the acquisition time, amplifier type, and the detector voltage of each channel. For more information, consult the documentation of FlowCal.io.FCSData
.