RGLab / flowCore

Core flow cytometry infrastructure
43 stars 25 forks source link

read.FCS : where does minRange = -111.00 come from ? #225

Closed phauchamps closed 2 years ago

phauchamps commented 2 years ago

Hello dear flowCore team !

Describe the bug

This is not a bug but rather a question. Where does the -111.00 'magic number' for assigning a minimum range to channels intensities come from ? This value seems to sometimes appear in pData(parameters(x)) when using read.FCS().

I found the following line in the code of read.FCS, which seems to be at the origin of this behaviour :

realMin <- pmin(zeroVals,pmax(-111, absMin, na.rm=TRUE), na.rm=TRUE)

To Reproduce Additional context I am importing a fcs file found on flowRepository : flowrepository name : FR-FCM-ZZ36 file name : _pbmcluca.fcs

negative values are found in the file, sometimes way below 'magic number' -111.00 for some of the channels, on a linear scale, although the intensities are prior to compensation (check done in flowJo). Therefore, this -111.00 minRange value is not in line with the actual negative values found in the expression matrix.

SamGG commented 2 years ago

Hi, To my knowledge, this mimics the behavior of FlowJo. I don't think there is any standard. Best.

phauchamps commented 2 years ago

Hi,

Is Sam answer the final one ? Any idea why the minRange is set to -111 (or then said differently, why FlowJo uses this threshold) ? Why using any implicit threshold to start with, and not exposing the latter as a parameter controllable by the user (with default=-111 if suitable) ?

Thanks,

Philippe

gfinak commented 2 years ago

This is all historical. flowCore was developed over a decade ago and I can only presume some of these settings were taken from how flowJo did things at the time. There was close collaboration between the open source and FJ teams.

Greg Finak

On Mon, Jan 31, 2022, 06:55 Philippe Hauchamps @.***> wrote:

Hi,

Is Sam answer the final one ? Any idea why the minRange is set to -111 (or then said differently, why FlowJo uses this threshold) ? Why using any implicit threshold to start with, and not exposing the latter as a parameter controllable by the user (with default=-111 if suitable) ?

Thanks,

Philippe

— Reply to this email directly, view it on GitHub https://github.com/RGLab/flowCore/issues/225#issuecomment-1025837316, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAKSI6IZTL7QUH56MR5Q3MDUY2PHVANCNFSM5MPZ4A6Q . You are receiving this because you are subscribed to this thread.Message ID: @.***>

phauchamps commented 2 years ago

Thanks for your answer Greg.

SamGG commented 2 years ago

Therefore, this -111.00 minRange value is not in line with the actual negative values found in the expression matrix.

Correct. The minRange is not defined in the FCS standard, not computed from the data but deduced from the header of the FCS file. The code line you found explains why the minRange is set to -111 when reading a file that seems to be directly originating from the instrument.

Because a code line is better than ten sentences, here is my typical code line to read a FCS file.

ff = read.FCS("pbmc_luca cd8.fcs", transformation = FALSE, min.limit = NULL, truncate_max_range = FALSE)

It does not avoid the -111 effect you pointed, but it ensures the data are not transformed.

PS: consider closing the issue unless Greg's answer does not fulfill your question.