CINXE.COM
Clojure Scripting
<!DOCTYPE html> <html> <head> <title>Clojure Scripting</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=3" /> <meta content="ImageJ Wiki" property="og:site_name"> <meta content="Clojure Scripting" property="og:title"> <meta content="article" property="og:type"> <meta content="The ImageJ wiki is a community-edited knowledge base on topics relating to ImageJ, a public domain program for processing and analyzing scientific images, and its ecosystem of derivatives and variants, including ImageJ2, Fiji, and others." property="og:description"> <meta content="https://imagej.github.io/scripting/clojure" property="og:url"> <meta content="https://imagej.github.io/media/icons/imagej2.png" property="og:image"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> <link rel="manifest" href="/site.webmanifest"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"> <meta name="msapplication-TileColor" content="#da532c"> <meta name="theme-color" content="#ffffff"> <link rel="stylesheet" href="/assets/css/lightbox.min.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css"/> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/dygraphs@2.1.0/dist/dygraph.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dygraphs@2.1.0/dist/dygraph.min.css" /> <link rel="stylesheet" href="/assets/css/main.css" /> <link rel="stylesheet" href="/assets/css/layout.css"/> <link rel="stylesheet" href="/assets/css/includes.css" /> <link rel="stylesheet" href="/assets/css/timeline.css"/> <link rel="stylesheet" href="/assets/css/dock.css"/> <noscript><link rel="stylesheet" href="/assets/css/noscript.css" /></noscript> <link rel="stylesheet" href="/assets/css/page.css" /> </head> <body class="is-preload"> <!-- Top bar --> <section id="top-bar"> <a href="/"><img id="site-logo" src="/media/icons/imagej2.png"></a> <div id="search-panel"> <div id="search-box"></div> </div> </section> <!-- Page-info --> <div class="page-info"> <a href="https://github.com/imagej/imagej.github.io/commits/main/_pages/scripting/clojure.md">Page history</a> <a href="https://github.com/imagej/imagej.github.io/edit/main/_pages/scripting/clojure.md">Edit this page</a> <a href="/editing">How do I edit this website?</a><br><a href="https://imagej.net/imagej-wiki-static/Clojure_Scripting">Original MediaWiki page</a></div> <section id="left-column" class="sidebar dock"> <!-- Menu --> <div class="menu dockable"> <div class="drag-handle"></div><h3>ImageJ Docs</h3> <ul> <li><a href="/downloads">Download</a></li> <li><details><summary>Learn</summary><ul> <li><details><summary><a href="/learn">ImageJ Basics</a></summary><ul> <li><a href="/tutorials">Tutorials</a></li> <li><a href="/learn/user-guides">User Guides</a></li> <li><a href="/learn/keyboard-shortcuts">Keyboard Shortcuts</a></li> <li><a href="/learn/tips-and-tricks">Tips and Tricks</a></li> <li><a href="/learn/troubleshooting">Troubleshooting</a></li> <li><a href="/learn/faq">Frequently Asked Questions</a></li> <li><details><summary><a href="/platforms">Supported Platforms</a></summary><ul> <li><a href="/platforms/windows">Windows</a></li> <li><a href="/platforms/macos">MacOS</a></li> <li><a href="/platforms/linux">Linux</a></li> <li><a href="/platforms/pi">Raspberry Pi</a></li> <li><a href="/platforms/android">Android</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/Supported Platforms --> <li><details><summary><a href="/formats">File Formats</a></summary><ul> <li><a href="/formats/bio-formats">Bio-Formats</a></li> <li><a href="/formats/video">Video formats</a></li> <li><a href="/formats/quicktime">QuickTime</a></li> <li><a href="/formats/tiff">TIFF</a></li> <li><a href="/formats/pdf">PDF</a></li> <li><a href="/formats/dicom">DICOM</a></li> <li><a href="/formats/lsm">Zeiss LSM</a></li> <li><a href="/formats/olympus">Olympus VSI</a></li> <li><a href="/formats/lurawave">Opera Flex</a></li> <li><a href="/formats/fib-sem">FIB-SEM</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/File Formats --> </ul></details></li> <!-- Learn/ImageJ --> <li><details><summary><a href="/imaging">Scientific Imaging</a></summary><ul> <li><a href="/imaging/principles">Principles of Scientific Imaging</a></li> <li><a href="/imaging/annotating-images">Annotating Images</a></li> <li><a href="/imaging/colocalization-analysis">Colocalization</a></li> <li><a href="/imaging/color-image-processing">Color Image Processing</a></li> <li><a href="/imaging/deconvolution">Deconvolution</a></li> <li><a href="/imaging/image-intensity-processing">Image Intensity Processing</a></li> <li><a href="/imaging/particle-analysis">Particle Analysis</a></li> <li><a href="/imaging/registration">Registration</a></li> <li><a href="/imaging/segmentation">Segmentation</a></li> <li><a href="/imaging/stack-slice-manipulations">Stack-slice Manipulations</a></li> <li><a href="/imaging/t-functions">T-functions</a></li> <li><a href="/imaging/tracking">Tracking</a></li> <li><a href="/imaging/visualization">Visualization</a></li> <li><a href="/imaging/z-functions">Z-functions</a></li> </ul></details></li> <!-- Learn/Scientific Imaging --> </ul></details></li> <!-- Learn --> <li><details open><summary><a href="/plugins">Extend</a></summary><ul> <li><a href="/list-of-extensions">List of Extensions</a></li> <li><details><summary><a href="/update-sites">Update Sites</a></summary><ul> <li><a href="/list-of-update-sites">List of Update Sites</a></li> <li><a href="/update-sites/following">Following an Update Site</a></li> <li><a href="/update-sites/setup">Creating an Update Site</a></li> <li><a href="/update-sites/tos">Terms of Service</a></li> <li><a href="/update-sites/automatic-uploads">Automatic Upload</a></li> <li><a href="/update-sites/core-uploads">Uploading to Core Sites</a></li> <li><a href="/update-sites/faq">Update Sites FAQ</a></li> <li><a href="/update-sites/stats">Statistics</a></li> </ul></details></li> <!-- Extend/Update Sites --> <li><details open><summary><a href="/scripting">Scripting</a></summary><ul> <li><a href="/scripting/basics">Scripting Basics</a></li> <li><a href="/scripting/script-editor">Script Editor</a></li> <li><a href="/scripting/parameters">Parameters</a></li> <li><a href="/scripting/user-input">User Input</a></li> <li><a href="/scripting/auto-imports">Auto Import</a></li> <li><a href="/scripting/templates">Templates</a></li> <li><a href="/scripting/batch">Batch Processing</a></li> <li><a href="/scripting/headless">Running Headlessly</a></li> <li><a href="/scripting/comparisons">Scripting Comparisons</a></li> <li><a href="/scripting/toolbox">Toolbox</a></li> <li><details open><summary>Languages</summary><ul> <li><a href="/scripting/beanshell">BeanShell Scripting</a></li> <li><a href="/scripting/groovy">Groovy Scripting</a></li> <li><a href="/scripting/macro">ImageJ Macro</a></li> <li><a href="/scripting/javascript">JavaScript</a></li> <li><a class="current-page">Lisp (Clojure)</a></li> <li><a href="/scripting/matlab">MATLAB</a></li> <li><a href="/scripting/jython">Python (Jython)</a></li> <li><a href="/scripting/python">Python (native)</a></li> <li><a href="/scripting/renjin">R (Renjin)</a></li> <li><a href="/scripting/jruby">Ruby (JRuby)</a></li> <li><a href="/scripting/scala">Scala Scripting</a></li> </ul></details></li> <!-- Extend/Scripting/Languages --> </ul></details></li> <!-- Extend/Scripting --> <li><details><summary><a href="/develop">Development</a></summary><ul> <li><a href="/develop/philosophy">Philosophy</a></li> <li><a href="/develop/architecture">Architecture</a></li> <li><a href="/develop/source">Source code</a></li> <li><a href="/develop/project-management">Project management</a></li> <li><a href="/develop/coding-style">Coding style</a></li> <li><a href="/develop/javadoc">Using Javadoc</a></li> <li><a href="/develop/debugging">Debugging</a></li> <li><a href="/develop/wish-list">Wish list</a></li> <li><details><summary>Tools</summary><ul> <li><a href="/develop/github">GitHub</a></li> <li><a href="/develop/maven">Maven</a></li> <li><a href="/develop/ci">CI/CD</a></li> <li><a href="/develop/dotfiles">Dotfiles</a></li> <li><details><summary><a href="/develop/ides">IDEs</a></summary><ul> <li><a href="/develop/eclipse">Eclipse</a></li> <li><a href="/develop/netbeans">NetBeans</a></li> <li><a href="/develop/intellij">IntelliJ IDEA</a></li> <li><a href="/develop/command-line">Command Line</a></li> </ul></details></li> </ul></details></li> <!-- Extend/Development/Tools --> <li><details><summary>Guides</summary><ul> <li><a href="/develop/plugins">Writing plugins</a></li> <li><a href="/develop/improving-the-code">Contributing to a plugin</a></li> <li><a href="/develop/releasing">Development lifecycle</a></li> <li><a href="/develop/building-a-pom">Building a POM</a></li> <li><a href="/develop/debugging-exercises">Hands-on debugging</a></li> <li><a href="/develop/writing-ops">Adding new ops</a></li> <li><a href="/develop/formats">Adding new formats</a></li> <li><a href="/develop/native-libraries">Using native libraries</a></li> <li><a href="/develop/tips">Tips for developers</a></li> <li><a href="/develop/cpp-tips">Tips for C++ developers</a></li> <li><a href="/develop/ij1-plugins">ImageJ 1.x plugins</a></li> <li><a href="/develop/versioning">Versioning</a></li> <li><a href="/develop/logging">Logging</a></li> <li><a href="/develop/uber-jars">Uber-JARs</a></li> </ul></details></li> <!-- Extend/Development/Guides --> <li><details><summary><a href="/develop/git">Git</a></summary><ul> <li><a href="/develop/git/eclipse">Git in Eclipse (EGit)</a></li> <li><a href="/develop/git/mini-howto">Git mini howto</a></li> <li><a href="/develop/git/workshop">Git workshop</a></li> <li><a href="/develop/git/conflicts">Git conflicts</a></li> <li><a href="/develop/git/topic-branches">Git topic branches</a></li> <li><a href="/develop/git/notes">Git notes</a></li> <li><a href="/develop/git/reflogs">Git reflogs</a></li> <li><a href="/develop/git/submodules">Git submodules</a></li> <li><a href="/develop/git/pinpoint-regressions">How to pinpoint regressions</a></li> <li><a href="/develop/git/publish-a-repository">How to publish a git repository</a></li> <li><a href="/develop/git/extract-a-subproject">How to extract a subproject</a></li> </ul></details></li> <!-- Extend/Development/Git --> </ul></details></li> <!-- Extend/Development --> </ul></details></li> <!-- Extend --> <li><details><summary><a href="/contribute">Contribute</a></summary><ul> <li><a href="/contribute/citing">Citing</a></li> <li><a href="/people">Contributors</a></li> <li><a href="/orgs">Organizations</a></li> <li><a href="/contribute/governance">Governance</a></li> <li><a href="/contribute/funding">Funding</a></li> <li><a href="/contribute/fiji">Contributing to Fiji</a></li> <li><details><summary><a href="/licensing">Licensing</a></summary><ul> <li><details><summary><a href="/licensing/open-source">Open Source</a></summary><ul> <li><a href="/licensing/apache">Apache</a></li> <li><a href="/licensing/bsd">BSD</a></li> <li><a href="/licensing/epl">EPL</a></li> <li><a href="/licensing/gpl">GPL</a></li> <li><a href="/licensing/lgpl">LGPL</a></li> <li><a href="/licensing/mit">MIT</a></li> <li><a href="/licensing/public-domain">Public domain</a></li> <li><a href="/licensing/big">BIG</a></li> </ul></details></li> <!-- Contribute/Licensing/Open Source --> <li><a href="/licensing/closed-source">Proprietary</a></li> </ul></details></li> <!-- Contribute/Licensing --> <li><details><summary><a href="/editing">Editing the Wiki</a></summary><ul> <li><a href="/editing/advanced">Advanced Editing</a></li> <li><a href="/editing/buttons">Buttons</a></li> <li><a href="/editing/citations">Citations</a></li> <li><a href="/editing/code">Source Code</a></li> <li><a href="/editing/debugging">Debugging</a></li> <li><a href="/editing/headers">Headers</a></li> <li><a href="/editing/icons">Icons</a></li> <li><a href="/editing/images">Images</a></li> <li><a href="/editing/keys">Keyboard Shortcuts</a></li> <li><a href="/editing/linking">Linking</a></li> <li><a href="/editing/math">Math Expressions</a></li> <li><a href="/editing/menu-paths">Menu Paths</a></li> <li><a href="/editing/navigation">Navigation</a></li> <li><a href="/editing/notices">Notices</a></li> <li><a href="/editing/people">People</a></li> <li><a href="/editing/pitfalls">Pitfalls</a></li> <li><a href="/editing/quizzes">Quizzes</a></li> <li><a href="/editing/statbox">Statbox</a></li> <li><a href="/editing/symbols">Symbols</a></li> <li><a href="/editing/tables">Tables</a></li> <li><a href="/editing/timelines">Timelines</a></li> <li><a href="/editing/tooltips">Tooltips</a></li> <li><a href="/editing/videos">Videos</a></li> <li><a href="/editing/whitespace">Whitespace</a></li> </ul></details></li> <!-- Contribute/Editing the Wiki --> </ul></details></li> <!-- Contribute --> <li><details><summary><a href="/discuss">Discuss</a></summary><ul> <li><a href="/discuss/bugs">Reporting Issues</a></li> <li><a href="/discuss/mailing-lists">Mailing Lists</a></li> <li><a href="/discuss/chat">Chat</a></li> </ul></details></li> <!-- Discuss --> <li><details><summary>Explore</summary><ul> <li><a href="/news">News</a></li> <li><details><summary><a href="/events">Events</a></summary><ul> <li><a href="/events/presentations">Presentations</a></li> <li><a href="/events/conferences">Conferences</a></li> <li><a href="/events/hackathons">Hackathons</a></li> <li><a href="/events">More...</a></li> </ul></details></li> <!-- Discuss/Events --> <li><details><summary><a href="/libs">Libraries</a></summary><ul> <li><a href="/libs/imagej-ops">ImageJ Ops</a></li> <li><a href="/libs/imagej-common">ImageJ Common</a></li> <li><a href="/libs/imagej-legacy">ImageJ Legacy</a></li> <li><a href="/libs/scijava">SciJava</a></li> <li><a href="/libs/scifio">SCIFIO</a></li> <li><details><summary><a href="/libs/imglib2">ImgLib2</a></summary><ul> <li><a href="/libs/imglib2/getting-started">Getting Started</a></li> <li><a href="/libs/imglib2/accessors">Accessors</a></li> <li><a href="/libs/imglib2/accessibles">Accessibles</a></li> <li><a href="/libs/imglib2/examples">Examples</a></li> <li><a href="/libs/imglib2/workshop-introductory">Introductory Workshop</a></li> <li><a href="/libs/imglib2/workshop-advanced">Advanced Workshop</a></li> <li><a href="/libs/imglib2/matlab">ImgLib2 images in MATLAB</a></li> <li><a href="/libs/imglib2/benchmarks">Benchmarks</a></li> <li><a href="/libs/imglib2/faq">FAQ</a></li> <li><a href="/libs/imglib2/developing">Developing ImgLib2</a></li> <li><a href="/libs/imglib2/discussion">ImgLib2 Discussion</a></li> </ul></details></li> <!-- Explore/Libraries/ImgLib2 --> <li><a href="/libs">More...</a></li> </ul></details></li> <!-- Explore/Libraries --> <li><details><summary><a href="/software">Software</a></summary><ul> <li><a href="/software/nih-image">NIH Image</a></li> <li><a href="/software/imagej">ImageJ</a></li> <li><a href="/software/imagej2">ImageJ2</a></li> <li><a href="/software/fiji">Fiji</a></li> <li><a href="/software">More...</a></li> </ul></details></li> <!-- Explore/Software --> </ul></details></li> <!-- Explore --> </ul> </div> </section> <section id="right-column" class="sidebar dock"> <!-- Vital stats --> <!-- Table of contents --> <div id="toc" class="toc menu dockable"> <div class="drag-handle"></div> <h3>Page contents</h3> <ul data-toc="#content" data-toc-headings="h1,h2,h3,h4,h5,h6"></ul> </div> </section> <!-- Page title --> <div class="container"> <header class="major special"> <a class="project-icon shadowed-box" href="/software/imagej2"><span class="tooltip"><img src="/media/icons/imagej2.png"><span class="tooltiptext" style="top: 80%; left: 25%; width: 20em">This page describes content relating to the ImageJ2 platform. Click the logo for details.</span></span></a> <h1>Clojure Scripting</h1> <span class="project-counterweight"> </span> </header> </div> <!-- Nav bar --> <!-- Main content --> <section id="page" class="main style1"> <div class="container"> <div class="box alt"></div> <div id="content" class="page-content"> <div class="notice" style="font-size: 2; background: #ebf2f8; border-left: 10px solid #67a1fe"><div class="notice-icon"><img src="/media/icons/info.svg" width="32"></div><div class="notice-content"><p>The content of this page has not been vetted since shifting away from MediaWiki. If you’d like to help, check out the <a href="/events/wiki-grand-opening/how-to-help">how to help guide</a>!</p> </div> </div> <p><a href="https://en.wikipedia.org/wiki/Clojure">Clojure</a> is a dialect of the <a href="https://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp programming language</a>. Clojure is a general-purpose programming language with an emphasis on functional programming.</p> <h1 id="clojure-tutorial-for-imagej">Clojure tutorial for ImageJ</h1> <p>Check out <a href="http://clojure.org">clojure website</a> and particularly the chapter on <a href="http://clojure.org/java_interop">Java interoperability</a>.</p> <p>Clojure is <em>not</em> a scripting language: Clojure compiles directly to JVM bytecode, and thus runs at native speed. Thus one must think of Clojure as a true alternative to Java the language, but much more expressive, flexible and powerful.</p> <p>See also:</p> <ul> <li><a href="http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Cookbook">Clojure Cookbook</a>.</li> <li><a href="http://clojure.org/api">The Clojure API</a> (listing of all available functions, with explanations).</li> <li><a href="http://clojure.org/cheatsheet">Clojure cheat sheet</a>: a summary of all the essentials.</li> </ul> <h2 id="using-clojure-inside-fiji">Using Clojure inside Fiji</h2> <p>Go to <span class="bc"><span>Plugins</span> › <span>Scripting</span> › <span>Clojure Interpreter</span></span>. The prompt accepts any clojure code. See also the <a href="/scripting/script-editor">Script Editor</a>.</p> <p>See <a href="/scripting">Scripting Help</a> for details on keybindings and how to use the interpreter. <kbd class="key">⌃ Ctrl</kbd> + <kbd class="key">)</kbd> will add all necessary ending parenthesis.</p> <p>A minimal, complete clojure example:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij</span><span class="w"> </span><span class="n">IJ</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">gold</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/openImage</span><span class="w"> </span><span class="s">"https://imagej.net/ij/images/AuPbSn40.jpg"</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="n">gold</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>To create scripts, just save them as .clj text files (with an underscore in the name) in any folder or subfolder of the <code class="language-plaintext highlighter-rouge">plugins</code> folder, and run <span class="bc"><span>Plugins</span> › <span>Scripting</span> › <span>Refresh Clojure Scripts</span></span> to update the menus (it’s done automatically at start up as well).</p> <p>To edit a script, just edit and save it with your favorite text editor.</p> <p>To execute a script, do any of:</p> <ul> <li>Select it from the plugins menus.</li> <li>Type ‘l’ (L), start typing its name, push the down arrow and then return to execute it.</li> <li>If it was the last executed command, just type <kbd class="key">⇧ Shift</kbd> + <kbd class="key">R</kbd> (shortcut to “Process - Repeat Command”).</li> </ul> <p>The script is <em>always</em> read directly from the source file, so no updating of menus is needed (unless its file name changes).</p> <h3 id="convenient-clojure-with-funimage">Convenient Clojure with Funimage</h3> <ul> <li><a href="https://github.com/funimage/funimage/">Funimage</a> provides a library for convenient Clojure coding within <a href="/software/imagej2">ImageJ2</a>. Alleviating much of the need for type-hinting, and some of the burdens involved in handling more complicated data structures, such as those from <a href="/libs/imglib2">ImgLib2</a>.</li> </ul> <p>See the <a href="/list-of-update-sites">list of update sites</a> for information on setting up the Funimage update site.</p> <h3 id="running-clojure-files-from-the-command-line">Running Clojure files from the command line</h3> <p>ImageJ2 can execute any clojure file directly:</p> <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./ImageJ-linux64 plugins/Examples/blend_two_images.clj </code></pre></div></div> <p>The file will run with the full classpath as set by ImageJ2, which includes all jars in <code class="language-plaintext highlighter-rouge">jars/</code> and <code class="language-plaintext highlighter-rouge">plugins/</code> folders, among others.</p> <h2 id="language-basics">Language basics</h2> <ul> <li>A ‘;’ defines the start of a comment, just like ‘//’ does in Java.</li> <li>A function definition declares parameters within [].</li> <li>Local variables are declared with <code class="language-plaintext highlighter-rouge">let</code>, and global variables with <code class="language-plaintext highlighter-rouge">def</code>.</li> <li>Functions are defined with <code class="language-plaintext highlighter-rouge">defn</code>, and are visible globally. Hence a function declared within a <code class="language-plaintext highlighter-rouge">let</code> statement has access to variables declared in it. This method enables closures.</li> </ul> <h3 id="importing-classes">Importing classes</h3> <p>To reference Java classes from Clojure you will need to import them. <br /></p> <div class="notice" style="font-size: 2; background: #e6e6e6; border-left: 10px solid #fadd8d"><div class="notice-icon"><img src="/media/icons/imagej2.png" /></div><div class="notice-content"><p>Unlike the original <a href="/software/imagej">ImageJ</a>, <a href="/software/imagej2">ImageJ2</a> (and therefore <a href="/software/fiji">Fiji</a>) does not automatically import any classes. Consequently, scripts written for ImageJ will not run in ImageJ2 without adding the proper imports. The rationale is that the auto-import feature is not safe. What if two classes of the same name live in two different packages? Or if a new class is introduced that makes formerly unique names ambiguous? All of a sudden, all of the scripts that reference the original class no longer work. In short: auto-imports are dangerously imprecise.</p> </div> </div> <p><br /> You can specify imports in Clojure in a few ways:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; A single import.</span><span class="w"> </span><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="n">java.util.Date</span><span class="p">)</span><span class="w"> </span><span class="c1">; Use it!</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">*now*</span><span class="w"> </span><span class="p">(</span><span class="nf">Date.</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="n">*now*</span><span class="p">)</span><span class="w"> </span><span class="c1">; Multiple imports at once.</span><span class="w"> </span><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">java.util</span><span class="w"> </span><span class="n">Date</span><span class="w"> </span><span class="n">Calendar</span><span class="p">)</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">java.net</span><span class="w"> </span><span class="n">URI</span><span class="w"> </span><span class="n">ServerSocket</span><span class="p">)</span><span class="w"> </span><span class="n">java.sql.DriverManager</span><span class="p">)</span><span class="w"> </span><span class="c1">; Import multiple classes in a namespace.</span><span class="w"> </span><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">foo.bar</span><span class="w"> </span><span class="p">(</span><span class="no">:import</span><span class="w"> </span><span class="p">(</span><span class="nf">java.util</span><span class="w"> </span><span class="n">Date</span><span class="w"> </span><span class="n">Calendar</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">java.util.logging</span><span class="w"> </span><span class="n">Logger</span><span class="w"> </span><span class="n">Level</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <h2 id="calling-methods-and-variables-on-a-java-object">Calling methods and variables on a java object</h2> <p>There are two ways, the second syntactic sugar of the first. Below, <code class="language-plaintext highlighter-rouge">imp</code> is a pointer to an ImagePlus:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; java-ish way:</span><span class="w"> </span><span class="p">(</span><span class="nb">.</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">getProcessor</span><span class="p">))</span><span class="w"> </span><span class="c1">; shorter java-ish way:</span><span class="w"> </span><span class="p">(</span><span class="nb">.</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="n">getProcessor</span><span class="p">)</span><span class="w"> </span><span class="c1">; lisp-ish way:</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>To call a method on an object returned by a method call, there is a simplified way:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; double way:</span><span class="w"> </span><span class="p">(</span><span class="nb">.</span><span class="w"> </span><span class="p">(</span><span class="nb">.</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">getProcessor</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">getPixels</span><span class="p">))</span><span class="w"> </span><span class="c1">; simplified double way:</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">getProcessor</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">getPixels</span><span class="p">))</span><span class="w"> </span><span class="c1">; super simplified (less parenthesis than java!)</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="n">getProcessor</span><span class="w"> </span><span class="n">getPixels</span><span class="p">)</span><span class="w"> </span><span class="c1">; or lisp-ish way:</span><span class="w"> </span><span class="p">(</span><span class="nf">.getPixels</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>Any number of concatenated method calls, both for static methods or for instances:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; Concatenated call to static and instance methods</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">WindowManager</span><span class="w"> </span><span class="n">getCurrentImage</span><span class="w"> </span><span class="n">getProcessor</span><span class="w"> </span><span class="n">getPixels</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>To call a variable or ‘field’, just do it like a method call but without the parentheses:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">.</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="n">changes</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>or more lisp-ish:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">.changes</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>To enhance readability, use <code class="language-plaintext highlighter-rouge">import</code> when appropriate. Imports remain visible throughout the current namespace:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">java.awt</span><span class="w"> </span><span class="n">Color</span><span class="w"> </span><span class="n">Rectangle</span><span class="p">)</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij.plugin.filter</span><span class="w"> </span><span class="n">PlugInFilter</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">new</span><span class="w"> </span><span class="n">Rectangle</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">500</span><span class="w"> </span><span class="mi">500</span><span class="p">)</span><span class="w"> </span><span class="c1">; It's the same as:</span><span class="w"> </span><span class="p">(</span><span class="nf">Rectangle.</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">500</span><span class="w"> </span><span class="mi">500</span><span class="p">)</span><span class="w"> </span><span class="c1">; A static field, call like a namespace:</span><span class="w"> </span><span class="n">PlugInFilter/DOES_ALL</span><span class="w"> </span></code></pre></div></div> <p>Choose whatever matches your mental schemes best.</p> <h2 id="calling-static-fields-and-methods-namespace-syntax">Calling static fields and methods: namespace syntax</h2> <p>To call a <code class="language-plaintext highlighter-rouge">static</code> field or method, use namespace syntax:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"does all: "</span><span class="w"> </span><span class="n">ij.plugin.filter.PlugInFilter/DOES_ALL</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.IJ/log</span><span class="w"> </span><span class="s">"Some logged text"</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>Above, notice how a class name is used instead of a pointer to call static fields and methods. Static fields and methods are just variables and functions that exist within the namespace of the class in which they are declared. Hence Clojure’s namespace syntax makes way more sense than java code, that doesn’t do such distinction and allows for loads of confusion (java allows invoking static methods and fields using a pointer to an instance of the class in which such static methods and fields are declared).</p> <h2 id="defining-variables-obtaining-the-current-image">Defining variables: obtaining the current image</h2> <p>As a local variable <code class="language-plaintext highlighter-rouge">imp</code> declared within a <code class="language-plaintext highlighter-rouge">let</code> statement:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.WindowManager/getCurrentImage</span><span class="p">)]</span><span class="w"> </span><span class="c1">; print its name</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nf">.getTitle</span><span class="w"> </span><span class="n">imp</span><span class="p">)))</span><span class="w"> </span><span class="c1">; Variable imp NOT visible from outside let statement:</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nf">.getTitle</span><span class="w"> </span><span class="n">imp</span><span class="p">))</span><span class="w"> </span><span class="n">---></span><span class="w"> </span><span class="n">ERROR</span><span class="w"> </span></code></pre></div></div> <p>As a general variable visible from the entire namespace:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">*imp*</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.WindowManager/getCurrentImage</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nf">.getTitle</span><span class="w"> </span><span class="n">*imp*</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>By convention, in lisp global variables are written with asterisks in the name.</p> <p>A <code class="language-plaintext highlighter-rouge">let</code> statement lets you declare any number of paired variable name / values, even referring to each other in sequence:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.WindowManager/getCurrentImage</span><span class="p">)</span><span class="w"> </span><span class="n">ip</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span><span class="n">pix</span><span class="w"> </span><span class="p">(</span><span class="nf">.getPixels</span><span class="w"> </span><span class="n">ip</span><span class="p">)</span><span class="w"> </span><span class="n">pix2</span><span class="w"> </span><span class="p">(</span><span class="nf">.getPixels</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">))]</span><span class="w"> </span><span class="c1">; do some processing ...</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="s">"number of pixels: "</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="n">pix</span><span class="p">))))</span><span class="w"> </span></code></pre></div></div> <p>Any number of <code class="language-plaintext highlighter-rouge">let</code> statements may be nested together:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.WindowManager/getCurrentImage</span><span class="p">)]</span><span class="w"> </span><span class="c1">; do whatever processing here</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">ip</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">]</span><span class="w"> </span><span class="c1">; print first pixel</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="p">(</span><span class="nf">.getPixel</span><span class="w"> </span><span class="n">ip</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">0</span><span class="p">))))))</span><span class="w"> </span></code></pre></div></div> <h2 id="creating-objects-invoking-constructors">Creating objects: invoking constructors</h2> <p>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):</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">ip</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.process.ByteProcessor.</span><span class="w"> </span><span class="mi">400</span><span class="w"> </span><span class="mi">400</span><span class="p">)</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.ImagePlus.</span><span class="w"> </span><span class="s">"my image"</span><span class="w"> </span><span class="n">ip</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">imp</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>An alternative syntax is to use the java-like <code class="language-plaintext highlighter-rouge">new</code> keyword, but it’s unnecessarily verbose:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">ip</span><span class="w"> </span><span class="p">(</span><span class="nb">new</span><span class="w"> </span><span class="n">ij.process.ByteProcessor</span><span class="w"> </span><span class="mi">400</span><span class="w"> </span><span class="mi">400</span><span class="p">)</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nb">new</span><span class="w"> </span><span class="n">ij.ImagePlus</span><span class="w"> </span><span class="s">"my image"</span><span class="w"> </span><span class="n">ip</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">imp</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <h2 id="defining-a-closure">Defining a closure</h2> <p>In the following a function is declared within the scope of the local variable <code class="language-plaintext highlighter-rouge">rand</code>, which contains an instance of java.util.Random. All calls to the function <code class="language-plaintext highlighter-rouge">rand-double</code> will use the same random number generator instance with seed 69997.</p> <p>The <code class="language-plaintext highlighter-rouge">dotimes</code> loop will then print 10 different pseudo-random numbers. If the <code class="language-plaintext highlighter-rouge">rand</code> was a new Random with seed 69997 every time, all 10 numbers would be exactly the same.</p> <p>You can think of a function inside a closure as a static function using a static variable (in Java), but it’s more than that, since the function will be able to access parameters on the global namespace and also in any other local namespace in which the <code class="language-plaintext highlighter-rouge">let</code> is declared. For example, another <code class="language-plaintext highlighter-rouge">let</code>, or even another <code class="language-plaintext highlighter-rouge">defn</code>!</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="nb">rand</span><span class="w"> </span><span class="p">(</span><span class="nf">java.util.Random.</span><span class="w"> </span><span class="mi">69997</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">rand-double</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">(</span><span class="nf">.nextDouble</span><span class="w"> </span><span class="nb">rand</span><span class="p">)))</span><span class="w"> </span><span class="p">(</span><span class="nb">dotimes</span><span class="w"> </span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="mi">10</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nf">rand-double</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>Above, note the dot ‘.’ after Random, which indicates we are calling the constructor (with a single parameter 69997, the pseudorandom generator seed to be used). Alternatively, one may use the java-like syntax: (new java.util.Random 69997) – note the absence of a dot now.</p> <h2 id="manipulating-images">Manipulating images</h2> <h3 id="imagej-image-internals-imageplus-imageprocessor-imagestack">ImageJ Image internals: ImagePlus, ImageProcessor, ImageStack</h3> <p>ImageJ has three basic objects:</p> <ul> <li>The <a href="https://imagej.net/ij/developer/api/ij/ImagePlus.html"><code class="language-plaintext highlighter-rouge">ImagePlus</code></a>, which wraps the ImageProcessor and contains properties and pointers to the ROI (region of interest) and the ImageWindow that may be displaying the image.</li> <li>The <a href="https://imagej.net/ij/developer/api/ij/process/ImageProcessor.html"><code class="language-plaintext highlighter-rouge">ImageProcessor</code></a>, which is an abstract class enabling the high-level manipulation of and access to pixels. Its subclasses each wraps a different kind of data type: <ul> <li><code class="language-plaintext highlighter-rouge">ByteProcessor</code> - <code class="language-plaintext highlighter-rouge">byte[]</code></li> <li><code class="language-plaintext highlighter-rouge">ShortProcessor</code> - <code class="language-plaintext highlighter-rouge">short[]</code></li> <li><code class="language-plaintext highlighter-rouge">FloatProcessor</code> - <code class="language-plaintext highlighter-rouge">float[]</code></li> <li><code class="language-plaintext highlighter-rouge">ColorProcessor</code> - <code class="language-plaintext highlighter-rouge">int[]</code> (byte-packed ARGB, but Alpha channel is ignored)</li> </ul> </li> <li>The <a href="https://imagej.net/ij/developer/api/ij/ImageStack.html"><code class="language-plaintext highlighter-rouge">ImageStack</code></a> which contains unfortunately not an array of <code class="language-plaintext highlighter-rouge">ImageProcessor,</code> but an <code class="language-plaintext highlighter-rouge">Object[]</code> containing an homogeneous list of equal length <code class="language-plaintext highlighter-rouge">byte[]</code>, or <code class="language-plaintext highlighter-rouge">float[]</code>, etc.</li> </ul> <p>For extensive documentation, see the <a href="http://albert.rierol.net/imagej_programming_tutorials.html#ImageJ%20programming%20basics">Anatomy of an ImageJ image</a> ImageJ programming basics tutorial.</p> <h3 id="conventions-in-naming-image-variables">Conventions in naming image variables</h3> <p>By convention, variables are named:</p> <ul> <li><code class="language-plaintext highlighter-rouge">imp</code> to mean ImagePlus</li> <li><code class="language-plaintext highlighter-rouge">ip</code> to mean ImageProcessor</li> <li><code class="language-plaintext highlighter-rouge">stack</code> to mean ImageStack</li> </ul> <h3 id="creating-a-new-image">Creating a new image</h3> <p>From scratch:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij</span><span class="w"> </span><span class="n">ImagePlus</span><span class="p">)</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij.process</span><span class="w"> </span><span class="n">ByteProcessor</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="s">"A new image"</span><span class="w"> </span><span class="p">(</span><span class="nf">ByteProcessor.</span><span class="w"> </span><span class="mi">400</span><span class="w"> </span><span class="mi">400</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="n">imp</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>From a file:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/openImage</span><span class="w"> </span><span class="s">"/path/to/an/image.tif"</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="n">imp</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <h3 id="creating-an-image-of-the-same-type-of-an-existing-one">Creating an image of the same type of an existing one</h3> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; The original</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-1</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="s">"The source image"</span><span class="w"> </span><span class="p">(</span><span class="nf">FloatProcessor.</span><span class="w"> </span><span class="mi">512</span><span class="w"> </span><span class="mi">512</span><span class="p">)))</span><span class="w"> </span><span class="c1">; The new empty image, of the same type as the old but larger</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-2</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="s">"The larger image of the same type"</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">imp-1</span><span class="w"> </span><span class="n">getProcessor</span><span class="w"> </span><span class="p">(</span><span class="nf">createProcessor</span><span class="w"> </span><span class="mi">768</span><span class="w"> </span><span class="mi">768</span><span class="p">))))</span><span class="w"> </span></code></pre></div></div> <p>Above, notice the parenthesis (createProcessor 768 768), which specify for which method those numbers are arguments for.</p> <h3 id="resizing-an-image">Resizing an image</h3> <p>The idea is to grab the ImageProcessor, duplicate it and resize it. The resizing returns a new ImageProcessor of the same type:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-1</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/openImage</span><span class="w"> </span><span class="s">"/path/to/image1.tif"</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-2</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="s">"A new larger one"</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">imp-1</span><span class="w"> </span><span class="n">getProcessor</span><span class="w"> </span><span class="p">(</span><span class="nf">createProcessor</span><span class="w"> </span><span class="mi">1024</span><span class="w"> </span><span class="mi">1024</span><span class="p">))))</span><span class="w"> </span><span class="c1">; Copy one into the other at top-left (hence 0,0 insert point):</span><span class="w"> </span><span class="p">(</span><span class="nb">doto</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp-2</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.insert</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp-1</span><span class="p">)</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">0</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>An alternative way would be to simply duplicate the processor of imp-1, and then enlarge it:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-3</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="s">"A copy with extra empty space"</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">imp-1</span><span class="w"> </span><span class="n">getProcessor</span><span class="w"> </span><span class="n">duplicate</span><span class="w"> </span><span class="p">(</span><span class="nf">resize</span><span class="w"> </span><span class="mi">768</span><span class="w"> </span><span class="mi">768</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <h3 id="resizing-an-imagestack">Resizing an ImageStack</h3> <p>This one is harder, because an ImageStack is just a wrapper for Object[] list of pixel arrays. ImageJ though provides a mid-level resizing method, via the <a href="https://imagej.net/ij/developer/api/ij/plugin/CanvasResizer.html">CanvasResizer</a> class:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij.plugin</span><span class="w"> </span><span class="n">CanvasResizer</span><span class="p">)</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij</span><span class="w"> </span><span class="n">IJ</span><span class="w"> </span><span class="n">ImagePlus</span><span class="p">))</span><span class="w"> </span><span class="c1">; Grab the image in the currently active ImageWindow:</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-1</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="c1">; function to resize images:</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">resize-image</span><span class="w"> </span><span class="s">"Takes an ImagePlus as argument and returns a new ImagePlus but resized to width,height, and with the contents copied starting from xoff,yoff"</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">xoff</span><span class="w"> </span><span class="n">yoff</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">resizer</span><span class="w"> </span><span class="p">(</span><span class="nf">CanvasResizer.</span><span class="p">)</span><span class="w"> </span><span class="n">stack</span><span class="w"> </span><span class="p">(</span><span class="nf">.getStack</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span><span class="n">imp-2</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="p">(</span><span class="nf">.getTitle</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="n">stack</span><span class="w"> </span><span class="p">(</span><span class="nf">.expandStack</span><span class="w"> </span><span class="n">resizer</span><span class="w"> </span><span class="n">stack</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">xoff</span><span class="w"> </span><span class="n">yoff</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.expandProcessor</span><span class="w"> </span><span class="n">resizer</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">xoff</span><span class="w"> </span><span class="n">yoff</span><span class="p">)))]</span><span class="w"> </span><span class="n">imp-2</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-2</span><span class="w"> </span><span class="p">(</span><span class="nf">resize-image</span><span class="w"> </span><span class="n">imp-1</span><span class="w"> </span><span class="mi">1024</span><span class="w"> </span><span class="mi">1024</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">0</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="n">imp-2</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>Note that the above function <code class="language-plaintext highlighter-rouge">resize-image</code> will work for both stacks and non-stack images.</p> <p>Of course nothing stops you from looping through the stack length, calling a new ImageProcessor for each slice, resizing it, composing a new ImageStack and with it a new ImagePlus.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; Grab the image in the currently active ImageWindow:</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-1</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">resize-stack</span><span class="w"> </span><span class="s">"Resize an ImageStack to new widht,height and copy its contents starting at xoff,yoff coordinate."</span><span class="w"> </span><span class="p">[</span><span class="n">stack</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">xoff</span><span class="w"> </span><span class="n">yoff</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">new-stack</span><span class="w"> </span><span class="p">(</span><span class="nf">ImageStack.</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">nil</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">(</span><span class="nf">.getSize</span><span class="w"> </span><span class="n">stack</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">ip</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">stack</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="mi">1</span><span class="p">))</span><span class="w"> </span><span class="o">#^</span><span class="n">ImageProcessor</span><span class="w"> </span><span class="n">ip2</span><span class="w"> </span><span class="p">(</span><span class="nf">.createProcessor</span><span class="w"> </span><span class="n">ip</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="n">h</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nf">.insert</span><span class="w"> </span><span class="n">ip2</span><span class="w"> </span><span class="n">ip</span><span class="w"> </span><span class="n">xoff</span><span class="w"> </span><span class="n">yoff</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.addSlice</span><span class="w"> </span><span class="n">new-stack</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="n">ip2</span><span class="p">)))</span><span class="w"> </span><span class="n">new-stack</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>Above, note that <em>stacks are 1-based,not 0-based!</em></p> <p>Also, we must declare the type of the <code class="language-plaintext highlighter-rouge">ip2</code> because clojure cannot decide between the ImageProcessor.addSlice(String,ImageProcessor) and ImageProcessor.addSlice(String,Object). You must make that choice for clojure.</p> <p>Notice that each time you call getProcessor on an ImageStack, it returns a new ImageProcessor instance in a very costly way, by calling a series of <code class="language-plaintext highlighter-rouge">instanceof</code> on the pixels arrays to figure out which kind of ImageProcessor subclass it should create.</p> <h3 id="resizing-an-image-or-imagestack-using-rois">Resizing an image or ImageStack using ROIs</h3> <p>ROIs (aka Region of Interest or selection) have bounds, defined by the minimal enclosing rectangle.</p> <p>The core idea is to set a ROI to an ImageProcessor and call <code class="language-plaintext highlighter-rouge">crop</code> to obtain a new, subcopy of it.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-cropped</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="s">"Cropped"</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">ip</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nf">.setRoi</span><span class="w"> </span><span class="n">ip</span><span class="w"> </span><span class="p">(</span><span class="nf">Roi.</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="mi">200</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">.crop</span><span class="w"> </span><span class="n">ip</span><span class="p">))))</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="n">imp-cropped</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>To handle any ImagePlus (with single slice or containing an ImageStack, i.e. many slices), see this function:</p> <p>(which assumes the ROI is contained fully within the image; otherwise for stacks it will throw an Exception stating that, rightly, dimensions do not match.)</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij.gui</span><span class="w"> </span><span class="n">Roi</span><span class="p">)</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij</span><span class="w"> </span><span class="n">ImagePlus</span><span class="p">)</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">ij.process</span><span class="w"> </span><span class="n">ImageProcessor</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">crop-image</span><span class="w"> </span><span class="s">"Crop an image by the bounds of a ROI, returning a new ImagePlus with the result."</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="n">roi</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">crop-processor</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[</span><span class="n">ip</span><span class="w"> </span><span class="n">roi</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">.setRoi</span><span class="w"> </span><span class="n">ip</span><span class="w"> </span><span class="n">roi</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.crop</span><span class="w"> </span><span class="n">ip</span><span class="p">))</span><span class="w"> </span><span class="n">stack</span><span class="w"> </span><span class="p">(</span><span class="nf">.getStack</span><span class="w"> </span><span class="n">imp</span><span class="p">)]</span><span class="w"> </span><span class="c1">; Return a new ImagePlus with a new cropped ImageProcessor</span><span class="w"> </span><span class="c1">; or a new cropped ImageStack:</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="p">(</span><span class="nf">.getTitle</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="n">stack</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">box</span><span class="w"> </span><span class="p">(</span><span class="nf">.getBounds</span><span class="w"> </span><span class="n">roi</span><span class="p">)</span><span class="w"> </span><span class="n">new-stack</span><span class="w"> </span><span class="p">(</span><span class="nf">ImageStack.</span><span class="w"> </span><span class="p">(</span><span class="nf">.width</span><span class="w"> </span><span class="n">box</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.height</span><span class="w"> </span><span class="n">box</span><span class="p">)</span><span class="w"> </span><span class="n">nil</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="p">(</span><span class="nf">.getSize</span><span class="w"> </span><span class="n">stack</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="nf">.addSlice</span><span class="w"> </span><span class="n">new-stack</span><span class="w"> </span><span class="p">(</span><span class="nf">.getSliceLabel</span><span class="w"> </span><span class="n">stack</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="mi">1</span><span class="p">))</span><span class="w"> </span><span class="o">#^</span><span class="n">ImageProcessor</span><span class="w"> </span><span class="p">(</span><span class="nf">crop-processor</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">stack</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="mi">1</span><span class="p">))</span><span class="w"> </span><span class="n">roi</span><span class="p">)))</span><span class="w"> </span><span class="n">new-stack</span><span class="p">)</span><span class="w"> </span><span class="c1">; Else single slice image:</span><span class="w"> </span><span class="p">(</span><span class="nf">crop-processor</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span><span class="n">roi</span><span class="p">)))))</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">imp-cropped</span><span class="w"> </span><span class="p">(</span><span class="nf">crop-image</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">Roi.</span><span class="w"> </span><span class="mi">100</span><span class="w"> </span><span class="mi">100</span><span class="w"> </span><span class="mi">300</span><span class="w"> </span><span class="mi">300</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="n">imp-cropped</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>The above works with both single images and stacks.</p> <h2 id="manipulate-images-using-imglib">Manipulate images using ImgLib</h2> <p>With <a href="/libs/imglib1">Imglib</a>, pixels are stored in native arrays of primitives such as int, float, double, etc. (or other more interesting forms, such as <a href="http://download.oracle.com/javase/1.5.0/docs/api/java/awt/Shape.html">Shape</a>. Such pixels are accessed with intermediate proxy objects that the JIT is able to completely remove out of the way.</p> <p>From Clojure, there are many ways in which to access the pixels. Here we list some examples of the pixels accessed as a Collection of accessor <a href="https://fiji.sc/javadoc/mpicbg/imglib/type/Type.html">Type</a> objects.</p> <h3 id="multiply-each-pixel-by-05">Multiply each pixel by 0.5</h3> <p>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.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; ASSUMES the current image is 32-bit</span><span class="w"> </span><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">test.imglib</span><span class="w"> </span><span class="p">(</span><span class="no">:import</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.image</span><span class="w"> </span><span class="n">Image</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">script.imglib</span><span class="w"> </span><span class="n">ImgLib</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.type.numeric.real</span><span class="w"> </span><span class="n">FloatType</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">ij</span><span class="w"> </span><span class="n">IJ</span><span class="p">]))</span><span class="w"> </span><span class="p">(</span><span class="nf">set!</span><span class="w"> </span><span class="n">*warn-on-reflection*</span><span class="w"> </span><span class="n">true</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="mf">0.5</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">FloatType</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">img</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">.mul</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">a</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>In a more functional style, below we create an image with the same dimensions as the wrapped image, and set its pixel values to those of the original image times 0.5:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">test.imglib</span><span class="w"> </span><span class="p">(</span><span class="no">:import</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.image</span><span class="w"> </span><span class="n">Image</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.cursor</span><span class="w"> </span><span class="n">Cursor</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">script.imglib</span><span class="w"> </span><span class="n">ImgLib</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.type.numeric</span><span class="w"> </span><span class="n">NumericType</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">ij</span><span class="w"> </span><span class="n">IJ</span><span class="p">]))</span><span class="w"> </span><span class="p">(</span><span class="nf">set!</span><span class="w"> </span><span class="n">*warn-on-reflection*</span><span class="w"> </span><span class="n">true</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="mf">0.5</span><span class="p">)</span><span class="w"> </span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">copy</span><span class="w"> </span><span class="p">(</span><span class="nf">.createNewImage</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="s">"copy"</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">with-open</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">Cursor</span><span class="w"> </span><span class="n">c1</span><span class="w"> </span><span class="p">(</span><span class="nf">.createCursor</span><span class="w"> </span><span class="n">img</span><span class="p">)</span><span class="w"> </span><span class="o">^</span><span class="n">Cursor</span><span class="w"> </span><span class="n">c2</span><span class="w"> </span><span class="p">(</span><span class="nf">.createCursor</span><span class="w"> </span><span class="n">copy</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">loop</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nf">.hasNext</span><span class="w"> </span><span class="n">c1</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">do</span><span class="w"> </span><span class="p">(</span><span class="nf">.fwd</span><span class="w"> </span><span class="n">c1</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.fwd</span><span class="w"> </span><span class="n">c2</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">NumericType</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="p">(</span><span class="nf">.getType</span><span class="w"> </span><span class="n">c1</span><span class="p">)</span><span class="w"> </span><span class="o">^</span><span class="n">NumericType</span><span class="w"> </span><span class="n">t2</span><span class="w"> </span><span class="p">(</span><span class="nf">.getType</span><span class="w"> </span><span class="n">c2</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nf">.set</span><span class="w"> </span><span class="n">t2</span><span class="w"> </span><span class="n">t1</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.mul</span><span class="w"> </span><span class="n">t2</span><span class="w"> </span><span class="n">a</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">recur</span><span class="p">)))))</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">copy</span><span class="w"> </span><span class="n">getDisplay</span><span class="w"> </span><span class="n">setMinMax</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="n">copy</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>The above, though, is unbearably verbose. A high-level access to the images enables mathematical operations without trading off any performance:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">test.imglib</span><span class="w"> </span><span class="p">(</span><span class="no">:import</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.image</span><span class="w"> </span><span class="n">Image</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.cursor</span><span class="w"> </span><span class="n">Cursor</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">script.imglib</span><span class="w"> </span><span class="n">ImgLib</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">script.imglib.math</span><span class="w"> </span><span class="n">Compute</span><span class="w"> </span><span class="n">Multiply</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">ij</span><span class="w"> </span><span class="n">IJ</span><span class="p">]))</span><span class="w"> </span><span class="p">(</span><span class="nf">set!</span><span class="w"> </span><span class="n">*warn-on-reflection*</span><span class="w"> </span><span class="n">true</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">copy</span><span class="w"> </span><span class="p">(</span><span class="nf">Compute/inFloats</span><span class="w"> </span><span class="p">(</span><span class="nf">Multiply.</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="mf">0.5</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">copy</span><span class="w"> </span><span class="n">getDisplay</span><span class="w"> </span><span class="n">setMinMax</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="n">copy</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>What’s more, the <a href="https://fiji.sc/javadoc/script/imglib/math/Compute.html">Compute</a>/inFloats method runs in parallel, with as many processors as your machine has cores. If you’d rather not execute the operation in parallel, add the desired number of threads as an argument to <code class="language-plaintext highlighter-rouge">inFloats</code>.</p> <p>All mathematical operations listed in java.lang.Math have a corresponding constructor for execution in Compute/inFloats. See the documentation for the <a href="https://fiji.sc/javadoc/script/imglib/math/package-frame.html">script.imglib.math package</a>.</p> <h3 id="normalize-an-image">Normalize an image</h3> <p>Assumes that <code class="language-plaintext highlighter-rouge">(IJ/getImage)</code> returns a 32-bit, float image. If that is not the case, convert the image to a float image first.</p> <p>The example below creates a new result image. The original image is untouched. This is accomplished with minimal friction but best performance (like hand-coded with cursors or better) by using the high-level scripting library of imglib, and the <a href="https://fiji.sc/javadoc/script/imglib/math/Compute.html">Compute</a>/inFloats method.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">test.imglib</span><span class="w"> </span><span class="p">(</span><span class="no">:import</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.image</span><span class="w"> </span><span class="n">Image</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">script.imglib</span><span class="w"> </span><span class="n">ImgLib</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">script.imglib.math</span><span class="w"> </span><span class="n">Compute</span><span class="w"> </span><span class="n">Subtract</span><span class="w"> </span><span class="n">Divide</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">ij</span><span class="w"> </span><span class="n">IJ</span><span class="p">]))</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="p">(</span><span class="nf">.size</span><span class="w"> </span><span class="n">img</span><span class="p">)</span><span class="w"> </span><span class="n">mean</span><span class="w"> </span><span class="p">(</span><span class="nb">reduce</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">%1</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="p">(</span><span class="nf">.getRealFloat</span><span class="w"> </span><span class="n">%2</span><span class="p">)</span><span class="w"> </span><span class="n">size</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="n">img</span><span class="p">)</span><span class="w"> </span><span class="n">variance</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="p">(</span><span class="nb">reduce</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">%1</span><span class="w"> </span><span class="p">(</span><span class="nf">Math/pow</span><span class="w"> </span><span class="p">(</span><span class="nb">-</span><span class="w"> </span><span class="p">(</span><span class="nf">.getRealFloat</span><span class="w"> </span><span class="n">%2</span><span class="p">)</span><span class="w"> </span><span class="n">mean</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="mi">2</span><span class="p">)))</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="n">img</span><span class="p">)</span><span class="w"> </span><span class="n">size</span><span class="p">)</span><span class="w"> </span><span class="n">std-dev</span><span class="w"> </span><span class="p">(</span><span class="nf">Math/sqrt</span><span class="w"> </span><span class="n">variance</span><span class="p">)</span><span class="w"> </span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="p">(</span><span class="nf">Compute/inFloats</span><span class="w"> </span><span class="p">(</span><span class="nf">Divide.</span><span class="w"> </span><span class="p">(</span><span class="nf">Subtract.</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="n">mean</span><span class="p">)</span><span class="w"> </span><span class="n">std-dev</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="n">getDisplay</span><span class="w"> </span><span class="n">setMinMax</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="n">normalized</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>There is a better way to compute the mean and variance of a collection of numbers, that involves traversing the collection only once. Clojure naturally helps with its very concise destructuring and its automatic promotion of numeric types to avoid overflow.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">test.imglib</span><span class="w"> </span><span class="p">(</span><span class="no">:import</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.image</span><span class="w"> </span><span class="n">Image</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">mpicbg.imglib.type.numeric</span><span class="w"> </span><span class="n">RealType</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">script.imglib</span><span class="w"> </span><span class="n">ImgLib</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">script.imglib.math</span><span class="w"> </span><span class="n">Compute</span><span class="w"> </span><span class="n">Subtract</span><span class="w"> </span><span class="n">Divide</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">ij</span><span class="w"> </span><span class="n">IJ</span><span class="p">]))</span><span class="w"> </span><span class="p">(</span><span class="nf">set!</span><span class="w"> </span><span class="n">*warn-on-reflection*</span><span class="w"> </span><span class="n">true</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="p">(</span><span class="nf">IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="p">(</span><span class="nf">.size</span><span class="w"> </span><span class="n">img</span><span class="p">)</span><span class="w"> </span><span class="p">[</span><span class="n">xs</span><span class="w"> </span><span class="n">x2s</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">reduce</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[</span><span class="n">accum</span><span class="w"> </span><span class="o">^</span><span class="n">RealType</span><span class="w"> </span><span class="n">t</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">xi</span><span class="w"> </span><span class="p">(</span><span class="nf">.getRealFloat</span><span class="w"> </span><span class="n">t</span><span class="p">)]</span><span class="w"> </span><span class="p">[(</span><span class="nb">+</span><span class="w"> </span><span class="p">(</span><span class="nf">accum</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="n">xi</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="p">(</span><span class="nf">accum</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="n">xi</span><span class="w"> </span><span class="n">xi</span><span class="p">))]))</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="n">img</span><span class="p">)</span><span class="w"> </span><span class="n">mean</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="n">size</span><span class="p">)</span><span class="w"> </span><span class="n">variance</span><span class="w"> </span><span class="p">(</span><span class="nb">-</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="n">x2s</span><span class="w"> </span><span class="n">size</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="n">mean</span><span class="w"> </span><span class="n">mean</span><span class="p">))</span><span class="w"> </span><span class="n">std-dev</span><span class="w"> </span><span class="p">(</span><span class="nf">Math/sqrt</span><span class="w"> </span><span class="n">variance</span><span class="p">)</span><span class="w"> </span><span class="o">^</span><span class="n">Image</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="p">(</span><span class="nf">Compute/inFloats</span><span class="w"> </span><span class="p">(</span><span class="nf">Divide.</span><span class="w"> </span><span class="p">(</span><span class="nf">Subtract.</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="n">mean</span><span class="p">)</span><span class="w"> </span><span class="n">std-dev</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">normalized</span><span class="w"> </span><span class="n">getDisplay</span><span class="w"> </span><span class="n">setMinMax</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="p">(</span><span class="nf">ImgLib/wrap</span><span class="w"> </span><span class="n">normalized</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>(Code adapted from a Common Lisp version by <a href="http://nklein.com/2011/02/calculating-the-mean-and-variance-with-one-pass/">Patrick Stein</a>.)</p> <h2 id="looping-an-array-of-pixels">Looping an array of pixels</h2> <p>For example, to find the min and max values:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; Obtain the pixels array from the current image</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.WindowManager/getCurrentImage</span><span class="p">)</span><span class="w"> </span><span class="n">pixels</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="n">getProcessor</span><span class="w"> </span><span class="n">getPixels</span><span class="p">)</span><span class="w"> </span><span class="nb">min</span><span class="w"> </span><span class="p">(</span><span class="nb">apply</span><span class="w"> </span><span class="nb">min</span><span class="w"> </span><span class="n">pixels</span><span class="p">)</span><span class="w"> </span><span class="nb">max</span><span class="w"> </span><span class="p">(</span><span class="nb">apply</span><span class="w"> </span><span class="nb">max</span><span class="w"> </span><span class="n">pixels</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="s">"min: "</span><span class="w"> </span><span class="nb">min</span><span class="w"> </span><span class="s">", max: "</span><span class="w"> </span><span class="nb">max</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>The above code does not explicitly loop the pixels: it simply applies a function to an array.</p> <p>To loop pixels one by one, use any of the following:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.WindowManager/getCurrentImage</span><span class="p">)</span><span class="w"> </span><span class="n">pixels</span><span class="w"> </span><span class="p">(</span><span class="nb">..</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="n">getProcessor</span><span class="w"> </span><span class="n">getPixels</span><span class="p">)]</span><span class="w"> </span><span class="c1">; First loop with "dotimes"</span><span class="w"> </span><span class="p">(</span><span class="nb">dotimes</span><span class="w"> </span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="n">pixels</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nb">aget</span><span class="w"> </span><span class="n">pixels</span><span class="w"> </span><span class="n">i</span><span class="p">)))</span><span class="w"> </span><span class="c1">; Second loop: with "loop -- recur"</span><span class="w"> </span><span class="p">(</span><span class="nb">loop</span><span class="w"> </span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="n">pixels</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb"><</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">len</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">do</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="s">": "</span><span class="w"> </span><span class="p">(</span><span class="nb">aget</span><span class="w"> </span><span class="n">pixels</span><span class="w"> </span><span class="n">i</span><span class="p">)))</span><span class="w"> </span><span class="p">(</span><span class="nf">recur</span><span class="w"> </span><span class="p">(</span><span class="nb">inc</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="n">len</span><span class="p">)))))</span><span class="w"> </span></code></pre></div></div> <p>Above, notice that the <code class="language-plaintext highlighter-rouge">loop -- recur</code> construct is essentially a <code class="language-plaintext highlighter-rouge">let</code> declaration, with a second call (<code class="language-plaintext highlighter-rouge">recur</code>) to reset the variables to something else. In this case, the next index in the array. Note how the len is simply given the same value over and over, just to avoid calling <code class="language-plaintext highlighter-rouge">(count pixels)</code> at each iteration.</p> <p>Of course, there are lispier ways to loop an array of pixels. For example, to obtain the average of all pixels, we can use function <code class="language-plaintext highlighter-rouge">reduce</code>, which takes the first two elements of a list, applies a function to them, and then applies the function to the result and the next element, etc:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">fp</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="n">pix</span><span class="w"> </span><span class="p">(</span><span class="nf">.getPixels</span><span class="w"> </span><span class="n">fp</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">instance?</span><span class="w"> </span><span class="n">ij.process.FloatProcessor</span><span class="w"> </span><span class="n">fp</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Average pixel intensity"</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="p">(</span><span class="nb">reduce</span><span class="w"> </span><span class="nb">+</span><span class="w"> </span><span class="n">pix</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="n">pix</span><span class="p">)))</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Not a 32-bit image"</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>Above, notice that one could have used also <code class="language-plaintext highlighter-rouge">apply</code> to apply <code class="language-plaintext highlighter-rouge">+</code> to all element of an array, with the same result:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Average pixel intensity"</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="p">(</span><span class="nb">apply</span><span class="w"> </span><span class="nb">+</span><span class="w"> </span><span class="n">pix</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="n">pix</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>To sum all pixels in an 8-bit image, one needs first to bit-and all bytes to 255, so they become integers and can be summed. But of course we should not <code class="language-plaintext highlighter-rouge">bit-and</code> the sum! To solve this, <code class="language-plaintext highlighter-rouge">reduce</code> accepts a first value (in this case, zero):</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">bp</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="n">pix</span><span class="w"> </span><span class="p">(</span><span class="nf">.getPixels</span><span class="w"> </span><span class="n">bp</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">instance?</span><span class="w"> </span><span class="n">ij.process.ByteProcessor</span><span class="w"> </span><span class="n">bp</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Average intensity: "</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="p">(</span><span class="nb">reduce</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[</span><span class="n">x1</span><span class="w"> </span><span class="n">x2</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">x1</span><span class="w"> </span><span class="p">(</span><span class="nb">bit-and</span><span class="w"> </span><span class="n">x2</span><span class="w"> </span><span class="mi">255</span><span class="p">)))</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">pix</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="n">pix</span><span class="p">))))</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Not an 8-bit image"</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>It could even be done using a local variable, but it’s ugly and undesirable (why create it when it’s not really needed)? Notice we need to create the local variable “sum” because variables declared by <code class="language-plaintext highlighter-rouge">let</code> are immutable.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">bp</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.IJ/getImage</span><span class="p">))</span><span class="w"> </span><span class="n">pix</span><span class="w"> </span><span class="p">(</span><span class="nf">.getPixels</span><span class="w"> </span><span class="n">bp</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">instance?</span><span class="w"> </span><span class="n">ij.process.ByteProcessor</span><span class="w"> </span><span class="n">bp</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">with-local-vars</span><span class="w"> </span><span class="p">(</span><span class="nf">sum</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="n">pixel</span><span class="w"> </span><span class="n">pix</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">var-set</span><span class="w"> </span><span class="n">sum</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="p">(</span><span class="nb">var-get</span><span class="w"> </span><span class="n">sum</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">bit-and</span><span class="w"> </span><span class="n">pixel</span><span class="w"> </span><span class="mi">255</span><span class="p">))))</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="p">(</span><span class="nb">var-get</span><span class="w"> </span><span class="n">sum</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="n">pix</span><span class="p">)))))</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Not an 8-bit image"</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <h2 id="executing-commands-from-the-menus">Executing commands from the menus</h2> <p>Any ImageJ menu command may be run on the active image:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">ij.IJ/doCommand</span><span class="w"> </span><span class="s">"Add Noise"</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>Be aware that the above starts a new Thread and forks. For reliable control, try the run method, which will wait until the plugin finishes execution.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">ij.IJ/run</span><span class="w"> </span><span class="s">"Add Noise"</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>For even more reliable control, run the command directly on a specified image, instead of a possibly changing current image:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.IJ/getImage</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.IJ/run</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="s">"Subtract..."</span><span class="w"> </span><span class="s">"value=25"</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>To find out which arguments can any command accept, open the Plugins - Macros - Macro Recorder and run the command manually.</p> <h2 id="creating-and-using-clojure-scripts-as-imagej-plugins">Creating and using Clojure scripts as ImageJ plugins</h2> <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>If the macros/StartupMacros.txt includes a call to the Refresh Clojure Scripts inside the AutoRun macro, then all your Clojure scripts will appear automatically on startup.</p> <p>To modify an script which exists already as a menu item, simply edit its file and run it by selecting it from the menus. No compiling necessary, and no need to call Refresh Clojure Scripts either (ther latter only for new scripts or at start up.)</p> <div class="notice" style="font-size: 2; background: #ffcccb; border-left: 10px solid #f57900"><div class="notice-icon"><img src="/media/icons/warning.png" /></div><div class="notice-content"><p>All scripts and commands from the interpreter will run within the same thread, and within the same clojure context.</p> </div> </div> <h2 id="using-java-beans-for-quick-and-convenient-access-to-an-objects-fields">Using java beans for quick and convenient access to an object’s fields</h2> <p>Essentially it’s all about using <code class="language-plaintext highlighter-rouge">get</code> methods in a trivial way. For example:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.WindowManager/getCurrentImage</span><span class="p">)</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">(</span><span class="nb">bean</span><span class="w"> </span><span class="n">imp</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="no">:title</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="no">:width</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="no">:height</span><span class="w"> </span><span class="n">b</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>Eventually Clojure may add support for <code class="language-plaintext highlighter-rouge">set</code> methods as well.</p> <h1> Examples </h1> <h2 id="fixing-overexposed-images-setting-a-pixel-value-to-a-desirable-one-for-all-overexposed-pixels">Fixing overexposed images: setting a pixel value to a desirable one for all overexposed pixels</h2> <p>The problem: <a href="http://ami.scripps.edu/software/leginon/">Leginon</a> or the Gatan TEM camera acquired an overexposed image, and set all pixels beyond range to zero.</p> <p>The solution: iterate all pixels; if the pixel is zero then set it to a desirable value, such as the maximum value of the main curve in the histogram (push ‘auto’ on the Brightness and Contrast dialog to see it.)</p> <p>In the example below, the <code class="language-plaintext highlighter-rouge">fix</code> function is called with the current image and the value 32500 as a floating point number. Notice also the type definition (which is optional) of the float pixel array, to enhance execution speed:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; Assumes a FloatProcessor image</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">fix</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="nb">max</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="o">#^</span><span class="n">floats</span><span class="w"> </span><span class="n">pix</span><span class="w"> </span><span class="p">(</span><span class="nf">.getPixels</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="nb">loop</span><span class="w"> </span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="p">(</span><span class="nb">int</span><span class="w"> </span><span class="mi">0</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb"><</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="p">(</span><span class="nb">alength</span><span class="w"> </span><span class="n">pix</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">do</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">(</span><span class="nb">aget</span><span class="w"> </span><span class="n">pix</span><span class="w"> </span><span class="n">i</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">aset</span><span class="w"> </span><span class="n">pix</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="nb">max</span><span class="p">)))</span><span class="w"> </span><span class="p">(</span><span class="nf">recur</span><span class="w"> </span><span class="p">(</span><span class="nb">inc</span><span class="w"> </span><span class="n">i</span><span class="p">)))))))</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.IJ/getImage</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nf">fix</span><span class="w"> </span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="mi">32500</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">.updateAndDraw</span><span class="w"> </span><span class="n">imp</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <h2 id="creating-a-script-for-imagej">Creating a script for ImageJ</h2> <p>Simply write the clojure script in a text file, and follow these conventions:</p> <ol> <li>Add an underscore <code class="language-plaintext highlighter-rouge">_</code> to its file name, and the extension <code class="language-plaintext highlighter-rouge">.clj</code>: <code class="language-plaintext highlighter-rouge">fix_leginon_images.clj</code></li> <li>Save it under <code class="language-plaintext highlighter-rouge">fiji/plugins/</code> folder, or a subfolder.</li> </ol> <p>When done, just run the <span class="bc"><span>PlugIns</span> › <span>Scripting</span> › <span>Refresh Clojure Scripts</span></span> plugin.</p> <p>Once saved and in the menus, you need <em>not</em> call refresh scripts ever again for that script. Just edit and save it’s text file, and run it again from the menus. Next time ImageJ2 opens, the script will automatically appear in the menus.</p> <p>See <a href="/scripting">Scripting Help</a> for more details, including how to use the built-in dynamic interpreter.</p> <h2 id="example-clojure-plugins-included-in-fiji">Example Clojure plugins included in Fiji</h2> <p>The <a href="/software/fiji">Fiji</a> distribution of ImageJ2 includes some Clojure examples:</p> <ul> <li><a href="https://github.com/fiji/fiji/blob/master/plugins/Examples/Multithreaded_Image_Processing.clj">Multithreaded_Image_Processing.clj</a>: illustrate, with macros (via <a href="http://clojure.org/macros#toc9">defmacro</a>), how to automatically multithread the processing of an image using arbitrary subdivision of the image, such as one line per thread, for as many threads as cores the CPU has.</li> <li><a href="https://github.com/fiji/fiji/blob/master/plugins/Examples/blend_two_images.clj">blend_two_images.clj</a>: illustrates how to open two images from an URL, and blend the gray image into each channel of the color image.</li> <li><a href="https://github.com/fiji/fiji/blob/master/plugins/Examples/celsius_to_fahrenheit.clj">celsius_to_fahrenheit.clj</a>: illustrates the usage of a Swing GUI, and how to instantiate anonymous classes from an interface (via <a href="http://clojure.org/java_interop#toc20">proxy</a> Clojure function). This example is taken from the <a href="http://clojure.org/jvm_hosted">Clojure website</a>.</li> <li><a href="https://github.com/fiji/fiji/blob/master/plugins/Examples/random_noise_example.clj">random_noise_example.clj</a>: illustrates how to declare a function inside a closure (for private access to, in this case, a unique instance of a random number generator), and then fill all pixels of a ByteProcessor image with a random byte value.</li> <li><a href="https://github.com/fiji/fiji/blob/master/plugins/Examples/Command_Launchers/Command_Launcher_Clojure.clj">Command_Launcher_Clojure.clj</a>: illustrates how to create a GUI with a KeyListener, so that the typed text changes color from red to black when it matches the name of an ImageJ command. This example is also under the <a href="/scripting/comparisons">Scripting comparisons</a>, along equivalent versions written in Java, <a href="/scripting/jython">Jython</a>, <a href="/scripting/javascript">Javascript</a> and <a href="/scripting/jruby">JRuby</a>.</li> <li><a href="https://github.com/fiji/fiji/blob/master/plugins/Analyze/Dynamic_ROI_Profiler.clj">Dynamic ROI Profiler</a>: illustrates how to add a MouseMotionListener and a WindowListener to an ImageWindow of an open image. Reads out the ROI (Region Of Interest), and if it’s a line, polyline or rectangle, plots the profile of pixel intensity along the line. As the mouse moves or edits the ROI on the image, the profile is updated.</li> </ul> <h1> Appendix </h1> <h2 id="defining-the-output-stream">Defining the output stream</h2> <p>The default output stream is at variable <code class="language-plaintext highlighter-rouge">*out*</code>, which you may redefine to any kind of PrintWriter:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">all-out</span><span class="w"> </span><span class="p">(</span><span class="nb">new</span><span class="w"> </span><span class="n">java.io.StringWriter</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">binding</span><span class="w"> </span><span class="p">[</span><span class="n">*out*</span><span class="w"> </span><span class="n">all-out</span><span class="p">]</span><span class="w"> </span><span class="c1">; any typed input here</span><span class="w"> </span><span class="c1">; All calls to pr, prn, println will print into all-out</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"this and that"</span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="c1">; Now show any printed out text in ImageJ's log window:</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.IJ/log</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="n">all-out</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <h2 id="destructuring">Destructuring</h2> <p>Destructuring is a shortcut to capture the contents of a variable into many variables.</p> <p>An example: when looping a map, we get the entry, not the key and value of each entry:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="n">e</span><span class="w"> </span><span class="p">{</span><span class="no">:a</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="no">:b</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="no">:c</span><span class="w"> </span><span class="mi">3</span><span class="p">}]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">e</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>Prints:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="no">:a</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="no">:b</span><span class="w"> </span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="no">:c</span><span class="w"> </span><span class="mi">3</span><span class="p">]</span><span class="w"> </span><span class="n">nil</span><span class="w"> </span></code></pre></div></div> <p>Each “entry” is represented by a vector with two values.</p> <p>Now to loop more conveniently, we can assign the key and value to variables, by what is called destructuring (note the <code class="language-plaintext highlighter-rouge">[k v]</code> where the <code class="language-plaintext highlighter-rouge">e</code> was before)</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[[</span><span class="n">k</span><span class="w"> </span><span class="n">v</span><span class="p">]</span><span class="w"> </span><span class="p">{</span><span class="no">:a</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="no">:b</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="no">:c</span><span class="w"> </span><span class="mi">3</span><span class="p">}]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="n">v</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>Prints:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">:a</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="no">:b</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="no">:c</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="n">nil</span><span class="w"> </span></code></pre></div></div> <p>Even better, we can preserve the whole entry as well, by using the keyword “:as”:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[[</span><span class="n">k</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="no">:as</span><span class="w"> </span><span class="n">e</span><span class="p">]</span><span class="w"> </span><span class="p">{</span><span class="no">:a</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="no">:b</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="no">:c</span><span class="w"> </span><span class="mi">3</span><span class="p">}]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">e</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>Prints:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">:a</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">[</span><span class="no">:a</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="no">:b</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="p">[</span><span class="no">:b</span><span class="w"> </span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="no">:c</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="p">[</span><span class="no">:c</span><span class="w"> </span><span class="mi">3</span><span class="p">]</span><span class="w"> </span><span class="n">nil</span><span class="w"> </span></code></pre></div></div> <h2 id="namespaces">Namespaces</h2> <ul> <li> <p>To list all existing namespaces:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="nb">all-ns</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="o">#</span><span class="n"><Namespace</span><span class="err">:</span><span class="w"> </span><span class="n">xml></span><span class="w"> </span><span class="o">#</span><span class="n"><Namespace</span><span class="err">:</span><span class="w"> </span><span class="n">zip></span><span class="w"> </span><span class="o">#</span><span class="n"><Namespace</span><span class="err">:</span><span class="w"> </span><span class="n">clojure></span><span class="w"> </span><span class="o">#</span><span class="n"><Namespace</span><span class="err">:</span><span class="w"> </span><span class="n">set></span><span class="w"> </span><span class="o">#</span><span class="n"><Namespace</span><span class="err">:</span><span class="w"> </span><span class="n">user></span><span class="p">)</span><span class="w"> </span></code></pre></div> </div> </li> <li> <p>To list all functions and variables of a specific namespace, first get the namespace object by name:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">ns-map</span><span class="w"> </span><span class="p">(</span><span class="nb">find-ns</span><span class="w"> </span><span class="ss">'xml</span><span class="p">))</span><span class="w"> </span></code></pre></div> </div> </li> </ul> <p>Note above the quoted string “xml” to avoid evaluating it to a (non-existing) value.</p> <ul> <li> <p>To list all functions and variables of all namespaces:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="nb">ns-map</span><span class="w"> </span><span class="p">(</span><span class="nb">all-ns</span><span class="p">))</span><span class="w"> </span></code></pre></div> </div> </li> </ul> <p>A nicer way to print all public functions and variables from all namespaces, sorted alphabetically:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="nb">name</span><span class="w"> </span><span class="p">(</span><span class="nb">all-ns</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[[</span><span class="n">k</span><span class="w"> </span><span class="n">v</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">sort</span><span class="w"> </span><span class="p">(</span><span class="nb">ns-publics</span><span class="w"> </span><span class="nb">name</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="n">v</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>Note above we use <em>destructuring</em>: the <code class="language-plaintext highlighter-rouge">[k v]</code> 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 <code class="language-plaintext highlighter-rouge">k</code> and <code class="language-plaintext highlighter-rouge">v</code> take the first and second values of each array pair in the sorted list of array pairs returned on applying <code class="language-plaintext highlighter-rouge">sort</code> to the <code class="language-plaintext highlighter-rouge">ns-publics</code>-generated table.</p> <h2 id="forgetremove-all-variables-from-a-namespace">Forget/Remove all variables from a namespace</h2> <p>To forget all variables from the user namespace, do:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="nb">ns-unmap</span><span class="w"> </span><span class="ss">'user</span><span class="w"> </span><span class="n">%</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">keys</span><span class="w"> </span><span class="p">(</span><span class="nb">ns-interns</span><span class="w"> </span><span class="ss">'user</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>The above maps the function <code class="language-plaintext highlighter-rouge">ns-unmap</code> to each variable name declared in the <code class="language-plaintext highlighter-rouge">user</code> namespace (using # to create a <a href="/scripting/clojure#lambda-functions">lambda function</a>), which is the same as the prompt namespace. To get the names of the variables, we use <code class="language-plaintext highlighter-rouge">ns-interns</code> to retrieve the map of variable names versus the variable contents, and extract the keys from it into a list.</p> <p><em>Thanks to AWizzArd from #clojure at irc.freenode.net for the tip.</em></p> <h2 id="jvm-arguments">JVM arguments</h2> <ul> <li> <p>To get the arguments passed to the JVM, see contents of variable <code class="language-plaintext highlighter-rouge">command-line-args</code></p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">*command-line-args*</span><span class="p">)</span><span class="w"> </span></code></pre></div> </div> </li> </ul> <h2 id="reflection">Reflection</h2> <ul> <li> <p>To list all methods of an object:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">print-java-methods</span><span class="w"> </span><span class="p">[</span><span class="n">obj</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="n">method</span><span class="w"> </span><span class="p">(</span><span class="nb">seq</span><span class="w"> </span><span class="p">(</span><span class="nf">.getMethods</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">=</span><span class="w"> </span><span class="p">(</span><span class="nb">class</span><span class="w"> </span><span class="n">obj</span><span class="p">)</span><span class="w"> </span><span class="n">java.lang.Class</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">identity</span><span class="w"> </span><span class="n">obj</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">class</span><span class="w"> </span><span class="n">obj</span><span class="p">))))]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">method</span><span class="p">)))</span><span class="w"> </span><span class="c1">; Inspect an object named imp, perhaps an image</span><span class="w"> </span><span class="p">(</span><span class="nf">print-java-methods</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span><span class="n">public</span><span class="w"> </span><span class="n">synchronized</span><span class="w"> </span><span class="nb">boolean</span><span class="w"> </span><span class="n">ij.ImagePlus.lock</span><span class="p">()</span><span class="w"> </span><span class="n">public</span><span class="w"> </span><span class="n">void</span><span class="w"> </span><span class="n">ij.ImagePlus.setProperty</span><span class="p">(</span><span class="nf">java.lang.String,java.lang.Object</span><span class="p">)</span><span class="w"> </span><span class="n">public</span><span class="w"> </span><span class="n">java.lang.Object</span><span class="w"> </span><span class="n">ij.ImagePlus.getProperty</span><span class="p">(</span><span class="nf">java.lang.String</span><span class="p">)</span><span class="w"> </span><span class="n">...</span><span class="w"> </span></code></pre></div> </div> </li> <li> <p>To list constructors, just use <code class="language-plaintext highlighter-rouge">.getConstructors</code> instead of <code class="language-plaintext highlighter-rouge">.getMethods</code>.</p> </li> </ul> <p>(Thanks to Craig McDaniel for posting the above function to Clojure’s mailing list.)</p> <h2 id="lambda-functions">Lambda functions</h2> <h3 id="declaration">Declaration</h3> <ul> <li>To declare functions on the fly, lambda style, with regex for arguments:</li> </ul> <p>For example, declare a function that takes 2 arguments, and returns the value of the first argument divided by 10, and multiplied by the second argument:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">doer</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="n">%1</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w"> </span><span class="n">%2</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nf">doer</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">2</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>Of course there’s no need to name the function, the above is just for illustration.</p> <h3 id="mapping-a-function-to-all-elements-in-a-list">Mapping a function to all elements in a list</h3> <ul> <li>To declare a nameless function, and apply it to each element of a list:</li> </ul> <p>In this case, increment by one each value of a list from 0 to 9:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">numbers</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w"> </span><span class="n">add-one</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="mi">1</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="n">add-one</span><span class="w"> </span><span class="n">numbers</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>There is no need to declare the names, the above is just for illustration. Above, we could have defined the function as #(+ %1 1):</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">%1</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="mi">10</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>… or of course use the internal function <code class="language-plaintext highlighter-rouge">inc</code> which does exactly that:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="nb">inc</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="mi">4</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>Beware that the <code class="language-plaintext highlighter-rouge">map</code> function above applies the given function to each element of a list, and returns a <em>new</em> list with the results.</p> <h2 id="built-in-documentation">Built-in documentation</h2> <p>Use the function <code class="language-plaintext highlighter-rouge">doc</code> to query any other function or variable. For example, the list generator function <code class="language-plaintext highlighter-rouge">range</code>:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">doc</span><span class="w"> </span><span class="nb">range</span><span class="p">)</span><span class="w"> </span><span class="n">-------------------------</span><span class="w"> </span><span class="n">clojure/range</span><span class="w"> </span><span class="p">([</span><span class="n">end</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">start</span><span class="w"> </span><span class="n">end</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">start</span><span class="w"> </span><span class="n">end</span><span class="w"> </span><span class="n">step</span><span class="p">])</span><span class="w"> </span><span class="n">Returns</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">lazy</span><span class="w"> </span><span class="nb">seq</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">nums</span><span class="w"> </span><span class="n">from</span><span class="w"> </span><span class="n">start</span><span class="w"> </span><span class="p">(</span><span class="nf">inclusive</span><span class="p">)</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">end</span><span class="w"> </span><span class="p">(</span><span class="nf">exclusive</span><span class="p">)</span><span class="n">,</span><span class="w"> </span><span class="n">by</span><span class="w"> </span><span class="n">step,</span><span class="w"> </span><span class="n">where</span><span class="w"> </span><span class="n">start</span><span class="w"> </span><span class="n">defaults</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="nb">and</span><span class="w"> </span><span class="n">step</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="mi">1</span><span class="nb">.</span><span class="w"> </span></code></pre></div></div> <p>Above, notice the function has three groups of possible arguments, denoted in brackets.</p> <p>When not knowing what to search for, you may try <code class="language-plaintext highlighter-rouge">find-doc</code> instead, which takes a string or regular expression as argument:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nb">find-doc</span><span class="w"> </span><span class="s">"ns-"</span><span class="p">)</span><span class="w"> </span><span class="n">-------------------------</span><span class="w"> </span><span class="n">clojure.core/ns-aliases</span><span class="w"> </span><span class="p">([</span><span class="n">ns</span><span class="p">])</span><span class="w"> </span><span class="n">Returns</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="nb">map</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">aliases</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">namespace.</span><span class="w"> </span><span class="n">-------------------------</span><span class="w"> </span><span class="n">clojure.core/ns-imports</span><span class="w"> </span><span class="p">([</span><span class="n">ns</span><span class="p">])</span><span class="w"> </span><span class="n">Returns</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="nb">map</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="nb">import</span><span class="w"> </span><span class="n">mappings</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">namespace.</span><span class="w"> </span><span class="n">...</span><span class="w"> </span><span class="n">etc.</span><span class="w"> </span></code></pre></div></div> <h3 id="defining-documentation-for-your-own-functions">Defining documentation for your own functions</h3> <p>So where does the documentation come from? Every definition of a function or macro or multimethod may take a description string before the arguments:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">area</span><span class="w"> </span><span class="s">"Computes the area of a rectangle."</span><span class="w"> </span><span class="p">[</span><span class="n">r</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="p">(</span><span class="nf">.width</span><span class="w"> </span><span class="n">r</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.height</span><span class="w"> </span><span class="n">r</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>… which the <code class="language-plaintext highlighter-rouge">doc</code> function prints, formatted:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nb">doc</span><span class="w"> </span><span class="n">area</span><span class="p">)</span><span class="w"> </span><span class="n">-------------------------</span><span class="w"> </span><span class="n">user/area</span><span class="w"> </span><span class="p">([</span><span class="n">r</span><span class="p">])</span><span class="w"> </span><span class="n">Computes</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">area</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">rectangle.</span><span class="w"> </span><span class="n">nil</span><span class="w"> </span></code></pre></div></div> <h3 id="defining-documentation-for-a-variable">Defining documentation for a variable</h3> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="o">#^</span><span class="p">{</span><span class="no">:doc</span><span class="w"> </span><span class="s">"The maximum number of connections"</span><span class="p">}</span><span class="w"> </span><span class="n">max-con</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>… which the <code class="language-plaintext highlighter-rouge">doc</code> function prints as:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nb">doc</span><span class="w"> </span><span class="n">max-con</span><span class="p">)</span><span class="w"> </span><span class="n">-------------------------</span><span class="w"> </span><span class="n">user/max-con</span><span class="w"> </span><span class="n">nil</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">maximum</span><span class="w"> </span><span class="n">number</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">connections</span><span class="w"> </span><span class="n">nil</span><span class="w"> </span></code></pre></div></div> <p>Function documentation is internally set like the above: <code class="language-plaintext highlighter-rouge">defn</code> 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).</p> <h3 id="adding-a-test-function-to-a-variable">Adding a test function to a variable</h3> <p>We first declare the variable, and then define it with a metadata map that includes a test function:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">declare</span><span class="w"> </span><span class="n">a</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="o">#^</span><span class="p">{</span><span class="no">:test</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">throw</span><span class="w"> </span><span class="p">(</span><span class="nf">Exception.</span><span class="w"> </span><span class="s">"Value under 10!"</span><span class="p">)))}</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="mi">6</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>… which we then test, by invoking the function <code class="language-plaintext highlighter-rouge">test</code> not on the value of the variable <code class="language-plaintext highlighter-rouge">a</code> (which could have its own metadata map), but on the variable <code class="language-plaintext highlighter-rouge">a</code> itself, referred to with the <code class="language-plaintext highlighter-rouge">#'a</code>:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">test</span><span class="w"> </span><span class="o">#</span><span class="ss">'a</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>The test results, in this case, in an exception being thrown:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java.lang.Exception: Value under 10! </code></pre></div></div> <p>Otherwise, it would just return the <code class="language-plaintext highlighter-rouge">:ok</code> keyword.</p> <h2 id="a-fibonacci-sequence-lazy-and-infinite-sequences">A fibonacci sequence: lazy and infinite sequences</h2> <p>A beautiful example of using lazy sequences and applying functions to one or more sequences at a time.</p> <p>Below, the sequence <code class="language-plaintext highlighter-rouge">fibs</code> is defined in such a way that it contains all possible <a href="https://en.wikipedia.org/wiki/Fibonacci_number">fibonacci numbers</a>. Since such sequence is infinite, we declared it as <code class="language-plaintext highlighter-rouge">lazy</code> sequence, that creates new elements only when they are asked for.</p> <p>The <code class="language-plaintext highlighter-rouge">lazy-cat</code> clojure function creates such lazy sequence by concatenation of two sequences: the first sequence is <code class="language-plaintext highlighter-rouge">0, 1</code> (which takes the role of feeder or initialization sequence), and the second sequence is the result of a <code class="language-plaintext highlighter-rouge">map</code> operation over two subsets of the <code class="language-plaintext highlighter-rouge">fibs</code> sequence itself: the full and the full minus the first element (hence the <code class="language-plaintext highlighter-rouge">rest</code> operation to obtain the list of all elements without the first).</p> <p>A <code class="language-plaintext highlighter-rouge">map</code> operation applies a function to each element of a sequence, or, when two or more sequences are provided, to the corresponding elements: those at index 0 in all sequences, those at index 1 in all sequences, etc.</p> <p>To generate the fibonacci sequence of numbers, a sum <code class="language-plaintext highlighter-rouge">+</code> operation is mapped to the numbers contained in the <em>self sequence</em> <code class="language-plaintext highlighter-rouge">fibs</code> and to the corresponding elements of the self sequence <code class="language-plaintext highlighter-rouge">fibs</code> minus the first element, i.e. <em>shifted by one</em>.</p> <p>In short, the lazy sequence <code class="language-plaintext highlighter-rouge">fibs</code> is an abstract way of representing a potentially infinite sequence, with an implementation containing a full abstract definition of <em>all</em> fibonacci numbers.</p> <p>Then we just <code class="language-plaintext highlighter-rouge">take</code> the first 10 elements of such lazy sequence, which are created on the fly.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">fibs</span><span class="w"> </span><span class="p">(</span><span class="nb">lazy-cat</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="nb">+</span><span class="w"> </span><span class="n">fibs</span><span class="w"> </span><span class="p">(</span><span class="nb">rest</span><span class="w"> </span><span class="n">fibs</span><span class="p">))))</span><span class="w"> </span><span class="p">(</span><span class="nb">take</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="n">fibs</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>Which outputs:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">0</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="mi">13</span><span class="w"> </span><span class="mi">21</span><span class="w"> </span><span class="mi">34</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <h3 id="printing-lazy-sequences-to-the-repl">Printing lazy sequences to the REPL</h3> <p>The REPL, when given a lazy sequence, will <em>traverse it in its entirety</em> to print it.</p> <p>Printing a potentially infinite lazy sequence to the REPL is something you don’t want to do: besides triggering computation of each element, it would fill all memory and throw an OutOfMemoryException. And you’d get bored seeing elements pass by.</p> <p>A good option is to print only part of it:</p> <ul> <li><code class="language-plaintext highlighter-rouge">take</code>: the first N elements.</li> <li><code class="language-plaintext highlighter-rouge">drop</code>: all elements beyond N.</li> <li><code class="language-plaintext highlighter-rouge">nth</code>: the nth element only.</li> </ul> <p>For infinite lazy sequences, <code class="language-plaintext highlighter-rouge">drop</code> wouldn’t save your REPL, and <code class="language-plaintext highlighter-rouge">take</code> could be perhaps too many still.</p> <p>To avoid accidental printing of complete lazy-sequences, you may set <code class="language-plaintext highlighter-rouge">*print-length*</code> to a reasonable number:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">set!</span><span class="w"> </span><span class="n">*print-length*</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>So now one can safely print the entire fibonnaci sequence, which will print only the first 5 elements, followeed by dots:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nf">set!</span><span class="w"> </span><span class="n">*print-length*</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="n">user=></span><span class="w"> </span><span class="n">fibs</span><span class="w"> </span><span class="p">(</span><span class="nf">0</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="n">...</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>The <code class="language-plaintext highlighter-rouge">*print-length*</code> applies to all sequences to be printed in the REPL, but is specially useful for very large lazy sequences.</p> <h2 id="creating-shallow-and-deep-sequences-from-java-arrays">Creating shallow and deep sequences from java arrays</h2> <p>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:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">pixels</span><span class="w"> </span><span class="p">(</span><span class="nb">into-array</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="mi">10</span><span class="p">)))</span><span class="w"> </span><span class="o">#</span><span class="ss">'user/pixels</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="n">pixels</span><span class="w"> </span><span class="p">[</span><span class="n">Ljava.lang.Integer</span><span class="c1">;@f30d8e</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">seq-pix</span><span class="w"> </span><span class="p">(</span><span class="nb">seq</span><span class="w"> </span><span class="n">pixels</span><span class="p">))</span><span class="w"> </span><span class="o">#</span><span class="ss">'user/seq-pix</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="n">seq-pix</span><span class="w"> </span><span class="p">(</span><span class="nf">0</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="mi">9</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>Now if we modify the native array, the sequence will reflect that change too when read:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="nb">aset</span><span class="w"> </span><span class="n">pixels</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">99</span><span class="p">)</span><span class="w"> </span><span class="mi">99</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="n">seq-pix</span><span class="w"> </span><span class="p">(</span><span class="nf">0</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">99</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="mi">9</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>The array was <em>not</em> duplicated. The only new object created was the shallow sequence:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="nb">class</span><span class="w"> </span><span class="n">seq-pix</span><span class="p">)</span><span class="w"> </span><span class="n">clojure.lang.ArraySeq</span><span class="w"> </span></code></pre></div></div> <p>To create a true deep duplicate of the array, one can do:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">pixels2</span><span class="w"> </span><span class="p">(</span><span class="nf">vec</span><span class="w"> </span><span class="n">pixels</span><span class="p">))</span><span class="w"> </span><span class="o">#</span><span class="ss">'user/pixels2</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="nb">class</span><span class="w"> </span><span class="n">pixels2</span><span class="p">)</span><span class="w"> </span><span class="n">clojure.lang.LazilyPersistentVector</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="n">pixels2</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">99</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="mi">9</span><span class="p">]</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">seq-pix2</span><span class="w"> </span><span class="p">(</span><span class="nb">seq</span><span class="w"> </span><span class="n">pixels2</span><span class="p">))</span><span class="w"> </span><span class="o">#</span><span class="ss">'user/seq-pix2</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="nb">class</span><span class="w"> </span><span class="n">seq-pix2</span><span class="p">)</span><span class="w"> </span><span class="n">clojure.lang.APersistentVector$Seq</span><span class="w"> </span></code></pre></div></div> <p>Or, in short:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">seq-pix2</span><span class="w"> </span><span class="p">(</span><span class="nb">seq</span><span class="w"> </span><span class="p">(</span><span class="nf">vec</span><span class="w"> </span><span class="n">pixels</span><span class="p">)))</span><span class="w"> </span><span class="o">#</span><span class="ss">'user/seq-pix2</span><span class="w"> </span></code></pre></div></div> <p>So now any changes to the original <code class="language-plaintext highlighter-rouge">pixels</code> array will not affect the new sequence:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">>>></span><span class="w"> </span><span class="p">(</span><span class="nb">aset</span><span class="w"> </span><span class="n">pixels</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">101</span><span class="p">)</span><span class="w"> </span><span class="mi">101</span><span class="w"> </span><span class="n">>>></span><span class="w"> </span><span class="n">seq-pix2</span><span class="w"> </span><span class="p">(</span><span class="nf">0</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">99</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="mi">9</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p><em>Thanks to Chouser and wwmorgan for examples on #clojure at irc.freenode.net</em></p> <h2 id="generating-java-classes-from-clojure-code">Generating java classes from clojure code</h2> <p>Using ahead of time (AOT) compilation with <a href="http://clojure.org/compilation">gen-class</a>, 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 <a href="/scripting/jython">jython</a>, <a href="/scripting/jruby">jruby</a>, <a href="/scripting/javascript">javascript</a>, and <a href="/scripting">any other</a>.</p> <p>One way to do so is to place a <a href="http://clojure.org/compilation">gen-class</a> declaration in a namespace block.</p> <p>Be aware: the <em>namespace</em> must match <em>the folder structure where the <code class="language-plaintext highlighter-rouge">.clj</code> file is and the file name of the <code class="language-plaintext highlighter-rouge">.clj</code> file</em>. For example, to generate a class named <code class="language-plaintext highlighter-rouge">fj.tests.process.FloatProcessorPlus</code>, you need a clojure file under <code class="language-plaintext highlighter-rouge">fj/tests/process/FloatProcessorPlus.clj</code>.</p> <p>To compile the clojure code to <code class="language-plaintext highlighter-rouge">.class</code> files, you need:</p> <ol> <li>A <code class="language-plaintext highlighter-rouge">classes/</code> folder in the current directory where <code class="language-plaintext highlighter-rouge">clojure.lang.Repl</code> is run. This folder will receive the generated <code class="language-plaintext highlighter-rouge">.class</code> files.</li> <li>Add to your classpath the top-level folder, in the example the ‘fj’ folder, and also the folder containing the .clj file itself.</li> <li>Add to your classpath the classes/ folder as well.</li> <li>In a clojure.lang.Repl, use the <code class="language-plaintext highlighter-rouge">compile</code> function.</li> </ol> <p>For example:</p> <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">mkdir </span>classes <span class="nv">$ </span>java <span class="nt">-cp</span> .:../../ij.jar:../../jars/clojure.jar:./classes/:./fj/tests/process/ clojure.lang.Repl </code></pre></div></div> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nf">compile</span><span class="w"> </span><span class="ss">'fj.tests.process.FloatProcessorPlus</span><span class="p">)</span><span class="w"> </span><span class="n">fj.tests.process.FloatProcessorPlus</span><span class="w"> </span><span class="n">user=></span><span class="w"> </span></code></pre></div></div> <p>The following clojure example contains a namespace declaration that includes some imports and also the gen-class. In the gen-class block, we define which class our code extends (in this case, ij.process.FloatProcessor), and which methods are to be created (with specific argument signatures and return object signature).</p> <p>Later, the compiler will assign a clojure function to each declared method, using the prefix string plus the method name to match a function.</p> <p>For example, with prefix <code class="language-plaintext highlighter-rouge">fp-</code> and method <code class="language-plaintext highlighter-rouge">fillValue</code>, the compiler will look for the clojure function <code class="language-plaintext highlighter-rouge">fp-fillValue</code>.</p> <p>Finally, a main method is not directly declared, but exists if a function named prefix + main (<code class="language-plaintext highlighter-rouge">fp-main</code> in the example) exists. We can use the main method to run the new class as an application.</p> <p>The example clojure code:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; Albert Cardona 20081203</span><span class="w"> </span><span class="c1">; Save this file as fj/tests/process/FloatProcessorPlus.clj</span><span class="w"> </span><span class="c1">; and compile it from a Repl or clojure script like:</span><span class="w"> </span><span class="c1">;</span><span class="w"> </span><span class="c1">; (compile 'fj.tests.process.FloatProcessorPlus)</span><span class="w"> </span><span class="c1">;</span><span class="w"> </span><span class="c1">; Be sure to set the classpath to point to the folder containing the above file, for example:</span><span class="w"> </span><span class="c1">; $ cd fiji/plugins/</span><span class="w"> </span><span class="c1">; $ mkdir -p tests/fj/tests/process</span><span class="w"> </span><span class="c1">; $ cd tests/fj/tests/process/</span><span class="w"> </span><span class="c1">; $ vim FloatProcessorPlus.clj</span><span class="w"> </span><span class="c1">; ...</span><span class="w"> </span><span class="c1">; $ cd ../../../</span><span class="w"> </span><span class="c1">; $ mkdir classes</span><span class="w"> </span><span class="c1">; $ java -cp ../../ij.jar:../../jars/clojure.jar:./classes/:.:./fj/tests/process/ clojure.lang.Repl</span><span class="w"> </span><span class="c1">; user=> (compile 'fj.tests.process.FloatProcessorPlus)</span><span class="w"> </span><span class="c1">; fj.tests.process.FloatProcessorPlus</span><span class="w"> </span><span class="c1">; user=></span><span class="w"> </span><span class="c1">;</span><span class="w"> </span><span class="c1">; The compilation will place the proper `.class` files under the proper directory</span><span class="w"> </span><span class="c1">; structure in the ./classes/ folder.</span><span class="w"> </span><span class="c1">;</span><span class="w"> </span><span class="c1">; Then run like any other java class with a static public void main method:</span><span class="w"> </span><span class="c1">; $ java -cp .:../../ij.jar:../../jars/clojure.jar:./classes fj.tests.process.FloatProcessorPlus</span><span class="w"> </span><span class="c1">;</span><span class="w"> </span><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">fj.tests.process.FloatProcessorPlus</span><span class="w"> </span><span class="p">(</span><span class="no">:import</span><span class="w"> </span><span class="p">(</span><span class="nf">ij</span><span class="w"> </span><span class="n">ImagePlus</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.process</span><span class="w"> </span><span class="n">FloatProcessor</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">java.util</span><span class="w"> </span><span class="n">Random</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="no">:gen-class</span><span class="w"> </span><span class="c1">; Could also use :implements</span><span class="w"> </span><span class="no">:extends</span><span class="w"> </span><span class="n">ij.process.FloatProcessor</span><span class="w"> </span><span class="c1">; Specify methods to expose as public,</span><span class="w"> </span><span class="c1">; with specific parameter types and return type:</span><span class="w"> </span><span class="no">:methods</span><span class="w"> </span><span class="p">[[</span><span class="n">fillMin</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="n">void</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">fillMax</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="n">void</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">fillValue</span><span class="w"> </span><span class="p">[</span><span class="nb">float</span><span class="p">]</span><span class="w"> </span><span class="n">void</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="n">randomize</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="n">void</span><span class="p">]]</span><span class="w"> </span><span class="c1">; Define a function prefix for the exposed methods: for example,</span><span class="w"> </span><span class="c1">; the fillMin public method is implemented by function fp-fillMin.</span><span class="w"> </span><span class="no">:prefix</span><span class="w"> </span><span class="s">"fp-"</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">fp-fillValue</span><span class="w"> </span><span class="p">[</span><span class="n">this</span><span class="w"> </span><span class="n">value</span><span class="p">]</span><span class="w"> </span><span class="s">"Set each pixel in the image to the given value."</span><span class="w"> </span><span class="p">(</span><span class="nf">.setPixels</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="p">(</span><span class="nb">into-array</span><span class="w"> </span><span class="n">Float/TYPE</span><span class="w"> </span><span class="p">(</span><span class="nb">replicate</span><span class="w"> </span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="p">(</span><span class="nf">.getWidth</span><span class="w"> </span><span class="n">this</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.getHeight</span><span class="w"> </span><span class="n">this</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">float</span><span class="w"> </span><span class="n">value</span><span class="p">)))))</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">fp-fillMin</span><span class="w"> </span><span class="p">[</span><span class="n">this</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">.fillValue</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">Float/MIN_VALUE</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">fp-fillMax</span><span class="w"> </span><span class="p">[</span><span class="n">this</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">.fillValue</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">Float/MAX_VALUE</span><span class="p">))</span><span class="w"> </span><span class="c1">; Declaring a function to be used as a java method, within a closure:</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">generator</span><span class="w"> </span><span class="p">(</span><span class="nf">Random.</span><span class="w"> </span><span class="p">(</span><span class="nf">System/currentTimeMillis</span><span class="p">))]</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">fp-randomize</span><span class="w"> </span><span class="p">[</span><span class="n">this</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">.setPixels</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="p">(</span><span class="nb">into-array</span><span class="w"> </span><span class="n">Float/TYPE</span><span class="w"> </span><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">.nextFloat</span><span class="w"> </span><span class="n">generator</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="p">(</span><span class="nf">.getWidth</span><span class="w"> </span><span class="n">this</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.getHeight</span><span class="w"> </span><span class="n">this</span><span class="p">))))))))</span><span class="w"> </span><span class="c1">; This function is seen as the static public void main function of a java class:</span><span class="w"> </span><span class="c1">; (add a parameter, like [args], if you would like to access the command-line args)</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">fp-main</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="s">"Test the generated class"</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">imp</span><span class="w"> </span><span class="p">(</span><span class="nf">ImagePlus.</span><span class="w"> </span><span class="s">"Test"</span><span class="w"> </span><span class="p">(</span><span class="nf">fj.tests.process.FloatProcessorPlus.</span><span class="w"> </span><span class="mi">100</span><span class="w"> </span><span class="mi">100</span><span class="p">))</span><span class="w"> </span><span class="n">ip</span><span class="w"> </span><span class="p">(</span><span class="nf">.getProcessor</span><span class="w"> </span><span class="n">imp</span><span class="p">)]</span><span class="w"> </span><span class="c1">; Testing access on "ImageProcessor" type</span><span class="w"> </span><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="n">imp</span><span class="p">)</span><span class="w"> </span><span class="c1">; Test some methods of our extended FloatProcessor class:</span><span class="w"> </span><span class="p">(</span><span class="nf">.randomize</span><span class="w"> </span><span class="n">ip</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.findMinAndMax</span><span class="w"> </span><span class="n">ip</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.updateAndDraw</span><span class="w"> </span><span class="n">imp</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <h2 id="references-concurrency-transactions-and-synchronization">References, concurrency, transactions and synchronization</h2> <p>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 <a href="http://albert.rierol.net/java_tricks.html#How%20to%20debug%20a%20multithreaded%20java%20program">debugging multithreaded java programs</a>).</p> <p>The most basic building blocks are <em><a href="http://clojure.org/refs">references</a></em>, which are created with the <code class="language-plaintext highlighter-rouge">ref</code> function, and modified within transaction blocks (defined by <code class="language-plaintext highlighter-rouge">dosync</code>) using <code class="language-plaintext highlighter-rouge">commute</code> or <code class="language-plaintext highlighter-rouge">alter</code> functions (and <a href="http://clojure.org/refs">others</a>).</p> <p>To read out the value of a reference, call <code class="language-plaintext highlighter-rouge">deref</code> or just <code class="language-plaintext highlighter-rouge">@</code> on it:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; Create a new reference named 'id' initializated to value zero:</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="p">(</span><span class="nb">ref</span><span class="w"> </span><span class="mi">0</span><span class="p">))</span><span class="w"> </span><span class="nb">-></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="c1">; Read out the value of the reference:</span><span class="w"> </span><span class="o">@</span><span class="n">id</span><span class="w"> </span><span class="nb">-></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="c1">; Increase the id by one, using built-in function "inc":</span><span class="w"> </span><span class="p">(</span><span class="nb">dosync</span><span class="w"> </span><span class="p">(</span><span class="nb">alter</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="nb">inc</span><span class="p">))</span><span class="w"> </span><span class="nb">-></span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="c1">; Set the value to 20 (ignoring the current value, given in cv:</span><span class="w"> </span><span class="p">(</span><span class="nb">dosync</span><span class="w"> </span><span class="p">(</span><span class="nb">alter</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[</span><span class="n">cv</span><span class="p">]</span><span class="w"> </span><span class="mi">20</span><span class="p">)))</span><span class="w"> </span><span class="nb">-></span><span class="w"> </span><span class="mi">20</span><span class="w"> </span></code></pre></div></div> <p>References are not type specific: any object may be assigned to the same reference. Whether that makes any sense is up to you.</p> <p>The <code class="language-plaintext highlighter-rouge">commute</code> and <code class="language-plaintext highlighter-rouge">alter</code> functions replace the value of the reference with that of the return value of a function given as argument. The function given as argument to <code class="language-plaintext highlighter-rouge">commute</code> and <code class="language-plaintext highlighter-rouge">alter</code> is given, in turn, the value of the reference (i.e. the dereferenced reference) and any other further arguments. The difference between <code class="language-plaintext highlighter-rouge">commute</code> and <code class="language-plaintext highlighter-rouge">alter</code> is that <code class="language-plaintext highlighter-rouge">commute</code> returns the dereferenced reference after the transaction is done, which may be different already (because of concurrent modifications) than the value that was set to the reference within the transaction; whereas <code class="language-plaintext highlighter-rouge">alter</code> returns the value that it had while the transaction was being done (i.e. the value returned by the function, the same that gets set as the value of the reference).</p> <p>In the following example, a unique id counter is incremented continuously by 1, and all ids are collected, unordered, into a vector. Both the next available id and the vector of all accessed ids are stored in references.</p> <p>Keep in mind the vector of ids assigned to the reference named ‘ls’ is always immutable: what we assign to the reference ‘ls’ below is a new vector, resulting from adding a new id to the old vector of ids. This immutability enables other threads to read the vector without locks. For performance, keep in mind that vectors, like many other clojure data structures, have structural sharing, so the new vector is not a duplication–even if it behaves like one.</p> <p>The assignment is done in a transaction, so no matter how many concurrent threads try to do so, the resulting vector will have all the ids.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; Albert Cardona 2008-12-18</span><span class="w"> </span><span class="c1">; Example clojure program using references and concurrent threads</span><span class="w"> </span><span class="c1">; that alter the value of the references.</span><span class="w"> </span><span class="c1">;</span><span class="w"> </span><span class="c1">; 10 threads running concurrently</span><span class="w"> </span><span class="c1">; each thread runs 100000 iterations</span><span class="w"> </span><span class="c1">; in each iteration the thread increments a counter 'id'</span><span class="w"> </span><span class="c1">; and adds it to a list 'ls' of ids.</span><span class="w"> </span><span class="c1">; At the end, we print the current value of 'id'</span><span class="w"> </span><span class="c1">; and the length of the list 'ls' of ids.</span><span class="w"> </span><span class="c1">;</span><span class="w"> </span><span class="c1">; No locks!</span><span class="w"> </span><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">fj.test.concurrent</span><span class="w"> </span><span class="p">(</span><span class="no">:import</span><span class="w"> </span><span class="p">(</span><span class="nf">java.util.concurrent</span><span class="w"> </span><span class="n">Executors</span><span class="w"> </span><span class="n">TimeUnit</span><span class="p">)))</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">ls</span><span class="w"> </span><span class="p">(</span><span class="nb">ref</span><span class="w"> </span><span class="p">[])</span><span class="w"> </span><span class="c1">; A reference to a vector storing a list if ids.</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="p">(</span><span class="nb">ref</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="c1">; The next unique id available.</span><span class="w"> </span><span class="n">n_threads</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="n">n_iterations</span><span class="w"> </span><span class="mi">100000</span><span class="w"> </span><span class="n">exec</span><span class="w"> </span><span class="p">(</span><span class="nf">Executors/newFixedThreadPool</span><span class="w"> </span><span class="n">n_threads</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Running"</span><span class="w"> </span><span class="n">n_threads</span><span class="w"> </span><span class="s">"threads x"</span><span class="w"> </span><span class="n">n_iterations</span><span class="w"> </span><span class="s">"iterations/thread..."</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">dotimes</span><span class="w"> </span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="n">n_threads</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">.submit</span><span class="w"> </span><span class="n">exec</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">(</span><span class="nb">dotimes</span><span class="w"> </span><span class="p">[</span><span class="n">t</span><span class="w"> </span><span class="n">n_iterations</span><span class="p">]</span><span class="w"> </span><span class="c1">; Obtain the next unique id:</span><span class="w"> </span><span class="c1">; (Note we use "alter" and not "commute", because alter</span><span class="w"> </span><span class="c1">; returns the result of the applied function, whereas</span><span class="w"> </span><span class="c1">; commute would return the dereferenced ref, which could</span><span class="w"> </span><span class="c1">; have already changed. Thanks to AWizzards for spotting</span><span class="w"> </span><span class="c1">; this.)</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">next-id</span><span class="w"> </span><span class="p">(</span><span class="nb">dosync</span><span class="w"> </span><span class="p">(</span><span class="nb">alter</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="nb">inc</span><span class="p">))]</span><span class="w"> </span><span class="c1">; Create a new vector made of</span><span class="w"> </span><span class="c1">; all previous ids and next-id,</span><span class="w"> </span><span class="c1">; and set it as the current list of ids:</span><span class="w"> </span><span class="p">(</span><span class="nb">dosync</span><span class="w"> </span><span class="p">(</span><span class="nb">commute</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="nb">conj</span><span class="w"> </span><span class="n">next-id</span><span class="p">)))))</span><span class="w"> </span><span class="n">nil</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">.shutdown</span><span class="w"> </span><span class="n">exec</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.awaitTermination</span><span class="w"> </span><span class="n">exec</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="n">TimeUnit/MINUTES</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"... done!"</span><span class="p">)</span><span class="w"> </span><span class="c1">; If there was any clash in setting the reference to the list of ids,</span><span class="w"> </span><span class="c1">; the count would be less than 1000000:</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Number of listed ids:"</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="o">@</span><span class="n">ls</span><span class="p">))</span><span class="w"> </span><span class="c1">; If any id was used twice, the next available id would be less than 1000000:</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Next available id:"</span><span class="w"> </span><span class="o">@</span><span class="n">id</span><span class="p">)</span><span class="w"> </span><span class="c1">; Check that there aren't any repeated ids:</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Number of repeated ids:"</span><span class="w"> </span><span class="p">(</span><span class="nb">-</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="o">@</span><span class="n">ls</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">count</span><span class="w"> </span><span class="p">(</span><span class="nb">set</span><span class="w"> </span><span class="o">@</span><span class="n">ls</span><span class="p">)))))</span><span class="w"> </span><span class="c1">; Make a hash set (with unique entries) from the list of ids</span><span class="w"> </span></code></pre></div></div> <h2 id="using-trycatchfinally-and-throwing-exceptions">Using try/catch/finally and throwing Exceptions</h2> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">try</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Going to throw ..."</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">throw</span><span class="w"> </span><span class="p">(</span><span class="nf">Exception.</span><span class="w"> </span><span class="s">"Testing error catching"</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Should not print, an Exception is thrown before"</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">catch</span><span class="w"> </span><span class="n">Exception</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Oops ... an error ocurred."</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.printStackTrace</span><span class="w"> </span><span class="n">e</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">finally</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Cleaning up!"</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>Of course you can throw any kind of exception you want. For example, in checking function arguments:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">java.awt</span><span class="w"> </span><span class="n">Rectangle</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">area</span><span class="w"> </span><span class="p">[</span><span class="o">#^</span><span class="n">Rectangle</span><span class="w"> </span><span class="n">r</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">not</span><span class="w"> </span><span class="p">(</span><span class="nb">instance?</span><span class="w"> </span><span class="n">Rectangle</span><span class="w"> </span><span class="n">r</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">throw</span><span class="w"> </span><span class="p">(</span><span class="nf">IllegalArgumentException.</span><span class="w"> </span><span class="s">"Can only compute the area of a Rectangle."</span><span class="p">)))</span><span class="w"> </span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="p">(</span><span class="nf">.width</span><span class="w"> </span><span class="n">r</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">.height</span><span class="w"> </span><span class="n">r</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>Above, despite the type declaration, one can pass any value to the <code class="language-plaintext highlighter-rouge">area</code> function and it will still work, but of course our class check will cut execution:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nf">area</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w"> </span><span class="n">java.lang.IllegalArgumentException</span><span class="err">:</span><span class="w"> </span><span class="n">Can</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="n">compute</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">area</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">Rectangle.</span><span class="w"> </span><span class="p">(</span><span class="nf">NO_SOURCE_FILE</span><span class="no">:0</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nf">area</span><span class="w"> </span><span class="p">(</span><span class="nf">Rectangle.</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="mi">10</span><span class="p">))</span><span class="w"> </span><span class="mi">100</span><span class="w"> </span></code></pre></div></div> <h2 id="executing-a-command-in-a-shell-and-capturing-its-output">Executing a command in a shell and capturing its output</h2> <p>First we define the macro <code class="language-plaintext highlighter-rouge">exec</code>:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">java.io</span><span class="w"> </span><span class="n">BufferedReader</span><span class="w"> </span><span class="n">InputStreamReader</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">defmacro</span><span class="w"> </span><span class="n">exec</span><span class="w"> </span><span class="s">"Execute a command on the shell, passing to the given function the lazy sequence of lines read as output, and the rest of arguments."</span><span class="w"> </span><span class="p">[</span><span class="n">cmd</span><span class="w"> </span><span class="n">pred</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="n">args</span><span class="p">]</span><span class="w"> </span><span class="o">`</span><span class="p">(</span><span class="nb">with-open</span><span class="w"> </span><span class="p">[</span><span class="n">br</span><span class="o">#</span><span class="w"> </span><span class="p">(</span><span class="nf">BufferedReader.</span><span class="w"> </span><span class="p">(</span><span class="nf">InputStreamReader.</span><span class="w"> </span><span class="p">(</span><span class="nf">.getInputStream</span><span class="w"> </span><span class="p">(</span><span class="nf">.exec</span><span class="w"> </span><span class="p">(</span><span class="nf">Runtime/getRuntime</span><span class="p">)</span><span class="w"> </span><span class="o">~</span><span class="n">cmd</span><span class="p">))))]</span><span class="w"> </span><span class="p">(</span><span class="o">~</span><span class="n">pred</span><span class="w"> </span><span class="p">(</span><span class="nb">line-seq</span><span class="w"> </span><span class="n">br</span><span class="o">#</span><span class="p">)</span><span class="w"> </span><span class="o">~@</span><span class="n">args</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>Some explanations on the above macro syntax (see also <a href="http://clojure.org/macros">clojure’s macro syntax page</a>):</p> <ul> <li>The backquote ` quotes the next expression, as defined by: `( <any code="" here=""> ). Which means the code block is *not* evaluated. But, unlike simple quote ', the backquote enables evaluation of expressions within the block when tagged with a \~ (a tilde).</any></li> <li>The ~ (tilde) evaluates the immediate expression. Can only be used in the context of a backquoted code block.</li> <li>The ~@ means <em>evaluate and expand</em>, which has the efect of placing the elements of a list as if they where declared in the code, without the list enclosure. So: `(~@(str “this” “that”)) results in: “thisthat”. In the example above, we expand the <code class="language-plaintext highlighter-rouge">& args</code>, which is a list containing all arguments given to the exec macro beyond the first and second (which are bound to <code class="language-plaintext highlighter-rouge">cmd</code> and <code class="language-plaintext highlighter-rouge">pred</code>, respectively). In this way, we lay down the proper function call of the <code class="language-plaintext highlighter-rouge">pred</code>, which is expected to be a function name (a predicate); the reason we use ~ on it is to evaluate <code class="language-plaintext highlighter-rouge">pred</code> so that it renders the pointer to the function itself. That <code class="language-plaintext highlighter-rouge">pred</code> function, by design, must accept a lazy sequence of text lines and any number of arguments afterwards.</li> <li>The # tagged at the end of a name expands to (gensym name), which results in creating a uniquely named symbol, to avoid name collisions.</li> <li>Any code present outside the backquote (none, in the case above) will be executed at macro read time, not at code execution time (aka run time)! So any precomputations are possible before laying down the code that will be executed at run time.</li> </ul> <p>Then we give the macro a command to execute and a function to process its stdout output.</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; List all files in the home directory:</span><span class="w"> </span><span class="p">(</span><span class="nf">exec</span><span class="w"> </span><span class="s">"ls /home/albert/"</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="n">line</span><span class="w"> </span><span class="n">%1</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">line</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>A second example, printing the file size of each listed file in the home directory:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; Print the size of each file in the home directory:</span><span class="w"> </span><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nf">java.io</span><span class="w"> </span><span class="n">File</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">dir</span><span class="w"> </span><span class="s">"/home/albert/"</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">exec</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="s">"ls "</span><span class="w"> </span><span class="n">dir</span><span class="p">)</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="nb">doseq</span><span class="w"> </span><span class="p">[</span><span class="n">line</span><span class="w"> </span><span class="n">%1</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nf">.length</span><span class="w"> </span><span class="p">(</span><span class="nf">File.</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="n">dir</span><span class="w"> </span><span class="n">line</span><span class="p">)))))))</span><span class="w"> </span></code></pre></div></div> <p>A third example, telling the music player XMMS2 to jump to a specific track in its playlist:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">track-number</span><span class="w"> </span><span class="mi">125</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">exec</span><span class="w"> </span><span class="p">(</span><span class="nb">str</span><span class="w"> </span><span class="s">"xmms2 jump "</span><span class="w"> </span><span class="n">track-number</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[</span><span class="n">lines</span><span class="p">]</span><span class="w"> </span><span class="n">lines</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>The above is an extract from a clojure GUI for XMMS2, available at github <a href="https://github.com/acardona/xmms2-clj/">xmms2-gui</a>.</p> <h2 id="creating-a-derivative-of-a-function">Creating a derivative of a function</h2> <p>The derivative of a function:</p> \[D f(x) = f'(x) = \lim_{dx\rightarrow 0}\frac{f(x + dx) - f(x)}{dx}\] <p>We can approximate the derivative by choosing an arbitrarily precise value of the increment <code class="language-plaintext highlighter-rouge">dx</code>.</p> <p>So first we define a function that takes any function as argument and returns a new function that implements its derivative. For convenience, we define it within a closure that specifies the arbitrarily precise increment <code class="language-plaintext highlighter-rouge">dx</code> (but we could just pass it as argument):</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">dx</span><span class="w"> </span><span class="p">(</span><span class="nb">double</span><span class="w"> </span><span class="mf">0.0001</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">derivative</span><span class="w"> </span><span class="p">[</span><span class="n">f</span><span class="p">]</span><span class="w"> </span><span class="s">"Return a function that is the derivative of the given function f, using dx increments."</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">/</span><span class="w"> </span><span class="p">(</span><span class="nb">-</span><span class="w"> </span><span class="p">(</span><span class="nf">f</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="p">(</span><span class="nb">double</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="n">dx</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nf">f</span><span class="w"> </span><span class="n">x</span><span class="p">))</span><span class="w"> </span><span class="n">dx</span><span class="p">))))</span><span class="w"> </span></code></pre></div></div> <p>Then, for any example function like the cube of x:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">cubic</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">a</span><span class="w"> </span><span class="p">(</span><span class="nb">double</span><span class="w"> </span><span class="n">x</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">a</span><span class="p">)))</span><span class="w"> </span></code></pre></div></div> <p>… we create its derivative function, which we place into a variable (note we use <code class="language-plaintext highlighter-rouge">def</code> and not <code class="language-plaintext highlighter-rouge">defn</code>):</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">cubic-prime</span><span class="w"> </span><span class="p">(</span><span class="nf">derivative</span><span class="w"> </span><span class="n">cubic</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>We can now call the cubic-prime function simply like any other function:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">cubic-prime</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="nb">-></span><span class="w"> </span><span class="mf">12.000600010022566</span><span class="w"> </span></code></pre></div></div> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">cubic-prime</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="nb">-></span><span class="w"> </span><span class="mf">27.00090001006572</span><span class="w"> </span><span class="p">(</span><span class="nf">cubic-prime</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="nb">-></span><span class="w"> </span><span class="mf">48.00120000993502</span><span class="w"> </span></code></pre></div></div> <p>The derivative of x^3 is 3 * x^2, which for an x of 4 equals 48. Our derivative is as precise as low is the value of the increment <code class="language-plaintext highlighter-rouge">dx</code>.</p> <p>The above code translated from lisp code at <a href="http://funcall.blogspot.com/2009/03/not-lisp-again.html">funcall blog</a>. Thanks <a href="http://www.blogger.com/profile/03233353484280456977">Joe Marshall</a> for sharing this perl.</p> <h2 id="pretty-printing-a-primitive-array">Pretty printing a primitive array</h2> <p>Suppose we create a primitive array of length 10:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">pa</span><span class="w"> </span><span class="p">(</span><span class="nb">make-array</span><span class="w"> </span><span class="n">Integer/TYPE</span><span class="w"> </span><span class="mi">10</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>If we print it, we get:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">pa</span><span class="p">)</span><span class="w"> </span><span class="o">#</span><span class="n"><int</span><span class="p">[]</span><span class="w"> </span><span class="p">[</span><span class="n">I</span><span class="o">@</span><span class="mi">169</span><span class="n">bc15></span><span class="w"> </span></code></pre></div></div> <p>… which is not very useful. Instead, let’s pretty print it.</p> <p>First, import the function <code class="language-plaintext highlighter-rouge">pprint</code> (and many other functions) from clojure-contrib pprint namespace:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nf">use</span><span class="w"> </span><span class="ss">'clojure.contrib.pprint</span><span class="p">)</span><span class="w"> </span></code></pre></div></div> <p>Then, use it:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nf">pprint</span><span class="w"> </span><span class="n">pa</span><span class="p">)</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="w"> </span></code></pre></div></div> <p>A similar result can be obtained by wrapping primitive arrays with <code class="language-plaintext highlighter-rouge">seq</code>, which generates a Collection view on the primitive array:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nb">seq</span><span class="w"> </span><span class="n">pa</span><span class="p">))</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="w"> </span></code></pre></div></div> <p>That <code class="language-plaintext highlighter-rouge">seq</code> creates only a view (and not a copy), you can convince yourself: changing the array changes the view, too:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">sa</span><span class="w"> </span><span class="p">(</span><span class="nb">seq</span><span class="w"> </span><span class="n">pa</span><span class="p">))</span><span class="w"> </span><span class="n">user=></span><span class="w"> </span><span class="n">sa</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nb">aset</span><span class="w"> </span><span class="n">pa</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="n">user=></span><span class="w"> </span><span class="p">(</span><span class="nf">pprint</span><span class="w"> </span><span class="n">pa</span><span class="p">)</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">7</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="n">user=></span><span class="w"> </span><span class="n">sa</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">7</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="n">,</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="w"> </span></code></pre></div></div> <h2 id="loading-an-image-file-into-a-byte-array">Loading an image file into a byte array</h2> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">import</span><span class="w"> </span><span class="p">[</span><span class="n">java.io</span><span class="w"> </span><span class="n">File</span><span class="w"> </span><span class="n">FileInputStream</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="o">^</span><span class="n">bytes</span><span class="w"> </span><span class="nb">load-file</span><span class="w"> </span><span class="s">"Load a file into a byte array."</span><span class="w"> </span><span class="p">[</span><span class="n">filepath</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">File</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">(</span><span class="nf">File.</span><span class="w"> </span><span class="n">filepath</span><span class="p">)</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="p">(</span><span class="nb">int</span><span class="w"> </span><span class="p">(</span><span class="nf">.length</span><span class="w"> </span><span class="n">f</span><span class="p">))</span><span class="w"> </span><span class="o">^</span><span class="n">bytes</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">(</span><span class="nf">byte-array</span><span class="w"> </span><span class="n">len</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">with-open</span><span class="w"> </span><span class="p">[</span><span class="o">^</span><span class="n">FileInputStream</span><span class="w"> </span><span class="n">fis</span><span class="w"> </span><span class="p">(</span><span class="nf">FileInputStream.</span><span class="w"> </span><span class="n">f</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="nb">loop</span><span class="w"> </span><span class="p">[</span><span class="n">offset</span><span class="w"> </span><span class="p">(</span><span class="nb">int</span><span class="w"> </span><span class="mi">0</span><span class="p">)]</span><span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb"><</span><span class="w"> </span><span class="n">offset</span><span class="w"> </span><span class="n">len</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">recur</span><span class="w"> </span><span class="p">(</span><span class="nf">unchecked-add</span><span class="w"> </span><span class="n">offset</span><span class="w"> </span><span class="p">(</span><span class="nf">.read</span><span class="w"> </span><span class="n">fis</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">offset</span><span class="w"> </span><span class="p">(</span><span class="nf">unchecked-subtract</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="n">offset</span><span class="p">)))))))</span><span class="w"> </span><span class="n">b</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> <p>… which then may be parsed as a <code class="language-plaintext highlighter-rouge">java.awt.Image</code>:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">img</span><span class="w"> </span><span class="p">(</span><span class="nf">javax.imageioImageIO/read</span><span class="w"> </span><span class="p">(</span><span class="nf">java.io.ByteArrayInputStream.</span><span class="w"> </span><span class="p">(</span><span class="nb">load-file</span><span class="w"> </span><span class="s">"/home/acardona/Desktop/t2/NileBend.jpg"</span><span class="p">))))</span><span class="w"> </span></code></pre></div></div> <p>… which then may be shown as an <code class="language-plaintext highlighter-rouge">ImagePlus</code>:</p> <div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">.show</span><span class="w"> </span><span class="p">(</span><span class="nf">ij.ImagePlus.</span><span class="w"> </span><span class="s">"nile bend"</span><span class="w"> </span><span class="n">img</span><span class="p">))</span><span class="w"> </span></code></pre></div></div> </div> </div> </section> <!-- Footer --> <section id="footer"> <ul class="icons"> <li><a href="https://forum.image.sc/tag/imagej" class="icon alt"><img src="/media/icons/image-sc.png" width="24" style="vertical-align: middle; margin-top: -10px"><span class="label">Forum</span></a></li> <li><a href="https://twitter.com/hashtag/ImageJ" class="icon brands alt fa-twitter"><span class="label">Twitter</span></a></li> <li><a href="https://github.com/imagej" class="icon brands alt fa-github"><span class="label">GitHub</span></a></li> </ul> <ul class="copyright"> <li>Design: <a href="http://html5up.net">HTML5 UP</a></li> </ul> </section> <!-- Hamburger menu --> <nav role="navigation"> <div id="ham-toggle"> <input type="checkbox" /> <span></span> <!-- top bun --> <span></span> <!-- hamburger --> <span></span> <!-- bottom bun --> <ul id="ham-menu"> <div class="menu"><h3>ImageJ Docs</h3> <ul> <li><a href="/downloads">Download</a></li> <li><details><summary>Learn</summary><ul> <li><details><summary><a href="/learn">ImageJ Basics</a></summary><ul> <li><a href="/tutorials">Tutorials</a></li> <li><a href="/learn/user-guides">User Guides</a></li> <li><a href="/learn/keyboard-shortcuts">Keyboard Shortcuts</a></li> <li><a href="/learn/tips-and-tricks">Tips and Tricks</a></li> <li><a href="/learn/troubleshooting">Troubleshooting</a></li> <li><a href="/learn/faq">Frequently Asked Questions</a></li> <li><details><summary><a href="/platforms">Supported Platforms</a></summary><ul> <li><a href="/platforms/windows">Windows</a></li> <li><a href="/platforms/macos">MacOS</a></li> <li><a href="/platforms/linux">Linux</a></li> <li><a href="/platforms/pi">Raspberry Pi</a></li> <li><a href="/platforms/android">Android</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/Supported Platforms --> <li><details><summary><a href="/formats">File Formats</a></summary><ul> <li><a href="/formats/bio-formats">Bio-Formats</a></li> <li><a href="/formats/video">Video formats</a></li> <li><a href="/formats/quicktime">QuickTime</a></li> <li><a href="/formats/tiff">TIFF</a></li> <li><a href="/formats/pdf">PDF</a></li> <li><a href="/formats/dicom">DICOM</a></li> <li><a href="/formats/lsm">Zeiss LSM</a></li> <li><a href="/formats/olympus">Olympus VSI</a></li> <li><a href="/formats/lurawave">Opera Flex</a></li> <li><a href="/formats/fib-sem">FIB-SEM</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/File Formats --> </ul></details></li> <!-- Learn/ImageJ --> <li><details><summary><a href="/imaging">Scientific Imaging</a></summary><ul> <li><a href="/imaging/principles">Principles of Scientific Imaging</a></li> <li><a href="/imaging/annotating-images">Annotating Images</a></li> <li><a href="/imaging/colocalization-analysis">Colocalization</a></li> <li><a href="/imaging/color-image-processing">Color Image Processing</a></li> <li><a href="/imaging/deconvolution">Deconvolution</a></li> <li><a href="/imaging/image-intensity-processing">Image Intensity Processing</a></li> <li><a href="/imaging/particle-analysis">Particle Analysis</a></li> <li><a href="/imaging/registration">Registration</a></li> <li><a href="/imaging/segmentation">Segmentation</a></li> <li><a href="/imaging/stack-slice-manipulations">Stack-slice Manipulations</a></li> <li><a href="/imaging/t-functions">T-functions</a></li> <li><a href="/imaging/tracking">Tracking</a></li> <li><a href="/imaging/visualization">Visualization</a></li> <li><a href="/imaging/z-functions">Z-functions</a></li> </ul></details></li> <!-- Learn/Scientific Imaging --> </ul></details></li> <!-- Learn --> <li><details open><summary><a href="/plugins">Extend</a></summary><ul> <li><a href="/list-of-extensions">List of Extensions</a></li> <li><details><summary><a href="/update-sites">Update Sites</a></summary><ul> <li><a href="/list-of-update-sites">List of Update Sites</a></li> <li><a href="/update-sites/following">Following an Update Site</a></li> <li><a href="/update-sites/setup">Creating an Update Site</a></li> <li><a href="/update-sites/tos">Terms of Service</a></li> <li><a href="/update-sites/automatic-uploads">Automatic Upload</a></li> <li><a href="/update-sites/core-uploads">Uploading to Core Sites</a></li> <li><a href="/update-sites/faq">Update Sites FAQ</a></li> <li><a href="/update-sites/stats">Statistics</a></li> </ul></details></li> <!-- Extend/Update Sites --> <li><details open><summary><a href="/scripting">Scripting</a></summary><ul> <li><a href="/scripting/basics">Scripting Basics</a></li> <li><a href="/scripting/script-editor">Script Editor</a></li> <li><a href="/scripting/parameters">Parameters</a></li> <li><a href="/scripting/user-input">User Input</a></li> <li><a href="/scripting/auto-imports">Auto Import</a></li> <li><a href="/scripting/templates">Templates</a></li> <li><a href="/scripting/batch">Batch Processing</a></li> <li><a href="/scripting/headless">Running Headlessly</a></li> <li><a href="/scripting/comparisons">Scripting Comparisons</a></li> <li><a href="/scripting/toolbox">Toolbox</a></li> <li><details open><summary>Languages</summary><ul> <li><a href="/scripting/beanshell">BeanShell Scripting</a></li> <li><a href="/scripting/groovy">Groovy Scripting</a></li> <li><a href="/scripting/macro">ImageJ Macro</a></li> <li><a href="/scripting/javascript">JavaScript</a></li> <li><a class="current-page">Lisp (Clojure)</a></li> <li><a href="/scripting/matlab">MATLAB</a></li> <li><a href="/scripting/jython">Python (Jython)</a></li> <li><a href="/scripting/python">Python (native)</a></li> <li><a href="/scripting/renjin">R (Renjin)</a></li> <li><a href="/scripting/jruby">Ruby (JRuby)</a></li> <li><a href="/scripting/scala">Scala Scripting</a></li> </ul></details></li> <!-- Extend/Scripting/Languages --> </ul></details></li> <!-- Extend/Scripting --> <li><details><summary><a href="/develop">Development</a></summary><ul> <li><a href="/develop/philosophy">Philosophy</a></li> <li><a href="/develop/architecture">Architecture</a></li> <li><a href="/develop/source">Source code</a></li> <li><a href="/develop/project-management">Project management</a></li> <li><a href="/develop/coding-style">Coding style</a></li> <li><a href="/develop/javadoc">Using Javadoc</a></li> <li><a href="/develop/debugging">Debugging</a></li> <li><a href="/develop/wish-list">Wish list</a></li> <li><details><summary>Tools</summary><ul> <li><a href="/develop/github">GitHub</a></li> <li><a href="/develop/maven">Maven</a></li> <li><a href="/develop/ci">CI/CD</a></li> <li><a href="/develop/dotfiles">Dotfiles</a></li> <li><details><summary><a href="/develop/ides">IDEs</a></summary><ul> <li><a href="/develop/eclipse">Eclipse</a></li> <li><a href="/develop/netbeans">NetBeans</a></li> <li><a href="/develop/intellij">IntelliJ IDEA</a></li> <li><a href="/develop/command-line">Command Line</a></li> </ul></details></li> </ul></details></li> <!-- Extend/Development/Tools --> <li><details><summary>Guides</summary><ul> <li><a href="/develop/plugins">Writing plugins</a></li> <li><a href="/develop/improving-the-code">Contributing to a plugin</a></li> <li><a href="/develop/releasing">Development lifecycle</a></li> <li><a href="/develop/building-a-pom">Building a POM</a></li> <li><a href="/develop/debugging-exercises">Hands-on debugging</a></li> <li><a href="/develop/writing-ops">Adding new ops</a></li> <li><a href="/develop/formats">Adding new formats</a></li> <li><a href="/develop/native-libraries">Using native libraries</a></li> <li><a href="/develop/tips">Tips for developers</a></li> <li><a href="/develop/cpp-tips">Tips for C++ developers</a></li> <li><a href="/develop/ij1-plugins">ImageJ 1.x plugins</a></li> <li><a href="/develop/versioning">Versioning</a></li> <li><a href="/develop/logging">Logging</a></li> <li><a href="/develop/uber-jars">Uber-JARs</a></li> </ul></details></li> <!-- Extend/Development/Guides --> <li><details><summary><a href="/develop/git">Git</a></summary><ul> <li><a href="/develop/git/eclipse">Git in Eclipse (EGit)</a></li> <li><a href="/develop/git/mini-howto">Git mini howto</a></li> <li><a href="/develop/git/workshop">Git workshop</a></li> <li><a href="/develop/git/conflicts">Git conflicts</a></li> <li><a href="/develop/git/topic-branches">Git topic branches</a></li> <li><a href="/develop/git/notes">Git notes</a></li> <li><a href="/develop/git/reflogs">Git reflogs</a></li> <li><a href="/develop/git/submodules">Git submodules</a></li> <li><a href="/develop/git/pinpoint-regressions">How to pinpoint regressions</a></li> <li><a href="/develop/git/publish-a-repository">How to publish a git repository</a></li> <li><a href="/develop/git/extract-a-subproject">How to extract a subproject</a></li> </ul></details></li> <!-- Extend/Development/Git --> </ul></details></li> <!-- Extend/Development --> </ul></details></li> <!-- Extend --> <li><details><summary><a href="/contribute">Contribute</a></summary><ul> <li><a href="/contribute/citing">Citing</a></li> <li><a href="/people">Contributors</a></li> <li><a href="/orgs">Organizations</a></li> <li><a href="/contribute/governance">Governance</a></li> <li><a href="/contribute/funding">Funding</a></li> <li><a href="/contribute/fiji">Contributing to Fiji</a></li> <li><details><summary><a href="/licensing">Licensing</a></summary><ul> <li><details><summary><a href="/licensing/open-source">Open Source</a></summary><ul> <li><a href="/licensing/apache">Apache</a></li> <li><a href="/licensing/bsd">BSD</a></li> <li><a href="/licensing/epl">EPL</a></li> <li><a href="/licensing/gpl">GPL</a></li> <li><a href="/licensing/lgpl">LGPL</a></li> <li><a href="/licensing/mit">MIT</a></li> <li><a href="/licensing/public-domain">Public domain</a></li> <li><a href="/licensing/big">BIG</a></li> </ul></details></li> <!-- Contribute/Licensing/Open Source --> <li><a href="/licensing/closed-source">Proprietary</a></li> </ul></details></li> <!-- Contribute/Licensing --> <li><details><summary><a href="/editing">Editing the Wiki</a></summary><ul> <li><a href="/editing/advanced">Advanced Editing</a></li> <li><a href="/editing/buttons">Buttons</a></li> <li><a href="/editing/citations">Citations</a></li> <li><a href="/editing/code">Source Code</a></li> <li><a href="/editing/debugging">Debugging</a></li> <li><a href="/editing/headers">Headers</a></li> <li><a href="/editing/icons">Icons</a></li> <li><a href="/editing/images">Images</a></li> <li><a href="/editing/keys">Keyboard Shortcuts</a></li> <li><a href="/editing/linking">Linking</a></li> <li><a href="/editing/math">Math Expressions</a></li> <li><a href="/editing/menu-paths">Menu Paths</a></li> <li><a href="/editing/navigation">Navigation</a></li> <li><a href="/editing/notices">Notices</a></li> <li><a href="/editing/people">People</a></li> <li><a href="/editing/pitfalls">Pitfalls</a></li> <li><a href="/editing/quizzes">Quizzes</a></li> <li><a href="/editing/statbox">Statbox</a></li> <li><a href="/editing/symbols">Symbols</a></li> <li><a href="/editing/tables">Tables</a></li> <li><a href="/editing/timelines">Timelines</a></li> <li><a href="/editing/tooltips">Tooltips</a></li> <li><a href="/editing/videos">Videos</a></li> <li><a href="/editing/whitespace">Whitespace</a></li> </ul></details></li> <!-- Contribute/Editing the Wiki --> </ul></details></li> <!-- Contribute --> <li><details><summary><a href="/discuss">Discuss</a></summary><ul> <li><a href="/discuss/bugs">Reporting Issues</a></li> <li><a href="/discuss/mailing-lists">Mailing Lists</a></li> <li><a href="/discuss/chat">Chat</a></li> </ul></details></li> <!-- Discuss --> <li><details><summary>Explore</summary><ul> <li><a href="/news">News</a></li> <li><details><summary><a href="/events">Events</a></summary><ul> <li><a href="/events/presentations">Presentations</a></li> <li><a href="/events/conferences">Conferences</a></li> <li><a href="/events/hackathons">Hackathons</a></li> <li><a href="/events">More...</a></li> </ul></details></li> <!-- Discuss/Events --> <li><details><summary><a href="/libs">Libraries</a></summary><ul> <li><a href="/libs/imagej-ops">ImageJ Ops</a></li> <li><a href="/libs/imagej-common">ImageJ Common</a></li> <li><a href="/libs/imagej-legacy">ImageJ Legacy</a></li> <li><a href="/libs/scijava">SciJava</a></li> <li><a href="/libs/scifio">SCIFIO</a></li> <li><details><summary><a href="/libs/imglib2">ImgLib2</a></summary><ul> <li><a href="/libs/imglib2/getting-started">Getting Started</a></li> <li><a href="/libs/imglib2/accessors">Accessors</a></li> <li><a href="/libs/imglib2/accessibles">Accessibles</a></li> <li><a href="/libs/imglib2/examples">Examples</a></li> <li><a href="/libs/imglib2/workshop-introductory">Introductory Workshop</a></li> <li><a href="/libs/imglib2/workshop-advanced">Advanced Workshop</a></li> <li><a href="/libs/imglib2/matlab">ImgLib2 images in MATLAB</a></li> <li><a href="/libs/imglib2/benchmarks">Benchmarks</a></li> <li><a href="/libs/imglib2/faq">FAQ</a></li> <li><a href="/libs/imglib2/developing">Developing ImgLib2</a></li> <li><a href="/libs/imglib2/discussion">ImgLib2 Discussion</a></li> </ul></details></li> <!-- Explore/Libraries/ImgLib2 --> <li><a href="/libs">More...</a></li> </ul></details></li> <!-- Explore/Libraries --> <li><details><summary><a href="/software">Software</a></summary><ul> <li><a href="/software/nih-image">NIH Image</a></li> <li><a href="/software/imagej">ImageJ</a></li> <li><a href="/software/imagej2">ImageJ2</a></li> <li><a href="/software/fiji">Fiji</a></li> <li><a href="/software">More...</a></li> </ul></details></li> <!-- Explore/Software --> </ul></details></li> <!-- Explore --> </ul> </div> </ul> </div> </nav> <div id="dock-overlay-left" class="dock-overlay" data-dock-target="left-column"></div> <div id="dock-overlay-right" class="dock-overlay" data-dock-target="right-column"></div> <!-- Search results --> <div id="search-results"> <div id="search-hits"></div> <div id="pagination"></div> </div> <!-- Scripts --> <!-- Libraries --> <script src="/assets/js/jquery.min.js"></script> <script src="/assets/js/jquery.scrolly.min.js"></script> <script src="/assets/js/browser.min.js"></script> <script src="/assets/js/breakpoints.min.js"></script> <script src="/assets/js/util.js"></script> <script src="/assets/js/jquery.toc.js"></script> <script src="/assets/js/lightbox.min.js"></script> <!-- Extensions --> <script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=default"> </script> <!-- Site code --> <script src="/assets/js/main.js"></script> <script src="/assets/js/dock.js"></script> <script src="/assets/js/code.js"></script> <!-- Anchors --> <script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script> <script>anchors.add('#page h1, #page h2, #page h3, #page h4, #page h5, #page h6');</script> <!-- Citations --> <script src="https://cdn.jsdelivr.net/npm/citation-js@0.4.0-9"></script> <script src="/assets/js/cite.js"></script> <!-- Search --> <script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.13.0/dist/algoliasearch-lite.umd.js"></script> <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.40.3/dist/instantsearch.production.min.js"></script> <script src="/assets/js/search.js"></script> <script src="/assets/js/search-tweaks.js"></script> </body> </html>