Closed DillonHammill closed 4 years ago
That's a cool idea. I'd be happy to incorporate it. If you want to submit it as a pull request we can take a look.
Is it possible to keep the point displayed on the plot after the click ?Right now it disappears immediately and you can't see the actual gate during the drawing process, which makes it difficult to make an accurate drawing. In terms of how to incorporate it into openCyto, one way is to register it as a plugin as you are current doing. If we are concerned about the interruption of batch process of the gating pipeline, we can keep this interactive drawing as the independent feature that takes a flowSet and return a list of polygonGates. We just need to come up a clean way of passing the static gates to the template(which has been an issue in the past)
@mikejiang I have just updated the package to include points when drawing gates, if you would like to try it out. I will play around with the pch argument to change the appearance.
Sorry I have not followed up on this sooner, I have been really busy...
This will be my first pull request, could you guys work me through how to do this properly?
It would be great if we could come up with a way to save the gates to an object so that when the user comes back to the analysis the gates are preserved - and not re-drawn each time.
Thanks
Hi, @DillonHammill Sorry for not getting back to you sooner. To submit a pull request, fork openCyto, add this code to openCyto, push in a new branch and you will have the option to submit it as a new pull request in the GitHub UI.
Hi @gfinak & @mikejiang,
Thanks for your help, I have submitted a pull request with the code for DrawGate - hopefully I have done this correctly.
Would it be possible to save the gating coordinates to the gatingTemplate
after gating (maybe a gate_coords
column which is updated after gating)? Then when applying the template we look if coordinates are present in the template and apply these directly, if not we run the gating function to determine the coordinates - which are then saved to the template for future reference?
It would be great if it could be added as one of the default gating methods.
Looks like it is possible to do this with ggplot using the grid.locator() function - I will look into this when I get time. The other alternative is to convert ggplot objects to plotly objects and use the lasso tool to define the coordinates of the gate.
Cheers!
Dillon
As I said earlier, we haven't come up a clean way of passing the static gates to the template
. Because csv
is flat-structured and only suitable for high-level abstract gating method description. The original motivation of adopting it as template format was to make it compact and human-readable.
adding the lengthy static gate coordinates directly to csv goes against that purpose.
The only way I can think of is to store them to the gatingTemplate
R object , which is graphNEL
. Then save it as rds
file, which can be loaded back and resused.
That's why I thought it was cleaner to run the interactive gate drawing
independently from gating
process. Because we don't want the behavior of modifying gatingTemplate
by the gating
as we applying it. Instead, we should
fs
GrawGate
tools to generate gates gatingTemplate
object (we will have to provide the API for that)Sounds great!
Hi guys,
I have made a few updates to the DrawGate
function, here is a summary of the changes:
DrawGate
function now returns gates instead of coordinates which should make things easier when setting up things external to the gating pipeline.gate_type
argument which defaults to "polygon"
.gate_type="interval"
multiple gates can be constructed when 2n points are selected.Each gate type prompts the user of the required input which is as follows:
"polygon"
requires input of at least 3 points to construct polygon."rectangle"
requires input of 4n points - each rectangle is constructed from the min and max input values."interval"
requires input of 2n points to define the lower and upper bounds of a 1D gate(s)."threshold"
requires input of 1 point to define the lower bound of the 1D gate."quadrant"
requires input of 1 point to define the center of the 4 rectangle gates.I would also like to add support for gate_type="ellipse"
based on user input. Perhaps the user can specify 4 points defining the limits of the gate in 2 dimensions? Do you guys have any suggestions of how I can achieve this?
Please try it out if you have time and let me know what you think:
devtools::install_github("DillonHammill/CytoGate")
registerPlugins(fun = gate_draw, methodName = "DrawGate")
Thanks again for all your help!
Dillon
I have no time to test it yet, but it sounds really great. From a drawing point of view, a rectangle could be defined by 3 points, the fourth one being easily inferred. You can imagine pointing a corner, then drawing an edge, and finally pointing the opposite corner of the first corner while drawing the entire rectangle. If the rectangle is parallel to the axes, only two points are sufficient. The same applies to an ellipse if we consider the rectangle that surrounds the ellipse. An alternate definition for an ellipse would be its centre, the big axis and the small axis. Why simplifying? IMHO, the less values I enter, the better I feel. I don't remember if you already mentioned the locator function, but it helped me in specifying parameters.
Thanks @SamGG!
I like the idea of supplying 2 points (diagonal) for rectangle gates as they are simply 2D interval gates. For rotated rectangles I think it is easier to use a polygon gate - the required number of points should be consistent for each gate type or else it may be confusing.
I have figured out a way of constructing ellipses from 4 points and will add support for these soon.
gate_type="ellipse"
is now supported!
"ellipse"
requires input of 4n points specifying the limits of the ellipse in two dimensions where n is the number of ellipses to construct. Yes multiple ellipsoidGates are supported!Thanks for your suggestions @SamGG.
Hi guys,
Last few updates:
N
which indicates the number of gates to construct - defaults to "1". Multi-gates are supported for all gate types except threshold and quadrant.gate_type = "polygon"
.interval
and threshold
gate types. For 2D interval gates an additional argument axis
must be supplied to indicate whether the "x"
or "y"
axis should be gated. 2D threshold gates return a rectangle gate selecting all points above the selected "x"
and "y"
co-ordinates.rectangle
gates now expect input of 2 diagonal points to construct the gate(s).Cheers, Dillon
Short vignette added to demonstrate gating methods and required inputs:
For ellipses only the 4 external points are required, the center point is inferred then plotted - I may remove this to avoid confusion.
Cheers, Dillon
Hi @mikejiang,
I was just wondering if you could elaborate a bit more on how you would save the gates? I would really like to get this working soon so I wouldn't mind giving it a try. I am still trying to get my head around what you have suggested so I would appreciate some guidance.
My understanding is that the samples should be loaded into a GatingSet
and a complete csv gating template applied with the gating coordinates being saved to the R template object. Or should gates be applied directly to a flowSet
? Then save the file as .rds
which can be reused. How should this file be handled the next time you visit the data?
Thanks again for all your help!
Dillon
I've pushed the change and now you can pass the gates directly to add_pop
call , which will convert your complex R objects to strings and thus suitable to be written to csv template and reused for new datasets.
Note that particular cell in the csv will be pretty lengthy, which contains the flat-text version of your gate object. But that is way it is.
See here for the complete demo http://rpubs.com/wjiang2/395270
That is excellent! Thanks so much! Can't wait to try it out later today.
Thanks Mike!
Hi @mikejiang,
I have given it a try but keep getting an error:
> template <- add_pop(
+ gs, alias = "NonDebris", parent = "root", pop = "+", dims = "FSC-A,SSC-A", gating_method = "gate_manual",
+ gating_args = list(gate=gateobj)
+ )
Error in .argParser(cur_args, split_args) : invalid gating argument:
<text>:1:11: unexpected '<'
1: c( gate = <
^
How about the demo code I post ? did it work for you? Have you updated your opencyto package?
I will try it and yes I have updated openCyto.
Yeah the demo code is giving the same error... openCyto version installed = 1.19.1
I can't reproduce your error. Here is my sessionInfo.txt
What's your print output of gateobj
? Can you also attach the traceback
as txt here?
print(gateobj) A list of 1 filters applied to a flowFrame.
traceback.txt
sessionInfo.txt
Can you compare your session info with mine to find out the discrepancies of the package version? Particularly data.table
After updating R and reinstalling packages this is now working! Thanks Mike!
Manual gating is now supported in CytoExploreR (https://dillonhammill.github.io/CytoExploreR/). Closing this issue.
Hi @gfinak & @mikejiang,
This is not an issue per se, but I have written an openCyto plugin that facilitates drawing polygonGates (FlowJo style) through openCyto.
Please feel free to try it out:
devtools::install_github("DillonHammill/CytoGate")
registerPlugins(fun = gate_draw, methodName = "DrawGate")
Simply define coordinates of polygonGate by left clicking on the plot and finish with a right click and selecting "stop".
At the moment the gates can only be drawn using base graphics but I will extend this ggcyto next week (hopefully).
Not sure if you guys are interested in incorporating manual gating routines like this into openCyto. I think that it will make the transition from other software (like FlowJo) to openCyto much easier.
Keen to hear your thoughts!
Dillon