Hello Curtis,

@Parameter(persist = false) private RectangleOverlay roi;

which appears to be populated only after the initializer is called
(its value is null in the initializer and valid in the run() method).

Hmm, that should not be the case. [..]
The issue might be typing-related: try using Overlay instead of
RectangleOverlay and see if that makes a difference.

Alternately: can you post an MVCE [3, 4] illustrating the issue?

https://gitlab.com/pendant-drop/pendant-drop.git
(checkout branch overlay_issue (commit 2887f8ec))

This is a MVCE that has parameters

    @Parameter
    private ImagePlus imp;

    @Parameter(persist = false)
    private RectangleOverlay region;

    @Parameter(persist = false)
    private Overlay overlay;

It compiles and executes with

mvn -o package && fiji --class-path \
target/pendant_drop-2.0.0-SNAPSHOT.jar Goutte_pendante.class

and logs the following to the console:

[INFO] imp parameter in initializer(): non-null
[INFO] region parameter in initializer(): null
[INFO] overlay parameter in initializer(): null
[INFO] imp parameter in preview(): non-null
[INFO] region parameter in preview(): non-null
[INFO] overlay parameter in preview(): non-null
[INFO] imp parameter in run(): non-null
[INFO] region parameter in run(): non-null
[INFO] overlay parameter in run(): non-null
[ERROR] Module threw exception
java.lang.NullPointerException
        at ij.plugin.frame.Recorder.addQuotes(Recorder.java:612)
...

Note 1) Since I switched to the OverlayService.getSelectionBounds()
solution you suggested in another thread, do not bother looking into
this for me. I just submit this MVCE in case the issue is more
important than I suspect.

Note 2) It appears (RectangleOverlay).toString() returns null in any
case.

Note 3) Overlay and RectangleOverlay have the same issue with respect
to initialization, but the reason I used RectangleOverlay is that I
did not see how to get the bounds of an Overlay.

I am sorry—the tutorials need to be improved. What sort of tutorial do you think would aid your understanding here?

More than a tutorial I missed some explanations on the technical
design of, and the interplay between, the different parts that now
make up ImageJ2. Instead of one single place to find the API and
Source of ij.*, things are split up into packages (org.scijava.*,
net.imagej.*, imglib) and it takes a bit to figure out how things are
organized and why this division of labour makes sense. So deciding
e.g. where to look for ROI/Overlay related stuff was not easy
(net.imagej? imglib? both seem to have bits). For someone used to the
often static, in any case ultra specific ImageJ1 API, understanding
what a context is, what Services are good for, how menus, views, even
whole GUIs are flexibly handled, how roughly plugins are recognized,
how and when annotations are parsed (what's an annotation anyway from
a Java perspective ?) and how they are instantiated and executed, well
all this is quite a lot of new stuff. Not to speak about understanding
how the new Dataset/ImageDisplay/Views classes replacing ImageJ1's
ImagePlus/ImageWindow/.. work together, and why some of them are
already deprecated ;-)

Now this very design still seems to be changing, so I understand
writing up something might be a bit early. Besides, it's a good thing
not to pin it down to early, and producing documentation wikis that
may soon prove outdated can be not only a waste of time, but even
prove quite perturbing later when they contradict reality. Even if I'd
like to see some gently (but technically oriented) introduction to the
class zoo and ecosystem of ImageJ2, and also a guide to plugin
programming specifically for the ImageJ1 veteran (with, for now, your
recommendation to just take advantage of the parameter harvesting
features but to stick to IJ1 data structures), I think this is
probably too early to do. But I just opened a sheet in an editor on
which I will jot down notes as I go ahead with my plugin, about
problems, discoveries and things I suddenly understand. Maybe this can
be a starting point or contribution for a transition guide.

If I do have ideas about specific programming examples for the
imagej-tutorials, I'll voice them of course.

In any case your reactivity on this list is simply invaluable, thanks
a lot for adding communication efforts to your programming mission.

best regards,
Adrian



On Mon, 24 Aug 2015 10:25:59 -0500
 Curtis Rueden <ctrue...@wisc.edu> wrote:
Hi Adrian,

Thanks for the suggestion, which almost does the job, except that the
initialization also depends on a parameter

@Parameter(persist = false) private RectangleOverlay roi;

which appears to be populated only after the initializer is called
(its value is null in the initializer and valid in the run() method).

Hmm, that should not be the case. Commands that include a single overlay parameter should automatically draw from the active image's active overlay, when possible [1]. This happens _before_ the initializers are called [2]
(because Priority.VERY_HIGH_PRIORITY > Priority.HIGH_PRIORITY).

The issue might be typing-related: try using Overlay instead of
RectangleOverlay and see if that makes a difference. If so, it is probably
a limitation of the ActiveOverlayPreprocessor [1]; patches welcome.

Alternately: can you post an MVCE [3, 4] illustrating the issue?

do I have to write a Preprocessor of some sorts

This is certainly possible to do, but I would hope not necessary.

can the initializer 'manually' call the code which normally harvest
the RectangleOverlay parameter later on ?

Sure, you can always code in whatever logic you want to the plugin
initializer method. But again, hopefully not necessary in this case.

even after some reading of the tutorials and the scijava source code
around org.scijava.command.CommandInfo my understanding of how the
plugin initialisation works is still poor.

I am sorry—the tutorials need to be improved. What sort of tutorial do you
think would aid your understanding here? The "execute-commands" and
"custom-preprocessor-plugin" tutorials are probably touch on these topics
most closely, although neither provides a real overview of the
pre-/post-processing chain in conjunction with module execution.

Would it make sense to distinguish (by an annotation ?) parameters
that are to be initialized from the context (i.e. services, active
image, roi etc), and whose lack should be immediately fatal to the
plugin (no UI harvesting, and in exchange can be assumed final for the
rest of the command execution), from parameters that, if they cannot
be populated from already available data, should be harvested through
a dialog (and may change several times) ?

Potentially, yes. Feel free to comment on the issue on GitHub!

Regards,
Curtis

[1]
https://github.com/imagej/imagej-common/blob/imagej-common-0.15.1/src/main/java/net/imagej/display/process/ActiveOverlayPreprocessor.java#L57

[2]
https://github.com/scijava/scijava-common/blob/scijava-common-2.44.2/src/main/java/org/scijava/module/process/InitPreprocessor.java#L49

[3] http://imagej.net/Bug_reporting_best_practices

[4] http://stackoverflow.com/help/mcve


On Mon, Aug 24, 2015 at 9:07 AM, Adrian Daerr <
adrian.da...@univ-paris-diderot.fr> wrote:

Hi Curtis,

I have parameters a, b, c whose initialisation depend on a common
calculation (depending on the image gotten through a previous
@Parameter ImagePlus imp): can I do this calculation in the
initialiser for the first parameter a, and then in the initialisers of b
and c rely on the fact that the calculation was already done ?


Perhaps simplest at the moment would be to give your command a global
initializer -- i.e., set the initializer method in the
@Plugin annotation itself, rather than on specific parameters.
The ImagePlus will be populated by a preprocessor _before_ the
initialize method is called, so when your global initializer gets
called you will already have access to the ImagePlus.


Thanks for the suggestion, which almost does the job, except that the
initialization also depends on a parameter

@Parameter(persist = false) private RectangleOverlay roi;

which appears to be populated only after the initializer is called (its
value is null in the initializer and valid in the run() method).

I am not sure how to solve this: do I have to write a Preprocessor of some sorts, or can the initializer 'manually' call the code which normally harvest the RectangleOverlay parameter later on ? Somehow the fact that ImagePlus is populated by a Preprocessor but RectangleOverlay isn't, seems linked to issues that I mentionned in another post[1], but even after some
reading of the tutorials and the scijava source code around
org.scijava.command.CommandInfo my understanding of how the plugin
initialisation works is still poor.

[1]
(e.g. that the Overlay appears in the harvesting dialog, or that an
Exception is thrown because of the overlay after command execution)

http://imagej-devel.54429.x6.nabble.com/Masking-Parameter-from-GUI-harvesting-td1098.html

But again, scijava/scijava-common#181 is very relevant here.


Would it make sense to distinguish (by an annotation ?) parameters that are to be initialized from the context (i.e. services, active image, roi etc), and whose lack should be immediately fatal to the plugin (no UI
harvesting, and in exchange can be assumed final for the rest of the
command execution), from parameters that, if they cannot be populated from already available data, should be harvested through a dialog (and may
change several times) ?

cheers,
Adrian


--
http://www.msc.univ-paris-diderot.fr/~daerr/

_______________________________________________
ImageJ-devel mailing list
ImageJ-devel@imagej.net
http://imagej.net/mailman/listinfo/imagej-devel

Reply via email to