Preventing @Parameter gui popup during scripted runs

ij2command
parameters
scripting
Tags: #<Tag:0x00007fd542de62e0> #<Tag:0x00007fd542de61a0> #<Tag:0x00007fd542de6038>

#1

Hi all,
after sticking with ij1-style plugins for a long time, I have finally decided to test the waters and start moving one of my internal tools over to ij2. In general the @Plugin framework seems to work very well, the whole @Parameter injection and gui-generation is really helpful, however I have found a little complication when running from scripts.

My use case is as follows: My plugin can either be run by providing a yaml file (which contains all necessary parameters), or an XML file which requires a few additional parameters to work. This works fine in GUI runs, however for scripted runs I would like to be able to just provide a yaml file and NOT have it display the usual popup. Right now my parameters look as follows:

	
	@Parameter(visibility = ItemVisibility.MESSAGE, required = false)
	private String label1 = "<html>Please select either:<br>"
			+ "a Cell Extractor Yaml File<br>"
			+ "a directory containing multiple Cell Extractor Yaml Files<br>"
			+ "or the XML output file of a Cell Counter</html>";
	
	@Parameter(label = " ", callback = "fileChanged", required = true)
	private File userFile;
	
	@Parameter(visibility = ItemVisibility.MESSAGE, required = false)
	private String label2 = "<html><br>"
			+ "The following fields only need to be filled in when using a Cell Counter XML file.<br>"
			+ "When selecting a yml file, the parameters are read from that file instead.</html>";
	
	@Parameter(label = "Image Path File:", required = false)
	private File imgPathFile;
	
	@Parameter(label = "Output Directory:", required = false)
	private File outFile;
	
	@Parameter(label = "Scale:", min = "0.1", max = "10", stepSize = "0.1", required = false)
	private double scale = 2.0;
	
	@Parameter(label = "Cube X-size:", min = "1", max = "500", required = false)
	private int cubeX = 50;
	
	@Parameter(label = "Cube Y-size:", min = "1", max = "500", required = false)
	private int cubeY = 50;
	
	@Parameter(label = "Cube Z-size:", min = "1", max = "500", required = false)
	private int cubeZ = 20;

I would now like to be able to run the plugin as follows:

run("My Plugin", "userfile=/path/to/someExampleFile.yml");

But it still displays the popup to populate the remaining parameters. As a matter of fact, this even extends to the messages:

run("My Plugin", "userfile=/path/to/someExampleFile.xml imgpathfile=/path/to/anImagePathFile.txt outfile=/some/random/output/dir scale=2.0 cubex=50 cubey=50 cubez=20");

Even when I provide all the parameters, a popup still appears. This popup will have only the messages visible but no option for the user to actually enter any data. Is there any way to prevent a popup from appearing when e.g. only non-required parameters are undefined?

Thanks,
Christian


#2

Dear @cniedwor,

So you actually have

  1. part of a plugin that does a computation and requires some parameters, and
  2. part of that plugin that reads parameters from files

Did I get that right? If that’s the case, you should have a Command that does the computation with all the required parameters (imgPathFile, outFile, etc) and an additional Command or maybe a Groovy script that reads in an XML or YAML file (i.e. it has one @Parameter userFile), parses the contents and passes the contents to the aforementioned Command that does the computation.

In that case, your two invocations would be

run("My Plugin (from YAML)", "userfile=/path/to/someExampleFile.yml");
run("My Plugin", "imgpathfile=/path/to/anImagePathFile.txt outfile=/some/random/output/dir scale=2.0 cubex=50 cubey=50 cubez=20");

And My Plugin (from YAML) effectively calls My Plugin with its parameters.

Best,
Stefan


#3

Still there’s clearly an issue with MESSAGE parameters apparently. They do not get recorded by the macro recorder (which is correct), but are not automatically resolved when called from a macro.

Consider this Groovy script named Input_Parameters.groovy:

#@ String (value = "Please select", visibility = "MESSAGE", required = false) label1
#@ File (label = " ", required = true) userFile
#@ String (value = "Not required", visibility = "MESSAGE", required = false) label2
#@ File (label = "Image Path File:", required = false) imgPathFile
#@ File (label = "Output Directory:", required = false) outFile
#@ double (label = "Scale:", min = "0.1", max = "10", stepSize = "0.1", required = false, value = 2.0) scale
#@ int (label = "Cube X-size:", min = "1", max = "500", required = false, value = 50) cubeX
#@ int (label = "Cube Y-size:", min = "1", max = "500", required = false, value = 50) cubeY
#@ int (label = "Cube Z-size:", min = "1", max = "500", required = false, value = 20) cubeZ

println "Done."

Running this from a macro:

run("Input Parameters", "userfile=foo imgpathfile=bar outfile=foo2 scale=0.0 cubex=0 cubey=0 cubez=0");

will result in a dialog like this:

image


#4

I guess the labels are not marked as resolved inputs then?


#5

Yes, that’s what I meant with:

Let’s open an issue for this. Does it go to scijava-common or rather to imagej-legacy?


#6

Good question! I would go for scijava-common although that’s just gut feeling…

EDIT to back up my gut feeling:

Plugins/Script_.groovy:

#@ String (value = "Please select", visibility = "MESSAGE", required = false) label1
#@ String (value = "Not required", visibility = "MESSAGE", required = false) label2
#@ double (label = "Scale:", min = "0.1", max = "10", stepSize = "0.1", required = false, value = 2.0) scale

println "Done."

Plugins/Call_Script.groovy:

#@ModuleService modules

moduleInfo = modules.getModuleById("script:Plugins/Script_.groovy");
module = modules.createModule(moduleInfo);
future = modules.run(module, true, ["scale": 1.0])
future.get();

#7

Thanks, that would indeed solve the yaml vs xml run thing, but the problem still remains that

run("My Plugin", "imgpathfile=/path/to/anImagePathFile.txt outfile=/some/random/output/dir scale=2.0 cubex=50 cubey=50 cubez=20");

triggers a popup despite the fact that the command contains all modifiable parameters. The popup shows just the messages and contains no user input. I can pass arbitrary values to the labels to prevent the popup:

run("My Plugin", "imgpathfile=/path/to/anImagePathFile.txt outfile=/some/random/output/dir scale=2.0 cubex=50 cubey=50 cubez=20 label1=foo label2=bar");

This works but is not very intuitive to an end-user who might want to use the plugin in a script and seems somewhat hacky. I want to make sure I’m not missing an intended clean way of preventing the popup (that I don’t yet know about)…

edit: was too slow replying - I can see the message issue was picked up, thanks!!
Until this is resolved I’ll see if I can find another way to design the UI/descriptions around it.


#8

Thanks for the illustrative example. Here’s the issue report:


#9
run("My Plugin", "imgpathfile=/path/to/anImagePathFile.txt outfile=/some/random/output/dir scale=2.0 cubex=50 cubey=50 cubez=20 label1=foo label2=bar");

In case anyone else ever needs to do something like that:
Make sure to set the persist flag to false for the labels, otherwise the gui looks pretty funny after the label hack :grin:


#10

Yup, that’s another open issue unfortunately: message fields should default to persist=false and required=false, see also here: