RGLab / flowWorkspace

flowWorkspace
GNU Affero General Public License v3.0
44 stars 21 forks source link

Issue with error of "Boolean gate referencing itself" #386

Closed carduncombe closed 1 year ago

carduncombe commented 1 year ago

I am having issues running the recompute() after adding a new gate with gs_pop_add. With this specific dataset, the error I am seeing the following when trying to add the existing defined gate PD1+ to the parent "/Lymphocytes/Single Cells/live/CD3+/CD8+/CSPTET+".

bg <- booleanFilter(`PD1+`)
> bg
booleanFilter filter 'PD1+' evaluating the expression:
PD1+
> nodeID2 <- gs_pop_add(gs, bg, parent="CSPTET+")

> gs_get_pop_paths(gs)
 [1] "root"                                                  "/Lymphocytes"                                         
 [3] "/Lymphocytes/Single Cells"                             "/Lymphocytes/Single Cells/live"                       
 [5] "/Lymphocytes/Single Cells/live/CD3+"                   "/Lymphocytes/Single Cells/live/CD3+/CD4+"             
 [7] "/Lymphocytes/Single Cells/live/CD3+/CD8+"            "/Lymphocytes/Single Cells/live/CD3+/CD8+/CSPTET+"            
[9]  "/Lymphocytes/Single Cells/live/CD3+/CD8+/CSPTET+/PD1+"

> recompute(gs)
Error in cpp_gating(x@pointer, y, alwaysLoadData, verbose, leaf.bool) : 
  The boolean gate is referencing to itself: PD1+

I have checked that the gates are all in the proper order, but keep this error keeps on appearing and can't identify why since it occurs to all samples. Have others seen this before and know how to troubleshoot?

djhammill commented 1 year ago

@carduncombe, the booleanFilter must reference nodes that already exist in the GatingSet. Looking at the nodes in your GatingSet it looks like there isn't a PD1+ node before you have attempted to add the booleanFilter. I'd recommend removing the PD1+ node using gs_pop_remove(gs, "PD1+") and then add an appropriate gate (e.g. rectangleGate, polygonGate etc.) with a filterId = "PD1+" using gs_pop_add(). BooleanFilters are designed to be used when you want to combine events from other nodes into a new node. For example, we may want to combine the events from the CD4+ and CD8+ nodes to create a T Cells node - then the booleanFilter would be booleanFilter('CD4+|CD8+', filterId = "T Cells"). The important boolean operators are ! - NOT, | - OR, & - AND.

carduncombe commented 1 year ago

Thanks so much for the response - I am just realizing I had not included the complete set of the nodes in my above code. I do have an existing PD1+ node that was manually gated in FlowJo then uploaded as with the rest of my nodes. Here is the list: gh_get_pop_paths(gs) [1] "root" "/Lymphocytes" [3] "/Lymphocytes/Single Cells" "/Lymphocytes/Single Cells/live" [5] "/Lymphocytes/Single Cells/live/CD3+" "/Lymphocytes/Single Cells/live/CD3+/CD4+" [7] "/Lymphocytes/Single Cells/live/CD3+/CD8+" "/Lymphocytes/Single Cells/live/CD3+/CD8+/CD44+" [9] "/Lymphocytes/Single Cells/live/CD3+/CD8+/CD44hi" "/Lymphocytes/Single Cells/live/CD3+/CD8+/CD44int" [11] "/Lymphocytes/Single Cells/live/CD3+/CD8+/CD62L+" "/Lymphocytes/Single Cells/live/CD3+/CD8+/CD62L-" [13] "/Lymphocytes/Single Cells/live/CD3+/CD8+/CD69+" "/Lymphocytes/Single Cells/live/CD3+/CD8+/CD69-" [15] "/Lymphocytes/Single Cells/live/CD3+/CD8+/CSPTET+" "/Lymphocytes/Single Cells/live/CD3+/CD8+/CXCR3+" [17] "/Lymphocytes/Single Cells/live/CD3+/CD8+/CXCR3-" "/Lymphocytes/Single Cells/live/CD3+/CD8+/LAG3+" [19] "/Lymphocytes/Single Cells/live/CD3+/CD8+/PD1+" "/Lymphocytes/Single Cells/live/CD3+/CD8+/PD1-" [21] "/Lymphocytes/Single Cells/live/CD3+/CD8+/TCF1+" "/Lymphocytes/Single Cells/live/CD3+/CD8+/TCF1-" [23] "/Lymphocytes/Single Cells/live/CD3+/CD8+/CSPTET+/PD1+"

I am wondering if the error would have to do with that the gates were previously defined in FlowJo so create new hierarchal combinations. I see the error when trying for anyone one of these gates.

djhammill commented 1 year ago

@carduncombe, are you trying to copy the PD1+ gate from the CD8+ node to the CSPTET+ node? In that case a refGate would be the appropriate gate type.

carduncombe commented 1 year ago

Yes, I am trying to create additional hierarchal gating, adding the same gate defined by CD8+/PD1+, to CD8+/CSPTET+, to create the new node of CD8+/CSPTET+/PD1+. Could please give an example of applying refGate to create this?

djhammill commented 1 year ago

The simplest approach would be to extract the PD1+ gate(s) from the CD8+ node(s) and then add it to the CSPTET+ node(s):

# extract list of original PD1+ gates per sample in GatingSet
gates <- gs_pop_get_gate(gs, "CD8+/PD1+")
# copy the PD1+ gates to the CSPTET+ node
gs_pop_add(gs, gate = gates, parent = "CSPTET+")
# re-apply gating
recompute()
carduncombe commented 1 year ago

Amazing! That worked! Thanks so much.

mikejiang commented 1 year ago

@djhammill Thank you for the detailed instructions!