How to use QuPath from a CLI?

1,430 views
Skip to first unread message

Paco González López

unread,
May 14, 2017, 12:51:56 PM5/14/17
to QuPath users
Hello!

I'd like to know how would you go about using QuPath from a (Linux) command line interface?
My best guess is writing a Java program that uses QuPath libraries, but maybe there is a better or easier way.

Expanding a bit on the problem, I have image annotations in a custom format (a JSON file with a list of points), that I want to be able to import to QuPath. I have already written a Groovy script that solves this. I also have 3 scripts that I want to apply to the annotations (incuding some QuPath plugins).

Right now, I'm thinking of writing a Java program that receives the arguments (the annotation file) and and processes the annotations, using the QuPath libraries. Is this possible at all without using the GUI to load an image and save the annotation?

Any suggestions are welcome!
F. Gonzalez.

Pete

unread,
May 14, 2017, 1:41:27 PM5/14/17
to QuPath users
It should be possible to run a script from the command line.... although I'm not entirely sure whether it is.

You can see hints of it in the code here.
From within the directory containing QuPathApp.jar, you would use
java -jar QuPathApp.jar /path/to/image/or/qupdata/file -script /path/to/script

It is a long time since I ever used this though, so I'm not sure if it still works.  It doesn't appear to use the same automatic imports that are applied in the script editor by default; meaning that, if required, you'd need to handle any of these (e.g. qupath.lib.scripting.QP) within the script; see this for some more information.

Writing a Java program would be an alternative.  I suspect you could use Groovy for this instead and run that from the command line.

Personally, I often write scripts in IntelliJ and then run them through QuPath - but not necessarily displaying any images.  The two ways to do this are:
1 - Using Run -> Run for project in the script editor
2 - Handling all file reading/saving from within the script, using qupath.lib.io.PathIO

The first method is useful if you want to batch-process one or more images within a project, effectively opening and processing them but without actually displaying this.  If you need to query the current image, you can use commands such as
getProjectEntry()
getCurrentImageData()
getCurrentImageData().getServer()
to check which image is currently being processed, perhaps in order to figure out an appropriate json file to import.  You would write your script for a single image, and apply it to as many as you want from within the project.

The second method gives a lot more flexibility, but also takes a bit more code.  For example, you might loop through all the images/data files in a directory.  You can read/write .qpdata files for an image with
PathIO.readImageData
PathIO.writeImageData
or even just read its object hierarchy if you do not need access to pixels with
PathIO.readHierarchy
But you should know that, with this approach, all I/O is internal to the script and so the 'currentImageData' isn't set automatically (as it is when you 'Run for project'); consequently, the methods in qupath.lib.scripting.QP/QPEx won't necessarily work because they don't know what image is intended.  Depending upon what your script does, you might need to call
QP.setBatchImageData(imageData);
QPEx.setBatchImageData(imageData);
at some point (it's recommended to use both).

Hopefully one or more of these methods helps.  If your interest is mostly on making the import straightforward, rather than necessarily running it from the command line, then there may be other options... such as adding an import option to the menus, or drag and drop support for the json files.

Paco González López

unread,
May 14, 2017, 2:20:49 PM5/14/17
to QuPath users

The second method gives a lot more flexibility, but also takes a bit more code.  For example, you might loop through all the images/data files in a directory.  You can read/write .qpdata files for an image with
PathIO.readImageData
PathIO.writeImageData
or even just read its object hierarchy if you do not need access to pixels with
PathIO.readHierarchy
But you should know that, with this approach, all I/O is internal to the script and so the 'currentImageData' isn't set automatically (as it is when you 'Run for project'); consequently, the methods in qupath.lib.scripting.QP/QPEx won't necessarily work because they don't know what image is intended.  Depending upon what your script does, you might need to call
QP.setBatchImageData(imageData);
QPEx.setBatchImageData(imageData);
at some point (it's recommended to use both).
This might be exactly what I need! I will look a bit deeper into PatIO, but the interface looks pretty straightforward. 
If I can extract the annotations from a .qpdata file using PathIO.readHierarchy a,extract the annotations and then tile them with PathROIToolsAwt.makeTiles((PathArea)roi, tileWidth, tileHeight, trimToROI); to get the ROIs of the tiles, I could almost consider the problem solved.
 
Hopefully one or more of these methods helps.  If your interest is mostly on making the import straightforward, rather than necessarily running it from the command line, then there may be other options... such as adding an import option to the menus, or drag and drop support for the json files.
I will definitely implement drag and drop support as well if I can.

Thank you for your answer, I think you hit the nail right on the head =)

Pete

unread,
May 14, 2017, 2:48:10 PM5/14/17
to QuPath users
Sounds good!  From a quick look, I see not all the docs are up-to-date.  It might help to know that, if you do need readImageData, you probably just want to specify the file and that the class is BufferedImage, while the other parameters can be null, i.e.
PathIO.readImageData(file, null, null, BufferedImage.class)

For drag and drop, you can use standard JavaFX or add a new handler to the list that QuPath loops through anyway.  In Groovy, it looks like this:

qupath.lib.gui.QuPathGUI.getInstance().getDefaultDragDropListener().addFileDropHandler { viewer, files -> 
    qupath.lib.gui.helpers.DisplayHelpers.showInfoNotification("Drag 'n drop", "Hello files: " +  files)
    return false // Should return true if we actually handle the files
}

If you don't mind running the script once each time, Groovy is fine.  Otherwise a extension would make it more permanent.

Paco González López

unread,
May 14, 2017, 3:57:14 PM5/14/17
to QuPath users
Yes, extensions are the way to go. The reason I wanted to use the command line was to automate some procedures to make my life easier. I suppose I will keep doing them manually, since it's for my bachelor's project and I don't have that much time to do things the way I'd like. Also, my main focus is on machine learning, so interface related things are the last thing I will do. Still, the fact that you can answer questions posted here is beyond great.

The software I'm developing is going to be used by a pathologist, so anything that involves momentarily glancing at code is a no-no. Right now my all my code is Python and Qupath Groovy scripting (super useful environment by the way), so part of my pending work is hiding it all as extensions.

Thank you again!

micros...@gmail.com

unread,
May 14, 2017, 6:58:15 PM5/14/17
to QuPath users
Mmm, this would be great, to be able to have a remote pathologist create a tiny annotation file that can be transmitted to an off-site data analyst for processing.  I really need to learn more programming, as that would be a fantastic workflow enhancer!

Adit Sanghvi

unread,
Aug 7, 2017, 11:38:21 AM8/7/17
to QuPath users
When I do java -jar QuPathApp.jar /path/to/image/or/qupdata/file -script /path/to/script

In my script, I then run L:
def imageData = QP.getCurrentImageData()

However, the imageData is null , even though the path to image is correct. Is this fixable?

Pete

unread,
Aug 7, 2017, 1:45:16 PM8/7/17
to QuPath users
Sorry, I think there is a missing -image in the code above.  Does this work?
java -jar QuPathApp.jar -image /path/to/image/or/qupdata/file -script /path/to/script

Adit Sanghvi

unread,
Aug 7, 2017, 1:48:19 PM8/7/17
to QuPath users
Thank you! 

I can access the image and running some scripts on it.
Reply all
Reply to author
Forward
0 new messages