Autodiscoverable Plugins in (Sci)Java

Hi,

cc @tinevez @NicoKiaru @imagejan @haesleinhuepf @nornil @seadaisy

As you may know, I am developing this software for processing of TB sized image data:


I already contains a number of processing steps (crop, bin, …), but I was wondering how I could make it easy for others to contribute additional processing steps.
I am thinking of some mechanism that would allow to auto-discover “plugins” on the class path and automatically add them to the menu tree. In fact, I am thinking that also all the current processing steps should probably be discovered in this way. Does someone have recommendations how to do this? Maybe defining some ImageProcessor interface and/or some @ImageProcessor annotation?

Thank you for your help!

2 Likes

Hi Tischi,

I think you are looking for the SciJava plugin/service mechanism. I did a course on this some time ago where we implement a zoo which uses an animal service which offers animal plugins. Exercise is to extend the code to put more animals in the zoo (solution). Furthermore, I’m almost sure that @ctrueden also has slides and/or more material about the scijava plugin/service mechanism.

Cheers,
Robert

4 Likes

Hello Tischi.

I second Robert: the SciJava discovery mechanism is great and I have used it for quite some time in about everything.

For instance in Mastodon, all the detection algorithm implements the SpotDetectorOp


(It does not have to be an Op).

Then an annotation with SciJava @Plugin makes concrete classes discoverable:

Finally I made this class that is in charge of collecting all the plugins that implement a certain interface:

It is used in the GUI like this:

		final PluginProvider< SpotDetectorOp > detectorprovider = new PluginProvider<>( SpotDetectorOp.class );
		final Context context = windowManager.getContext();
		context .inject( detectorprovider );
		this.names = detectorprovider.getVisibleNames();
		this.descriptions = detectorprovider.getDescriptions();
		this.classes = detectorprovider.getClasses();
4 Likes

Thanks a lot guys! I will give it a try!

1 Like

This looks awesome! May I reuse it? I would probably just C&P for now not to have mastodon as a dependency…
General note: you guys have so many awesome things in Mastodon that are of general use that it may make sense to think about factoring some out into other repos, at some point, “soooon” :wink:

3 Likes

Go forth and copy & paste!

As for refactoring into other repos, Tobias already put some of the most general things in specialized repo. For instance the scijava-listeners come from Mastodon. Some stuff in the ui-behavior too. For the rest, releasing Mastodon is my top priority :slight_smile:

While I have you online, I am investigating how people do block-processing with limited RAM. Can you point me in BDP2 where you create your blocks and pass them to your algorithms?

2 Likes
  1. For previewing the data (i.e. people browsing around in BDV) I just create a CachedCellImg where one cell typically is one z-plane. This takes care of the lazy-computation in the preview mode.
  2. In the end when people want to actually re-save the processed data, I replace the CellLoader by a loader that loads one 3D volume (i.e. one channel and timepoint) in one go, because this is faster than loading plane by plane. And then I process each volume with this function: https://github.com/bigdataprocessor/bigdataprocessor2/blob/ee4da2c79eb894ab83c51f0ec915f74292ae3c66/src/main/java/de/embl/cba/bdp2/utils/IntervalImageViews.java#L208
    • The name of the class IntervalImageViews is a misnomer for this because, this is not a View but this method actually forces all the computations (stacked Views and Conversions) to be done for the asked-for volume

If that’s too confusing I am happy to zoom.

1 Like

This class looks like it’s not specific to mastodon-tracking at all, is it?

I’m actually surprised that you needed such a class, I would have expected SciJava to have some functionality like this already. What does it add to PluginService? (I didn’t look at the source in detail yet.)

Please, guys, before proliferating useful code in this way, make an effort to push it upstream somewhere in scijava :pray:

Indeed, the efforts by @tpietzsch are very valuable. scijava-listeners, scijava-optional, ui-behavior and others are already used by other projects, and are minimal dependencies each.

In addition to the examples pointed out by @haesleinhuepf and @tinevez already, I’d like to add a few more examples of repositories that use the SciJava plugin discovery (and nicely illustrate its use, in my opinion):

1 Like

@imagejan Do you think it would be possible to organise a multi-day course on SciJava, covering both how to use it and how to contribute to it? I know couple of people, including myself, that would be interested to learn!

2 Likes

I would also be interested :slightly_smiling_face:

2 Likes

Hi everyone. I’m here to learn too, so thanks a lot for the info.

3 Likes

Thanks! I think I managed thanks to your great help!

2 Likes

Sure, great idea! What format did you have in mind? We’ve had the learnathons in Dresden for a couple of years now, but an online format might be more suitable currently. A few days with one online session per day, with some time in between to try out stuff on your own? It would be good to have @ctrueden on board with this, as he’s the one who can tell us most about the intended architecture.

:+1: I am certain you could teach us all how you employed SciJava functionality in scijava-search and other projects, in addition to:

Maybe we can also organize a kind of online live code review where we discuss how SciJava functionality is used in several projects, and how they might be able to benefit from it even more.

2 Likes

Great, thanks for sharing!

While there’s no date for a SciJava course or the next hackathon yet, let me post a few comments here:

For a better separation of concerns, I think it would be best practice to use an interface instead of an abstract class for type annotations. Other SciJava experts might want to correct me, or to elaborate on this if necessary.

It’s unfortunate (in my opinion) that you felt the need to implement this Image class to link pixel data with metadata. It shows that we apparently still don’t have a satisfying solution for this in the ImageJ2/SciJava ecosystem.
It reminds me of @ctrueden’s work on RichImage (six years back), see also this old issue: imagej/imagej-common#46

Instead of string concatenation for the menuPath, you can also use the menu attribute with nested @Menu annotations, see e.g.:

2 Likes

I’m happy to share what I know, but I also have knowledge gaps, e.g. when it comes to scijava parameters… :wink:

First of all thanks a lot for all the suggestions!

My logic was that I think I want to force contributors to contribute an extension of the AbstractImageProcessingCommand, because some stuff that’s happening in there seems vital for the current logic of the code. I am not sure how to achieve this with an interface right now. Do you have a suggestion?

Instead of string concatenation for the menuPath , you can also use the menu attribute with nested @Menu annotations, see e.g.:

Thanks! That works! Apart from being more readable, are there more advantages?

It’s unfortunate (in my opinion) that you felt the need to implement this Image class to link pixel data with metadata. It shows that we apparently still don’t have a satisfying solution for this in the ImageJ2/SciJava ecosystem.

Yes, I good point! I grew historically as I was first just having a RandomAccessibleInterval and then I added stuff on top. Maybe an ImgPlus may also do the job.

  1. Is it possible to instantiate an ImgPlus from an 5D (x,y,z,c,t) RandomAccessibleInterval ?
  2. I heard some rumours that there were some ideas to not any longer longer support the ImgPlus class?
  3. What would you say is the currently recommended class to use for a single resolution image? For multi-resolution I think SourceAndConverter does the job very nicely! Having said this maybe I should also use it for single resolution…

I don’t think you need this PluginProvider thing (I say without having studied it carefully!).

In SciJava Common, there is a service interface called PTService intended for services that want to manage a particular kind of plugin (the “PT” stands for “plugin type”). There are some further patterns on top of PTService.

Please read the javadoc for PTService and let me know if you have any questions:

2 Likes