library(flowCore)
library(flowWorkspace)
library(cytoqc)
path <- "~/remote/fh/fast/gottardo_r/mike_working/lyoplate_out/parsed"
centers <- c('BIIR','CIMR','Miami','NHLBI','Stanford','UCLA','Yale')

Load gs

panel <- "bcell"
gslist <- sapply(centers, function(center) {
  message("Center: ", center)
  gs <- load_gs(file.path(path, center, panel))
})

QC Check gates

cqc_data <- cqc_gs_list(gslist)

#group by gates
groups <- cqc_check(cqc_data, "gate")
groups
group_id nGatingSet gate
2 6 24hi 38hi, 27- IgD-, 27- IgD+, 27+ IgD-, 27+ IgD+, 27hi 38hi, CD19, CD19 AND CD20, CD19 AND NOT CD20, CD20, CD3, LYM, not dead, root, singlets
1 1 24hi 38hi, 27- IgD-, 27- IgD+, 27+ IgD-, 27+ IgD+, 27hi 38hi, CD19, CD19 AND CD20, CD19 AND NOT CD20, CD20, CD3, LYM, not dead, root
#vis the difference
plot_diff(groups)

# match reference
match_result <- cqc_match(groups, ref = 1, select = c(2))
match_result
cqc_fix(match_result)

cqc_check(cqc_data, "gate")
group_id nGatingSet gate
1 7 24hi 38hi, 27- IgD-, 27- IgD+, 27+ IgD-, 27+ IgD+, 27hi 38hi, CD19, CD19 AND CD20, CD19 AND NOT CD20, CD20, CD3, LYM, not dead, root

QC check for channel

groups <- cqc_check(cqc_data, "channel")
groups
group_id nGatingSet channel
1 1 <Alexa Fluor 488-A>, <AmCyan-A>, <APC-A>, <APC-Cy7-A>, <Pacific Blue-A>, <PE YG-A>, <PE-Cy7 YG-A>, <PerCP-Cy5-5-A>, FSC-A, FSC-H, FSC-W, SSC-A, SSC-H, SSC-W, Time
2 1 <Am Cyan-A>, <APC-A>, <APC-Cy7-A>, <FITC-A>, <Pacific Blue-A>, <PE-A>, <PE-Cy7-A>, <PerCP-Cy5-5-A>, FSC-A, FSC-H, FSC-W, SSC-A, SSC-H, SSC-W, Time
3 1 <AmCyan-A>, <APC-A>, <APC-Cy7-A>, <FITC-A>, <Pacific Blue-A>, <PE Cy7 YG-A>, <PE-A>, <PerCP-Cy5-5-A>, FSC-A, FSC-W, SSC-A, SSC-W, Time
4 1 <APC-A>, <APC-Cy7-A>, <FITC-A>, <PE-A>, <PE-Cy7-A>, <PerCP-Cy5-5-A>, <V450-A>, <V500-A>, FSC-A, SSC-A, Time
5 1 <APC-A>, <APC-H7-A>, <BD Horizon V450-A>, <BD Horizon V500-A>, <FITC-A>, <PE-A>, <PE-Cy7-A>, <PerCP-Cy5-5-A>, FSC-A, FSC-H, FSC-W, SSC-A, SSC-H, SSC-W, Time
6 1 <APC-A>, <APC-H7-A>, <FITC-A>, <PE-A>, <PE-Cy7-A>, <PerCP-Cy5-5-A>, <V450-A>, <V500-A>, FSC-A, FSC-H, SSC-A, SSC-H, Time
7 1 <B515-A>, <B710-A>, <G560-A>, <G780-A>, <R660-A>, <R780-A>, <V450-A>, <V545-A>, FSC-A, FSC-H, FSC-W, SSC-A, SSC-H, SSC-W, Time

Channels are very different across centers so move on to check marker

groups <- cqc_check(cqc_data, "marker")
groups
group_id nGatingSet marker
4 2 CD19, CD20, CD24, CD27, CD3, CD38, IgD, Live Green
1 1 CD19 PerCP-Cy55, CD20 APC-H7, CD24 PE, CD27 PE-Cy7, CD3 V450, CD38 APC, IgD V500, Live Dead FITC
2 1 CD19, CD20, CD24, CD27, CD3, CD38, IgD, LIVE
3 1 CD19, CD20, CD24, CD27, CD3, CD38, IgD, LIVE DEAD
5 1 CD19, CD20, CD24, CD27, CD3, CD38, IGD, LIVE_GREEN
6 1 CD19, CD20, CD24, CD27, CD3, CD38, IgD, Live/Dead

Markers are more standardized and go ahead to further clean it

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

Apply the fix and update checks

cqc_fix(res)
cqc_check(cqc_data, "marker")
group_id nGatingSet marker
1 7 CD19, CD20, CD24, CD27, CD3, CD38, IgD, LIVE

Use the marker as reference to standardize the channels across centers

res <- cqc_check(cqc_data, "panel", by = "marker")
res
marker group 1(n=1) group 2(n=1) group 3(n=1) group 4(n=1) group 5(n=1) group 6(n=1) group 7(n=1)
CD19 <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <B710-A>
CD20 <APC-Cy7-A> <APC-Cy7-A> <APC-Cy7-A> <APC-Cy7-A> <APC-H7-A> <APC-H7-A> <R780-A>
CD24 <PE YG-A> <PE-A> <PE-A> <PE-A> <PE-A> <PE-A> <G560-A>
CD27 <PE-Cy7 YG-A> <PE-Cy7-A> <PE Cy7 YG-A> <PE-Cy7-A> <PE-Cy7-A> <PE-Cy7-A> <G780-A>
CD3 <Pacific Blue-A> <Pacific Blue-A> <Pacific Blue-A> <V450-A> <BD Horizon V450-A> <V450-A> <V450-A>
CD38 <APC-A> <APC-A> <APC-A> <APC-A> <APC-A> <APC-A> <R660-A>
IgD <AmCyan-A> <Am Cyan-A> <AmCyan-A> <V500-A> <BD Horizon V500-A> <V500-A> <V545-A>
LIVE <Alexa Fluor 488-A> <FITC-A> <FITC-A> <FITC-A> <FITC-A> <FITC-A> <B515-A>
res <- cqc_match(res, ref = 1)
res
marker Ref group group 2(n=1) group 3(n=1) group 4(n=1) group 5(n=1) group 6(n=1) group 7(n=1)
CD19 <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <PerCP-Cy5-5-A> <B710-A>
CD20 <APC-Cy7-A> <APC-Cy7-A> <APC-Cy7-A> <APC-Cy7-A> <APC-H7-A> <APC-H7-A> <R780-A>
CD24 <PE YG-A> <PE-A> <PE-A> <PE-A> <PE-A> <PE-A> <G560-A>
CD27 <PE-Cy7 YG-A> <PE-Cy7-A> <PE Cy7 YG-A> <PE-Cy7-A> <PE-Cy7-A> <PE-Cy7-A> <G780-A>
CD3 <Pacific Blue-A> <Pacific Blue-A> <Pacific Blue-A> <V450-A> <BD Horizon V450-A> <V450-A> <V450-A>
CD38 <APC-A> <APC-A> <APC-A> <APC-A> <APC-A> <APC-A> <R660-A>
IgD <AmCyan-A> <Am Cyan-A> <AmCyan-A> <V500-A> <BD Horizon V500-A> <V500-A> <V545-A>
LIVE <Alexa Fluor 488-A> <FITC-A> <FITC-A> <FITC-A> <FITC-A> <FITC-A> <B515-A>
cqc_fix(res)
cqc_check(cqc_data, "panel", by = "marker")
marker group 1(n=7)
CD19 <PerCP-Cy5-5-A>
CD20 <APC-Cy7-A>
CD24 <PE YG-A>
CD27 <PE-Cy7 YG-A>
CD3 <Pacific Blue-A>
CD38 <APC-A>
IgD <AmCyan-A>
LIVE <Alexa Fluor 488-A>

check channel again

groups <- cqc_check(cqc_data, "channel")
groups
group_id nGatingSet channel
1 4 <Alexa Fluor 488-A>, <AmCyan-A>, <APC-A>, <APC-Cy7-A>, <Pacific Blue-A>, <PE YG-A>, <PE-Cy7 YG-A>, <PerCP-Cy5-5-A>, FSC-A, FSC-H, FSC-W, SSC-A, SSC-H, SSC-W, Time
2 1 <Alexa Fluor 488-A>, <AmCyan-A>, <APC-A>, <APC-Cy7-A>, <Pacific Blue-A>, <PE YG-A>, <PE-Cy7 YG-A>, <PerCP-Cy5-5-A>, FSC-A, FSC-H, SSC-A, SSC-H, Time
3 1 <Alexa Fluor 488-A>, <AmCyan-A>, <APC-A>, <APC-Cy7-A>, <Pacific Blue-A>, <PE YG-A>, <PE-Cy7 YG-A>, <PerCP-Cy5-5-A>, FSC-A, FSC-W, SSC-A, SSC-W, Time
4 1 <Alexa Fluor 488-A>, <AmCyan-A>, <APC-A>, <APC-Cy7-A>, <Pacific Blue-A>, <PE YG-A>, <PE-Cy7 YG-A>, <PerCP-Cy5-5-A>, FSC-A, SSC-A, Time
diff(groups)
group_id nGatingSet channel
1 4 FSC-H, FSC-W, SSC-H, SSC-W
2 1 FSC-H, SSC-H
3 1 FSC-W, SSC-W

Remove H/W channels

res <- cqc_match(groups, ref = 4) 
res
cqc_fix(res)

Coerce it directly into single GatingSet (zero-copying)

gs <- merge_list_to_gs(cqc_data)
gs
## A GatingSet with 63 samples