Using command-line parameters with a groovy script in QuPath

Is it possible to pass command-line parameters to a QuPath groovy script? Something like:

QuPath-0.2.3 script -i image.tif myscript.groovy param1 param2 param3 --param4=small

Thanks!

1 Like

'Fraid not. If really needed it you could write them to a text file and then read that from the script.

3 Likes

Thanks @petebankhead!

1 Like

Hey @petebankhead,

I’d also be interested in this, so I had a look at your code and had a go at hacking something together.

My thinking is that we pass the arguments as a string with the -a / --args option, which will be split into appropriate chunks and pass them on to the groovy script as a global variable named “args” containing an array of strings, one for each argument. This is already kind of how groovy is expected to behave, and I was lucky that in the QuPath Groovy, the global variable args (or this.args) isn’t defined.

So first, I added the “-a / --args” option to src/main/qupath/QuPath.java:

@Option(names = {"-a", "--args"}, description = "Arguments passed to the Groovy script as a string", paramLabel = "arguments")
private String scriptArgument;

I then split the scriptArgument string into chunks using this stack overflow answer – The appropriate method was just pasted into the ScriptCommand class.

Then I added an attribute named “args” to the context of the engine running the script:

        // Define "args" as a global Groovy variable
        String[] argsArray = translateCommandline(argsString);
        context.setAttribute("args", argsArray, ScriptContext.ENGINE_SCOPE);

That’s all! When you need to run a script with arguments, do it this way:

>".\build\dist\QuPath-0.2.3\QuPath-0.2.3 (console).exe" script myscript.groovy -a "tata \"toto titi\" tutu"
23:54:31.178 [main] [INFO ] qupath.ScriptCommand - Setting tile cache size to 8180.00 MB (25.0% max memory)
23:54:31.372 [main] [INFO ] qupath.lib.scripting.QP - Initializing type adapters
Showing args:
[tata, toto titi, tutu]

myscript.groovy is just this:

println "Showing args:"
println args

As you can see, escaping strings seems to work just fine (\“toto titi\” in my example above). And I personally don’t need more to pass a path to a script.

I also modified executeScript() in DefaultScriptEditor.java for consistency:

	private void executeScript(final ScriptTab tab, final String script, final Project<BufferedImage> project, final ImageData<BufferedImage> imageData) {
		ScriptEditorControl console = tab.getConsoleComponent();
		
		ScriptContext context = new SimpleScriptContext();
		var writer = new ScriptConsoleWriter(console, false);
		context.setWriter(writer);
        String[] argsArray = new String[0];
        context.setAttribute("args", argsArray, ScriptContext.ENGINE_SCOPE);

… and args is just an empty array in the Script Editor:
image

My two modified files are attached, let me know if there’s any mileage in this :slight_smile:

Cheers,
Egor

QuPath.java.txt (16.8 KB) DefaultScriptEditor.java.txt (75.2 KB)

3 Likes

Thanks Egor, that’s fantastic! It works perfectly!