Script of the Day: Batch exporting annotation measurements
Export all the measurements for all the annotations in a project, in an orderly way.
The first two scripts deal with some difficulties around exporting annotation measurements.
QuPath has a built-in command to export TMA results under File → Export TMA data, and even a data viewer for results. It’s also possible to use Measure → Show annotation measurements and save the results for a single image. But batch-exporting isn’t as easy as it probably should be.
Problem
To run a script across multiple images in a project, you can use Run → Run for project in the script editor.
What this does, effectively, is open each selected image in the project, run the script for that image, and save the results in a .qpdata
file.
If you only want to export, but not change anything related to the image and save a new data file, you should use ‘Run → Run for project (without save)’.
One of the many things that can be done in a script is to write a new file, e.g. to export results. To do this, you would normally specify the name of the file you want to write.
The trouble is that if you then Run for project such an export, you’ll only see the results for the last file that was processed. Each time the script is run for a new image, the last file will be overwritten. This is probably not what you want.
Solution
The solution is to calculate a new (and preferably unique) name for the export file within the script.
Since we can assume the script is running for a project, the following shows a script can be used to determine a file name based on the name of the image being processed:
// Get the 'project image entry' corresponding to the image
// currently being processed by the script
def entry = getProjectEntry()
// Get the name for the image & append a suitable file extension
// (here, .txt)
def name = entry.getImageName() + '.txt'
The next task is to determine where to save the file, i.e. in which directory.
This could be some absolute path to somewhere on your computer, but then the script wouldn’t be very portable. It’s much nicer to save the results in a directory relative to the project.
The following line refers to a subdirectory inside the project called annotation results
:
def path = buildFilePath(PROJECT_BASE_DIR, 'annotation results')
Now we still need to do two things before we can write our results there:
- Make sure the directory exists! If it doesn’t, any attempt to write to it will fail.
mkdirs
helps here, creating the directory if necessary. - Join together the directory path and the file name.
mkdirs(path)
path = buildFilePath(path, name)
Saving the annotations simply requires:
saveAnnotationMeasurements(path)
The only (optional) extra thing to do is to log where exactly we wrote the file, in case we can’t find it later. This also helps make sure we can see that the script has finished running.
The following line does this, where println
means ‘print and take a new line’:
println 'Results exported to ' + path
If we had wanted, we could also have used parenthesis - but Groovy doesn’t insist on it.
println('Results exported to ' + path)
That’s it! In the next script we’ll look at how to merge these exported files together to create a single results table, suitable for import into a spreadsheet or some other software.