Hi Stefan, Very sorry for the long delay in reply. I should be faster in subsequent replies, if you have further questions.
> What are the precoditions assumed when running a (headless) command What happens is highly dependent on *how* you invoke the command... > may the command assume that its initializer, if any, has been executed > prior to executing its run-Method? I assume you are familiar with this tutorial: https://github.com/imagej/imagej-tutorials/blob/master/execute-commands/src/main/java/ExecuteCommands.java Note that when executing an ImageJ module using the ModuleService, the run methods (for the past couple of releases) have a "boolean process" flag. When process=true, the pre- and post-processing steps are run. This notably includes running the module initializer preprocessing step. > may the initializer-Method assume some of the parameter of the command > already set (as e.g. a single ImageDisplay), and of course, which > parameters? The InitPreprocessor calls module#initialize(), whose behavior can be overridden, but the default implementation of which is here: https://github.com/imagej/imagej/blob/imagej-2.0.0-beta-7.8/core/core/src/main/java/imagej/module/AbstractModule.java#L75 In short: the module initializer is called first, followed by the individual initializers of each parameter, if any. As for *when* this occurs: the InitPreprocessor has "HIGH" priority: https://github.com/imagej/imagej/blob/imagej-2.0.0-beta-7.8/core/core/src/main/java/imagej/module/process/InitPreprocessor.java#L50 So it happens before many other preprocessors: $ grep 'priority = ' $(git ls-files | grep Preprocessor) core/core/src/main/java/imagej/display/ActiveDisplayPreprocessor.java: priority = Priority.VERY_HIGH_PRIORITY) core/core/src/main/java/imagej/module/process/CheckInputsPreprocessor.java: priority = InputHarvester.PRIORITY - 1) core/core/src/main/java/imagej/module/process/DebugPreprocessor.java:@Plugin(type = PreprocessorPlugin.class, priority = Priority.FIRST_PRIORITY) core/core/src/main/java/imagej/module/process/GatewayPreprocessor.java: priority = Priority.VERY_HIGH_PRIORITY) core/core/src/main/java/imagej/module/process/InitPreprocessor.java:@Plugin(type = PreprocessorPlugin.class, priority = Priority.HIGH_PRIORITY) core/core/src/main/java/imagej/module/process/LoadInputsPreprocessor.java: priority = Priority.VERY_LOW_PRIORITY + 1) core/core/src/main/java/imagej/module/process/SaveInputsPreprocessor.java: priority = Priority.VERY_LOW_PRIORITY - 1) core/core/src/main/java/imagej/module/process/ServicePreprocessor.java: priority = Priority.VERY_HIGH_PRIORITY) core/core/src/main/java/imagej/module/process/ValidityPreprocessor.java: priority = Priority.VERY_HIGH_PRIORITY + 1) core/data/src/main/java/imagej/data/display/ActiveImagePreprocessor.java: priority = Priority.VERY_HIGH_PRIORITY) core/ui/src/main/java/imagej/ui/FilePreprocessor.java: priority = Priority.VERY_LOW_PRIORITY + 1) core/ui/src/main/java/imagej/ui/UIPreprocessor.java:@Plugin(type = PreprocessorPlugin.class, priority = Priority.VERY_HIGH_PRIORITY) So the ones that happen before InitPreprocessor are: 1) DebugPreprocessor 2) ValidityPreprocessor 3) ActiveDisplayPreprocessor 4) ActiveImagePreprocessor 5) GatewayPreprocessor 6) ServicePreprocessor 7) UIPreprocessor The DebugPreprocessor just logs some debugging output. The ValidityPreprocessor makes sure that the module is fundamentally well-formed (e.g., no "final" @Parameter variables, since those cannot be set via reflection). The other five (2-7) all set various types of variables based on the state of the ImageJ application context -- for example, all Service parameters are filled in. So that's why you never see the ImageJ UI prompt for them. It should be case that Alida can reuse the default pre- and post-processing plugin stack -- in other words, you should be able to pass "process=true" to the ModuleService#run and everything will "just work". Let us know if not, and we can troubleshoot. As long as no UI has been shown, you will be in headless mode and no dialogs should ever be shown. (If one does pop up, it is probably a bug.) > as an example, the DuplicateImage command adds input parameters to > itself in its initializer-method depending on the inputDisplay. Thus > is seems that DuplicateImage requires, that inputDisplay is set prior > to calling its initializer and that the user is asked for further > parameters lateron. Yes, it works in that case because the ActiveDisplayPreprocessor runs before the InitPreprocessor, so inputDisplay is indeed already set. > more generally, are there parameters of commands set by the standard > ij2 preprocessos besides a single unresolved Dataset? And is there an > easy way to figure out what preprocessors are run in which order in > the standard ij2 context? Yes, the preprocessors are (by default) those mentioned above. You can get the list of them programmatically: pre = pluginService.createInstancesOfType(PreprocessorPlugin.class) This gives you one instance each of each preprocessor, in priority order. Alternately, if you don't want to instantiate them but only inspect the plugin metadata: infos = pluginService.getPluginsOfType(PreprocessorPlugin.class) > What is your concept to run a headless command from command line (or > shell script), which adds input parameters dependent on the value of > other input parameters? On the CLI, we'll harvest values from the user at the same point in time that we currently do it via the UI. So most of the other preprocessing will be done; there will be a "CLIInputHarvesterPlugin" that prompts the user to type in these values using System.in or similar. We have not yet created this preprocessor plugin, but it would be very straightforward. If you need this, let me know -- it would be a fun side project. :-) > Do you encourcage to dynamically add input parameters to commands? Encourage? Definitely not. Unfortunately, there are certain commands that basically require this functionality. Use your IDE to check the subtype hierarchy of DynamicCommand to find them. But as a rule of thumb: headless modules should not be dynamic. Dynamic commands are *much* more challenging to support across many different environments (CellProfiler, KNIME, OMERO, Alida, etc.) *much* more challenging. > Is there (still) a static method to get hold of the context, as a > while ago was possible via ImageJ.getContext() in order not to (very) > often create a new context (or it the context impemented as a > singelton)? And how does this work out if running command "truely" > headless that is from command line without ij2 GUI? The SciJava context is definitely not a singleton. But you can use it that way if you want: just create one a static variable in your own codebase somewhere; e.g.: public static final imagej.ImageJ IJ = new imagej.ImageJ(); Then you'll always have your ImageJ gateway, easily accessible from all your code. But I would caution you that if your design relies on statics like that, it will be fundamentally less flexible then if you always inject a Context in places where one is needed. We have taken great pains to make all of ImageJ2 work in that way... > is it remnants, that some ContextCommands have services as parameters > as they - if I understand correctly - could retrievee the services > from their contex? We feel that writing the services as @Parameters is cleaner, because those services are, in some sense, "inputs" to the module's operation. There are many ways to express a module's inputs, but our goal is for modules to declare their inputs in the most specific way possible. (We fall short of that goal in many places, but are very open to refactoring to improve things on a case by case basis.) For example, you could write: @Parameter private Context context; And then call "context.service(ModuleService.class).run(...)" but that is less specific than: @Parameter private ModuleService moduleService; And then calling "moduleService.run(...)". This latter form more clearly expresses the fact that it is actually the ModuleService, and not the Context as a whole, that is required for operation. As another example, you could declare an ImageDisplayService parameter and then use it to extract the active image display, then extract the active dataset from that, and finally process it. But it is much cleaner to declare the parameter as a Dataset in the first place, so that the module *could* be used with inputs besides just the active image display's active dataset. For other environments (CellProfiler/KNIME/OMERO/Alida/etc.), the notion of an "active image display" might not make sense, so using a Dataset inputs is better. > has ij2 already support to execute a headless command from the command > line or shell script I actually added something like that last week: a rudimentary interactive script interpreter. It is mainly for testing the ImageJ OPS project right now, but it supports whatever scripting language you want to use, with whatever ImageJ code you want to throw at it. https://github.com/imagej/imagej-scripting-cli Example of usage: $ git clone git://github.com/imagej/imagej-scripting-cli ... code is downloaded ... $ cd imagej-scripting-cli $ mvn ... code compiles ... $ mvn exec:exec ... Maven spits out some stuff ... ImageJ script interpreter: javascript > dataset = ij.dataset().open("/Users/curtis/data/toucan.png"); toucan.png > w = dataset.max(0); 160 > h = dataset.max(1); 148 > future = ij.command().run("imagej.plugins.commands.app.AboutImageJ", true, []); java.util.concurrent.FutureTask@2698dd08 > module = future.get(); imagej.plugins.commands.app.AboutImageJ > module.getOutput("display").getClass(); class imagej.data.display.DefaultImageDisplay Once we have the CLI input harvesting plugin, this will be a little slicker in that "ij.module().run(...)" and "ij.command().run(...)" will be usable for modules that take "real" inputs. Regards, Curtis On Thu, Mar 13, 2014 at 4:39 AM, Stefan Posch <po...@informatik.uni-halle.de > wrote: > Hi Curtis, hi Johannes, > > we have a few questions regarding commands and command execution > to wrap them for our graphical editor and also command line execution > of operators resp. commands. > > What are the precoditions assumed when running a (headless) command > > o may the command assume that its initializer, if any, has been executed > prior to executing its run-Method? > > o may the initializer-Method assume some of the parameter of the command > already set > (as e.g. a single ImageDisplay), and of course, which parameters? > > as an example, the DuplicateImage command adds input parameters to > itself > in its initializer-method depending on the inputDisplay. > Thus is seems that DuplicateImage requires, that inputDisplay is set > prior to > calling its initializer and that the user is asked for further > parameters lateron. > > o more generally, are there parameters of commands set by the standard > ij2 preprocessos > besides a single unresolved Dataset? > And is there an easy way to figure out > what preprocessors are run in which order in the standard ij2 context? > > - What is your concept to run a headless command from command line (or > shell script), which > adds input parameters dependent on the value of other input parameters? > > Do you encourcage to dynamically add input parameters to commands? > > - Is there (still) a static method to get hold of the context, as a while > ago was > possible via ImageJ.getContext() in order not to (very) often create a > new > context (or it the context impemented as a singelton)? > And how does this work out if running command "truely" headless that is > from command line without ij2 GUI? > > - is it remnants, that some ContextCommands have services as parameters > as they - if I understand correctly - could retrievee the services from > their contex? > > - has ij2 already support to execute a headless command from the command > line or shell script > > Thanks a lot and cheers > > Stefan > -- > Prof. Dr.-Ing. Stefan Posch, > Institut fuer Informatik, Martin-Luther-Universitaet > Halle-Wittenberg > Von-Seckendorff-Platz 1, 06099 Halle (Saale) > phone: ++49 345 55-24728 > fax: ++49 345 55-27039 > e-mail: stefan.po...@informatik.uni-halle.de > www: www.informatik.uni-halle.de/~posch/ > > _______________________________________________ > ImageJ-devel mailing list > ImageJ-devel@imagej.net > http://imagej.net/mailman/listinfo/imagej-devel >
_______________________________________________ ImageJ-devel mailing list ImageJ-devel@imagej.net http://imagej.net/mailman/listinfo/imagej-devel