Nothing
xmlElementsByTagName <- function(...)suppressWarnings(XML::xmlElementsByTagName(...))
compact <- function (x)
{
null <- vapply(x, is.null, logical(1))
x[!null]
}
#' the parameter range from the flow data associated with GatingHierarchy
#' @param ... GatingHierarchy object
#' @param na.rm not used
#' @param type character of "instrument" or "data" indicating whether to retrieve the instrument or the actual data range
#' @param raw.scale logical whether convert the range from transformed scale to raw scale
#' @return matrix
#' @examples
#' \dontrun{
#' range(gh, type = "data")#return data range
#' range(gh) #return instrument range
#' range(gh, raw.scale = TRUE) #inverse transform the range to the raw scale
#' }
range.GatingHierarchy <- function(..., na.rm = FALSE, type = c("instrument", "data"), raw.scale = FALSE){
type <- match.arg(type)
gh <- list(...)[[1]]
fr <- gh_pop_get_data(gh, use.exprs = type == "data")
rng <- range(fr, type = type)
if(raw.scale)
{
chnls <- names(rng)
translist <- gh_get_transformations(gh, only.function = FALSE)
for(chnl in chnls)
{
trans <- translist[[chnl]]
if(!is.null(trans))
{
rng[, chnl] <- trans$inverse(rng[, chnl])
}
}
}
rng
}
is.cytof <- function(gs){
any(grepl("Event_length", colnames(gs)))
}
######################################
#common APIs related to processing comp, trans, gates
#to prepare the GatingML output that can be shared by both cytobank and flowJo modules
######################################
#' @importFrom flowWorkspace gh_pop_get_data
#' @importFrom flowCore compensation identifier identifier<- compensatedParameter asinhtGml2 logicletGml2 logtGml2
export_comp_trans <- function(gs, flowEnv, cytobank.default.scale = FALSE, type = c("cytobank", "flowJo"))
{
type <- match.arg(type)
#parse comp and channel names
comp <- gh_get_compensations(gs[[1]])#assuming the comp is identical across samples
if(is.null(comp)){
#no compensation and channel names in transformation are not prefixed
chnls <- colnames(gs_pop_get_data(gs))
prefix_chnls_orig <- chnls
}else{
chnls <- as.vector(parameters(comp))
#retrieve the prefix for latter trans matching
cmp <- gs_get_compensation_internal(gs@pointer, sampleNames(gs)[[1]])
prefix <- cmp$prefix
suffix <- cmp$suffix
prefix_chnls_orig <- paste0(prefix, chnls, suffix)
}
#add comp
if(!is.null(comp)){
if(type == "cytobank"){
#prefix the channels since cytobank expect that
prefix_chnls <- paste0("Comp_", chnls)
rownames(comp@spillover) <- prefix_chnls #change fluorochromes and leave detector(colnames) unchanged
}else{
#prefix the channels
prefix_chnls <- paste0("Comp-", chnls)
# prefix_chnls <- chnls #flowJo use the raw channel name
# rownames(comp@spillover) <- prefix_chnls #change fluorochromes
# markers <- markernames(gs)
# rownames(comp@spillover) <- markers #change detector to marker names because flowJo seems to expect that
}
comp <- compensation(comp@spillover)
compId <- identifier(comp)
compId <- paste("Spill", compId, sep = "_")
identifier(comp) <- compId
flowEnv[[compId]] <- comp
}else{
compId <- "FCS"
prefix_chnls <- chnls
}
#add trans (assume it is identical across samples)
trans <- gh_get_transformations(gs[[1]], only.function = FALSE)
if(length(trans) == 0)
stop("no transformation is found in GatingSet!")
trans.Gm2objs <- list()
rescale.gate <- FALSE
for(transName in names(trans)){
trans.obj <- trans[[transName]]
type <- trans.obj[["name"]]
# ind <- sapply(chnls, grepl, x = transName, USE.NAMES = FALSE)
ind <- prefix_chnls_orig == transName#do strict match due to the possible mismatch for cases like CD3 vs CD33
nMatched <- sum(ind)
if(nMatched > 1)
stop("More than one channels matched to transformation: ", transName)
else if(nMatched == 1){
trans.func <- trans.obj[["transform"]]
chnl <- chnls[ind]
prefix_chnl <- prefix_chnls[ind]
prefix_chnl_orig <- prefix_chnls_orig[ind]
# if(is.null(comp))
# param.obj <- prefix_chnl
# else
param.obj <- compensatedParameter(prefix_chnl
, spillRefId = compId
, searchEnv = flowEnv
, transformationId = prefix_chnl)
if(type %in% c("asinhtGml2", "flowJo_fasinh")){
#extract parameters
env <- environment(trans.func)
transID <- paste0("Tr_Arcsinh_", prefix_chnl)
flowEnv[[transID]] <- asinhtGml2(parameters = param.obj
, M = env[["m"]]
, T = env[["t"]]
, A = env[["a"]]
, transformationId = transID
)
}else if(type == "logicleGml2"){
#extract parameters
env <- environment(trans.func)
transID <- paste0("Tr_logicleGml2_", prefix_chnl)
flowEnv[[transID]] <- logicletGml2(parameters = param.obj
, M = env[["M"]]
, T = env[["T"]]
, A = env[["A"]]
, W = env[["W"]]
, transformationId = transID
)
}else if(type %in% c("logicle", "flowJo_logicle")){
#extract parameters
env <- environment(trans.func)
transID <- paste0("Tr_logicle_", prefix_chnl)
flowEnv[[transID]] <- logicletGml2(parameters = param.obj
, M = env[["m"]]
, T = env[["t"]]
, A = env[["a"]]
, W = as.vector(env[["w"]])
, transformationId = transID
)
rescale.gate <- TRUE
}else if(type %in% c("flowJo_biexp")){
transID <- paste0("Tr_logicle_", prefix_chnl)
param <- attr(trans.func,"parameters")
flowEnv[[transID]] <- logicletGml2(parameters = param.obj
, M = param[["pos"]]
, T = param[["maxValue"]]
, A = param[["neg"]]
, W = log10(-param[["widthBasis"]]) / 2
, transformationId = transID
)
rescale.gate <- TRUE
}else if(type == "flowJo_flog"){
env <- environment(trans.func)
transID <- paste0("Tr_flog_", prefix_chnl)
flowEnv[[transID]] <- logtGml2(parameters = param.obj
, M = 1
, T = 1
, transformationId = transID
)
rescale.gate <- TRUE
}else if(type == "logtGml2"){
stop("logtGml2 is not supported yet!")#there is some issue associated with gate truncation at negative side during exporting, need to further troubleshoot
env <- environment(trans.func)
transID <- paste0("Tr_flog_", prefix_chnl)
flowEnv[[transID]] <- logtGml2(parameters = param.obj
, M = env[["decade"]]
, T = env[["max_val"]]
, boundMin = env[["min_val"]]
, transformationId = transID
)
rescale.gate <- TRUE
}else{
# browser()
stop("unsupported trans: ", type)
}
if(cytobank.default.scale){
rescale.gate <- TRUE
#overwrite the customed scale with default one
flowEnv[[transID]] <- asinhtGml2(parameters = param.obj
, M = 0.43429448190325176
, T = ifelse(is.cytof(gs), 5.8760059682190064, 176.2801790465702)
, A = 0.0
, transformationId = transID)
}
#save another copy of trans.obj in the list
trans.Gm2objs[[prefix_chnl_orig]] <- flowEnv[[transID]]
}
}
return(list(trans.Gm2objs = trans.Gm2objs, trans = trans, compId = compId))
}
#' @importFrom flowCore eval
processGate <- function(gate, gml2.trans, compId, flowEnv, rescale.gate = FALSE, orig.trans){
params <- as.vector(parameters(gate))
prefixed_chnls_orig <- names(gml2.trans)
for(i in seq_along(params)){
param <- params[i]
# ind <- sapply(chnls, function(chnl)grepl(chnl, param), USE.NAMES = FALSE)
ind <- prefixed_chnls_orig == param
nMatched <- sum(ind)
if(nMatched == 0){
chnl <- gate@parameters[[i]]@parameters
#can't use "uncompensated" because it will cause multiple entries when paring gate back into openCyto through cytobank_to_gatingset
gate@parameters[[i]] <- compensatedParameter(chnl
, spillRefId = compId #"uncompensated"
, searchEnv = flowEnv
, transformationId = chnl
)
}else if(nMatched == 1){
prefixed_chnl_orig <- prefixed_chnls_orig[ind]
orig.trans.obj <- orig.trans[[which(ind)]]
gml2.trans.obj <- gml2.trans[[prefixed_chnl_orig]]
if(rescale.gate){
inv.fun <- orig.trans.obj[["inverse"]]
trans.fun <- eval(gml2.trans.obj)
#rescale
gate <- rescale_gate(gate, inv.fun, param)
gate <- rescale_gate(gate, trans.fun, param)
}
#attach trans reference
gate@parameters[[i]] <- gml2.trans.obj
}else if(nMatched > 1)
stop("multiple trans matched to :", param)
}
# round
gate
}
inverse <- function(gate, boundary){
UseMethod("inverse")
}
inverse.polygonGate <- function(gate, ...){
gate@boundaries <- inverse.polygon(gate@boundaries, ...)
gate
}
inverse.ellipsoidGate <- function(gate, ...){
inverse(as(gate, "polygonGate"), ...)
}
inverse.rectangleGate <- function(gate, ...){
param <- as.vector(parameters(gate))
if(length(param) == 1){
stop("to be implemented!")
}else
inverse(as(gate, "polygonGate"), ...)
}
inverse.polygon <- function(mat, boundary){
dims <- colnames(mat)
stopifnot(all(dims %in% colnames(boundary)))
#enlarge the boundary to ensure the negated polygon includes all events outside of original polygon
boundary["min", ] <- boundary["min", ] - 1e4
boundary["max", ] <- boundary["max", ] + 1e4
x <- dims[1]
y <- dims[2]
#find the top most point as starting point
ind <- which.max(mat[, y])
#reorder mat starting from top most
nRow <- nrow(mat)
orig.seq <- seq_len(nRow)
seq1 <- ind:nRow
seq2 <- setdiff(orig.seq, seq1)
new.seq <- c(seq1, seq2)
new.seq
mat.new <- mat[new.seq, ]
mat.inv <- mat.new[1, ]
#extend to upper bound
pt1 <- c(mat.new[1, x], boundary["max", y])
mat.inv <- rbind(mat.inv, pt1, deparse.level = 0)
#left top
mat.inv <- rbind(mat.inv, c(boundary["min", x], boundary["max",y]))
#left bottom
mat.inv <- rbind(mat.inv, c(boundary["min", x], boundary["min",y]))
#right bottom
mat.inv <- rbind(mat.inv, c(boundary["max", x], boundary["min",y]))
#right top
mat.inv <- rbind(mat.inv, c(boundary["max", x], boundary["max",y]))
#back to first extended point
mat.inv <- rbind(mat.inv, pt1, deparse.level = 0)
#connect to the remain mat.new in reverse order
mat.inv <- rbind(mat.inv, mat.new[rev(seq_len(nRow)[-1]), ])
# plot(mat.inv, type = "n")
# polygon(mat.new, col = "red")
# polygon(mat.inv, col = "blue")
mat.inv
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.