<div dir="ltr">Hi Brian,<div><br></div><div><div>> So far in ImageJ2 I have been writing java applications that start by</div><div>> instantiating an ImageJ app and then use that to access services and</div><div>> run commands. Basically following the tutorials. </div>
<div>> </div><div>> So how are things intended to work in a script?? Is there a simpler</div><div>> api somewhere like the IJ API?? Or does one still need to use the</div><div>> service APIs in a script??</div>
<div><br></div><div>The intent is to use the ImageJ gateway in your scripts (but see my P.S. below). So that way, what you've learned in the tutorials is equally applicable to scripting. From my perspective, writing:</div>
<div><br></div><div> ij.ui().showDialog("Hello world!");</div><div><br></div><div>is just as easy to read and write as:</div><div><br></div><div> IJ.showDialog("Hello world!");</div><div><br></div><div>
The advantages of IJ2's service-based approach are many:</div><div><br></div><div>1) Routines are naturally grouped according to which service they are in, so you can use IDE autocompletion to first browse the available services, and then browse the methods available for a particular service. Whereas if you browse IJ.<ctrl+space> you get one massive list of methods that I personally find somewhat overwhelming.</div>
<div><br></div><div>2) The ImageJ application context can be extended with additional services, which are also available via compile-safe ij.get(...).fooBar() calls.</div><div><br></div><div>3) Core service implementations can be overridden to behave differently, unlike the static IJ.* methods which can never be overridden (unless you use byte-code manipulation, which is serious voodoo).</div>
<div><br></div><div>4) All scripting languages use one unified API. There is no separate list of "macro language functions" in IJ2.</div><div><br></div><div><div>> I'm wondering if there is a more concise way to run the command and</div>
<div>> get the output?? Something more like this....</div><div>> </div><div>> output=command.run("somecommand");</div><div>> </div><div>> Basically a way to run the command, have it automatically block, and</div>
<div>> return the output(s) (if they exist). I could write a wrapper but</div><div>> first I want to make sure I know what all ready exists.</div></div><div><br></div><div>Nope, we don't have that. I think the ambiguity of returning an Object[] in some unspecified order is not very friendly. I guess we could return the output map, but then it's hardly shorter than:</div>
<div><br></div><div>outputs = command.run("somecommand").get().getOutputs();</div><div><br></div><div>There is already an unfortunate proliferation of run method signatures in ModuleService and CommandService, so I am honestly loath to add any more. But if you have an idea for a method to make the API more convenient, let us know!</div>
<div><br></div><div>Regards,</div><div>Curtis</div><div><br></div><div>P.S. ImageJ master now has a working Script Editor with parameter annotations, thanks to Johannes's efforts. I also made a branch to support "@ImageJ" auto-filling [1], although it won't merge to master until after the next release of SciJava Common.</div>
<div><br></div><div>[1] <a href="https://github.com/imagej/imagej/compare/gateway-autofill">https://github.com/imagej/imagej/compare/gateway-autofill</a></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Wed, Feb 19, 2014 at 11:22 AM, Brian Northan <span dir="ltr"><<a href="mailto:bnorthan@gmail.com" target="_blank">bnorthan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div><div><div><div>Hi Curtis, Johannes and list<br><br></div><div>The scripting is working well. <br></div><div><br></div><div>One quick question. To run a command and retrieve the output I basically have this<br>
</div><div><br></div><div>--snip--<br></div><div># @CommandService command<br><br></div>module=command.run("somecommand").get();<br></div>output=module.getOutputs().get("output");<br><br></div><div>(or)<br>
output = module.getOutputs().values().toArray()[0];<br></div><div>--snap--<br><br></div><div>I'm wondering if there is a more concise way to run the command and get the output?? Something more like this....<br>
</div><div>
<br></div>output=command.run("somecommand");<br><br></div><div>Basically a way to run the command, have it automatically block, and return the output(s) (if they exist). I could write a wrapper but first I want to make sure I know what all ready exists. <br>
</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Feb 18, 2014 at 4:14 PM, Brian Northan <span dir="ltr"><<a href="mailto:bnorthan@gmail.com" target="_blank">bnorthan@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div>Thanks very much Johannes and Curtis<br><br></div>Johannes' code snippet works perfectly. That's exactly what I needed to know. How to access the services from a script. Now that I know how to do that I can try some more complicated stuff (use the datasetservice and commandservice to open images and perform operations). I will let you know if any questions come up. Please let me know any additional information or tips that will be helpful. <br>
<br>Thanks again<span><font color="#888888"><br><br></font></span></div><span><font color="#888888">Brian<br></font></span></div><div><div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Tue, Feb 18, 2014 at 2:26 PM, Curtis Rueden <span dir="ltr"><<a href="mailto:ctrueden@wisc.edu" target="_blank">ctrueden@wisc.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><p dir="ltr">Hi Brian,</p>
<p dir="ltr">I am out of the office today, and will reply in more detail later, but just wanted to quickly add: the example Johannes wrote should work with the current master branch as well as the recent 2.0.0-beta-7.7 release. Specifically, it will work if you "Run Script" since the parameter parsing mechanism etc. is all already in place. It just doesn't work from the Script Editor yet since that tool needs some TLC still. As Johannes says, I am still actively hacking on scripting support.</p>
<p dir="ltr">Also note that you can inject a Context parameter then make a new ImageJ gateway object wrapping it to easily access services the same way the tutorials do. (I forget whether ImageJ gateways are injectable ATM but if not, they will be.)</p>
<p dir="ltr">Anyway, please let us know if you are unable to run such scripts.</p>
<p dir="ltr">Regards,<br>
Curtis <br></p><div><div>
<div class="gmail_quote">On Feb 18, 2014 12:41 PM, "Johannes Schindelin" <<a href="mailto:Johannes.Schindelin@gmx.de" target="_blank">Johannes.Schindelin@gmx.de</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Brian,<br>
<br>
On Tue, 18 Feb 2014, Brian Northan wrote:<br>
<br>
> Now I am trying to understand how one should be accessing ImageJ2<br>
> functionality from the scripts. In ImageJ1 I use the static functions in<br>
> the IJ class, IJ.run, IJ.openImage etc.<br>
<br>
Yeah, in IJ2 you have to use a context. The static functions of ImageJ 1.x<br>
do not allow you to insulate separate processes from each other. That<br>
leads to surprising results, e.g. when you try to put more than one<br>
ImageJ 1.x applet into the same web page: it simply won't work, ever.<br>
<br>
> So far in ImageJ2 I have been writing java applications that start by<br>
> instantiating an ImageJ app and then use that to access services and run<br>
> commands. Basically following the tutorials.<br>
><br>
> So how are things intended to work in a script?? Is there a simpler api<br>
> somewhere like the IJ API?? Or does one still need to use the service APIs<br>
> in a script??<br>
<br>
This is a work in progress right now, under heavy construction.<br>
Eventually, something like this will work:<br>
<br>
-- snip --<br>
# @StatusService status<br>
# @OUTPUT String greeting<br>
<br>
status.showStatus(1, 2, "In progress...")<br>
status.warn("This is a gentle warning")<br>
status.showStatus(2, 2)<br>
<br>
greeting = "Hello, world!"<br>
-- snap --<br>
<br>
In other words, your input and output parameters will be specified using a<br>
syntax similar to ImageJ2 commands' at the top of the script.<br>
<br>
Ciao,<br>
Johannes<br>
</blockquote></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>