imglib / imglib2-ij

Translation between ImgLib & ImageJ data structures (both 1.x and 2)
Other
4 stars 8 forks source link

Cannot duplicate wrapped virtual stack #17

Closed ctrueden closed 6 years ago

ctrueden commented 6 years ago

Attempting to invoke the duplicate() method of a net.imglib2.img.display.imagej virtual stack data structure does not work. This prevents some use cases e.g. Morphological Segmentation:

[ERROR] Module threw exception
java.lang.UnsupportedOperationException
    at net.imglib2.img.display.imagej.AbstractVirtualStack.duplicate(AbstractVirtualStack.java:344)
    at inra.ijpb.plugins.MorphologicalSegmentation.run(MorphologicalSegmentation.java:1624)
    at ij.IJ.runUserPlugIn(IJ.java:222)
    at ij.IJ.runPlugIn(IJ.java:186)
    at ij.IJ.runPlugIn(IJ.java:175)
    at net.imagej.legacy.command.LegacyCommand.run(LegacyCommand.java:59)
    at org.scijava.command.CommandModule.run(CommandModule.java:199)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:168)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:127)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:66)
    at org.scijava.thread.DefaultThreadService$3.call(DefaultThreadService.java:238)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

To reproduce the above exception, enable the IJBP-plugins update site, open a big cell image, then try running the "Morphological Segmentation" plugin on it.

tpietzsch commented 6 years ago

@maarzt Please make this a priority. This needs to work

maarzt commented 6 years ago

Ok, this is a priority. But how to duplicate a VirtualStack that wraps arround an imglib2 image?

  1. Duplicate only the wrapper, and wrap the same imglib2 image. (That's propably not the correct approach as data is share between the "duplicate" and original.)
  2. Create an ImageStack and copy all pixels.
  3. Copy the imglib2 image and create a new wrapper arround that.
  4. Or something else?

To me the second option seems to be the way to go. Because the result of the duplicate would be a fully functional IJ1 ImageStack.

tpietzsch commented 6 years ago

Create an ImageStack and copy all pixels.

This one.

The problem is that some IJ1 functionality does not work with VirtualStacks. Usually if you want to use these things, you duplicate the image to get a non-virtual one. So copy everything is exactly what we want. It will not work for really big stuff etc, but that's not the point in this case...

maarzt commented 6 years ago

Ok, it's done, @tpietzsch should be ready for merge and release

tpietzsch commented 6 years ago

I released imglib2-ij-2.0.0-beta-42, and uploaded to the Java-8 Fiji update site

ctrueden commented 6 years ago

Wow, thanks for the fast response, guys! 🥇

ctrueden commented 6 years ago

@maarzt @tpietzsch There is a similar issue/question for the ImgFactory of a SCIFIOImgPlus. I'd like to discuss+decide in person in Dresden what the best thing to do would be for the ImgFactory of the SCIFIOImgPlus.

For reference, here is an example stack trace snippet exhibiting the limitation:

Call setReader(Reader) before invoking create()
    at io.scif.img.cell.SCIFIOCellImgFactory.create(SCIFIOCellImgFactory.java:366)
    at io.scif.img.cell.SCIFIOCellImgFactory.create(SCIFIOCellImgFactory.java:92)
    at net.imagej.DefaultDataset$1.makeImgPlus(DefaultDataset.java:744)
    at net.imagej.DefaultDataset$1.create(DefaultDataset.java:731)
    at net.imagej.DefaultDataset$1.create(DefaultDataset.java:720)
    at net.imglib2.img.ImgFactory.create(ImgFactory.java:168)
    at net.imagej.ops.create.img.Imgs.create(Imgs.java:64)

See also https://github.com/imagej/imagej-omero/issues/92#issue-328204329 for where this can happen in practice.