FCS (.fcs, .lmd)
Background & Context
-
- FCS molecular biology format.
- Standard format for storing and exchanging flow cytometry data.
- Mixed ASCII/binary format.
- Stores signal intensities for cell events as an array.
- Metainformation about the data acquisition is stored in the file.
Import & Export
- Import["file.fcs"] returns an array representing the cellular events stored in the file.
- Export["file.fcs",{paramnames,events}] exports a list of parameter names and an array of events to the FCS format.
- Export["file.fcs",{paramnames,paramreagents,events}] exports a list of parameter names, a list of parameter reagents, and an array of events to the FCS format.
- Import["file.fcs",elem] imports the specified element from an FCS file.
- Import["file.fcs",{{elem1,elem2,…}}] imports multiple elements.
- The import format can be specified with Import["file","FCS"] or Import["file",{"FCS",elem,…}].
- Export["file.fcs",{expr1,expr2,…},{{elem1,elem2,…}}] treats each expri as specifying the corresponding elemi.
- Export["file.fcs",expr,opt1->val1,…] exports expr with the specified option elements taken to have the specified values.
- Export["file.fcs",{elem1->expr1,elem2->expr2,…},"Rules"] uses rules to specify the elements to be exported.
- See the following reference pages for full general information:
-
Import, Export import from or export to a file CloudImport, CloudExport import from or export to a cloud object ImportString, ExportString import from or export to a string ImportByteArray, ExportByteArray import from or export to a byte array
Import Elements
- General Import elements:
-
"Elements" list of elements and options available in this file "Summary" summary of the file "Rules" list of rules for all available elements - File metadata:
-
"Header" raw file header given as a list of rules - Data representation elements:
-
"Events" cellular events as an array "ParameterName" parameter names as a list of rules (import) or a list (export) "ParameterReagent" parameter reagents as a list of rules (import) or a list (export) - Additional data elements:
-
"Data" cellular events as an array "LabeledData" list of rules for data stored in the file - Import uses the "Events" element by default for the FCS format.
- Export requires at least a list of parameter names and an array of events.
- Export can optionally take a list of parameter reagents. All other optional keys must be specified via the "OptionalKeys" option.
Options
- Advanced Export options:
-
"DataType" Automatic data type used to encode events "OptionalKeys" {} optional keys to include in the header, as a list of rules - The Wolfram Language attempts to identify the most compact format in which the events can be encoded. Automatic data type identification may be overridden via the "DataType" option.
- Valid settings for "DataType" are:
-
"UnsignedInteger8" 8-bit unsigned integer "UnsignedInteger16" 16-bit unsigned integer "UnsignedInteger24" 24-bit unsigned integer "UnsignedInteger32" 32-bit unsigned integer "Real32" IEEE single-precision real number "Real64" IEEE double-precision real number - The Wolfram Language will automatically overwrite certain protected keys (such as "$BEGINDATA" and "$BYTEORD") that are specified in "OptionalKeys". Thus, if you are re-exporting an imported FCS file, you may directly set "OptionalKeys" to the value of the "Header" element from the imported FCS file. Parameter reagents ("$PnS" keys) will be removed from "OptionalKeys" only if parameter reagents are provided in the main Export expression.
Examples
open all close allBasic Examples (7)
Read the file header from a sample FCS file:
Import["ExampleData/5k.fcs", {"FCS", "Header"}]//Short[#, 3]&Read the parameter names and reagents:
Import["ExampleData/5k.fcs", {"FCS", {"ParameterReagent", "ParameterName"}}]Read events and display the first several in a table:
{events, params} = Import["ExampleData/5k.fcs", {"FCS", {"Events", "ParameterName"}}];
TableForm[Transpose[events[[ ;; 5]]], TableHeadings -> {params[[All, 2]], None}]Export an array of event values with parameter names:
ExportString[{{"FSC-A", "SSC-A"}, {{1, 2}, {1, 2}, {1, 3}, {1, 4}, {1, 5}}}, "FCS"]Specify a data type to use when exporting:
ExportString[{{"FSC-A", "SSC-A"}, {{1, 2}, {1, 2}, {1, 3}, {1, 4}, {1, 5}}}, "FCS", "DataType" -> "UnsignedInteger16"]Export an array of event values with parameter names and parameter reagents:
ExportString[{{"FSC-A", "SSC-A"}, {"P1", "P2"}, {{1, 2}, {1, 2}, {1, 3}, {1, 4}, {1, 5}}}, "FCS"]Export a version of a data file with the same header, but with a small subset of the events:
{pns, evs, head} = Import["ExampleData/5k.fcs", {"FCS", {"ParameterName", "Events", "Header"}}];ExportString[{"ParameterName" -> pns[[All, 2]], "Events" -> evs[[ ;; 5]]}, "FCS", "OptionalKeys" -> head]Scope (6)
Plot the untransformed events in a density histogram:
events = Import["ExampleData/5k.fcs", {"FCS", "Events"}];
DensityHistogram[events[[All, {2, 1}]], 100, AspectRatio -> 1, AxesOrigin -> {-200, -200}, PlotRange -> Full, FrameLabel -> {"FSC-W", "FSC-A"}]Plot the events with axes transformed by ArcSinh as a shaded contour plot:
events = Import["ExampleData/5k.fcs", {"FCS", "Events"}];
ticks = {ArcSinh[# / 150], #, Scaled[0.00005]}& /@ {1, 10, 100, 1000, 10000, 100000};
scaling = {ArcSinh[# / 150]&, 150Sinh[#]&};
range = {ArcSinh[-200 / 150], ArcSinh[10000 / 150]};SmoothDensityHistogram[
ArcSinh[# / 150]& /@ events[[ ;; 5000, {6, 9}]],
ColorFunction -> ColorData["Rainbow"],
Mesh -> 10,
FrameTicks -> {{ticks, None}, {ticks, None}},
RegionFunction -> (#3 > 0.01&),
ScalingFunctions -> scaling,
PlotRange -> {range, range},
FrameLabel -> Text /@ Style /@ {"B220", "CD90"}]Use FindClusters to automatically detect similar groups of cells:
events = Import["ExampleData/5k.fcs", {"FCS", "Events"}];
xticks = Join[
(*Major labeled ticks*)
{ArcSinh[# / 150], #}& /@ (10 ^ Range[Log10[1], Log10[100000]]),
-{ArcSinh[# / 150], #}& /@ (10 ^ Range[Log10[1], Log10[100000]]),
(*Minor unlabeled ticks*)
{ArcSinh[# / 150], ""}& /@
Flatten@Outer[Times, 10 ^ Range[0, 4], Join[Range[-9, -1], Range[9]]]
];
ListPlot[FindClusters[ArcSinh[# / 150]& /@ events[[All, {6, 9}]], 3], AspectRatio -> 1, AxesOrigin -> {ArcSinh[-200 / 150], ArcSinh[-200 / 150]}, PlotRange -> Full, AxesLabel -> {Text@Style@"B220", Text@Style@"CD90"}, Ticks -> {xticks, xticks}]Create a grid of 25 of the possible biaxial plots:
{params, events} = Import["ExampleData/5k.fcs", {"FCS", {"ParameterReagent", "Events"}}];(*Global plot range*)
pr = Round[ArcSinh[# / 150]& /@ {Min[events[[All, 4 ;; 8]]], Max[events[[All, 4 ;; 8]]]}, 0.25];
labels = Text[Style[#]]& /@ params[[4 ;; 8, 2]];
Grid[
Join[Partition[{Null}~Join~(Rotate[#, π / 2]& /@ labels), 1],
Join[{labels},
Table[ListPlot[ArcSinh[# / 150]& /@ events[[All, {y, x}]], AspectRatio -> 1, ImageSize -> {80, 80}, FrameTicks -> None, Frame -> True, PlotRange -> {pr, pr}, AxesOrigin -> {-0.5, -0.5}], {x, 4, 8}, {y, 4, 8}]], 2]]Perform polygon gating of cell populations:
{strings, params, events} = Import["ExampleData/5k.fcs", {"FCS", {"ParameterReagent", "ParameterName", "Events"}}];(*Ray casting algorithm*)
PointInPolygonQ[{x_, y_}, poly_] := PointInPolygonQi[x, y, poly];
PointInPolygonQi = Compile[{{ptx, _Real}, {pty, _Real}, {poly, _Real, 2}}, Module[{i, j, c = False, vertx, verty},
{vertx, verty} = Transpose@poly;
For[i = 1;j = Length[vertx], i ≤ Length[vertx], j = i++,
If[(((verty[[i]] > pty) ≠ (verty[[j]] > pty)) && (ptx < (vertx[[j]] - vertx[[i]]) * (pty - verty[[i]]) / (verty[[j]] - verty[[i]]) + vertx[[i]])), c = !c];
];
Return[c]
]];(*Use reagent names when available*)
params = Table[strings[[i, 2]] /. " " -> params[[i, 2]], {i, Length@strings}];is = ImageSize -> {300, 300};
twoDopts = {PlotRange -> {{-.5, 7}, {-.5, 7}}, is, AspectRatio -> 1, AxesOrigin -> {-0.5, -0.5}};
Manipulate[
Column[
{
Labeled[Overlay[{
ListPlot[Map[ArcSinh[# / 150]&, events[[All, {Position[params, x1][[1, 1]], Position[params, y1][[1, 1]]}]], {2}],
twoDopts
],
Graphics[{EdgeForm[Thick], Opacity[0.5], Red, Polygon[pt]}, Frame -> True, twoDopts]
(*Note that we're showing the frame, ticks and labels for both parts of the overlay to provide visual verification that they're overlaid properly*)
}, is], {x1, y1}, {Bottom, Left}, RotateLabel -> True],
subpop = Pick[events[[All, {Position[params, x2][[1, 1]], Position[params, y2][[1, 1]]}]], Map[PointInPolygonQ[#, pt]&, Map[ArcSinh[# / 150]&, events[[All, {Position[params, x1][[1, 1]], Position[params, y1][[1, 1]]}]], {2}]]];
If[SecondDisplay == "2D",
If[Length@subpop > 0,
Labeled[
ListPlot[Map[ArcSinh[# / 150]&, subpop, {2}], twoDopts], {x2, y2}, {Bottom, Left}, RotateLabel -> True], Graphics[{White, Rectangle[]}, is]],
Labeled[SmoothHistogram[Map[ArcSinh[# / 150]&, subpop[[All, 1]]], AspectRatio -> 1, is], x2, Bottom]
]
}
]
,
{{pt, {{-.25, 1.55}, {-.25, 3.25}, {0.5, 3.75}, {1.1, 3.25}, {1.1, 1.75}, {.5, 1.5}}}, Locator, LocatorAutoCreate -> True},
{{x1, params[[6]]}, params, ControlType -> PopupMenu},
{{y1, params[[9]]}, params, ControlType -> PopupMenu},
{{x2, params[[11]]}, params, ControlType -> PopupMenu},
{{y2, params[[7]]}, params, ControlType -> PopupMenu},
{{SecondDisplay, "1D", "Secondary Plot Type"}, {"2D", "1D"}},
ControlPlacement -> {Automatic, Top, Top, Bottom, Bottom, Bottom},
SaveDefinitions -> True
]The FCS standard does not support negative integers:
ExportString[{"ParameterName" -> {"FSC-A", "SSC-A"}, "Events" -> {{1, -2}, {1, 2}, {1, 3}, {1, 4}, {1, 5}}}, "FCS"]Alternatively, export negative integers as reals:
ExportString[{"ParameterName" -> {"FSC-A", "SSC-A"}, "Events" -> {{1, -2}, {1, 2}, {1, 3}, {1, 4}, {1, 5}}}, "FCS", "DataType" -> "Real32"]Related Guides
History
Introduced in 2012 (9.0)