Creating a script to run on the project
Most scripts will start in the Workflow tab, with the Create script button.
That will generate a list of commands that you have run, which you can then trim down to the ones you really need for your analysis. As long as you have an entirely automated process (no manual editing, putting down annotation Points, etc), creating a script is usually fairly straightforward. After running through some ideas for this section, I felt like a concrete example would be the best way to help understand the process.
The original TIFF image used in this post is LuCa-7color_[13860,52919]_1x1component_data.tif from Perkin Elmer, part of Bio-Formats sample data available under CC-BY 4.0.
*Stolen from Pete
Here is a list of commands I used while playing around with the LuCa multichannel image. You can see from the list that I tinkered with various watershed cell detection options, and jumped around a bit with what I was looking at. When I click Create script, I get something like this:
If I were to run this right now, it would attempt to replicate all of those commands, and I don’t really want to run 5 cell detections. I agree with my image being fluorescent, and the createSelectAllObject(true); line outlines my single field of view with an annotation object, so those are both good. In a brightfield whole slide image those lines might be replaced with something more like:
Since I have an annotation, and I know that it is selected, I then want to run my final cell detection command (assuming I was improving my cell detection each time!).
Now I have something like this:
Note: On Windows based systems, the file path needs to be written with double backslashes. In 0.1.2, you may need to edit this manually.
Looking at the rest, I don’t want to clearAllObjects() right in the middle of my script! So I will definitely remove that. I also have a random createSelectAllObject() at the end of the script that I don’t need. I would like to run the trained classifier, however, so I will keep that. I also want to see cluster measurements, so I will keep that line as well. Come to think of it, if I want to run this project multiple times, I will not want to keep adding objects on top of objects, so I should really place one of those lines near the top. Think of all of these lines as LEGO building blocks, and you want to add them all in the correct order. I also want to run my cluster analysis AFTER I have classified my cells! So I will move that to the bottom.
Now I get something a little bit more like I would want when I run the whole script:
However, I also want to extract some annotation level data from each of the images in my project!
If I go to Measurements:
And look at my annotation measurements (in 0.1.3), I get something like this:
If I were in 0.1.2, I would insert a script like this at the end of my current script in order to add percentage positive and cell density measurements per classification to the parent annotation.
For now, though, these measurements will do for the demo. Now we turn to some of Pete’s scripts from his blog. The first script we add to the end of any script we want to run for the project.
This script creates a new folder within the project folder to store a text file for the current image.
With the combined script, we can now Run for project…
And select all of the files that we want. This only makes sense if your files are all similar
Now I have a selection of text files in an “annotation results” folder. Well, that’s not really what I wanted, I wanted a single file where I can peruse all of my image data at once! Pete has also provided a script for this here.
Copy that into a new script window and run it, targeting the annotation results folder within your project.
If you never modify the first, single file, script that writes everything to the annotation results folder, you can make a one line change to prevent the popup and navigation. It will assume that all of your individual text files are in the default location within the project as defined in the script above.
Swap this line:
def dirResults = QuPathGUI.getSharedDialogHelper().promptForDirectory()
For this line:
def dirResults = new File(buildFilePath(PROJECT_BASE_DIR, 'annotation results'))
Now if you look in your annotation results folder, you should have a Combined_results.txt file that can be opened in pretty much any spreadsheet program!
WARNING: Run for project… does not appear to edit the image that is currently open, even if that image is one of the images included in the run. However, it IS editing that data file in the background. As such, QuPath will see that the data file has been edited (without showing you any of the changes on the screen) and will ask you if you want to save your data. The correct answer to this is usually NOOOOOOOOOOOOOOO. If you select yes, you will be overwriting the results of the Run for project… with the data currently visible on screen.
That’s it! You made it! Well. Maybe. I wrote most of this in a day, so I am certain there will be glaring errors and gaps (above and beyond the ones I am already aware of !!) that may prevent this guide from being as useful as it could be. Feel free to start a topic or send me a message and I will try to clarify or fix up as much as I can. I have also toyed with the idea of keeping one consistent image throughout most of the steps, so that everyone could follow along with their own copy… but time, time, time.
I will definitely be adding a section on the Pixel classifier once that is fully functional, but for now I am avoiding that and the alignment tool, among others.
Good luck with all of your analysis!