Jython imp.getSlice() gives different result on different PCs

plugin
roi
Tags: #<Tag:0x00007fd54879e008> #<Tag:0x00007fd54879dd60>

#1

Hello,
I am trying to make my Jython plugin run on a new PC, and found an strange error. My plugin listens when user clicks over an image stack, and adds cursor positions (x,y and slice #) to ROI manager. The slice # is recorded using imp.getSlice() function:

class ML(MouseAdapter):
      def mousePressed(self, keyEvent):
          global iROI, xlist, ylist, zlist
          iROI += 1
          canv = imp.getCanvas()
          p = canv.getCursorLoc()
          z = imp.getSlice()
          roi = OvalRoi(p.x - radius, p.y - radius, radius*2, radius*2)
          roi.setPosition(z)
          imp.setRoi(roi)
          manager.addRoi(roi)
          manager.runCommand('Draw')

This works fine on one machine (z = 1,2,…,N), but always gives same z-slice position z = 1 in another machine. Exactly the same copy of Fiji. Both machines are running Windows 7, latest Java (1.8.0_66, 64-bit), up-to-date Fiji (ImageJ 1.51n).
I don’t even know how to approach this problem. Could anyone give some hints?
Thanks!

The whole code is shown below, sorry for length.

    from ij import IJ
    from ij.plugin.frame import RoiManager
    from java.awt.event import MouseAdapter, KeyEvent, KeyAdapter
    from ij.gui import GenericDialog, WaitForUserDialog, GenericDialog, Roi, OvalRoi, Toolbar, Overlay
    from ij.io import SaveDialog
    def getOptions():
        global listener, xlist, ylist, zlist, manager
        gd = GenericDialog("Target Selection")
        gd.addChoice('type', ['point', 'circle', 'spiral'], 'point')
        gd.addNumericField("                power (%)", 85, 0)
        gd.addNumericField("                duration (millisec)", 3, 0) 
        gd.addNumericField("                (optional) radius of a circle/spiral", 5, 0) 
        gd.addNumericField("                (optional) num. of turns per circle/spiral", 3, 0)
        gd.addNumericField("                take image after every .. entries", 1, 0)
        gd.addNumericField("                interval between entries (ms)", 5000, 0)
        gd.addNumericField("                Z-start of stack (microns)", 0, 0)
        gd.addNumericField("                Z-step of stack (microns)", 5, 0)
        gd.addNumericField("                (optional) add offset to X coordinates", 0, 0)
        gd.addNumericField("                (optional) add offset to Y coordinates", 0, 0)  
        gd.addNumericField("                (optional) imaging stack # for excitation onset (0,1,..)", 0, 0) 
        gd.addMessage('Press ENTER to save\n')
        gd.addMessage('Press ESC to restart\n')
        gd.showDialog()
        profileType = gd.getNextChoice()
        power = gd.getNextNumber()
        duration = gd.getNextNumber() 
        r = gd.getNextNumber()
        Nturns = gd.getNextNumber()
        camTriggerEvery = gd.getNextNumber()
        prewait = gd.getNextNumber()
        zStart = gd.getNextNumber()
        zStep = gd.getNextNumber()
        xOffset = gd.getNextNumber()
        yOffset = gd.getNextNumber()
        tmIndex = gd.getNextNumber()
        if gd.wasCanceled():
            IJ.setTool(Toolbar.RECTANGLE)
            return 
        else: 
            return r, power, profileType, duration, Nturns, camTriggerEvery, zStart, zStep, prewait, xOffset, yOffset, tmIndex

    def reset():
        global radius, iROI, power, profileType, duration, Nturns, xlist, ylist, zlist, camTriggerEvery, zStart, zStep, prewait, xOffset, yOffset, tmIndex
        xlist = []
        ylist = []
        zlist = []
        manager.runCommand('Reset')
        manager.runCommand('Show All')
        iROI = 0
        options = getOptions()
        if options is not None:
            radius, power, profileType, duration, Nturns, camTriggerEvery, zStart, zStep, prewait, xOffset, yOffset, tmIndex = options
     
    class ML(MouseAdapter):
        def mousePressed(self, keyEvent):
            global iROI, xlist, ylist, zlist
            iROI += 1
            canv = imp.getCanvas()
            p = canv.getCursorLoc()
            z = imp.getSlice()
            print('z = ' + str(z))
            roi = OvalRoi(p.x - radius, p.y - radius, radius*2, radius*2)
            roi.setName('z' + str(z) + 'cell' + str(iROI))
            roi.setPosition(z)
            imp.setRoi(roi)
            manager.addRoi(roi)
            manager.runCommand('Draw')

    class ListenToKey(KeyAdapter):
        def keyPressed(this, event):
            doSomething(event)

    def doSomething(keyEvent):
      """ A function to react to key being pressed on an image canvas. """
      global iROI, xlist, ylist, zlist, power, profileType, duration, Nturns, camTriggerEvery, zStart, zStep, prewait, xOffset, yOffset, tmIndex
      if keyEvent.getKeyCode() == 10: # Enter is pressed!
          #do something
        keyEvent.consume()

    # MAIN code         
    imp = IJ.getImage()
    IJ.setTool(Toolbar.RECTANGLE)
    manager = RoiManager.getInstance()
    if manager is None:
        manager = RoiManager();   
    reset()
    listener = ML()
    keyLis = ListenToKey()
    win = imp.getWindow()
    win.getCanvas().addMouseListener(listener)
    win.getCanvas().addKeyListener(keyLis)

#2

Update: I found the bug, it was because ImagePlus API has two similar functions, getSlice() and getCurrentSlice(). I used the former and it was a source of bug. When I changed to latter, it worked as intended. Is the getSlice() simply deprecated?


#3

Dear @nvladimus,

It is not. ImagePlus however mixes handling of regular stacks and hyperstacks. You should use getSlice/getChannel/getFrame for Z/C/T dimensions of a hyperstack and getCurrentSlice for a regular stack… both return values in most cases but are not readily usable like in your case.

Best,
Stefan


#4

Thanks, this is good to know.