Proposed API for Reading and Writing FCS files
v01.08 - May 22, 2000
ISAC Data File Standards Committee
Introduction
The Flow Cytometry Standard (FCS) data file format is uniformly used by flow cytometry instrument manufacturers, software developers, and researchers. The widespread adoption of FCS as a community standard, beginning in 1986, has been particularly important for the growth of third party software vendors and thus enhanced the data analysis options available to users while reducing the pressure on instrument manufacturers to provide all analysis capabilities in a single package. While compatibility of FCS files produced by different vendors is high, some differences in implementation exist.
The International Society for Analytical Cytology (ISAC) adopted the latest version of FCS (3.0) as its official standard in 1998, but conversion from FCS 2.0 has not been initiated by vendors. In part this is testimony to the success of FCS 2.0, with vendors feeling little need for the additional features of the new version.
In order to facilitate implementation of FCS 3.0, to improve standardization between vendors, to ease development of flow cytometry data analysis software by researchers, to enable simple and rapid transitions to future standards, and to facilitate future definition of XML objects, the ISAC Data File Standards Committee has begun development of a public domain; platform-independent software package for reading and writing FCS files. The committee plans for the package to be available as a plug-in or dynamic linked library for all popular operating systems. It is antipated that the package will be widely used by both commercial developers and researchers.
This document contains a draft API for the package, in the form of definitions for classes and methods to represent and access information from FCS files. This draft is being made available for public comment prior to implementation. Please send comments to
murphy@cmu.edu.Class Definitions & Brief Overview
Note. Some classes defined below are specified to exist only within the context of another class. These classes cannot be created by users (and their constructors should therefore be protected or private). They are only meaningful within a larger context. For example, a CFCSData class requires information about the parameters associated with it; however, the parameters are stored in a different class. It is impossible to have a CFCSData class without it knowing what the associated CFCSParameters class is. This linkage is maintained by the parent CFCSDataSet class at the time of creation (thus, in this example, the CFCSDataSet must be a "friend" of the CFCSData class). These classes, when retrieved by the user, are still linked to the CFCSSystem: therefore, if the user modifies their contents, the CFCSSystem is modified.
Other classes can be created by the user (e.g., CFCSParameter). For these classes, when a "Get" function is performed to retrieve that class from the CFCSDataSet, the API copies the information into the class. If these classes are modified by the user, then the CFCSDataSet remains unmodified. The user must call a "Replace" function to copy modifications back into the CFCSDataSet.
An error and any additional information that is returned by all functions defined in this API.
Representation of a single FCS file. This class is responsible for all i/o, maintaining information about the file, and owns all subclasses. A CFCSSystem can be input or output, but not both (in order to switch between reading and writing, issue a Close() and then a re-open for writing). The streaming direction is defined at the time that it is associated with a file-path (URL). It is acceptable that the CFCSSystem members may not be useable unless linked to a file for input or output. Thus, the linking operation for input will likely cause the file keywords & other information to be read in.
Representation of a single FCS data set. Exists only with the context of CFCSSystem. An FCS file may contain multiple data sets, each of which is completely independent of the others. For example, a single FCS file may contain data sets for more than one sample, more than one gating of the same sample, and/or more than one data type for the same sample. It is illegal to close a CFCSSystem that has been opened for output without having created at least one CFCSDataSet within it.
Representation of a keyword set. This class exists only within the context of an existing CFCSDataSet. This class is responsible for retrieving or setting keywords, checking consistency, and returning compatibility errors.
Representation of a single keyword. This class returns the name or value of the keyword, and is responsible for determining keyword value legality. The class can also return/set keyword values in different formats (character, integer, floating point, enumerated types, etc.). This class can exist on its own; getting a CFCSKeyword from the CFCSKeywords retrieves a copy of the keyword & value; to modify, the "Replace" function must be used.
Representation of the collection of parameters in a single dataset. This class exists only within the context of a CFCSDataSet.
A class that specifies a data parameter. This class can exist on its own; retrieving a CFCSParameter from the CFCSParameters class returns a copy of the parameter; to modify, the "Replace" function must be used.
A pure virtual class that is inherited by the following data type classes:
Representation of a listmode data segment. This class has the functionality to retrieve or set individual events or sets of events. Exists only with the context of CFCSDataSet.
Representation of a correlated data segment. Exists only with the context of CFCSDataSet.
Representation of an uncorrelated data setment. Exists only with the context of CFCSDataSet.
Representation of a data segment that is not in TEXT, DATA, or ANALYSIS format. Exists only with the context of CFCSDataSet.
Error codes
Notes: all error code names start with "CFCS"; that designation is left off here for brevity. The second column denotes the severity: whether the error message is success, informational or fatal--i.e., for informational errors, the API was able to resolve the issue on its own or the calling program might succeed by re-trying. The last column denotes what should be placed in the "additional message" field upon return from the API, for possible display to the user.
Error Code |
S |
Stream |
Explanation |
Additional Information |
Success |
S |
Both |
No error occured |
|
StreamAlreadyOpen |
F |
Both |
The stream is already associated to a URL |
|
FileNotFound |
F |
Input |
URL could not be opened |
System Error message |
FileNotFCS |
F |
Input |
URL points to non-FCS file |
|
VersionNotSupported |
F |
Input |
FCS version too high for this library |
Version |
FileNotCreated |
F |
Output |
URL could not be created |
System Error message |
BadStreamDirection |
F |
Both |
Ouput was attempted on read-only or vice versa |
|
NoSuchEvent |
F |
Input |
Requested event number <1 or >$TOT |
|
NoSuchParameter |
F |
Input |
Requested parameter number <1 or >$PAR |
|
MemoryFull |
F |
Both |
System memory request failed |
|
SystemError |
F |
Both |
System error |
System Error message |
IncompatibleValue |
F |
Output |
Keyword value is not compatible |
Specific error message |
NotFCSCompliant |
I |
Input |
FCS structure is not compliant with version |
Specific error message |
BadFCS |
F |
Input |
FCS structure is bad and not recoverable |
Specific error message |
StreamNotOpen |
F |
Both |
Stream has not been opened successfully |
|
ioError |
F |
Both |
i/o error occurred while reading or writing file |
System error message |
NetworkIOError |
I |
Both |
Networking error occurred; may be recoverable by re-trying operation |
System error message |
InvalidSegment |
F |
Output |
Assignment of a keyword to an invalid segment was attempted. |
|
SegmentNotPresent |
I |
Input |
The requested segment does not exist |
|
KeywordNotFound |
F |
Input |
Requested keyword does not exist |
|
KeywordExists |
F |
Output |
Keyword with name already exists |
|
BadKeywordIndex |
F |
Input |
Keyword index <0 or >#keywords |
|
BadValueConversion |
F |
Input |
Keyword value could not be converted |
|
IllegalValue |
F |
Output |
Value is not appropriate for keyword |
|
InconsistentValue |
F |
Output |
Value is not consistent with other keywords |
Name of inconsistent keyword |
CannotModifyValue |
F |
Output |
Keyword cannot be modified: $TOT, $PAR, $FIL, |
|
KeywordModified |
I |
Output |
Keyword exists but was replaced |
Previous value |
UndefinedAttribute |
F |
Both |
Desired attribute was never declared |
|
InconsistentAttribute |
F |
Output |
Parameter attribute inconsistent with previously-declared attribute |
|
ParameterIncomplete |
F |
Output |
Not all parameter attributes have been set |
Missing attributes |
OutOfRange |
I |
|
During parameter scale<->channel conversion, channel number is >= $PnR or <0. |
|
DataTypeUndefined |
F |
Output |
Data mode has not been defined |
|
HistogramOutOfRange |
I |
Input |
Histogram bin larger than requested size allows |
array indices of bad bin value |
ParametersUndefined |
F |
Output |
Data cannot be added to a dataset before the parameters have been fully defined |
|
BadSourceSet |
F |
Output |
Source data set for copy is invalid |
|
NoSuchDataSet |
F |
Both |
Desired set doesnt exist |
|
KeywordUndefined |
F |
|
Keyword has not been initialized |
|
Required Public Class Members
Note: base types include "SInt32" (signed integer, 32 bit length), "UInt16" (unsigned integer, 16 bit length), , "CString" (pointer to a null-terminated array of char).
All routines might return "MemoryFull" or "SystemError" error messages. Any routine which is specified as useable only for "Input", "Output", or "Both" can return the "StreamNotOpen" error. Any routine which is specified for "Input" or "Output" may return "BadStreamDirection" error.
SInt32 errorNumber
One of the values listed in the Table of Section 2. >0 implies nonfatal; 0 is success; <0 is fatal error.
CString additionalInformation
Any additional information that the program may wish to display to the user.
operator SInt32
Casting a CFCSError as a SInt32 returns the errorNumber member.
operator CString
Casting a CFCSError as a CString returns the additionalInformation member.
CFCSError& nextError
If there are multiple errors, then this linked list may be followed to determine all errors associated with the last call.
Notes: the destructor for CFCSError must be sure to destroy the entire linked list of errors. Note that calling routines can distinguish success (errorNumber = 0) from fatal errors (<0) from informational errors (>0).
CString getErrorMessage()
Returns the error message text corresponding to the errorNumber.
CFCSError Open(CString url)
Stream Direction: Undefined only
Possible errors: StreamAlreadyOpen, FileNotFound, FileNotFCS, VersionNotSupported, ioError, NetworkIOError, BadFCS, NotFCSCompliant
Opens the url for reading. Parses keywords and returns any errors related to FCS specifications, consistencies, etc.
CFCSError Create(CString url)
Stream Direction: Undefined only
Possible errors: StreamAlreadyOpen, FileNotCreated, ioError, NetworkIOError
Opens the url for writing. Sets the DataSet count to zero.
CFCSError GetCount(UInt32 setIdx)
Stream Direction: Both
Returns the number of currently-defined data sets.
CFCSError GetDataSet(UInt32 setIdx, CFCSDataSet set)
Stream Direction: Both
Possible errors: NoSuchDataSet
Gets the specified data set (Input only)
CFCSError CreateDataSet(CFCSDataSet set, CFCSDataType type)
Stream Direction: Output
Possible errors: NoSuchDataSet
For output only, creates a new data set, and returns it in the argument. The set index is incremented by one; the new data set will be the last one. The type of the data is specified here (i.e., listmode, correlated, or uncorrelated) therefore, the $MODE keyword for this data set will be defined. The $PAR and the $TOT keywords will be set to zero.
CFCSError CreateDataSet(CFCSDataSet new, CFCSDataSet src)
Stream Direction: Output
Possible errors: NoSuchDataSet, BadSourceSet
For output only, creates a new data set (new) as a copy of the data set src, but with no data or analysis segments in it (but parameters & keywords are copied and modified as necessary). "src" may belong to a different CFCSSystem.
CFCSError DeleteDataSet(UInt32 setIdx)
Stream Direction: Output
Possible errors: NoSuchDataSet
For output only, deletes the specified data set.
CFCSError GetVersion()
Stream Direction: Both
Returns the version number of the current file.
CFCSError Close()
Stream Direction: Both
Possible errors: ioError, NetworkIOError
Closes the URL associated with this system.
CFCSError GetData(CFCSData data)
Stream Direction: Both
Returns the data associated with the current set. The type of the data can be determined by the CFCSData class; then, "data" can be dynamically-cast into the appropriate class type.
CFCSError GetKeywords(CFCSKeywords keywords)
Stream Direction: Both
Returns the keywords class for this system. Modifying "keywords" is an error unless associated with an output stream. Also use this function prior to creating keywords or adding to them.
CFCSError GetParameters(CFCSParameters parameters)
Stream Direction: Both
Returns the parameters class for this system.
CFCSError GetAnalysisSegment(CFCSAnalysisSegment data)
Stream Direction: Both
Possible errors: NoAnalysisSegment
Returns the analysis segment class for a particular data set.
CFCSError GetOtherSegment(Uint32 segIdx, CFCSOtherSegment data)
Stream Direction: Both
Possible errors: NoOtherSegment
Returns a class containing the contents of a requested "OTHER" segment for a particular data set. The segIdx requested must be greater than 3, since TEXT is segment 1, DATA is segment 2, and ANALYSIS is segment 3.
CFCSError GetCount(long count)
Stream Direction: Both
Returns the total number of keywords currently defined (combined between TEXT and ANALYSIS segments).
CFCSError GetKeyword(long index, CFCSKeyword keyword))
Stream Direction: Input
Possible errors: BadKeywordIndex
Returns the class pointing to the keyword. Can only be used with input streams (because index could go bad with DeleteKeyword functions).
CFCSError GetKeyword(CString name, CFCSKeyword keyword)
Stream Direction: Both
Possible errors: KeywordNotFound
Returns the keyword named "name". (Note: the class returned is a "copy" of the actual keyword).
CFCSError AddKeyword(CFCSKeyword keyword)
Stream Direction: Output
Possible errors: KeywordExists, InconsistentValue, CannotModifyValue
Adds the keyword to the current list. Can only be used with output streams. If the keyword already exists, then the keyword is replaced by that specified in the parameter (i.e., "ReplaceKeyword" functionality), and an informational error is returned.
CFCSError ReplaceKeyword(CFCSKeyword keyword)
Stream Direction: Output
Possible errors: KeywordNotFound, InconsistentValue, CannotModifyValue
Replaces the keyword with that specified by the parameter. If the keyword doesn't exist, then an error is returned. Can only be used with output streams.
CFCSError DeleteKeyword(CString name)
Stream Direction: Output
Possible errors: KeywordNotFound, CannotModifyValue
Deletes the keyword corresponding to "name". Can only be used with output streams. Cannot delete certain keywords (i.e., those that associated with existing parameters, or that define the data type, etc.)
CFCSError GetKeywordName(CString name)
Possible errors: KeywordUndefined
Copies the keyword's name to "name".
CFCSError GetKeywordValue(CString value)
Possible errors: KeywordUndefined
Copies the keyword's value to "value".
CFCSError GetKeywordValue(SInt32 value)
Possible errors: KeywordUndefined, BadValueConversion
If possible, converts keyword's value to "value". If not, "value" is set to zero and an error is returned.
CFCSError GetKeywordValue(double value)
Possible errors: KeywordUndefined, BadValueConversion
If possible, converts keyword's value to "value". If not, "value" is set to zero and an error is returned.
CFCSError SetKeywordName(CString name)
Assigns the keyword's name as "name".
CFCSError SetKeywordValue(CString value)
Possible errors: IllegalValue
Assigns the keyword's value as "value".
CFCSError SetKeywordValue(SInt32 value)
Possible errors: IllegalValue
Assigns the keyword's value as "value".
CFCSError SetKeywordValue(double value)
Possible errors: IllegalValue
Assigns the keyword's value as "value".
CFCSError GetKeywordSource(UInt32 segIdx)
Returns the source segment of the keyword (1=TEXT, 3=ANALYSIS).
CFCSError SetKeywordSource(UInt32 segIdx)
Possible errors: IllegalSegment
Assigns the source segment of the keyword (1=TEXT, 3=ANALYSIS).
CFCSError GetCount(long count)
Stream Direction: Both
Returns the number of parameters currently defined.
CFCSError GetParameter(long parmNum, CFCSParameter parm)
Stream Direction: Both
Possible errors: NoSuchParameter
Returns the parameter corresponding to parmNum.
CFCSError AddParameter(CFCSParameter parm)
Stream Direction: Output
Possible errors: ParameterIncomplete
Adds the parameter to the system. Creates the necessary additional keywords in the keyword section; modifies $PAR. Only for output. Before adding parameter, "parm" is checked for consistency of attributes.
CFCSError ReplaceParameter(long parmNum, CFCSParameter parm)
Stream Direction: Output
Possible errors: InconsistentValue
Replaces the existing parameter at index parmNum with that specified. Only for output. Before replacing parameter, "parm" is checked for consistency of attributes.
CFCSError DeleteParameter(long parmNum)
Stream Direction: Output
Possible errors: NoSuchParameter
Delete the parameter designated. All other parameter indices are bumped up by one; keyword names are changed accordingly. Only for output.
CFCSError GetShortName(CString name)
Possible errors: UndefinedAttribute
CFCSError SetShortName(CString name)
Possible errors: IllegalValue
Operates on the value corresponding to $PnN.
CFCSError GetName(CString name)
Possible errors: UndefinedAttribute
CFCSError SetName(CString name)
Operates on the value corresponding to $PnS.
CFCSError GetFieldSize(UInt32 bits)
Possible errors: UndefinedAttribute
CFCSError SetFieldSize(UInt32 bits)
Possible errors: InconsistentAttribute, IllegalValue
Operates on the value corresponding to $PnB. Check for consistency with range.
CFCSError GetRange(UInt32 range)
Possible errors: UndefinedAttribute
CFCSError SetRange(UInt32 range)
Possible errors: InconsistentAttribute, IllegalValue
Operates on the value corresponding to $PnR. Check for consistency with bits.
CFCSError GetGain(double gain)
Possible errors: UndefinedAttribute
CFCSError SetGain(double gain)
Possible errors: IllegalValue
Operates on the value corresponding to $PnG. Should be 1 for log parameters?
CFCSError GetFilter(CString filter)
Possible errors: UndefinedAttribute
CFCSError SetFilter(CString filter)
Operates on the value corresponding to $PnF.
CFCSError GetExcitationWavelength(UInt32 lambda)
Possible errors: UndefinedAttribute
CFCSError SetExcitationWavelength(UInt32 lambda)
Possible errors: IllegalValue
Operates on the value corresponding to $PnL.
CFCSError GetLaserPower(double power)
Possible errors: UndefinedAttribute
CFCSError SetLaserPower(double power)
Possible errors: IllegalValue
Operates on the value corresponding to $PnO.
CFCSError GetEmittedPercent(double percent)
Possible errors: UndefinedAttribute
CFCSError SetEmittedPercent(double percent)
Possible errors: IllegalValue
Operates on the value corresponding to $PnP.
CFCSError GetVoltage(double voltage)
Possible errors: UndefinedAttribute
CFCSError SetVoltage(double voltage)
Possible errors: IllegalValue
Operates on the value corresponding to $PnV.
CFCSError SetLogDecades(double decades)
Possible errors: UndefinedAttribute
CFCSError GetLogDecades(double decades)
Possible errors: IllegalValue
Operates on the value corresponding to the second value of $PnE. Zero implies liear scaling, in which case the offset should be zero and the gain must be nonzero.
CFCSError GetOffset(double offset)
Possible errors: UndefinedAttribute
CFCSError SetOffset(double offset)
Possible errors: IllegalValue
Operates on the value corresponding to the first value of $PnE.
CFCSError ScaleToChannel(double scale, UInt32 channel)
Possible errors: UndefinedAttribute, OutOfRange
Using scaling information, converts the value corresponding to "scale" into a channel number. Out-of-range values are properly converted but flagged with an informational error message.
CFCSError ChannelToScale(UInt32 channel, double scale)
Possible errors: UndefinedAttribute, OutOfRange
Using scaling information, converts a channel number into a scaled value. Out-of-range values are properly converted but flagged with an informational error message.
Note: functions in subclasses that Get data may return I/O errors. It is conceivable that "Set" functions might also return I/O errors, depending on implementation.
CFCSError GetType(CFCSDataType type)
Stream Direction: Both
Returns the type of this class (Listmode, uncorrelated, or correlated).
CFCSError GetCount(UInt32 count)
Stream Direction: Both
Returns the total number of events in the listmode dataset.
CFCSError GetEvent(UInt32 index, UInt8 byteArray)
CFCSError GetEvent(UInt32 index, UInt16 shortArray)
CFCSError GetEvent(UInt32 index, UInt32 longArray)
Stream Direction: Input
Possible errors: NoSuchEvent
Returns the single event specified by "index" into an array of 8, 16, or 32-bit values. (See below for general retrieval function). Only the most significant bits of parameter values are returned if truncation is performed. The array in the parameter must have (at least) $PAR entries; each entry on return will correspond to the indexed parameter value for that event.
CFCSError GetEvent(UInt32 index, double floatArray)
Stream Direction: Input
Possible errors: NoSuchEvent, OutOfRange
Same as above, but returns the Scale value of the parameter (i.e., arithmetic conversion is performed)
CFCSError GetEvents(UInt32 startIndex, UInt32 endIndex, UInt32 longTable)
Stream Direction: Input
Possible errors: NoSuchEvent
Returns a series of events starting and ending with the specified indices. longTable is a two dimensional array, where the inner dimension (most rapidly changing) equals the number of parameters ($PAR) and the outer dimension is at least as great as the number of events requested.
CFCSError AddEvent(UInt32 index, UInt32 longArray)
Stream Direction: Output
For output, adds an event at the specific index to the list mode data. "longArray" must have at least $PAR entries. This routine can only be used if $PnB for all parameters is less than or equal to 32.
CFCSError AddEvent(UInt32 index, double floatArray)
Stream Direction: Output
Possible Errors: OutOfRange
For output, adds an event at the specified index to the list mode data. The values in doubleArray are individually converted to channel numbers for storing in the list mode set.
CFCSError AddEvents(UInt32 startIndex, UInt32 endIndex, UInt32 longTable)
Stream Direction: Output
For output, adds a series of events starting and ending with the specified indices to the list mode data. longTable is a two dimensional array, where the inner dimension (most rapidly changing) equals the number of parameters ($PAR) and the outer dimension is the number of events being added.
CFCSError GetEvent(UInt32 index, UInt8 nBytes, UInt8 longTable)
CFCSError AddEvent(UInt32 index, UInt8 nBytes, UInt8 longTable)
Stream Direction: (as above)
General input/output routines when parameters have more than 32 bits. nBytes is the number of bytes used to specify each event, and must be at least as great as the largest $PnB value times 8. longTable is a two dimensional array, where the inner dimension (most rapidly changing) equals nBytes, and the outer dimension equals $PAR. Use this routine when one or more $PnB values are greater than 32.
CFCSError GetArray(UInt32 longTable)
Stream Direction: Input
Possible errors: HistogramOutOfRange
Returns the counts in the correlated histogram. longTable is a two dimensional array, where the inner dimension (most rapidly changing) corresponds to the first parameter and equals $P1R, and the outer dimension is at least as large as $P2R. If $PnB for either parameter is >31 AND any given bin value is >2^32, then an error is returned (that specifies which bin(s) were out of range).
CFCSError SetArray(UInt32 longTable)
Stream Direction: Output
Defines the counts in the correlated histogram. longTable is a two dimensional array, where the inner dimension (most rapidly changing) corresponds to the first parameter and equals $P1Rr, and the outer dimension is at least as large as $P2R.
CFCSError GetArray(UInt8 nBytes, UInt32 longTableArray)
CFCSError SetArray(UInt8 nBytes, UInt32 longTableArray)
Stream Direction: (as above)
Possible errors: (as above)
General size access. Returns the counts in this dataset. longTableArray is a three dimensional array, where the inner dimension (most rapidly changing) is nBytes, the second dimension corresponds to the first parameter and equals $P1Rr, and the third dimension is at least as large as $P2R.
CFCSError GetArray(UInt32 parmIndex, UInt32 longArray)
Stream Direction: Input
Possible errors: HistogramOutOfRange
Returns the counts in the uncorrelated histogram for a particular parameter. longArray is an array of size at least as large as $PnR for the parameter. If $PnB is >31 AND any given bin value is >2^32, then an error is returned (that specifies which bin(s) were out of range). parmIndex is the parameter number requested.
CFCSError SetArray(UInt32 parmIndex, UInt32 longArray)
Stream Direction: Output
Possible errors: NoSuchParameter
Defines the counts in the uncorrelated histogram for a particular parameter. longArray is an array of size $PnR. parmIndex is the parameter number being stored.
CFCSError GetArray(UInt32 parmIndex, UInt8 nBytes, UInt32 longTable)
CFCSError SetArray(UInt32 parmIndex, UInt8 nBytes, UInt32 longTable)
Stream Direction: (as above)
Possible errors: (as above)
General size access. Returns/Defines the counts in the uncorrelated histogram for a particular parameter. longTable is a two dimensional array, where the inner dimension (most rapidly changing) is nBytes, and the second dimension is at least as large as $PnR.
Suggested Class Members (Protected or Private)
None.
UInt32 nSets
CFCSDataSet datasetclass[nSets]
CFCSKeywords keywordClass
CFCSParameters parametersClass
CFCSData dataClass
None.
None.
None.
CString shortName, fullName, filter
UInt32 bits, range, lambda
double gain, power, percent, decades, offset
bool pNSDefined, pnNDefined, pNBDefined,
The latter flags denote whether or not the attribute have been specified (by the FCS file or by the user program).
UInt32 type
The parent class for all FCS data types.
Uint32 nevents, nparam
UInt32 lmdata[nevents, nparam]
Uint32 nchanx, nchany
UInt32 cmdata[nchanx, nchany]
Uint32 nchan, nparam
UInt32 umdata[nchan, nparam]
Example code.
// Handle a CFCSError
// Returns 0 if no errors; -1 if any errors in the chain are fatal, and
// +1 if all nonzero errors are informational. Prints all error messages.
bool FailIfError(CFCSError error)
{
CFCSError currentError = error;
UInt32 errorType = 0;
while (currentError.nextError != 0)
{
print(currentError.GetErrorMessage(), currentError.additionalInformation);
if (currentError.errorNumber < 0)
errorType = -1;
else if (currentError.errorNumber 0 and errorType == 0)
errorType = 1;
}
return errorType;
}
// Read in an FCS file, and print the version and all associated keywords for each data set.
program main
{
CFCSSystem system;
CFCSDataSet set;
"URL" filePath;
CString version, keyName, keyValue;
CFCSKeywords fcsKeywords;
CFCSKeyword keyword;
CFCSError error;
long iSet, count, idx, nSets;
error = system.Open(filePath);
if (FailIfError(error) != 0) break;
error = system.GetVersion(version);
print(version);
error = system.GetCount(nSets);
for (iSet = 1; iSet <= nSets; iSet++)
{
print("Keywords for set #", iSet);
error = system.GetDataSet(iSet, set);
error = set.GetKeywords(fcsKeywords);
error = fcsKeywords.GetCount(count);
for (idx=0; idx < count; idx++)
{
fcsKeywords.GetKeyword(idx, keyword);
keyword.GetName(keyName);
keyword.GetValue(keyValue);
print(keyName, ": ", keyValue);
}
}
error = system.Close()
}
// Gate an FCS file, removing all values of P1 < 100 channels for all listmode datasets in the file (skipping any non listmode datasets)
program main
{
CFCSSystem readSystem, writeSystem;
CFCSDataSet readSet, writeSet;
CFCSData readData, writeData;
CFCSDataType readDataType
"URL" inputFile, outputFile;
CFCSListModeData readList, writeList;
CFCSError error;
long nSet, nParm, iset, nCells, idx, nGatedEvents, eventSize;
error = readSystem.Open(inputFile);
if (FailIfError(error) != 0) break;
error = readSystem.GetCount(nSet)
error = writeSystem.Create(outputFile);
if (FailIfError(error) != 0) break;
for (iset = 1; iset <= nSet; iset++)
{
error = readSystem.GetDataSet(iset, readSet);
error = readSet.GetParameters(parmList);
error = parmList.GetCount(nParm);
error = readSet.GetData(readData);
error = readData.GetType(readDataType);
if (readDataType == ListModeData)
{
error = readData.GetCount(nCells);
error = writeSystem.CreateDataSet(writeSet, readSet);
error = writeSet.GetData(writeData);
readList = <dynamic_cast (CFCSListMode) readData;
writeList = <dynamic_cast (CFCSListMode) writeData;
// allocate an array to hold one event
eventSize = nParm * sizeof(UInt32); // let's not worry about $PnB 32
event = malloc(eventSize);
nGatedEvents = 0;
for (idx = 1; idx <= nCells; idx++)
{
error = readList.GetEvent(idx, event);
if (event[0] 100)
{
nGatedEvents++;
writeList.AddEvent(nGatedEvents, event);
}
}
}
}
readSystem.Close();
writeSystem.Close();
}