morphonets / SNT

The ImageJ framework for quantification of neuronal anatomy
https://imagej.net/plugins/snt
GNU General Public License v3.0
42 stars 18 forks source link

Example Script - Instantiate the SNT service from python #67

Open schluta opened 3 years ago

schluta commented 3 years ago

Feature Request: It seems all of the example scripts for using the SNT plugin from python through pyimagej are using the MouseLightLoader to load a remote dataset. I am trying to instantiate the service and use it locally (potentially in a headless manner). I have tried both the SNT class initialize and SNTService initialize functions but neither have worked for me. It would really help to see an example of instantiating the plugin from python. I need to use other python packages so using the scripting interface from within Fiji will not work for me.

if os.path.isdir(fiji_path):
    #ij = imagej.init('sc.fiji:fiji', headless=False)
    ij = imagej.init(fiji_path, headless=False)
    #ij = imagej.init()
    print(ij.getVersion()) #'2.2.0/1.53c'
    ui = ij.ui()
    context = ij.getContext()
    ui.showUI()
else:
    print("Cannot proceed: Fiji not found!")
#
SNTService = jimport('sc.fiji.snt.SNTService')
SNT = jimport('sc.fiji.snt.SNT')
#Path = jimport('sc.fiji.snt.Path')
#PathAndFillManager = jimport('sc.fiji.snt.PathAndFillManager')
#SNTUI = jimport('sc.fiji.snt.SNTUI')
Tree = jimport('sc.fiji.snt.Tree')
PointInImage = jimport('sc.fiji.snt.util.PointInImage')

snt_inst = SNT(context, "./test.tif")
# Documentation Resources: https://imagej.net/SNT:_Scripting
# Latest SNT API: https://morphonets.github.io/SNT/
def run():

    snt = SNTService()

Output

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by net.imagej.patcher.LegacyInjector (file:/Applications/Fiji.app/jars/ij1-patcher-1.2.1.jar) to method java.lang.ClassLoader.findLoadedClass(java.lang.String)
WARNING: Please consider reporting this to the maintainers of net.imagej.patcher.LegacyInjector
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2.3.0/1.53f
Traceback (most recent call last):
  File "/Users/s/workspace/neuron/neuron_auto_native.py", line 30, in <module>
    snt_inst = SNT(context, "/Users/s/Desktop/test.tif")
TypeError: No matching overloads found for constructor sc.fiji.snt.SNT(org.scijava.Context,str), options are:
    public sc.fiji.snt.SNT(org.scijava.Context,sc.fiji.snt.PathAndFillManager)
    public sc.fiji.snt.SNT(org.scijava.Context,ij.ImagePlus) throws java.lang.IllegalArgumentException

If I do not try to run the SNT constructor then I get the following Output:

Traceback (most recent call last):
  File "SNTService.java", line 169, in sc.fiji.snt.SNTService.initialize
  File "SNTService.java", line 181, in sc.fiji.snt.SNTService.initialize
  File "SNT.java", line 341, in sc.fiji.snt.SNT.<init>
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/s/workspace/neuron/neuron_auto_native.py", line 76, in <module>
    run()
  File "/Users/s/workspace/neuron/neuron_auto_native.py", line 51, in run
    plugin = snt.initialize("/Users/s/Desktop/test.tif", True) # image, whether UI should be shown
org.scijava.NullContextException: org.scijava.NullContextException: Before attempting to use this object, please set its context by calling the setContext(...) method.

If I try and run the SNT.initialize method I get either the following based on which one I try:

TypeError: No matching overloads found for *static* sc.fiji.snt.SNT.initialize(ij.ImagePlus), options are:
     public void sc.fiji.snt.hyperplanes.MultiDThreePanes.initialize(ij.ImagePlus,int)
     public void sc.fiji.snt.SNT.initialize(ij.ImagePlus)
     public void sc.fiji.snt.SNT.initialize(boolean, int, int)

TypeError: No matching overloads found for *static* sc.fiji.snt.SNT.initialize(bool, int, int), options are:
     public void sc.fiji.snt.hyperplanes.MultiDThreePanes.initialize(ij.ImagePlus,int)
     public void sc.fiji.snt.SNT.initialize(ij.ImagePlus)
     public void sc.fiji.snt.SNT.initialize(boolean, int, int)
carshadi commented 3 years ago

Hi @schluta ,

To initialize the plugin with a local Fiji installation subscribed to the Neuroanatomy update site through pyimagej:

import imagej

ij = imagej.init(fiji_path, headless=False) # set True if headless
ij.ui().showUI() # comment out if headless

from scyjava import jimport

SNTUtils = jimport('sc.fiji.snt.SNTUtils')
print("We are running SNT %s" % SNTUtils.VERSION)

SNTService = jimport('sc.fiji.snt.SNTService')
# Retrieve the SNTService instance associated with the main application context
sntService = ij.get(SNTService.class_)

# Initialize the plugin
plugin = sntService.initialize("./test.tif", True) # Start UI, set False if headless

On the first error, it is due to the second argument to SNT(), which expects either a PathAndFillManager instance or ImagePlus instance, instead of a file path String

snt_inst = SNT(context, "./test.tif")

On the second error, the SNTService created via snt = SNTService() does not have a SciJava Context associated with it, so it is not very useful in that state. We can get the context-aware service instance using sntService = ij.get(SNTService.class_)

For the third error, my guess is you tried to call SNT.initialize() on the SNT class itself, instead of an instance.

snt_inst.initialize(imp)

In any case, it is preferred to start the plugin via one of the SNTService.initialize() flavors as these perform some internal initialization and checks which would have to be re-scripted if constructing an SNT instance manually.

You may also find the discussion https://github.com/morphonets/SNT/issues/60 interesting