<div dir="ltr"><div>Hi Jan<br><br></div>The following might work for the create op -- it takes a java array not a python list....<br><div><div><div><div><div><div><br>from jarray import array<br>blank=ops.createimg(array([100, 50], 'l'))<br></div><div><br></div><div>Brian<br></div><div><br><br></div></div></div></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 28, 2015 at 11:53 AM, Jan Eglinger <span dir="ltr"><<a href="mailto:jan.eglinger@gmail.com" target="_blank">jan.eglinger@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all,<br>
<br>
some follow-up questions regarding imagej-ops:<br>
<br>
I tried to use some basic ops in python. From the 2014 wiki announcement [1] and the python template [2], I assumed something like this would work in python:<br>
<br>
# @OpService ops<br>
# @DisplayService display<br>
<br>
blank = ops.create([100, 50])<br>
<br>
display.createDisplay(blank)<br>
<br>
But a choice of candidate functions is listed in output:<br>
<br>
**********************************************<br>
Request:<br>
- createimg(<br>
Integer,<br>
Integer)<br>
<br>
Candidates:<br>
1. (Img output) =<br>
net.imagej.ops.create.DefaultCreateImg(<br>
==> Type outType?,<br>
ImgFactory fac?,<br>
long[] dims)<br>
Inconvertible type: java.lang.Integer => net.imglib2.type.Type<capture of ?><br>
2. (ImgPlus output) =<br>
net.imagej.ops.create.CreateEmptyImgCopy(<br>
ImgPlus input)<br>
Too many arguments: 2 > 1<br>
3. (Img output) =<br>
net.imagej.ops.create.CreateImgNativeType(<br>
ImgFactory fac,<br>
NativeType outType,<br>
Dimensions dims)<br>
Not enough arguments: 2 < 3<br>
4. (Img output) =<br>
net.imagej.ops.create.CreateImgDifferentNativeType(<br>
==> Img input,<br>
NativeType type)<br>
Inconvertible type: java.lang.Integer => net.imglib2.img.Img<capture of ?><br>
5. (ImgPlus output) =<br>
net.imagej.ops.create.CreateEmptyImgPlusCopy(<br>
ImgPlus input)<br>
Too many arguments: 2 > 1<br>
**********************************************<br>
<br>
and I am unsure if I have to provide image type and factory here.<br>
<br>
<br>
Similarly, for the subtract op:<br>
<br>
# @OpService ops<br>
# @StatisticsService stats<br>
# @net.imagej.Dataset inData<br>
# @OUTPUT net.imagej.Dataset outData<br>
<br>
outData = inData.duplicate()<br>
<br>
mean = stats.alphaTrimmedMean(inData, 0)<br>
print mean<br>
<br>
ops.subtract(outData, inData, mean)<br>
<br>
I am getting the following list of candidates:<br>
<br>
**********************************************<br>
Request:<br>
- math.subtract(<br>
DefaultDataset,<br>
DefaultDataset,<br>
Double)<br>
<br>
Candidates:<br>
1. (Object result) =<br>
net.imagej.ops.onthefly.ArithmeticOp$SubtractOp(<br>
Object result,<br>
Object a,<br>
Object b)<br>
Inputs do not conform to op rules<br>
result = blobs.gif<br>
a = blobs.gif<br>
b = 103.26857775590551<br>
2. (int result) =<br>
net.imagej.ops.math.PrimitiveMath$IntegerSubtract(<br>
int a,<br>
int b)<br>
Too many arguments: 3 > 2<br>
3. (long result) =<br>
net.imagej.ops.math.PrimitiveMath$LongSubtract(<br>
long a,<br>
long b)<br>
Too many arguments: 3 > 2<br>
4. (float result) =<br>
net.imagej.ops.math.PrimitiveMath$FloatSubtract(<br>
float a,<br>
float b)<br>
Too many arguments: 3 > 2<br>
5. (double result) =<br>
net.imagej.ops.math.PrimitiveMath$DoubleSubtract(<br>
double a,<br>
double b)<br>
Too many arguments: 3 > 2<br>
6. (RealType out) =<br>
net.imagej.ops.arithmetic.real.RealSubtract(<br>
==> RealType out,<br>
RealType in,<br>
double constant)<br>
Inconvertible type: net.imagej.DefaultDataset => capture of ?<br>
**********************************************<br>
<br>
is there a way with the type-unsafe scripting languages to get ops to use the correct function? Or am I misunderstanding the concept of imagej-ops here?<br>
<br>
Thanks again for any hints.<br>
<br>
Jan<br>
<br>
<br>
[1] <a href="http://fiji.sc/2014-04-04_-_Announcing_ImageJ_OPS" target="_blank">http://fiji.sc/2014-04-04_-_Announcing_ImageJ_OPS</a><br>
[2] <a href="https://github.com/imagej/imagej-legacy/blob/master/src/main/resources/script_templates/Python/OpsThresholdIJ1Analyze.py" target="_blank">https://github.com/imagej/imagej-legacy/blob/master/src/main/resources/script_templates/Python/OpsThresholdIJ1Analyze.py</a><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On 28.04.2015 09:03, Jan Eglinger wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Dear Mark and Curtis,<br>
<br>
thank you very much for the quick replies and helpful pointers!<br>
<br>
Jan<br>
<br>
<br>
On <a href="tel:27.04.2015%2020" value="+12704201520" target="_blank">27.04.2015 20</a>:42, Curtis Rueden wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Jan,<br>
<br>
Here is another version of the script, which avoids wrapping each<br>
Dataset in another ImgPlus (which the framework would then wrap into yet<br>
another Dataset....):<br>
<br>
# @DisplayService display<br>
# @OpService ops<br>
# @net.imagej.Dataset inputData1<br>
# @net.imagej.Dataset inputData2<br>
<br>
inputData1.setName("my1")<br>
inputData2.setName("my2")<br>
display.createDisplay(inputData1)<br>
display.createDisplay(inputData2)<br>
<br>
But note that you also don't need to explicitly call createDisplay. Any<br>
output parameters of your script will automatically have displays<br>
created for them. E.g.:<br>
<br>
# @OUTPUT net.imagej.Dataset outputData<br>
<br>
Will be shown at the conclusion of the script.<br>
<br>
Apologies for the appalling lack of documentation -- it would be great<br>
to flesh out the wiki docs about all this.<br>
<br>
HTH,<br>
Curtis<br>
<br>
On Mon, Apr 27, 2015 at 1:23 PM, Mark Hiner <<a href="mailto:hiner@wisc.edu" target="_blank">hiner@wisc.edu</a><br>
<mailto:<a href="mailto:hiner@wisc.edu" target="_blank">hiner@wisc.edu</a>>> wrote:<br>
<br>
Hi Jan,<br>
<br>
>an error message is displayed: "A Dataset is required but none<br>
exist."<br>
<br>
This was due to limitations with the input preprocessor presenting<br>
the list of datasets. Since ImagePluses aren't explicitly tracked by<br>
the IJ2 framework, having an ImagePlus recognized as a Dataset<br>
requires some extra layers. We had covered the single input case<br>
(which is why your first script worked) but not the general<br>
multi-input case. There is an issue tracking the multi-input<br>
<<a href="https://github.com/imagej/imagej-legacy/issues/106" target="_blank">https://github.com/imagej/imagej-legacy/issues/106</a>> case, which I<br>
resolved today. So this should work as intended in our next release<br>
- and thank you for the motivation to wrap this up!<br>
<br>
You can also manually enable ImagePlus <> Dataset synchronization to<br>
ensure ImagePluses always have a corresponding Dataset:<br>
<a href="http://imagej.net/Compatibility#Translation_of_data_structures" target="_blank">http://imagej.net/Compatibility#Translation_of_data_structures</a><br>
<br>
>(where can this title be set, by the way?)<br>
<br>
For the multiple choice input selection, the labels are based on the<br>
name of the input type. Since the input type is Dataset, the Dataset<br>
name is used (which delegates to the wrapped ImgPlus). In your code<br>
you are applying labels to the Display, but not the underlying<br>
dataset - if you name the ImgPlus, or explicitly create a Dataset<br>
and set its name, that name will propagate up to the input chooser<br>
(and the Display). As a side note, you should use the<br>
net.imagej.ImgPlus instead of the net.imglib2.meta.<br>
<br>
An updated script would be:<br>
<br>
<br>
# @DisplayService display<br>
# @OpService ops<br>
# @net.imagej.Dataset inputData1<br>
# @net.imagej.Dataset inputData2<br>
<br>
from net.imagej import ImgPlus<br>
<br>
display.createDisplay(ImgPlus(inputData1, "my1"))<br>
display.createDisplay(ImgPlus(inputData2, "my2"))<br>
<br>
Hope that helps. Let me know if you have any other questions.<br>
<br>
Best,<br>
Mark<br>
<br>
On Mon, Apr 27, 2015 at 8:58 AM, Jan Eglinger<br>
<<a href="mailto:jan.eglinger@gmail.com" target="_blank">jan.eglinger@gmail.com</a> <mailto:<a href="mailto:jan.eglinger@gmail.com" target="_blank">jan.eglinger@gmail.com</a>>> wrote:<br>
<br>
Dear all,<br>
<br>
*** TL;DR:<br>
How do I proceed to get multiple input Datasets as ImageJ2<br>
parameters from open images in Fiji?<br>
***<br>
<br>
I was recently exploring ImageJ2 scripting in Fiji and found the<br>
OpsThresholdIJ1Analyze template [1] in the script editor very<br>
helpful.<br>
<br>
When trying to get more than one @net.imagej.Dataset input<br>
parameter however, I noticed some inconsistencies.<br>
Let me try to illustrate with the two following scripts:<br>
<br>
# @DisplayService display<br>
# @OpService ops<br>
# @net.imagej.Dataset inputData1<br>
<br>
from net.imglib2.meta import ImgPlus<br>
<br>
display.createDisplay("my1", ImgPlus(inputData1))<br>
<br>
<br>
The above script re-displays the current image as expected (I<br>
tried with the Blobs sample image open, which will be<br>
re-displayed with a non-inverted LUT.)<br>
<br>
When I ask for two input datasets (right after a fresh start of<br>
Fiji with only the Blobs sample image open):<br>
<br>
# @DisplayService display<br>
# @OpService ops<br>
# @net.imagej.Dataset inputData1<br>
# @net.imagej.Dataset inputData2<br>
<br>
from net.imglib2.meta import ImgPlus<br>
<br>
display.createDisplay("my1", ImgPlus(inputData1))<br>
display.createDisplay("my2", ImgPlus(inputData2))<br>
<br>
an error message is displayed: "A Dataset is required but none<br>
exist."<br>
The same error message is displayed when I open a second image<br>
in Fiji before running the script.<br>
<br>
Now, when I run script #2 after script #1 was run at least once,<br>
I get a dialog with two choices "InputData1" and "InputData2",<br>
both choice fields containing "blobs.gif" and a number of<br>
"Untitled" entries (where can this title be set, by the way?).<br>
<br>
I guess that a choice is only displayed if there are ImageJ2<br>
datasets (i.e. wrapped ImagePlus) already available. The single<br>
input case seems to be special-cased as it auto-wraps the<br>
currently open image.<br>
<br>
So how do I proceed to get more than one input in ImageJ2<br>
scripting from open (ImageJ1-)images?<br>
<br>
Thanks for your advice,<br>
Regards,<br>
Jan<br>
<br>
<br>
[1]:<br>
<br>
<a href="https://github.com/imagej/imagej-legacy/blob/master/src/main/resources/script_templates/Python/OpsThresholdIJ1Analyze.py" target="_blank">https://github.com/imagej/imagej-legacy/blob/master/src/main/resources/script_templates/Python/OpsThresholdIJ1Analyze.py</a><br>
<br>
<br>
</blockquote></blockquote>
<br>
_______________________________________________<br>
ImageJ-devel mailing list<br>
<a href="mailto:ImageJ-devel@imagej.net" target="_blank">ImageJ-devel@imagej.net</a><br>
<a href="http://imagej.net/mailman/listinfo/imagej-devel" target="_blank">http://imagej.net/mailman/listinfo/imagej-devel</a><br>
</div></div></blockquote></div><br></div>