← 输入框|github.com|刷新
Skip to content

Ensure simplification framework is robust enough to support ij.ImagePlus #109

Open

Description

@hinerm

It would be nice to have converter implementations between the core image data structures in ImageJ. The hope would be to give potential uses of typing requests the best chance of success out-of-the-box.

As part of implementing these converters let's also build up the documentation with uses of image typing requests in op calls.

Activity

  1. added this to the 1.0.0 milestone on Jan 18, 2023
  2. hinerm commented on Jan 20, 2023

    @hinerm
    MemberAuthor

    See this branch for manual examples.

    Ideally we would auto-generate these for all arities and desired image types.

  3. gselzer commented on Aug 18, 2023

    @gselzer
    Member

    Okay, I had some fun with type variables and made some lifting Ops that are super general, working on any RAI implementations so long as there is a create Op that satisfies. I was actually able to remove some adaptors that became obsolete because of these, and I'm hoping to do Computers, etc. along these lines.

    @hinerm can you elaborate on what you mean, though, by "common image types"? Do you mean just lifting Ops, like you had on the branch you linked, or do you mean somethign else?

  4. ctrueden commented on Sep 26, 2023

    @ctrueden
    Member

    By "core image data structures" here we mean:

    1. ImageJ2: net.imagej.Dataset and net.imagej.ImgPlus
    2. ImageJ: ij.ImagePlus
    3. ImgLib2: RandomAccessibleInterval and IterableInterval and Img

    This touches on the simplification work: all of the above should boil down to some canonical simple "image" type. Note that (1) is really just a case of (3), because those types extend ImgLib2 types. (For Dataset, the imagej2-legacy module has a type extractor that reifies the generic type properly despite the broken compile-time typing.)

    So the main issue is (2): how do we support passing ImagePlus objects directly to Ops matching attempts, and have it "just work" matching op implementations designed for ImgLib2?

  5. changed the title [-]Add converters for common image types[/-] [+]Ensure simplification framework is robust enough to support ij.ImagePlus[/+] on Sep 26, 2023
  6. hinerm commented on Oct 26, 2023

    @hinerm
    MemberAuthor

    Ideally we would auto-generate these for all arities and desired image types.

    This work looks like it was already done and merged. That branch was done and I think should have been deleted

  7. gselzer commented on Oct 26, 2023

    @gselzer
    Member

    As far as running Ops on ImagePluses goes, here's what we tried:

    • Using imagej-legacy: Theoretically, we could create a set of Ops that know how to access the LegacyImageMap using the LegacyService. Unfortunately, this is very prone to the following exception, which was not solved by any of the theories @ctrueden , @hinerm or I had:
    [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.183 s <<< FAILURE! -- in net.imagej2.legacy.types.DatasetTypeExtractorTest
    [ERROR] net.imagej2.legacy.types.DatasetTypeExtractorTest.testDatasetTypeExtractor -- Time elapsed: 0.031 s <<< ERROR!
    java.lang.ExceptionInInitializerError
    	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    	at org.junit.platform.commons.util.ReflectionUtils.newInstance(ReflectionUtils.java:552)
    	at org.junit.jupiter.engine.execution.ConstructorInvocation.proceed(ConstructorInvocation.java:56)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    	at org.junit.jupiter.api.extension.InvocationInterceptor.interceptTestClassConstructor(InvocationInterceptor.java:73)
    	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
    	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:62)
    	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestClassConstructor(ClassBasedTestDescriptor.java:363)
    	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateTestClass(ClassBasedTestDescriptor.java:310)
    	at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateTestClass(ClassTestDescriptor.java:79)
    	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:286)
    	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
    	at java.base/java.util.Optional.orElseGet(Optional.java:369)
    	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
    	at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
    	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
    	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    	at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:56)
    	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
    	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
    	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122)
    	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
    	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
    	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
    	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
    Caused by: java.lang.RuntimeException: No _hooks field found in ij.IJ
    It appears that this class was already defined in the class loader!
    Please make sure that you initialize the LegacyService before using
    any ImageJ 1.x class. You can do that by adding this static initializer:
    
    	static {
    		LegacyInjector.preinit();
    	}
    
    To debug this issue, start the JVM with the option:
    
    	-javaagent:/home/gselzer/.m2/repository/net/imagej/ij1-patcher/1.2.6/ij1-patcher-1.2.6.jar
    
    To enforce pre-initialization, start the JVM with the option:
    
    	-javaagent:/home/gselzer/.m2/repository/net/imagej/ij1-patcher/1.2.6/ij1-patcher-1.2.6.jar=init
    
    	at net.imagej.patcher@1.2.6/net.imagej.patcher.CodeHacker.javaAgentHint(CodeHacker.java:826)
    	at net.imagej.patcher@1.2.6/net.imagej.patcher.LegacyInjector.alreadyPatched(LegacyInjector.java:436)
    	at net.imagej.patcher@1.2.6/net.imagej.patcher.LegacyInjector.preinit(LegacyInjector.java:383)
    	at net.imagej.patcher@1.2.6/net.imagej.patcher.LegacyInjector.preinit(LegacyInjector.java:379)
    	at net.imagej2.legacy@0-SNAPSHOT/net.imagej2.legacy.types.DatasetTypeExtractorTest.<clinit>(DatasetTypeExtractorTest.java:56)
    	... 71 more
    Caused by: java.lang.NoSuchFieldException: _hooks
    	at java.base/java.lang.Class.getField(Class.java:1999)
    	at net.imagej.patcher@1.2.6/net.imagej.patcher.LegacyInjector.alreadyPatched(LegacyInjector.java:427)
    	... 74 more
    
    [DEBUG] Closing the fork 1 after saying GoodBye.
    • using imglib2-ij: This doesn't work because the needed package, net.imglib2.img, exists in imglib2 as well, and duplicate packages seems to be forbidden by JPMS. We will probably need to wait for imglib2-ij to be JPMS-ified by @tpietzsch to pursue this route.

    Fortunately, if someone really wants to run an Op on an ImagePlus, they could always use the ConvertService or just ask for an Img in their script (instead of an ImagePlus), so I think for now we should just not worry about this.

  8. modified the milestones: 1.0.0, unscheduled on Oct 26, 2023
  9. added a commit that references this issue on May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions