Skip to content, Skip to search


Clojure Scripting

117 bytes removed, 21:45, 15 February 2011
Replace h3 and h4 for == and ===, so that the page breaks into editable chunks.
*[ Clojure cheat sheet]: a summary of all the essentials.
<h3>== Using Clojure inside Fiji</h3>==
Go to "Plugins - Scripting - Clojure Interpreter". The prompt accepts any clojure code. See also Fiji's [[Script Editor]].
<h4>=== Running Clojure files from the command line</h4>===
Fiji can execute any clojure file directly:
<h4>=== Getting a REPL without the usual ImageJ GUI</h4>===
The simplest is:
Just make sure to have the jline.jar in your classpath (or drop it into fiji/jars folder).
<h4>=== Debugging with the Java Debugger</h4>===
If you have launched fiji with an agentlib, you may then connect to it via the <i>jdb</i>:
Within the jdb prompt, type "help".
<h3>== Language basics</h3>==
<p>A ';' defines the start of a comment, just like '//' does in Java.</p>
<p>A function definition declares parameters within [].</p>
<h3>== Calling methods and variables on a java object</h3>==
<p>There are two ways, the second syntactic sugar of the first. Below, <b>imp</b> is a pointer to an ImagePlus:</p>
<h3>== Calling static fields and methods: namespace syntax</h3>==
<p>To call a <b>static</b> field or method, use namespace syntax:</p>
<h3>== Defining variables: obtaining the current image</h3>==
As a local variable <b>imp</b> declared within a <i>let</i> statement:
<h3>== Creating objects: invoking constructors</h3>==
A constructor is invoked by adding a dot '.' to the name of a class, followed by the arguments. Below, we create an ImageProcessor and then an ImagePlus with it, and finally we print the ImagePlus, which invokes toString() on it (like in java):
<h3>== Defining a closure</h3>==
<p>In the following a function is declared within the scope of the local variable <b>rand</b>, which contains an instance of java.util.Random. All calls to the function <i>rand-double</i> will use the same random number generator instance with seed 69997.</p>
<p>The <i>dotimes</i> loop will then print 10 different pseudo-random numbers. If the <b>rand</b> was a new Random with seed 69997 every time, all 10 numbers would be exactly the same.</p>
<h3>== Manipulating images</h3>==
<h4>=== ImageJ Image internals: ImagePlus, ImageProcessor, ImageStack</h4>===
ImageJ has three basic objects:
<h4>=== Conventions in naming image variables</h4>===
By convention, variables are named:
<h4>=== Creating a new image</h4>===
From scratch:
<h4>=== Creating an image of the same type of an existing one</h4>===
<source lang="lisp">
Above, notice the parenthesis (createProcessor 768 768), which specify for which method those numbers are arguments for.
<h4>=== Resizing an image</h4>===
The idea is to grab the ImageProcessor, duplicate it and resize it. The resizing returns a new ImageProcessor of the same type:
<h4>=== Resizing an ImageStack</h4>===
This one is harder, because an ImageStack is just a wrapper for Object[] list of pixel arrays.
<h4>=== Resizing an image or ImageStack using ROIs</h4>===
ROIs (aka Region of Interest or selection) have bounds, defined by the minimal enclosing rectangle.
The above works with both single images and stacks.
<h3>== Manipulate images using ImgLib</h3>==
With [[Imglib]], pixels are stored in native arrays of primitives such as int, float, double, etc. (or other more interesting forms, such as [ Shape]. Such pixels are accessed with intermediate proxy objects that the JIT is able to completely remove out of the way.
<h4>=== Multiply each pixel by 0.5</h4>===
Multiply in place each value by 0.5. The ImgLib/wrap is a thin wrapper that accesses directly the pixel array. Hence the original image will be changed.
All mathematical operations listed in java.lang.Math have a corresponding constructor for execution in Compute/inFloats. See the documentation for the [ script.imglib.math package].
<h4>=== Normalize an image</h4>===
Assumes that <i>(IJ/getImage)</i> returns a 32-bit, float image. If that is not the case, convert the image to a float image first.
<h3>== Looping an array of pixels</h3>==
<p>For example, to find the min and max values:</p>
<h3>== Executing commands from the menus</h3>==
<p>Any ImageJ menu command may be run on the active image:</p>
<source lang="lisp">
To find out which arguments can any command accept, open the Plugins - Macros - Macro Recorder and run the command manually.
<h3>== Creating and using Clojure scripts as ImageJ plugins</h3>==
<p>Simply create a text file with the script inside, and place it in the plugins menu or any subfolder. Then call Plugins - Scripting - Refresh Clojure Scripts to make it appear on the menus.</p>
<p><b>Very important:</b> all scripts and commands from the interpreter will run within the same thread, and within the same clojure context.</p>
<h3>== Using java beans for quick and convenient access to an object's fields</h3>==
<p>Essentially it's all about using <i>get</i> methods in a trivial way. For example:</p>
<source lang="lisp">
<h3>== Fixing overexposed images: setting a pixel value to a desirable one for all overexposed pixels</h3>==
The problem: [ Leginon] or the Gatan TEM camera acquired an overexposed image, and set all pixels beyond range to zero.
<h3>== Creating a script for ImageJ</h3>==
Simply write the clojure script in a text file, and follow these conventions:
See [[Scripting Help]] for more details, including how to use the built-in dynamic interpreter.
<h3>== Example Clojure plugins included in Fiji</h3>==
Open the plugins/Examples/ folder in Fiji installation directory. You'll find three Clojure examples:
<h3>== Defining the output stream</h3>==
The default output stream is at variable <i>*out*</i>, which you may redefine to any kind of PrintWriter:
<source lang="lisp">
<h3>== Destructuring</h3>==
Destructuring is a shortcut to capture the contents of a variable into many variables.
<h3>== Namespaces</h3>==
* To list all existing namespaces:
<source lang="lisp">
Note above we use <i>destructuring</i>: the [k v] take the values of the key and the value of each entry in the ns-publics table. Actually, since we first sort the table, the k and v take the first and second values of each array pair in the sorted list of array pairs returned on applying <i>sort</i> to the <i>ns-publics</i>-generated table.
<h3>== Forget/Remove all variables from a namespace</h3>==
To forget all variables from the user namespace, do:
<source lang="lisp">
<i>Thanks to AWizzArd from #clojure at for the tip.</i>
<h3>== JVM arguments</h3>==
* To get the arguments passed to the JVM, see contents of variable *command-line-args*
<source lang="lisp">
<h3>== Reflection</h3>==
* To list all methods of an object:
(Thanks to Craig McDaniel for posting the above function to Clojure's mailing list.)
<h3>== Lambda functions</h3>==<h4>=== Declaration</h4>===
* To declare functions on the fly, lambda style, with regex for arguments:
Of course there's no need to name the function, the above is just for illustration.
<h4>=== Mapping a function to all elements in a list</h4>===
* To declare a nameless function, and apply it to each element of a list:
Beware that the <i>map</i> function above applies the given function to each element of a list, and returns a <b>new</b> list with the results.
<h3>== Built-in documentation</h3>==
Use the function <b><i>doc</i></b> to query any other function or variable. For example, the list generator function <i>range</i>:
<source lang="lisp">
... etc.
<h4>=== Defining documentation for your own functions</h4>===
So where does the documentation come from? Every definition of a function or macro or multimethod may take a description string before the arguments:
<source lang="lisp">
<h4>=== Defining documentation for a variable</h4>===
<source lang="lisp">
Function documentation is internally set like the above: <i>defn</i> is a macro that defines a function and puts the second argument as the doc string of the variable that points to the function body (among many other things).
<h4>=== Adding a test function to a variable</h4>===
We first declare the variable, and then define it with a metadata map that includes a test function:
Otherwise, it would just return the <i>:ok</i> keyword.
<h3>== A fibonacci sequence: lazy and infinite sequences</h3>==
A beautiful example of using lazy sequences and applying functions to one or more sequences at a time.
(0 1 1 2 3 5 8 13 21 34)
<h4>=== Printing lazy sequences to the REPL</h4>===
The REPL, when given a lazy sequence, will <b>traverse it in its entirety</b> to print it.
The <b>*print-length*</b> applies to all sequences to be printed in the REPL, but is specially useful for very large lazy sequences.
<h3>== Creating shallow and deep sequences from java arrays</h3>==
Many clojure functions take sequences, not native java arrays, as arguments. A java native array can be wrapped by a shallow sequence like the following:
<i>Thanks to Chouser and wwmorgan for examples on #clojure at</i>
<h3>== Generating java classes in .class files from clojure code</h3>==
Using ahead of time (AOT) compilation with [ gen-class], any clojure code can be compiled to a java class. Such class can then be used from java code, or from any scripting language like [[Jython Scripting|jython]], [[JRuby Scripting|jruby]], [[Javascript Scripting|javascript]], and [[:Category:Scripting|any other]].
<h3>== References, concurrency, transactions and synchronization</h3>==
Clojure supports thread concurrency without explicit locks. Compared to java code, this is a gigantic step forward: locks, and particularly multiple locks, are very hard to get right and very, very hard to debug properly (but see [ debugging multithreaded java programs]).
<h3>== Using try/catch/finally and throwing Exceptions</h3>==
<source lang="lisp">
<h3>== Executing a command in a shell and capturing its output</h3>==
First we define the macro <i>exec</i>:
<source lang="lisp">
<h3>== Creating a derivative of a function</h3>==
The derivative of a function:
<h3>== Pretty printing a primitive array</h3>==
Suppose we create a primitive array of length 10:
<h3>== Loading an image file into a byte array</h3>==
<source lang="lisp">
Emailconfirmed, uploaders