<div dir="ltr">Hi Graeme,<div><br></div><div>Based on the list that you & Ilan sent me a while back, I started a spreadsheet detailing priority targets for support within OMERO:</div><div><br></div><div><a href="https://docs.google.com/spreadsheet/ccc?key=0Ancmne1B9NOwdGxQOEpKSVVGbk1TQ1ZSMHEzWHFwbmc&usp=sharing">https://docs.google.com/spreadsheet/ccc?key=0Ancmne1B9NOwdGxQOEpKSVVGbk1TQ1ZSMHEzWHFwbmc&usp=sharing</a><br>
</div><div><br></div><div>Anyone is free to check it out and comment if desired. Some of the items on your list were quite general, and/or not totally clear to me, so edit away as needed.</div><div><br></div><div><div>> my questions were motivated by the desire to write plugins for IJ1</div>
<div>> that will not be obsolete in IJ2, and preferably be able to be run</div><div>> headlessly, e.g. from OMERO.</div></div><div><br></div><div>OK, thanks for clarifying.</div><div><br></div><div><div>> It seems that ImageJ2 also uses a run method as the entry point for</div>
<div>> running a command? (correct me if I am wrong) In that case, at least</div><div>> the run method would have to be replaced.</div></div><div><br></div><div>ImageJ2's commands use Runnable's run(). ImageJ1 plugins use a custom PlugIn interface's run(String). So they are technically compatible, though I wouldn't necessarily recommend creating a hybrid. ;-)</div>
<div><br></div><div><div>> I was not so worried about ImageJ1's dialogs (which I expected would</div><div>> *not* be OK in a headless plugin)</div></div><div><br></div><div>Actually, confusingly, you *can* use GenericDialog when running headless in a macro because of the javassist hacks I mentioned. When running from a macro, the dialog is never actually shown, but instead parameters are harvested from the macro options string.</div>
<div><br></div><div><div>> It sounds as though converting IJ1 plugins to use the IJ2 API is</div><div>> likely be more productive than trying to use the legacy IJ1 API from</div><div>> an IJ2 plugin (headless), but is the latter already known to be</div>
<div>> hopeless? If not, I might be tempted to try a little.</div></div><div><br></div><div>I wouldn't say hopeless. In many cases, you *can* run IJ1 plugins headless, as explained on the Fiji wiki Headless page I linked before (<a href="http://fiji.sc/Headless">http://fiji.sc/Headless</a>). My next step for the OMERO integration will be create an ImageJ2 command "Run Script" which executes a given script or IJ1 macro. Then I can start testing calling IJ1 macro code headless from OMERO and see how well it works in practice.</div>
<div><br></div><div>That said, I stand by my suggestion that *new* code would be better written as an ImageJ2 command because otherwise it won't be easily accessible from the growing number of contexts I mentioned such as CellProfiler and KNIME.</div>
<div><br></div><div><div>> Until now I have chosen to write for IJ1 since the IJ2 API is still a</div><div>> moving target and has a smaller user base, but I guess IJ2 / ImgLib2</div><div>> already makes a lot of sense for headless processing tasks. Would you</div>
<div>> say that once imagej2-b9-rois is out, the IJ2 API will be fairly</div><div>> stable going forward?</div></div><div><br></div><div>My promise is that when ImageJ 2.0.0 final is released, *then* the API will be stable, with old API being properly deprecated for long periods of time, etc. Before that, I do not want to make any promises. The API is growing more and more stable with each release, but it is tough to say what "fairly stable" really means here.</div>
<div><br></div><div>One idea I had recently is to start bringing some components of ImageJ2 out of beta in phases. The scijava-common component is already out of beta. Some IJ2 components such as ij-core are already extremely stable. The scifio library will probably be out of beta (and hence stable) within a year. But the hard stuff remains: the ij-data component, how it ties in to ImgLib2 (which also needs to come out of beta at some point), and the IJ2 display model. Those may need to bake a little longer.</div>
<div><br></div><div>Regards,</div><div>Curtis</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Oct 23, 2013 at 4:02 PM, Graeme Ball <span dir="ltr"><<a href="mailto:graemeball@googlemail.com" target="_blank">graemeball@googlemail.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">Hi Curtis,<div><br></div><div>thank you for your reply - that certainly clears up some of my questions. Yes, my questions were motivated by the desire to write plugins for IJ1 that will not be obsolete in IJ2, and preferably be able to be run headlessly, e.g. from OMERO.</div>
<div><br></div><div>If possible, when I write (ImageJ1) plugins I try to confine any GUI calls to the run method, and all of the real work to an exec method that does not require interactive input. It seems that ImageJ2 also uses a run method as the entry point for running a command? (correct me if I am wrong) In that case, at least the run method would have to be replaced.</div>
<div><br></div><div>I was not so worried about ImageJ1's dialogs (which I expected would *not* be OK in a headless plugin), but was more concerned about ImagePlus, Roi etc. which make heavy use of awt classes. If these also cannot be used headlessly, then I guess a legacy mode with virtual UI, or re-writing to use the IJ2 API are the only real options. </div>
<div><br></div><div>It sounds as though converting IJ1 plugins to use the IJ2 API is likely be more productive than trying to use the legacy IJ1 API from an IJ2 plugin (headless), but is the latter already known to be hopeless? If not, I might be tempted to try a little.</div>
<div><br></div><div>Until now I have chosen to write for IJ1 since the IJ2 API is still a moving target and has a smaller user base, but I guess IJ2 / ImgLib2 already makes a lot of sense for headless processing tasks. Would you say that once imagej2-b9-rois is out, the IJ2 API will be fairly stable going forward?</div>
<div class="im">
<div><br></div><div>Thanks & Best Regards,</div><div><br></div><div>Graeme</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div class="im">On Wed, Oct 23, 2013 at 6:45 PM, Curtis Rueden <span dir="ltr"><<a href="mailto:ctrueden@wisc.edu" target="_blank">ctrueden@wisc.edu</a>></span> wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>
<div dir="ltr"><div class="im"><div>
<div>Hi Graeme,</div>
<div><br>
</div>
<div>Sorry for the delay in reply. Writing to a public mailing list is better. I am CCing imagej-devel and ome-devel since your questions are very technical, and related to those two projects.</div>
<div><br>
</div>
</div></div><div class="im"><div><div>> I thought I would Email you directly because the ImageJ-devel</div>
<div>> mailing list seems to be intended for core project development.</div>
<div><br>
</div>
</div></div><div class="im"><div><div>From <a href="http://developer.imagej.net/mailing-lists" target="_blank">http://developer.imagej.net/mailing-lists</a>:</div>
<div>
<div>> ImageJ: For general user and developer discussion about ImageJ. This</div>
<div>> list is the best place to go for help with your specific use case.</div>
<div>></div>
<div>> ImageJ-devel: For technical and developer discussion of the ImageJ2</div>
<div>> project. This list is for programmers contributing code to ImageJ2, or</div>
<div>> interested in technical discussions surrounding such development.</div>
</div>
<div><br>
</div>
</div></div><div>Both are public mailing lists intended for use by the community, not just for core project development. The wording of ImageJ-devel is phrased that way because ImageJ2 is still in beta and if you are using it for your projects, you are an early adopter
who is almost certainly "interested in technical discussions" surrounding core development.</div><div class="im"><div>
<div><br>
</div>
<div>
<div>> 1. I was looking for example plugins (& example minimal plugin</div>
<div>> project), but get 404's when I try to look at the HelloWorld and</div>
<div>> GradientImage examples here:-</div>
<div>> <a href="http://developer.imagej.net/writing-imagej2-plugins" target="_blank">http://developer.imagej.net/writing-imagej2-plugins</a></div>
<div>> (I found the github repo & Fiji wiki ImgLib2 examples)</div>
</div>
<div><br>
</div>
</div></div><div class="im"><div><div>All links on that page should be working again.</div>
<div><br>
</div>
</div></div><div class="im"><div><div>
<div>> 2. I see an example of calling IJ2 from a legacy plugin, but am also</div>
<div>> interested in doing the reverse, and unsure what the limitations are.</div>
</div>
<div><br>
</div>
</div></div><div class="im"><div><div>The limitations are evolving. Legacy support is very challenging to get right. That said, it should work to call ImageJ1 data structures from an ImageJ2 style command. There is a LegacyService for converting between IJ1 and IJ2 data structures, although
the API still needs work.</div>
<div><br>
</div>
<div>Note that at the moment, ImageJ2 commands are only discovered and exposed in the modern ImageJ2 UI. We are exploring ways of blending things in additional ways, such as allowing the ImageJ1/Fiji legacy UI to discover and allow execution of IJ2 commands.</div>
<div><br>
</div>
<div>What is your goal? You want to write a plugin that is available from both IJ1 and IJ2? If so, structuring it as a legacy IJ1 plugin (which may or may not leverage certain IJ2 API internally as demonstrated in calling-modern-from-legacy) is the way to go
for now.</div>
<div><br>
</div>
</div></div><div class="im"><div><div>
<div>> 3. What are the constraints / requirements for running plugins</div>
<div>> (including legacy wrapped in IJ2?) headless, with a view to running</div>
<div>> from OMERO in future?</div>
</div>
<div><br>
</div>
</div></div><div class="im"><div><div>In IJ2 terms, the ImgLib2 library is fully usable headless. If your IJ2 command does not depend on ij-ui you probably will be able to run it headlessly. The requirements, in general, are the same as running any Java code headless: do not use AWT or Swing
or other UI, especially Windows/Frames/Dialogs.<br>
</div>
<div><br>
</div>
<div>Unfortunately, you cannot just take a legacy IJ1 plugin and "wrap in IJ2." The problem is that fundamentally, IJ1 is filled with java.awt references including some core classes extending java.awt.Dialog and java.awt.Frame, which are illegal to even instantiate
headlessly.</div>
<div><br>
</div>
<div>We have some crazy hacks in Fiji to allow limited execution of IJ2 code headless even when it would normally use those AWT window classes. It works by using bytecode manipulation (javassist library) to rewrite parts of IJ1 at runtime to avoid references
to those classes. However, in some cases things will still blow up. It should go without saying that any time an IJ1 plugin asks the user for input (e.g., the WaitForUserInput dialog), it will fail when trying to run headless.</div>
<div><br>
</div>
<div>All of that said, we may be able to support calling many IJ1 plugins headlessly from OMERO in the same way we support it headlessly in general: using by install Xvfb on the server side. This gets around the limitations of java.awt.headless=true, in favor
of actually giving Java a virtual/offscreen UI. See: <a href="http://fiji.sc/Headless" target="_blank">http://fiji.sc/Headless</a></div>
<div><br>
</div>
<div>As of this writing, I have not yet tried to get legacy IJ1 plugins working from OMERO. The reason is that I know it will be a lot of effort, for something that would only be transitional. We are writing IJ2 precisely to avoid the sorts of problems incurred
by IJ1's heavy use of AWT in core classes. IJ2 maintains a strict separation of concerns, and its commands have typed inputs and outputs, which are a natural match to other paradigms such as OMERO scripts, CellProfiler modules, and KNIME nodes. Mapping IJ1
plugins to those paradigms is difficult not only due to headless issues but also because in general there is no easy way to know the actual inputs and outputs of the plugin, since IJ1 plugins do not declare that metadata.</div>
<div><br>
</div>
<div>So in conclusion, while I sympathize with the desire to execute ImageJ1 plugins from OMERO, ultimately a better direction is to rewrite plugins of interest as ImageJ2 commands so we truly get a "write once, run anywhere" effect with the whole software
ecosystem interoperating with ImageJ2.</div>
<div><br>
</div>
</div></div><div><div class="im"><div>
<div>> Apologies if I missed some documentation, or a more appropriate</div>
</div></div><div class="im"><div><div>> community forum to ask these questions, and me know if I am jumping</div>
<div>> the gun and would be better waiting a few months.</div>
</div></div></div><div class="im"><div>
<div><br>
</div>
<div>Not at all; these are good questions and not well explained online. I added a couple of short entries to the online FAQ:</div>
<div><br>
</div>
<div><a href="http://developer.imagej.net/can-i-call-imagej2-api-imagej1-plugin" target="_blank">http://developer.imagej.net/can-i-call-imagej2-api-imagej1-plugin</a><br>
</div>
<div>
<div><a href="http://developer.imagej.net/can-i-call-imagej1-api-imagej2-command" target="_blank">http://developer.imagej.net/can-i-call-imagej1-api-imagej2-command</a><br>
</div>
<div><br>
</div>
</div>
<div>Please let me know if there are other topics you would like to see covered on the website.</div>
<div><br>
</div>
<div>Regards,</div>
<div>Curtis</div>
</div></div></div>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote"><div class="im"><div>On Thu, Sep 26, 2013 at 6:39 PM, Graeme Ball <span dir="ltr">
<<a href="mailto:graemeball@googlemail.com" target="_blank">graemeball@googlemail.com</a>></span> wrote:<br>
</div></div><div><div class="h5"><div><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">
<div>Hi Curtis, </div>
<div><br>
</div>
<div>I have a few questions about writing plugins for ImageJ2, </div>
<div>and I thought I would Email you directly because the </div>
<div>ImageJ-devel mailing list seems to be intended for core </div>
<div>project development. </div>
<div><br>
</div>
<div>1. I was looking for example plugins (& example minimal </div>
<div> plugin project), but get 404's when I try to look at </div>
<div> the HelloWorld and GradientImage examples here:- </div>
<div> <a href="http://developer.imagej.net/writing-imagej2-plugins" target="_blank">http://developer.imagej.net/writing-imagej2-plugins</a> </div>
<div> (I found the github repo & Fiji wiki ImgLib2 examples) </div>
<div><br>
</div>
<div>2. I see an example of calling IJ2 from a legacy plugin, </div>
<div> but am also interested in doing the reverse, and </div>
<div> unsure what the limitations are. </div>
<div><br>
</div>
<div>3. What are the constraints / requirements for running </div>
<div> plugins (including legacy wrapped in IJ2?) headless, </div>
<div> with a view to running from OMERO in future? </div>
<div><br>
</div>
<div>Apologies if I missed some documentation, or a more </div>
<div>appropriate community forum to ask these questions, and </div>
<div>let me know if I am jumping the gun and would be better </div>
<div>off waiting a few months. </div>
<div><br>
</div>
<div>Thanks & Best Regards, </div>
<div><br>
</div>
<div>Graeme</div>
<div><br>
</div>
<div>
<div>-- </div>
<div>--------------------------- </div>
<div>Dr. Graeme Ball </div>
<div>Department of Biochemistry </div>
<div>University of Oxford </div>
<div>South Parks Road </div>
<div>Oxford OX1 3QU </div>
<div>Phone <a href="tel:%2B44-1865-613-359" value="+441865613359" target="_blank">
+44-1865-613-359</a> </div>
<div>---------------------------</div>
</div>
</div>
</blockquote>
</div></div></div></div></div>
<br>
</div>
</div>
</blockquote></div><br></div></div>
</blockquote></div><br></div>