Open ctrueden opened 9 years ago
+1
I have been recently thinking about the fact that DefaultDataset
is in large part a wrapper for ImgPlus
and plenty of methods are just decorators. Would you rather merge DefaultDataset
and ImgPlus
(or just make ImgPlus
implement Dataset
) or go with something like AbstractDataset
that both Dataset
and ImgPlus
extend?
@rejsmont To get an broader idea of what is planned for these type hierarchies in ImageJ Common and SciJava Common, see the data-model label as well as scijava/scijava-common#157 and this news post, and this topic branch and this git repository.
This data model work is currently priority 5 on my primary priority list.
Regarding Dataset
and ImgPlus
specifically: the current plan is for Dataset
to become a container of multiple images (e.g. Img
, RandomAccessibleInterval
, and/or IterableInterval
... left intentionally open-ended). That way, reading a file with SCIFIO for example can always return a single Dataset
which may contain multiple N-dimensional structures, or just one. And these structures can all have open-ended metadata attached, both structural and otherwise. The metadata will be accessible from some interface Rich
... we may end up with e.g. RichImg extends Rich, Img
and RichRAI extends Rich, RandomAccessibleInterval
, RichII extends Rich, IterableInterval
etc... although one goal is to avoid proliferating too many interfaces like that. Regardless, Dataset
will remain an interface, and be much thinner than it is now.
One thorny issue is how to "recover" the generic parameter (e.g. T extends RealType<T>
) in code—how to go from Dataset dataset
to RichImg<T> img = dataset.image(0)
or some such. It may not be possible to do this without some kind of unchecked warning.
All of this will be a few more months (at least) in coming, but should hopefully be much nicer than what we have now. Once we have this, imagej-common will finally be able to graduate from 0.x
to 1.0.0
, and ImageJ2 as a whole can stop being 2.0.0-rc-xyz
and graduate to 2.0.0
.
@ctrueden if I understand correctly this means then that one should already avoid passing Dataset
as a parameter for ops directly, as once refactoring is done, it may result in unexpected behavior... Imagine a Dataset
from LIF file with multiple images in there - what would ops do if you pass such a dataset to it?
EDIT: I could imagine it taking dataset.image(0)
as a sane default and giving a warning on the console.
@rejsmont Absolutely; this will be a quite serious breaking change in backward compatibility. The Dataset
interface will probably not even implement any of the ImgLib2 image interfaces anymore, so existing ops typed on Dataset
will need to be massaged to either: A) accept a type like Img
or RichImg
instead; or B) extract the image(s) of interest from the dataset via something like dataset.image(0)
.
In general, if you are concerned about things working in the future with no code changes, then it is crucial to use only components released at 1.x or later. Components versioned at 0.x are still incubating and subject to disruptive changes. We will of course do what we can to minimize it, but the fact is that the ImageJ2 data model needs substantial changes to work well into the future.
Both imglib2
and scijava-common
are stable, so you can write e.g. a Command
plugin which uses @Parameter RandomAccessibleInterval<T> image
or whatnot and that should continue to work for a long time. Alternately, you can write @Parameter private ImagePlus imp
and that will also work, although then of course you tie yourself to ImageJ 1.x, which has its own downsides. Please be aware that ImageJ Ops is also still at 0.x, and there are going to be changes to that project as well, including the Op
interface itself no longer extending Command
. Ops written now will need massaging in the future to adapt to changing APIs. However, Ops is fundamentally based on ImgLib2, so I do not expect people will need to "rewrite from scratch" ops which are written now... only that you might need to change e.g. extends AbstractUnaryFunctionOp<T, T>
to implements FunctionOp<T, T>
and rename T calculate(T in)
to T apply(T in)
instead. The main issue is with code written now, published, and then never updated again—that sort of code will not keep working for the next 10 years with no maintenance.
This issue has been mentioned on Image.sc Forum. There might be relevant details there:
https://forum.image.sc/t/autodiscoverable-plugins-in-sci-java/43613/15
These two classes should be one thing.
This is one primary goal of the "rich image" work. Relevant related resources are: