imagej / imagej-scripting

ImageJ-specific applications of the SciJava script languages
Other
25 stars 15 forks source link

run method of op service does not work with Clojure #28

Closed kephale closed 7 years ago

kephale commented 7 years ago

Never ran into this issue because I construct functions from the Op classes themselves. I ran into this issue because ops like scaleView take additional inputs that have to have matching generics; however, generics cannot be encoded at all from Clojure. I tried using the run method of (.op ij) but it does not work even on simple cases. This is the test script:

#@ImageJ ij

(def clown (.open (.io ij) "http://imagej.net/images/clown.png"))

(def scale-factors [0.5 0.5 1])

(def interp-strat (net.imglib2.interpolation.randomaccess.NLinearInterpolatorFactory.))

; Works
(def filter-clown (.gauss (.filter (.op ij)) clown (double-array [0.5 0.5 0])))

; Doesn't work
(def filter-clown (.run (.op ij) "gauss" clown (double-array [0.5 0.5 0])))

; Doesnt work
;(def scaled-clown (.scaleView (.transform (.op ij)) clown scale-factors interp-strat))
; Doesnt work
;(def scaled-clown (.run (.op ij) "scaleView" clown scale-factors interp-strat))
ctrueden commented 7 years ago

It seems this is a limitation of Clojure: it does not support Java varargs in an automagical way.

Your first "Doesn't work" example can be made to work as follows:

(def filter-clown (.run (.op ij) "gauss" (into-array Object [clown (double-array [5.0 5.0 0])])))

Similarly, your third "Doesn't work" will work as follows:

(def scaled-clown (.run (.op ij) "scaleView" (into-array Object [clown scale-factors interp-strat])))

The second one above has other problems: the currently released version of Ops has errors in the TransformNamespace such that the transform.scaleView methods are named scale instead of scaleView. You also need to coerce the scale factor sequence into a Java array. So the following will work:

def scaled-clown (.scale (.transform (.op ij)) clown (double-array [0.5 0.5 1]) interp-strat))

Note that errors in the transform namespace have been corrected on the imagej-ops master branch, so the above will change to .scaleView with the next release.

ctrueden commented 7 years ago

It might be convenient to define a runOp function. Here's an example:

#@ImageJ ij

(defn runOp [opName args] (.run (.op ij) opName (into-array Object args)))

(def clown (.open (.io ij) "http://imagej.net/images/clown.png"))
(def scale-factors [0.5 0.5 1])
(def interp-strat (net.imglib2.interpolation.randomaccess.NLinearInterpolatorFactory.))

(def scaled-clown (runOp "scaleView" [clown scale-factors interp-strat]))

scaled-clown