Posted by
dscho on
URL: http://imagej.273.s1.nabble.com/How-to-pass-an-array-from-a-plugin-to-a-macro-tp5002492p5002501.html
Hi Emmanue,
On Mon, 1 Apr 2013, Emmanuel Levy wrote:
> On 1 Apr 2013, at 20:13, Johannes Schindelin <
[hidden email]> wrote:
>
> > On Mon, 1 Apr 2013, Emmanuel Levy wrote:
> >
> >> I wrote a simple plugin that puts all pixel values of a selected ROI
> >> into a 1D table. What I can't figure out is how to pass the resulting 1D
> >> array to a macro calling the plugin? i.e., similarly to getStatistics,
> >> which makes a histogram array available in the macro calling the
> >> function for example.
> >
> > [...]
> >
> > In your case, the easiest may be a work-around: you *can* set the ROI
> > thusly:
> >
> > dummy = new float[myT.length];
> > image.setRoi(new PointRoi(myT, dummy, dummy.length));
>
> [...]
>
> I'm not sure I explained my question clearly, all I want is to pass an
> array of values back to the macro language to process it, not set or
> modify a ROI.
I understood your question. And I pointed out that you can use the ROI to
transport an array to the macro: after setting the ROI as I illustrated,
getSelectionCoordinates(myT, dummy) will put the array values into the
*macro* array called myT.
> E.g., just like one has access to the value of "hist" after calling
> getStatistics, id like to have access to myT.
getStatistics is not really a macro function, it is a *built-in* function.
There are a couple of such functions which allow passing variables by
reference (even uninitialized ones), e.g. getStatistics and
getSelectionCoordinates.
Such functions illustrate exactly my point about making the core of the
macro language brittle: its design does not include by-reference passing,
just by-value passing. Now we have a mix, and no way to define
by-reference passing outside the few pre-defined functions in the macro
core.
Having said that, there is actually a way to extend the macro language: by
calling Functions.registerExtensions(). It is a little clumsy to use, but
in theory, something like this should work:
-- snip --
import ij.macro.ExtensionDescriptor;
import ij.macro.Functions;
import ij.macro.MacroExtension;
import ij.plugin.PlugIn;
public class Macro_Test_Extension implements PlugIn, MacroExtension {
private float[] array = { 1, 2, 3 };
@Override
public void run(String arg) {
Functions.registerExtensions(this);
}
private ExtensionDescriptor[] descriptors = {
ExtensionDescriptor.newDescriptor("getArray", this,
ARG_OUTPUT | ARG_ARRAY)
};
@Override
public ExtensionDescriptor[] getExtensionFunctions() {
return descriptors;
}
@Override
public String handleExtension(String name, Object[] args) {
if (name.equals("getArray")) {
Double[] copy = new Double[array.length];
for (int i = 0; i < copy.length; i++) {
copy[i] = new Double(array[i]);
}
((Double[][])args[0])[0] = copy;
}
return "";
}
}
-- snap --
Alas, it does not. The problem is -- as I mentioned earlier -- that the
macro language was not designed to handle such things and the extension
mechanism was only bolted onto it. Therefore, array output variables are
not supported.
And as I pointed out, you probably get Wayne to add support for that, but
the macro language will become more and more brittle that way, and your
macro will not get faster.
At some stage you will have to convert it to Javascript anyway, and the
later you do it, the more work it will be.
Ciao,
Johannes
--
ImageJ mailing list:
http://imagej.nih.gov/ij/list.html