< Back to QuPath article list 

Variables, Strings and Printing

I would have started with print statements, but I want to use some variables in print statements, so, surprise, here we go!

In Groovy, objects do not need classes, so you can go ahead and use any of them:

 
String hello = "Hello" hello = "Hello" def hello = "Hello"

They will all accomplish roughly the same thing, but with a couple of caveats. Anything you "def" cannot be re-created - so that can be helpful in preventing you from overwriting a variable you already created in a long script.

 
aString = "hello" aString = "goodbye"

The above is fine, while the two lines below will throw an error.

 
def aString = "hello" def aString = "goodbye"

A brief interlude for printing!

 
print "Hello world" print("Hello world") println("Hello world")

All of these will print "Hello world", go ahead and test it.


Tying back into the above "def" variables...

While you cannot re-create a defined variable, you can still reassign a def variable.

 
def aString = "hello" aString = "goodbye" print aString

The print statement will print "goodbye"

You can also include variables within strings - and this will be very useful for manipulating QuPath commands!

 
def aString = "cruel" print("Hello "+aString+" world")

Potentially more useful, QuPath uses strings for its commands, such as cell detection:

 
runPlugin('qupath.imagej.detect.cells.WatershedCellDetection', '{"detectionImage": "PL 4uM_D7_4_01d16h00m.tif",  "requestedPixelSizeMicrons": 0.5,  "backgroundRadiusMicrons": 8.0,  "medianRadiusMicrons": 0.0,  "sigmaMicrons": 1.5,  "minAreaMicrons": 10.0,  "maxAreaMicrons": 400.0,  "threshold": 25.0,  "watershedPostProcess": true,  "cellExpansionMicrons": 5.0,  "includeNuclei": true,  "smoothBoundaries": true,  "makeMeasurements": true}');

But what if we want to use:

 
def sigma = 0.5

in place of the sigmaMicrons value that is hard-coded in? Same as above, we insert it with + signs, though there is one further trick here. The outer quote marks for the whole string are single quotes ‘. That is the string we need to break up to insert a variable, not the inner double quotes for labels like "sigmaMicrons."

With sigma defined as above:

 
runPlugin('qupath.imagej.detect.cells.WatershedCellDetection', '{"detectionImageBrightfield": "Hematoxylin OD",  "requestedPixelSizeMicrons": 0.5,  "backgroundRadiusMicrons": 8.0,  "medianRadiusMicrons": 0.0,  "sigmaMicrons": '+sigma+',  "minAreaMicrons": 10.0,  "maxAreaMicrons": 400.0,  "threshold": 0.1,  "maxBackground": 2.0,  "watershedPostProcess": true,  "cellExpansionMicrons": 5.0,  "includeNuclei": true,  "smoothBoundaries": true,  "makeMeasurements": true}');

Essentially, replace the number you want to adjust with ‘+variable+’

You may need to scroll to the right to see where +sigma+ is inserted.

This method can be used to adjust most QuPath runPlugin commands, like adding intensity features, generating cells, or removing fragments and holes.

Finally, I have not gotten into functions yet, but there is one last type of print statement you need to know for more advanced coding, and that is logging.

 
import org.slf4j.Logger; import org.slf4j.LoggerFactory; Logger logger = LoggerFactory.getLogger(QuPathGUI.class);

These three lines set you up with a "logger" which you can then use to write out statements similar to "print", except the logger statements will still work in places like within functions or Buttons - places that print does not.

 
logger.info("Fly, you fools!")


The main reason I am covering this information first is because printing is one of the easiest ways to troubleshoot your scripts.

How many cells do I have at a certain point in the script?

 
print(getCellObjects().size())

What annotations exist at this step, if any?

 
print(getAnnotationObjects())

Does my variable have a value I expect (the variable totalArea needs to exist!)?

 
print("Total area of cells: " + totalArea)

And sometimes, if you can’t figure out where your script is crashing due to a loop, a simple

 
print("Here")

to show that you made it that far, or include an x=0 and x=x+1 in a loop

 
print("Loop number: "+x)

Additional information!

Other information can be converted into a string using toString()

 
int x = 5 print(x.toString())

Use .contains("something") to check if a string contains another string. Does my cell’s class contain CD68? This can be very useful when dealing with the multiplex classifier results.

 
cell.getPathClass().toString().contains("CD68")

There are other ways to insert variables into strings, such as using

 
print("The number is $numberVariable")

There are plenty of better general Groovy resources than this, and I cannot cover everything, so explore!