Specify output parameters for ImageJ2 commands

@imagejan @stelfrich @jkh1
Is there somewhere an example for an IJ2 Command that not only contains the input parameters but also the output parameters? I guess, e.g., for automatically building KNIME nodes from IJ2 Commands also the output information must be provided?!

@NicoKiaru @ctrueden Could you maybe point me to an example?

Hi @Christian_Tischer,

I use plenty of these things. What you need to know is that if the output parameter has no way of being displayed, it’s being discarded. Unless you call the command programmatically. If you call it programmtically, you can get any outputs by doing:

Out out0 = (Out) (command.run(MyCommand.class, true, "input0", in).get().getOutput("out0"));

If you want to display it using an UI, you can have a look at this discussion:

Best,

Nico

2 Likes

Ok! Looks easy enough, basically, that’s it?

@Parameter(type = ItemIO.OUTPUT)

Then, related to that, I think @haesleinhuepf showed once how to programmatically find out the input and output parameters of given a Command. I think it was something like below:

SomeSortOfInputsMap = getInputs( SomeCommand.class ); 
SomeSortOfOutputsMap = getOutputs( SomeCommand.class );

Is there some mechanism like this?

Noooow I know why you mention me repeatedly with @-Parameter-related questions: You mix me up with the other dreadlock guy :wink: Sorry, but I hardly work with @-Parameters these days

1 Like

Somehow I thought it was you, really :wink:
Anyway @maarzt, could you help here?
@haesleinhuepf, if you run into him, could you point him here? :slight_smile:

1 Like

Your first place to go for examples is the ImageJ Tutorials.

$ git grep OUTPUT
maven-projects/add-two-datasets/src/main/java/AddTwoDatasets.java:      @Parameter(label = "Result 1", type = ItemIO.OUTPUT)
maven-projects/add-two-datasets/src/main/java/AddTwoDatasets.java:      @Parameter(label = "Result 2", type = ItemIO.OUTPUT)
maven-projects/add-two-datasets/src/main/java/AddTwoDatasets.java:      @Parameter(label = "Result 3", type = ItemIO.OUTPUT)
maven-projects/create-a-new-op/src/main/java/CreateANewOp.java:         @Parameter(type = ItemIO.OUTPUT)
maven-projects/create-a-new-op/src/main/java/Ramp.java: @Parameter(type = ItemIO.OUTPUT)
maven-projects/create-a-new-op/src/main/java/RandomBlobs.java:  @Parameter(type = ItemIO.OUTPUT)
maven-projects/low-pass-filter/src/main/java/LowPassFilter.java:        @Parameter(type = ItemIO.OUTPUT)
maven-projects/metadata/src/main/java/GetMetadata.java:    @Parameter(label = "Metadata", type = ItemIO.OUTPUT)
maven-projects/simple-commands/src/main/java/GradientImage.java:        @Parameter(type = ItemIO.OUTPUT)
maven-projects/simple-commands/src/main/java/GradientImage.java:                // NB: Because the dataset is declared as an "OUTPUT" above,
maven-projects/simple-commands/src/main/java/HelloWorld.java: * {@code @Parameter(type = ItemIO.OUTPUT)} annotation.
maven-projects/simple-commands/src/main/java/HelloWorld.java:   @Parameter(type = ItemIO.OUTPUT)
maven-projects/simple-commands/src/main/java/OpenImage.java:    @Parameter(type = ItemIO.OUTPUT)
maven-projects/swing-example/src/main/java/DeconvolutionCommand.java:   @Parameter(type = ItemIO.OUTPUT)
maven-projects/swing-example/src/main/java/DeconvolutionCommandSwing.java:      @Parameter(type = ItemIO.OUTPUT)
maven-projects/using-ops/src/main/java/UsingOpsDog.java:    @Parameter(type = ItemIO.OUTPUT)
maven-projects/widget-demo/src/main/java/WidgetDemo.java:       // ItemIO.OUTPUT rather than the usual ItemIO.INPUT. Output parameter
maven-projects/widget-demo/src/main/java/WidgetDemo.java:       @Parameter(label = "Results", type = ItemIO.OUTPUT)

Edit: Ah, I guess that example does not yet show how to harvest the outputs. The run() method returns a Future<Module>. Call get() on it to block until execution is complete, and receive the Module. Call getOutputs() on the Module to receive a map of the output key/value pairs.

4 Likes

@ctrueden thank you very much for the answer!
As I told you already in an e-mail once, we are interested in automatically generating binary code from SciJava Commands such that they could be run “in the cloud”.
I guess one would also need for this a PostProcessor that writes all the module outputs to disk, such that they can be read by the next processing modules.

  1. Does such a WriteOutputsToDiskPostprocessor exist already?
  2. How does all of this relate to ImageJ-Server? Is ImageJ-Server in fact already doing some of the automated wrapping of Commands into something that can be called from non-Java applications?

@Christian_Tischer in addition to the tutorials and examples above, you can also have a look at these ImageJ2 command plugins:

They all define some outputs and have a headless=true annotation, so they get auto-rendered as #knime nodes by the KNIME ImageJ integration.


Regarding PostprocessorPlugins, here are some source code links for your inspiration:

4 Likes

No, I have not seen any implementation of that. Decisions would need to be made regarding how to serialize/externalize/marshal each object.

To an extent, yes; see the imagej-server API documentation. You could e.g. use this to query and invoke modules from other languages such as JavaScript. However, code would still need to be written to harvest and persist the outputs after execution—the ImageJ Server does not do this itself.

Please note that the ImageJ Server is not under active development at the moment due to lack of resources, and needs some work to reduce security risks associated with using it. See:

1 Like

Yes, yes it’s possible to use the CommandService and CommandInfo:

CommandService commandService = ...;
List<CommandInfo> commandInfos = commandService.getCommandsOfType(Command.class);
CommandInfo commandInfo = commandInfos.get(0);
Iterable<ModuleItem<?>> inputs = commandInfo.inputs();
Iterable<ModuleItem<?>> outputs = commandInfo.outputs();	
2 Likes