Closed gselzer closed 1 year ago
Thanks for the report! @carshadi, do you have time to look into it?
@gselzer, actually I don't understand why this happens. If I understand correctly DefaultOpMatchingService finds this OP, but fails to create a Command, presumably because OpCandidate#OpInfo() is null!? Is this correct? How can we have it so OpInfo is not null? How do we set it?
Also, BTW, this op (written by @carshadi) improves the original tubeness Op, by allowing multiple scales (as in the Frangi op). At the time we did not submit it to net.imagej.ops because we had not done enough testing, but now we can confirm that it works great, so maybe now that is the time!?
According to this stack overflow post https://stackoverflow.com/a/18024061 , this can happen if the class doesn't have a default (empty) constructor.
Wow. That seems to fix it! I had never seen this before!
So adding a dummy constructor works:
public Tubeness() {
// do nothing
}
However, setting it to private does not work. It needs to be public. But now if someone tries to use that constructor, the computation will fail because the spacing
and scales
fields are not set. What is the recommendation:
But above all, why does this happen? Funny enough the IDE suggests removing the empty constructor as it does nothing :)
For 1) I'm not sure there will be sensible defaults since getting a decent result requires knowing the voxel size of the image. 2) makes more sense to me. I am also not too familiar with how Op parameters are populated. Does running it in this way call the empty constructor and populate the @Parameter
annotated fields with the given arguments?
ops.run("filter.tubeness", out, input, spacing, scale, numThreads)
OK. I think the empty constructor is needed earlier on by the OpService, when looking up which Ops are available. The fix is now in place with 47a319d
Describe the bug Running the Tubeness Op throws a
NullPointerException
when run withops.run
. I originally saw this running in napari-imagejTo Reproduce
Neuroanatomy
is enabled within Fijiout = ops.create().img(input) spacing = [2.0, 2.0] scale = [2.0, 2.0] numThreads = 2
ops.run("filter.tubeness", out, input, spacing, scale, numThreads)
[java.lang.Enum.toString] [ERROR] Command errored: filter.tubeness java.lang.NullPointerException at net.imagej.ops.DefaultOpMatchingService.createModule(DefaultOpMatchingService.java:571) at net.imagej.ops.DefaultOpMatchingService.moduleConforms(DefaultOpMatchingService.java:486) at net.imagej.ops.DefaultOpMatchingService.filterMatches(DefaultOpMatchingService.java:292) at net.imagej.ops.DefaultOpMatchingService.filterMatches(DefaultOpMatchingService.java:137) at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:94) at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:82) at net.imagej.ops.OpEnvironment.module(OpEnvironment.java:253) at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:136) at net.imagej.ops.OpListingModule.run(OpListingModule.java:68) at org.scijava.module.ModuleRunner.run(ModuleRunner.java:165) at org.scijava.module.ModuleRunner.call(ModuleRunner.java:125) at org.scijava.module.ModuleRunner.call(ModuleRunner.java:64) at org.scijava.thread.DefaultThreadService.lambda$wrap$2(DefaultThreadService.java:247) 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:750) [ERROR] Cannot create module: sc.fiji.snt.filter.Tubeness org.scijava.module.ModuleException: org.scijava.InstantiableException: java.lang.InstantiationException: sc.fiji.snt.filter.Tubeness at org.scijava.command.CommandModule.instantiateCommand(CommandModule.java:251) at org.scijava.command.CommandModule.(CommandModule.java:98)
at org.scijava.command.CommandInfo.createModule(CommandInfo.java:326)
at org.scijava.module.DefaultModuleService.createModule(DefaultModuleService.java:167)
at net.imagej.ops.DefaultOpMatchingService.createModule(DefaultOpMatchingService.java:565)
at net.imagej.ops.DefaultOpMatchingService.moduleConforms(DefaultOpMatchingService.java:486)
at net.imagej.ops.DefaultOpMatchingService.filterMatches(DefaultOpMatchingService.java:292)
at net.imagej.ops.DefaultOpMatchingService.filterMatches(DefaultOpMatchingService.java:137)
at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:94)
at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:82)
at net.imagej.ops.OpEnvironment.module(OpEnvironment.java:253)
at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:136)
at net.imagej.ops.OpListingModule.run(OpListingModule.java:68)
at org.scijava.module.ModuleRunner.run(ModuleRunner.java:165)
at org.scijava.module.ModuleRunner.call(ModuleRunner.java:125)
at org.scijava.module.ModuleRunner.call(ModuleRunner.java:64)
at org.scijava.thread.DefaultThreadService.lambda$wrap$2(DefaultThreadService.java:247)
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:750)
Caused by: org.scijava.InstantiableException: java.lang.InstantiationException: sc.fiji.snt.filter.Tubeness
at org.scijava.plugin.PluginInfo.createInstance(PluginInfo.java:309)
at org.scijava.command.CommandInfo.createInstance(CommandInfo.java:248)
at org.scijava.command.CommandModule.instantiateCommand(CommandModule.java:248)
... 20 more
Caused by: java.lang.InstantiationException: sc.fiji.snt.filter.Tubeness
at java.lang.Class.newInstance(Class.java:427)
at org.scijava.plugin.PluginInfo.createInstance(PluginInfo.java:304)
... 22 more
Caused by: java.lang.NoSuchMethodException: sc.fiji.snt.filter.Tubeness.()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 23 more