SofieVG/FlowSOM

ReadInput/AddFlowframe: doc

SamGG opened this issue · 6 comments

SamGG commented

Hi. To be more precise, when no compensation matrix is given, but compensation is wanted (compensate = TRUE), the spillover matrix is searched in the first flowFrame (or FCS file), and the next flowFrames (or FCS files) will be compensated with this spillover matrix, not their own.
To be short, the compensation matrix of the flowSOM object is the one of the first FCS, and all added FCS are compensated with it.

FlowSOM/R/1_readInput.R

Lines 10 to 13 in 7d1fcfc

#' @param compensate logical, does the data need to be compensated
#' @param spillover spillover matrix to compensate with
#' If \code{NULL} and compensate=\code{TRUE}, we will
#' look for \code{$SPILL} description in fcs file.

FlowSOM/R/1_readInput.R

Lines 130 to 163 in 7d1fcfc

#' Add a flowFrame to the data variable of the FlowSOM object
#'
#' @param fsom FlowSOM object, as constructed by the ReadInput function
#' @param flowFrame flowFrame to add to the FlowSOM object
#'
#' @return FlowSOM object with data added
#'
#' @seealso \code{\link{ReadInput}}
AddFlowFrame <- function(fsom, flowFrame){
# Compensation
if(fsom$compensate){
if(is.null(fsom$spillover)){
if(!is.null(flowFrame@description$SPILL)){
fsom$spillover <- flowFrame@description$SPILL
} else if (!is.null(flowFrame@description$`$SPILLOVER`)){
if(class(flowFrame@description$`$SPILLOVER`)=="matrix"){
fsom$spillover = flowFrame@description$`$SPILLOVER`
flowFrame@description$SPILL = fsom$spillover
} else {
spilloverStr <- strsplit(
flowFrame@description$`$SPILLOVER`,
",")[[1]]
n <- as.numeric(spilloverStr[1])
fsom$spillover <- t(matrix(as.numeric(spilloverStr[(n+2):
length(spilloverStr)]),ncol=n))
colnames(fsom$spillover) <- spilloverStr[2:(n+1)]
flowFrame@description$SPILL <- fsom$spillover
}
} else {
stop("No compensation matrix found")
}
}
flowFrame <- flowCore::compensate(flowFrame, fsom$spillover)
}

L135 ... and spillover matrix instantiated (?)
Thanks for reviewing my comments. Best.

SamGG commented

Hi. I just have noticed that you updated the code fff3982. That's fine, but you are the developer and don't have to follow any wish. Thanks.
Because of this new behavior of FlowSOM, I was a little bit worried about the mapping of new data. I reviewed the code in that view, and I am pretty sure you already did, but I will appreciate if you could check again the impact of the absence of the spillover in the FlowSOM object when mapping new data to it.
I think that the code should check that the spillover argument is a matrix at

FlowSOM/R/1_readInput.R

Lines 164 to 166 in fff3982

} else {
spillover <- fsom$spillover
}

Best.

Hi, thank you very much for your input!
I thought with the last update to the code, I addressed the issue you specified before:
If spillover is NULL en compensate is TRUE, we will always look for the file-specific one, instead of accidentally reusing the first one. Alternatively, if spillover is not NULL, the given value (indeed assumed to be a matrix, I can add the check) will be used.
For the NewData function, the spillover argument that is passed to this function call will have precedence: if this contains a matrix, this is used. If it is NULL, I assume the user wants to do the same as in the original FlowSOM call, i.e. using the specified matrix value from that spillover argument, or if it was NULL in the original call as well, we look for the spillover matrix identified in the file.

Could you explain clearer to me what you think is going wrong in the current version of the code? I am not sure if I understand your last remark.

Best,
Sofie

SamGG commented

Nothing's wrong with the current code.
I checked your first point and agreed.
I wanted to be absolutely sure about how NewData will manage flowFrame when compensate is TRUE but spillover is NULL.
The 3rd point is an addendum in order to verify that the argument passed to spillover is of class "matrix" in the same way it is done a few lines above and to throw an error if it is not.

if(class(flowFrame@description$`$SPILLOVER`)=="matrix"){

Best.

Dear Sophie,
Many thanks for FlowSOM! I'm very excited to use it. I am having trouble with the method AddFlowFrame(). Specifically, the function doesn't appear to exist. I've just updated R to the latest stable version, 3.6.0, and installed FlowSOM v1.16.0 using BiocManager::install("FlowSOM").
I have done extensive pre-processing (compensation, transformation, and pre-gating) on my data outside of FlowSOM, and everything is held in a flowSet. I built a FlowSOM object on an aggregated and sampled subset of the data (for efficiency) and now would like to add back all of the original data. It seemed like AddFlowFrame could be used iteratively for each frame of the flowSet. However, it does not appear that the function AddFlowFrame() exists. Could you let me know if I'm doing something wrong or if you have any suggestions?
Many thanks again!
Wade

Many thanks Sofie. Will give it a go!
Cheers,
Wade