How to make a macro or js recordable?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

How to make a macro or js recordable?

lechristophe
Hi,

I have a collection of macros and javascripts, and I'd like to write macros
that chain some of these to automate my workflow. The problem is that when
I use the Macro recorder, it does not pick anything after running these
macros or scripts. How can I modify them in order to run them from another
macro with their arguments ie something like run("Macro", "arguments")?

You can see an exemple of a script I'd like to record and run here:
https://github.com/cleterrier/ChriSTORM/blob/master/Process%20locs%20files%20(batch)/Batch_NS_into_TS.js

and a macro:
https://github.com/cleterrier/ChriSTORM/blob/master/Reconstruct%20Images%20(batch)/Generate_Reconstructions.ijm

Thanks for your help,

Christophe

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: How to make a macro or js recordable?

Gabriel Landini
On Saturday 05 Mar 2016 12:00:34 Christophe Leterrier wrote:

> I have a collection of macros and javascripts, and I'd like to write macros
> that chain some of these to automate my workflow. The problem is that when
> I use the Macro recorder, it does not pick anything after running these
> macros or scripts. How can I modify them in order to run them from another
> macro with their arguments ie something like run("Macro", "arguments")?
>
> You can see an exemple of a script I'd like to record and run here:
> <a href="https://github.com/cleterrier/ChriSTORM/blob/master/Process%20locs%20files%2">https://github.com/cleterrier/ChriSTORM/blob/master/Process%20locs%20files%2
> 0(batch)/Batch_NS_into_TS.js
>
> and a macro:
> https://github.com/cleterrier/ChriSTORM/blob/master/Reconstruct%20Images%20(
> batch)/Generate_Reconstructions.ijm

http://rsbweb.nih.gov/ij/developer/macro/functions.html#R

runMacro(name)
Runs the specified macro or script, which is assumed to be in the Image macros
folder. A full file path may also be used. Returns any string argument
returned by the macro or the last expression evaluated in the script. For an
example, see the CalculateMean macro. See also: eval.

runMacro(name, arg)
Runs the specified macro or script, which is assumed to be in the macros
folder, or use a full file path. The string argument 'arg' can be retrieved by
the macro or script using the getArgument() function. Returns the string
argument returned by the macro or the last expression evaluated in the script.
See also: getArgument.

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: How to make a macro or js recordable?

lechristophe
Thanks Gabriel!

I found this answer as well:
http://imagej.1557.x6.nabble.com/Possible-to-call-a-javascript-script-or-function-w-arguments-from-a-macro-tp5006888p5006893.html

The problem is that if I use getArgument(), then the macro or script fails
when I run it directly. For a script it says:

nashorn:mozilla_compat.js:67 ReferenceError: "getArgument" is not defined
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
at
jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:319)
at
jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:291)
at jdk.nashorn.internal.objects.Global.__noSuchProperty__(Global.java:1432)
at
jdk.nashorn.internal.scripts.Script$Recompilation$32$1362A$\=nashorn\!mozilla_compat.value-1$__noSuchProperty__(nashorn:mozilla_compat.js:67)
at
jdk.nashorn.internal.scripts.Script$33$Batch_NS_Into_TS.:program(/Users/christo/Travail/Labo/Processing/Fiji_current/Fiji.app/plugins/ChriSTORM/Process
locs files (batch)/Batch_NS_Into_TS.js:11)
at
jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640)
at
jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at
jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
at
jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
at
jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
at
jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:150)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249)
at org.scijava.script.ScriptModule.run(ScriptModule.java:174)
at org.scijava.module.ModuleRunner.run(ModuleRunner.java:167)
at org.scijava.module.ModuleRunner.call(ModuleRunner.java:126)
at org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
at
org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

Is it possible to have a script or macro that can be run either directly or
called by another macro? How can I test this in the called macro/script?

Christophe

On Sat, Mar 5, 2016 at 12:37 PM, Gabriel Landini <[hidden email]>
wrote:

> On Saturday 05 Mar 2016 12:00:34 Christophe Leterrier wrote:
> > I have a collection of macros and javascripts, and I'd like to write
> macros
> > that chain some of these to automate my workflow. The problem is that
> when
> > I use the Macro recorder, it does not pick anything after running these
> > macros or scripts. How can I modify them in order to run them from
> another
> > macro with their arguments ie something like run("Macro", "arguments")?
> >
> > You can see an exemple of a script I'd like to record and run here:
> >
> <a href="https://github.com/cleterrier/ChriSTORM/blob/master/Process%20locs%20files%2">https://github.com/cleterrier/ChriSTORM/blob/master/Process%20locs%20files%2
> > 0(batch)/Batch_NS_into_TS.js
> >
> > and a macro:
> >
> https://github.com/cleterrier/ChriSTORM/blob/master/Reconstruct%20Images%20(
> > batch)/Generate_Reconstructions.ijm
>
> http://rsbweb.nih.gov/ij/developer/macro/functions.html#R
>
> runMacro(name)
> Runs the specified macro or script, which is assumed to be in the Image
> macros
> folder. A full file path may also be used. Returns any string argument
> returned by the macro or the last expression evaluated in the script. For
> an
> example, see the CalculateMean macro. See also: eval.
>
> runMacro(name, arg)
> Runs the specified macro or script, which is assumed to be in the macros
> folder, or use a full file path. The string argument 'arg' can be
> retrieved by
> the macro or script using the getArgument() function. Returns the string
> argument returned by the macro or the last expression evaluated in the
> script.
> See also: getArgument.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: How to make a macro or js recordable?

Gabriel Landini
On Saturday 05 Mar 2016 13:50:09 Christophe wrote:
> The problem is that if I use getArgument(), then the macro or script fails
> when I run it directly.

I see what you mean. In a macro you can get the argument, and test if it is
empty and if so, get the variables with a dialogue.

I used the code below in a macro that uses 2 image names as arguments if
called from somewhere else, or asks for them in "direct mode".

//--get open file names and show dialog
arg = getArgument();
if (lengthOf(arg)>0){
    argi = split(arg, "");
    ImgX=argi[0];
    ImgY=argi[1];
}
else{
   // get the image names
    setBatchMode(true);
    title=getTitle();
    imagen=newArray(nImages);
    imagen[0]=title;

    j=0;
    for (i=1;i<=nImages();i++) {
        selectImage(i);
        temp=getTitle();
        if (temp!=title)
            imagen[++j]=temp;
    }

    selectWindow(title);
    setBatchMode(false);

    Dialog.create("Input image names");
    Dialog.addChoice("X",imagen, imagen[0]);
    Dialog.addChoice("Y",imagen, imagen[1]);
    Dialog.show();

    ImgX=Dialog.getChoice();
    ImgY=Dialog.getChoice();
}

then here comes the rest of the code and ImgX and ImgY variables have a value
either from the argument of from the interactive dialog.

Mind you, it is probably better to write it in Java.

Cheers

Gabriel

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: How to make a macro or js recordable?

lechristophe
In reply to this post by lechristophe
Looks like I have found a way to do it.

This in a script:

if (typeof(getArgument) == "function") IJ.log("arg="+getArgument());

does get arguments if they exist, and allows to run the script directly.
For macros the presence of getArgument() doesn't trigger an error.

Christophe

On Sat, Mar 5, 2016 at 1:50 PM, Christophe Leterrier <
[hidden email]> wrote:

> Thanks Gabriel!
>
> I found this answer as well:
>
> http://imagej.1557.x6.nabble.com/Possible-to-call-a-javascript-script-or-function-w-arguments-from-a-macro-tp5006888p5006893.html
>
> The problem is that if I use getArgument(), then the macro or script fails
> when I run it directly. For a script it says:
>
> nashorn:mozilla_compat.js:67 ReferenceError: "getArgument" is not defined
> at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
> at
> jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:319)
> at
> jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:291)
> at jdk.nashorn.internal.objects.Global.__noSuchProperty__(Global.java:1432)
> at
> jdk.nashorn.internal.scripts.Script$Recompilation$32$1362A$\=nashorn\!mozilla_compat.value-1$__noSuchProperty__(nashorn:mozilla_compat.js:67)
> at
> jdk.nashorn.internal.scripts.Script$33$Batch_NS_Into_TS.:program(/Users/christo/Travail/Labo/Processing/Fiji_current/Fiji.app/plugins/ChriSTORM/Process
> locs files (batch)/Batch_NS_Into_TS.js:11)
> at
> jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640)
> at
> jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
> at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
> at
> jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
> at
> jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
> at
> jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
> at
> jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:150)
> at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249)
> at org.scijava.script.ScriptModule.run(ScriptModule.java:174)
> at org.scijava.module.ModuleRunner.run(ModuleRunner.java:167)
> at org.scijava.module.ModuleRunner.call(ModuleRunner.java:126)
> at org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
> at
> org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
> at java.util.concurrent.FutureTask.run(FutureTask.java:266)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
> at java.lang.Thread.run(Thread.java:745)
>
> Is it possible to have a script or macro that can be run either directly
> or called by another macro? How can I test this in the called macro/script?
>
> Christophe
>
> On Sat, Mar 5, 2016 at 12:37 PM, Gabriel Landini <[hidden email]>
> wrote:
>
>> On Saturday 05 Mar 2016 12:00:34 Christophe Leterrier wrote:
>> > I have a collection of macros and javascripts, and I'd like to write
>> macros
>> > that chain some of these to automate my workflow. The problem is that
>> when
>> > I use the Macro recorder, it does not pick anything after running these
>> > macros or scripts. How can I modify them in order to run them from
>> another
>> > macro with their arguments ie something like run("Macro", "arguments")?
>> >
>> > You can see an exemple of a script I'd like to record and run here:
>> >
>> <a href="https://github.com/cleterrier/ChriSTORM/blob/master/Process%20locs%20files%2">https://github.com/cleterrier/ChriSTORM/blob/master/Process%20locs%20files%2
>> > 0(batch)/Batch_NS_into_TS.js
>> >
>> > and a macro:
>> >
>> https://github.com/cleterrier/ChriSTORM/blob/master/Reconstruct%20Images%20(
>> > batch)/Generate_Reconstructions.ijm
>>
>> http://rsbweb.nih.gov/ij/developer/macro/functions.html#R
>>
>> runMacro(name)
>> Runs the specified macro or script, which is assumed to be in the Image
>> macros
>> folder. A full file path may also be used. Returns any string argument
>> returned by the macro or the last expression evaluated in the script. For
>> an
>> example, see the CalculateMean macro. See also: eval.
>>
>> runMacro(name, arg)
>> Runs the specified macro or script, which is assumed to be in the macros
>> folder, or use a full file path. The string argument 'arg' can be
>> retrieved by
>> the macro or script using the getArgument() function. Returns the string
>> argument returned by the macro or the last expression evaluated in the
>> script.
>> See also: getArgument.
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: How to make a macro or js recordable?

Jan Eglinger
In reply to this post by lechristophe
Hi Christophe,


if you place both scripts and macros somewhere in your ./plugins folder
(preferably into ./plugins/Scripts/<Menu>/<Submenu>), you can run them
as a menu command and use the macro recorder [1] to get the required
command to run each of them with the correct parameters.

In your case, the "parent" macro would look like this then:

     run("Batch NS into TS", "use_drift-corrected_xy use_warp-corrected
use_drift-corrected_z z=1");
     run("Generate Reconstructions", "raw=1 converter=2 em=3");

In order for this to work, you just have to make sure that each of the
labels in your dialogs is unique up to the first occurence of a space ("
") character, so you will have to use underscores for some of the
parameters, e.g. lines 29-33 of your Javascript file:

     var gd = new GenericDialog("Translator Options");
     gd.addCheckbox("Use_drift-corrected_XY coordinates", xydrift_def);
     gd.addCheckbox("Use_warp-corrected coordinates", warp_def);
     gd.addCheckbox("Use_drift-corrected_Z coordinates", zdrift_def);
     gd.addNumericField("Z_uncertainty_factor", zfactor_def, 1, 3, "* XY
uncertainty");


Hope that helps,
Jan



[1]: http://imagej.net/Macro_recorder


On 05.03.16 12:00, Christophe Leterrier wrote:

> Hi,
>
> I have a collection of macros and javascripts, and I'd like to write macros
> that chain some of these to automate my workflow. The problem is that when
> I use the Macro recorder, it does not pick anything after running these
> macros or scripts. How can I modify them in order to run them from another
> macro with their arguments ie something like run("Macro", "arguments")?
>
> You can see an exemple of a script I'd like to record and run here:
> https://github.com/cleterrier/ChriSTORM/blob/master/Process%20locs%20files%20(batch)/Batch_NS_into_TS.js
>
> and a macro:
> https://github.com/cleterrier/ChriSTORM/blob/master/Reconstruct%20Images%20(batch)/Generate_Reconstructions.ijm
>
> Thanks for your help,
>
> Christophe
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html