ScriptParameters as arguments in a Jython Plugin

Dear all,
I’ve developed a plugin with two input arguments and one output argument in Jython.
something like this:

# @Short(label="FLIP channel", value=1, min=1) FLIP_CH
# @Short(label="pre bleach frames", value=5, min=1) preBleachFrames
#@output ImagePlus imp_out

from ij import IJ,ImagePlus,WindowManager,ImageStack
from ij.plugin.frame import RoiManager
from ij.plugin import Duplicator

IJ.log(str(preBleachFrames))
imp_raw = IJ.getImage()
IJ.run(imp_raw, "Select None", "")
DUPL = Duplicator()
imp_out = DUPL.run(imp_raw,FLIP_CH, FLIP_CH, 1,1,preBleachFrames,imp_raw.getNFrames())

I put it on the Plugin folder of Fiji.
How can I call it from another script with the input arguments?
How can I collect the output image from another script?
The recorder doesn’t record the input arguments for example.

I remember some years ago, it worked fine.
I was able at least to launch it with input arguments this way:

IJ.run(my_script,"FLIP_CH=1 preBleachFrames=60"

now this way doesn’t work anymore.

thanks,
Emanuele

1 Like

so the solution is to use the ScriptService, as pointed out in some others post:

in this case the script calling the plugin could be something like that:

#@ScriptService scriptservice


from ij import IJ
from java.io import File

outputs = scriptservice.run(File('/Applications/Fiji.app/plugins/ScriptJ_param.py'), True,'imp_raw',IJ.getImage(),'FLIP_CH',1,'preBleachFrames',5)
imp_out = outputs.get().getOutputs()['imp_out']
imp_out.show()
1 Like

The ScriptService is just one possible solution.

An easier one (in my opinion) is to save your script in a subfolder of /Applications/Fiji.app/scripts/ instead of plugins (such that it appears as a menu entry), and then let the macro recorder do its job.

For example:

  • Save script in /Applications/Fiji.app/scripts/Plugins/My_Custom_Scripts/ScriptJ_param.py
  • Run Plugins > My Custom Scripts > ScriptJ param with the recorder active
  • And here’s your command:
    IJ.run("ScriptJ param", "flip_ch=1 prebleachframes=5");
    
1 Like

I tried it but it records this:

IJ.run("ScriptJ param", "");

moreover, if I launch:

IJ.run("ScriptJ param", "FLIP_CH=1 preBleachFrames=10");

it will not use the arguments I am passing, it will create the dialog GUI asking me the ScriptParameters.

Using IJ.run method, besides, doesn’t permit (at least it’s not clear to me how) to decide on which image to use the plugin. (with scriptService I passed imp_raw as an argument for example)
Another thing that I am able to do with scriptService and I don’t know how to do with IJ.run is getting the output, in this simple example the imp_out ImagePlus.

1 Like

Ah, alright, I might have explanations for the issues you’re seeing :slightly_smiling_face:

That’s likely because you use call to IJ.run inside your script, and these can trigger “premature” recording of your script command, before the input parameters are included (which technically is happening in a ModulePostprocessor).

Try to use all lower case in your parameters, as I suggested above. I think that’s what the recorder would record if you hadn’t any IJ.run calls (you can test this of course…):

IJ.run("ScriptJ param", "flip_ch=1 prebleachframes=10");

In fact, if the recording happens correctly, it should use the IJ.run(ImagePlus, String, String) signature, and record:

IJ.run(imp, "ScriptJ param", "flip_ch=1 prebleachframes=10");

… and the imp is the image being processed.

Of course, this requires that in your script, you use an #@ ImagePlus input parameter instead of calling IJ.getImage()


Finally,

indeed, IJ.run doesn’t return anything, so if it doesn’t show the image so that you can get it again with IJ.getImage() (which would be bad practice anyway), you’re screwed.

So you’re good staying with ScriptService indeed :slightly_smiling_face:

1 Like

I will try your suggestions next week,
and let you know.
thanks for your time,
have a nice day
Emanuele

1 Like

Wow, I didn’t know about this. Is it some limitation of concurrent ImageJ1 command executions? A thread state/safety issue?

:+1: Seconded. Do not use ij.* stuff unless there is no other option—due to exactly this sort of weirdness.

1 Like

I remember stumbling upon this issue a decade ago or so… , when writing a Java plugin that used IJ.run calls. If I remember correctly, @Wayne suggested to me at that time to preferably use a lower level API to run certain commands. It’s also not the case for every call to IJ.run(), just to specific plugins.
Unfortunately, I can’t find this documented in any email or forum conversation :slightly_frowning_face:

Anyhow, @emartini, replacing this call in your script:

IJ.run(imp_raw, "Select None", "")

by:

imp_raw.deleteRoi()

fixes the parameter recording for me at least.

1 Like

yes thank you.
I also didnt know (like @ctrueden) that IJ.run can create this kind of issues with scriptparameters
good to know

Just to be clear on this: the issue is not specific to SciJava script parameters, but true for all commands recorded by the macro recorder (and therefore also exists with plain ImageJ 1.x).

1 Like