@parameter choice update in component callback

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

@parameter choice update in component callback

MEYENHOFER Felix
Hi

I couldn’t find any hint that it is possible to update the choices of a parameter (declared with the annotator) in a callback that for another parameter. For example; I have a file chooser and once a file hase been chosen, I want to read some file metadata and then update the choices of the combobox that allows to select the images series.
Since I could not figure a way to do it, I wanted to ask here if it is possible at all?

Furthermore, is it possible to get a directory chooser instead of a file chooser in the configuration dialog of a command using the @Parameter annotation?

Best regards,

-------------------------------------
Felix Meyenhofer
University of Fribourg
Departement of Medicine - Anatomy
1, Rte. Albert Gockel
CH-1700 Fribourg

Tel:  +41 26 300 85 45
Web:  www.unifr.ch/anatomy
      www.unifr.ch/bioimage
-------------------------------------

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

Jan Eglinger
Hi Felix and all,

On 20.08.2015 10:06, MEYENHOFER Felix wrote:
> I couldn’t find any hint that it is possible to update the choices of a parameter (declared with the annotator) in a callback that for another parameter. For example; I have a file chooser and once a file hase been chosen, I want to read some file metadata and then update the choices of the combobox that allows to select the images series.
> Since I could not figure a way to do it, I wanted to ask here if it is possible at all?
>

I think dynamic adjustment of parameters isn't possible currently, but I
agree that it would be a great thing to have.

I know quite some use cases where either a DialogListener or a series of
subsequent dialogs are used in ImageJ 1.x plugins to adjust parameter
choice to previously harvested input.

> Furthermore, is it possible to get a directory chooser instead of a file chooser in the configuration dialog of a command using the @Parameter annotation?
>

Yes, by using the
     style = "directory"
attribute. See *Templates > Python > Process Folder* in the script
editor, and this related discussion:
   https://github.com/imagej/imagej-legacy/pull/114

Best,
Jan

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

Curtis Rueden
Hi Felix, Jan and everyone,

> I couldn’t find any hint that it is possible to update the choices of
> a parameter (declared with the annotator) in a callback that for
> another parameter.

It is possible to dynamically adjust parameters from Java code [1]. You can also dynamically add and remove parameters. Such commands extend the DynamicCommand class.

There are many examples currently in the imagej-plugins-commands project; e.g.:

However, a couple of notes:

- This pattern makes the command less reusable from other contexts, because some contexts require a priori knowledge about the number and types of input and output parameters.

- The user interface currently does not properly refresh the input harvester dialog if changes are made to parameters from a callback. So while you can technically do things like change the choices array of a multiple-choice input, the user will not actually see it.

- What does work currently is to determine the multiple-choice values at initialization time, based on the values of parameters which have already been populated earlier, such as an active dataset. This is what many of the DynamicCommand implementations in imagej-plugins-commands do.

Really, there are _five_ different classes of commands here:

1) Totally fixed, with inputs and outputs known in advance.
2) Updates parameter attributes (such as choices—but not # or type of inputs/outputs) once during initialization.
3) Updates parameter number and type (i.e., adding/removing inputs/outputs) once during initialization.
4) Updates parameter attributes repeatedly e.g. during callbacks.
5) Updates parameter number and type repeatedly e.g. during callbacks.

Of these, type #1 is most desirable for a variety of reasons. Failing that, types #2 and #3 can be done right now using DynamicCommand and it works properly from the ImageJ UI—but not from other contexts like CellProfiler, KNIME, etc. Types #4 and #5 can also be coded but will not work properly from the UI in ImageJ because the input harvester is not rebuilt on callbacks.

See also:

Regards,
Curtis

[1] Dynamically updating parameters from scripts would be a different story. No plans to do that any time soon...

On Thu, Aug 20, 2015 at 6:50 AM, Jan Eglinger <[hidden email]> wrote:
Hi Felix and all,

On 20.08.2015 10:06, MEYENHOFER Felix wrote:
I couldn’t find any hint that it is possible to update the choices of a parameter (declared with the annotator) in a callback that for another parameter. For example; I have a file chooser and once a file hase been chosen, I want to read some file metadata and then update the choices of the combobox that allows to select the images series.
Since I could not figure a way to do it, I wanted to ask here if it is possible at all?


I think dynamic adjustment of parameters isn't possible currently, but I agree that it would be a great thing to have.

I know quite some use cases where either a DialogListener or a series of subsequent dialogs are used in ImageJ 1.x plugins to adjust parameter choice to previously harvested input.

Furthermore, is it possible to get a directory chooser instead of a file chooser in the configuration dialog of a command using the @Parameter annotation?


Yes, by using the
    style = "directory"
attribute. See *Templates > Python > Process Folder* in the script editor, and this related discussion:
  https://github.com/imagej/imagej-legacy/pull/114

Best,
Jan


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

Adrian Daerr
Hi Curtis, Felix, Jan, and others,

In the CommandWithPreview tutorial example[*] that Curtis sent to
the list a few weeks back, there is a @Parameter which is
initialised to a value depending on the initialisation of another
parameter:

@Parameter private ImagePlus imp;

@Parameter(persist = false, initializer = "initTitle") private String
title;

/** Initializes the {@link #title} parameter. */
protected void initTitle() {
        title = initialTitle = imp.getTitle();
}

[*]
https://github.com/imagej/imagej-tutorials/blob/master/commands-with-preview/src/main/java/CommandWithPreview.java

Doesn't that allow doing what Felix would like to do, by
populating the combobox through such an initialiser ?

Are the parameters populated/initialised in the order they
appear? In particular, is the initialisation done serially or can
there be parallel execution of initialisers ? I ask because 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 ?

cheers,
Adrian



On Thu, 20 Aug 2015 17:13:11 -0500
  Curtis Rueden <[hidden email]> wrote:

> Hi Felix, Jan and everyone,
>
>> I couldn’t find any hint that it is possible to update the choices
>>of
>> a parameter (declared with the annotator) in a callback that for
>> another parameter.
>
> It is possible to dynamically adjust parameters from Java code [1].
>You can
> also dynamically add and remove parameters. Such commands extend the
> DynamicCommand class.
>
> There are many examples currently in the imagej-plugins-commands
>project;
> e.g.:
> https://github.com/imagej/imagej-plugins-commands/blob/imagej-plugins-commands-0.5.1/src/main/java/net/imagej/plugins/commands/restructure/AddAxis.java
>
> However, a couple of notes:
>
> - This pattern makes the command less reusable from other contexts,
>because
> some contexts require a priori knowledge about the number and types
>of
> input and output parameters.
>
> - The user interface currently does not properly refresh the input
> harvester dialog if changes are made to parameters from a callback.
>So
> while you can technically do things like change the choices array of
>a
> multiple-choice input, the user will not actually see it.
>
> - What does work currently is to determine the multiple-choice
>values at
> initialization time, based on the values of parameters which have
>already
> been populated earlier, such as an active dataset. This is what many
>of the
> DynamicCommand implementations in imagej-plugins-commands do.
>
> Really, there are _five_ different classes of commands here:
>
> 1) Totally fixed, with inputs and outputs known in advance.
> 2) Updates parameter attributes (such as choices—but not # or type
>of
> inputs/outputs) once during initialization.
> 3) Updates parameter number and type (i.e., adding/removing
>inputs/outputs)
> once during initialization.
> 4) Updates parameter attributes repeatedly e.g. during callbacks.
> 5) Updates parameter number and type repeatedly e.g. during
>callbacks.
>
> Of these, type #1 is most desirable for a variety of reasons.
>Failing that,
> types #2 and #3 can be done right now using DynamicCommand and it
>works
> properly from the ImageJ UI—but not from other contexts like
>CellProfiler,
> KNIME, etc. Types #4 and #5 can also be coded but will not work
>properly
> from the UI in ImageJ because the input harvester is not rebuilt on
> callbacks.
>
> See also:
> * https://github.com/scijava/scijava-common/issues/42
> * https://github.com/scijava/scijava-common/issues/43
> * https://github.com/CellProfiler/CellProfiler/issues/647
>
> Regards,
> Curtis
>
> [1] Dynamically updating parameters from scripts would be a
>different
> story. No plans to do that any time soon...
>
> On Thu, Aug 20, 2015 at 6:50 AM, Jan Eglinger
><[hidden email]>
> wrote:
>
>> Hi Felix and all,
>>
>> On 20.08.2015 10:06, MEYENHOFER Felix wrote:
>>
>>> I couldn’t find any hint that it is possible to update the choices
>>>of a
>>> parameter (declared with the annotator) in a callback that for
>>>another
>>> parameter. For example; I have a file chooser and once a file hase
>>>been
>>> chosen, I want to read some file metadata and then update the
>>>choices of
>>> the combobox that allows to select the images series.
>>> Since I could not figure a way to do it, I wanted to ask here if it
>>>is
>>> possible at all?
>>>
>>>
>> I think dynamic adjustment of parameters isn't possible currently,
>>but I
>> agree that it would be a great thing to have.
>>
>> I know quite some use cases where either a DialogListener or a
>>series of
>> subsequent dialogs are used in ImageJ 1.x plugins to adjust
>>parameter
>> choice to previously harvested input.
>>
>> Furthermore, is it possible to get a directory chooser instead of a
>>file
>>> chooser in the configuration dialog of a command using the
>>>@Parameter
>>> annotation?
>>>
>>>
>> Yes, by using the
>>     style = "directory"
>> attribute. See *Templates > Python > Process Folder* in the script
>>editor,
>> and this related discussion:
>>   https://github.com/imagej/imagej-legacy/pull/114
>>
>> Best,
>> Jan
>>
>>
>> _______________________________________________
>> ImageJ-devel mailing list
>> [hidden email]
>> http://imagej.net/mailman/listinfo/imagej-devel
>>

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

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

Curtis Rueden
Hi Adrian,

> Doesn't that allow doing what Felix would like to do, by populating
> the combobox through such an initialiser ?

I think what Felix wants is to set a parameter's "choices" attribute -- i.e., the values that will appear in the input harvester UI's dropdown list box.

It can be done with a DynamicCommand, but right now it only works from an initializer, not from a callback. So if you want to populate the choice once from, say, the active Dataset, it works. But if you want to update the choices e.g. every time the user moves a numerical slider, it will not work because the UI will not update.

See also:

> Are the parameters populated/initialised in the order they appear? In
> particular, is the initialisation done serially or can there be
> parallel execution of initialisers ?

Initialization is currently implemented serially [1].

> 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.

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

Regards,
Curtis


On Fri, Aug 21, 2015 at 6:18 AM, Adrian Daerr <[hidden email]> wrote:
Hi Curtis, Felix, Jan, and others,

In the CommandWithPreview tutorial example[*] that Curtis sent to
the list a few weeks back, there is a @Parameter which is
initialised to a value depending on the initialisation of another
parameter:

@Parameter private ImagePlus imp;

@Parameter(persist = false, initializer = "initTitle") private String title;

/** Initializes the {@link #title} parameter. */
protected void initTitle() {
        title = initialTitle = imp.getTitle();
}

[*]
https://github.com/imagej/imagej-tutorials/blob/master/commands-with-preview/src/main/java/CommandWithPreview.java

Doesn't that allow doing what Felix would like to do, by
populating the combobox through such an initialiser ?

Are the parameters populated/initialised in the order they
appear? In particular, is the initialisation done serially or can
there be parallel execution of initialisers ? I ask because 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 ?

cheers,
Adrian




On Thu, 20 Aug 2015 17:13:11 -0500
 Curtis Rueden <[hidden email]> wrote:
Hi Felix, Jan and everyone,

I couldn’t find any hint that it is possible to update the choices of
a parameter (declared with the annotator) in a callback that for
another parameter.

It is possible to dynamically adjust parameters from Java code [1]. You can
also dynamically add and remove parameters. Such commands extend the
DynamicCommand class.

There are many examples currently in the imagej-plugins-commands project;
e.g.:
https://github.com/imagej/imagej-plugins-commands/blob/imagej-plugins-commands-0.5.1/src/main/java/net/imagej/plugins/commands/restructure/AddAxis.java

However, a couple of notes:

- This pattern makes the command less reusable from other contexts, because
some contexts require a priori knowledge about the number and types of
input and output parameters.

- The user interface currently does not properly refresh the input
harvester dialog if changes are made to parameters from a callback. So
while you can technically do things like change the choices array of a
multiple-choice input, the user will not actually see it.

- What does work currently is to determine the multiple-choice values at
initialization time, based on the values of parameters which have already
been populated earlier, such as an active dataset. This is what many of the
DynamicCommand implementations in imagej-plugins-commands do.

Really, there are _five_ different classes of commands here:

1) Totally fixed, with inputs and outputs known in advance.
2) Updates parameter attributes (such as choices—but not # or type of
inputs/outputs) once during initialization.
3) Updates parameter number and type (i.e., adding/removing inputs/outputs)
once during initialization.
4) Updates parameter attributes repeatedly e.g. during callbacks.
5) Updates parameter number and type repeatedly e.g. during callbacks.

Of these, type #1 is most desirable for a variety of reasons. Failing that,
types #2 and #3 can be done right now using DynamicCommand and it works
properly from the ImageJ UI—but not from other contexts like CellProfiler,
KNIME, etc. Types #4 and #5 can also be coded but will not work properly
from the UI in ImageJ because the input harvester is not rebuilt on
callbacks.

See also:
* https://github.com/scijava/scijava-common/issues/42
* https://github.com/scijava/scijava-common/issues/43
* https://github.com/CellProfiler/CellProfiler/issues/647

Regards,
Curtis

[1] Dynamically updating parameters from scripts would be a different
story. No plans to do that any time soon...

On Thu, Aug 20, 2015 at 6:50 AM, Jan Eglinger <[hidden email]>
wrote:

Hi Felix and all,

On 20.08.2015 10:06, MEYENHOFER Felix wrote:

I couldn’t find any hint that it is possible to update the choices of a
parameter (declared with the annotator) in a callback that for another
parameter. For example; I have a file chooser and once a file hase been
chosen, I want to read some file metadata and then update the choices of
the combobox that allows to select the images series.
Since I could not figure a way to do it, I wanted to ask here if it is
possible at all?


I think dynamic adjustment of parameters isn't possible currently, but I
agree that it would be a great thing to have.

I know quite some use cases where either a DialogListener or a series of
subsequent dialogs are used in ImageJ 1.x plugins to adjust parameter
choice to previously harvested input.

Furthermore, is it possible to get a directory chooser instead of a file
chooser in the configuration dialog of a command using the @Parameter
annotation?


Yes, by using the
    style = "directory"
attribute. See *Templates > Python > Process Folder* in the script editor,
and this related discussion:
  https://github.com/imagej/imagej-legacy/pull/114

Best,
Jan


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel


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


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

MEYENHOFER Felix
Hi Adrian, Jan and Curtis

I went through the tutorials and found about the initialisation method. Curtis was absolutely right about what I wanted to do. Thanks for the detailed explanations. In fact I was aiming for the use case 4) update parameter attributes several times during callbacks. Since the file chooser could have its input changed several times (typically a click accident, mistake of choice or such), It would be odd for the user if the UI get’s updated only once.

The alternative of course is to use an OpenDialog previous to the configuration dialog. Or to program the the dialog from scratch (but this certainly does not improve reusability neither).

The proposal https://github.com/scijava/scijava-common/issues/181 sounds like a promising idea to me. 

Felix

On 22 Aug 2015, at 6:10 , Curtis Rueden <[hidden email]> wrote:

Hi Adrian,

> Doesn't that allow doing what Felix would like to do, by populating
> the combobox through such an initialiser ?

I think what Felix wants is to set a parameter's "choices" attribute -- i.e., the values that will appear in the input harvester UI's dropdown list box.

It can be done with a DynamicCommand, but right now it only works from an initializer, not from a callback. So if you want to populate the choice once from, say, the active Dataset, it works. But if you want to update the choices e.g. every time the user moves a numerical slider, it will not work because the UI will not update.

See also:

> Are the parameters populated/initialised in the order they appear? In
> particular, is the initialisation done serially or can there be
> parallel execution of initialisers ?

Initialization is currently implemented serially [1].

> 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.

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

Regards,
Curtis


On Fri, Aug 21, 2015 at 6:18 AM, Adrian Daerr <[hidden email]> wrote:
Hi Curtis, Felix, Jan, and others,

In the CommandWithPreview tutorial example[*] that Curtis sent to
the list a few weeks back, there is a @Parameter which is
initialised to a value depending on the initialisation of another
parameter:

@Parameter private ImagePlus imp;

@Parameter(persist = false, initializer = "initTitle") private String title;

/** Initializes the {@link #title} parameter. */
protected void initTitle() {
        title = initialTitle = imp.getTitle();
}

[*]
https://github.com/imagej/imagej-tutorials/blob/master/commands-with-preview/src/main/java/CommandWithPreview.java

Doesn't that allow doing what Felix would like to do, by
populating the combobox through such an initialiser ?

Are the parameters populated/initialised in the order they
appear? In particular, is the initialisation done serially or can
there be parallel execution of initialisers ? I ask because 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 ?

cheers,
Adrian




On Thu, 20 Aug 2015 17:13:11 -0500
 Curtis Rueden <[hidden email]> wrote:
Hi Felix, Jan and everyone,

I couldn’t find any hint that it is possible to update the choices of
a parameter (declared with the annotator) in a callback that for
another parameter.

It is possible to dynamically adjust parameters from Java code [1]. You can
also dynamically add and remove parameters. Such commands extend the
DynamicCommand class.

There are many examples currently in the imagej-plugins-commands project;
e.g.:
https://github.com/imagej/imagej-plugins-commands/blob/imagej-plugins-commands-0.5.1/src/main/java/net/imagej/plugins/commands/restructure/AddAxis.java

However, a couple of notes:

- This pattern makes the command less reusable from other contexts, because
some contexts require a priori knowledge about the number and types of
input and output parameters.

- The user interface currently does not properly refresh the input
harvester dialog if changes are made to parameters from a callback. So
while you can technically do things like change the choices array of a
multiple-choice input, the user will not actually see it.

- What does work currently is to determine the multiple-choice values at
initialization time, based on the values of parameters which have already
been populated earlier, such as an active dataset. This is what many of the
DynamicCommand implementations in imagej-plugins-commands do.

Really, there are _five_ different classes of commands here:

1) Totally fixed, with inputs and outputs known in advance.
2) Updates parameter attributes (such as choices—but not # or type of
inputs/outputs) once during initialization.
3) Updates parameter number and type (i.e., adding/removing inputs/outputs)
once during initialization.
4) Updates parameter attributes repeatedly e.g. during callbacks.
5) Updates parameter number and type repeatedly e.g. during callbacks.

Of these, type #1 is most desirable for a variety of reasons. Failing that,
types #2 and #3 can be done right now using DynamicCommand and it works
properly from the ImageJ UI—but not from other contexts like CellProfiler,
KNIME, etc. Types #4 and #5 can also be coded but will not work properly
from the UI in ImageJ because the input harvester is not rebuilt on
callbacks.

See also:
* https://github.com/scijava/scijava-common/issues/42
* https://github.com/scijava/scijava-common/issues/43
* https://github.com/CellProfiler/CellProfiler/issues/647

Regards,
Curtis

[1] Dynamically updating parameters from scripts would be a different
story. No plans to do that any time soon...

On Thu, Aug 20, 2015 at 6:50 AM, Jan Eglinger <[hidden email]>
wrote:

Hi Felix and all,

On 20.08.2015 10:06, MEYENHOFER Felix wrote:

I couldn’t find any hint that it is possible to update the choices of a
parameter (declared with the annotator) in a callback that for another
parameter. For example; I have a file chooser and once a file hase been
chosen, I want to read some file metadata and then update the choices of
the combobox that allows to select the images series.
Since I could not figure a way to do it, I wanted to ask here if it is
possible at all?


I think dynamic adjustment of parameters isn't possible currently, but I
agree that it would be a great thing to have.

I know quite some use cases where either a DialogListener or a series of
subsequent dialogs are used in ImageJ 1.x plugins to adjust parameter
choice to previously harvested input.

Furthermore, is it possible to get a directory chooser instead of a file
chooser in the configuration dialog of a command using the @Parameter
annotation?


Yes, by using the
    style = "directory"
attribute. See *Templates > Python > Process Folder* in the script editor,
and this related discussion:
  https://github.com/imagej/imagej-legacy/pull/114

Best,
Jan


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel


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



_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

Adrian Daerr
In reply to this post by Curtis Rueden
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

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

Curtis Rueden
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





On Mon, Aug 24, 2015 at 9:07 AM, Adrian Daerr <[hidden email]> 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


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

Adrian Daerr
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 <[hidden email]> 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 <
> [hidden email]> 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
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: @parameter choice update in component callback

Curtis Rueden
Hi Adrian,

> (checkout branch overlay_issue (commit 2887f8ec))
>
> This is a MVCE that has parameters

Thanks, I was able to replicate the problems using your code.

I tried to reproduce using a script with various parameter combinations mirroring yours, but was initially unsuccessful. It seems the problem is a little subtle.

It is likely related to the syncing of IJ1 and IJ2 data structures. So I'm not going to worry about further for the time being—that logic will be revised in the future anyway.

> 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.

The best I have to offer right now is:

> 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.

That would be fantastic! It is physically impossible for Mark and me to write the entire wiki...

Regards,
Curtis

On Thu, Aug 27, 2015 at 2:18 PM, Adrian Daerr <[hidden email]> wrote:
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 <[hidden email]> 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 <
[hidden email]> 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
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel