QC for GatingSet

library(knitr)
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
icuSetCollate(locale="en_US")
library(flowCore)
library(flowWorkspace)
library(cytoqc)
flowDataPath <- system.file("extdata", package = "flowWorkspaceData")
gs <- load_gs(file.path(flowDataPath,"gs_manual"))
gs1 <- gs_clone(gs)
sampleNames(gs1) <- "1.fcs"

# simplify the tree
nodes <- gs_get_pop_paths(gs1)
for(toRm in nodes[grepl("CCR", nodes)])
  gs_pop_remove(gs1, toRm)

#simulate tree discrepancy

# remove two terminal nodes
gs2 <- gs_clone(gs1)
sampleNames(gs2) <- "2.fcs"
gs_pop_remove(gs2, "DPT")
gs_pop_remove(gs2, "DNT")


# remove singlets gate
gs3 <- gs_clone(gs2)
lapply(gs3, gh_pop_move, node = "CD3+", to= "not debris")
gs_pop_remove(gs3, "singlets")
sampleNames(gs3) <- "3.fcs"

# spin the branch to make it isomorphic
gs4 <- gs_clone(gs3)
# rm cd4 branch first
gs_pop_remove(gs4, "CD4")
# add it back
gs_pop_add(gs4, gs_pop_get_gate(gs3, "CD4"), parent = "CD3+")
# add all the chilren back
for(toAdd in gs_pop_get_children(gs3, "CD4"))
{
    thisParent <- gs_pop_get_parent(gs3[[1]], toAdd)
    gs_pop_add(gs4, gs_pop_get_gate(gs3, toAdd), parent = thisParent)
}
sampleNames(gs4) <- "4.fcs"

gs5 <- gs_clone(gs4)
# add another redundant node
gs_pop_add(gs5, gs_pop_get_gate(gs, "CD4/CCR7+ 45RA+")[[1]], parent = "CD4")
gs_pop_add(gs5, gs_pop_get_gate(gs, "CD4/CCR7+ 45RA-")[[1]], parent = "CD4")
sampleNames(gs5) <- "5.fcs"

#gate name typo
gs_pop_set_name(gs5, "CD3+", "cd3")

#simulate channel discrepancy

#difference lazor
gs_update_channels(gs2, map = data.frame(old = c("B710-A")
                                          , new = c("QDot 655-A")
                                          )
                      )

#redundant
cs <- gs_cyto_data(gs3)
fr <- cs[[1, return = "flowFrame"]]
new_col <- exprs(fr)[,8,drop=F]
colnames(new_col) <- "channelA"
fr <- fr_append_cols(fr, new_col)
tmp <- tempfile()
write.FCS(fr, tmp)
cs <- load_cytoset_from_fcs(tmp)
sampleNames(cs) <- sampleNames(gs3)
gs_cyto_data(gs3)  <- cs

#case
gs_update_channels(gs4, map = data.frame(old = c("R660-A")
                                          , new = c("r660")
                                          )
                      )

QC Check gates

cqc_data <- cqc_gs_list(list(gs1,gs2,gs3,gs4,gs5))

#group by gates
groups <- cqc_check(cqc_data, "gate")
groups

#vis the difference
plot_diff(groups)

# match reference
match_result <- cqc_match(groups, ref = 3)
match_result

cqc_fix(match_result)

cqc_check(cqc_data, "gate")

QC check for channel

groups <- cqc_check(cqc_data, "channel")
groups

Match against the reference to find discrepancy

match_result <-  cqc_match(groups, ref = 2)
match_result

Apply the fix

cqc_fix(match_result)

Refresh QC report

groups <- cqc_check(cqc_data, "channel")
groups

Drop groups that can not be fixed

groups <- cqc_drop_groups(groups, 2)
cqc_data <- cqc_get_data(groups)
length(cqc_data)

QC for marker

#simulate channel discrepancy

cf <- get_cytoframe_from_cs(gs_cyto_data(cqc_data[[1]]), 1)
cf_rename_marker(cf, "CD4 PcpCy55", "CD4 PcpCy")
cf_rename_marker(cf, "CD8 APCH7", "CD8")


#redundant
cf <- get_cytoframe_from_cs(gs_cyto_data(cqc_data[[2]]), 1)
markernames(cf) <- c(`Time` = "time")
#summarise marker groups
groups <- cqc_check(cqc_data, "marker")
groups

Standardize the markers

res <- cqc_match(groups, ref = 2) 
res

cqc_fix(res)

update checks

cqc_check(cqc_data, "marker")

Coerce it directly into GatingSetList (zero-copying)

gs <- merge_list_to_gs(cqc_data)
gs


RGLab/cytoqc documentation built on Jan. 25, 2023, 11:05 p.m.