updated on Thu Jan 26 00:18:00 UTC 2012
[aur-mirror.git] / imagej / imagej
blobb92c879a0ce44d9aa2d53ad7f773254a14929af0
1 #!/bin/bash
3 # imagej.sh - a not so simple wrapper script used to run ImageJ
5 # Copyright © 2008 Paolo Ariano
6 # Authors: Paolo Ariano (paolo dot ariano at unito dot it)
7 # Last modified date: 19 Sept 2008
9 # This is a not so simple wrapper script used to run ImageJ in Unix but
10 # optimized for Debian GNU/Linux, this is a merge between my original script
11 # and a more exhaustive one from Jon Jackson (jjackson at familyjackson dot net)
13 # Edited 2009 Giulio Guzzinati
14 # Authors: Giulio Guzzinati (skarn86junk () gmail DOT it)
15 # Last modified date: 24 May 2009
17 #This script has been edited for usage with Arch Linux by Giulio Guzzinati
19 # This program is free software; you can redistribute it and/or modify it
20 # under the terms of the GNU Lesser General Public Licenseas published by
21 # the Free Software Foundation, either version 3 of the License, or (at
22 # your option) any later version. See the file Documentation/LGPL3 in the
23 # original distribution for details. There is ABSOLUTELY NO warranty.
24 # This program is free software, but comes with no warrenty or guarantee
25 # send bug reports or feedback to me or to debian bug tracking system
28 # setup environment
29 set +u # don't give error for unset variables (matters for environment variables)
30 shopt -s extglob # allow extended pattern matching
32 ##################### DEFINE JAVA_HOME #####################
34 if [ -z "/opt/java/jre" ] ; then
35 JAVA_HOME=$(/opt/java/jre -l | head -1 | cut -d' ' -f 3)
36 else
37 JAVA_HOME=$(/usr -l | head -1 | cut -d' ' -f 3)
41 ##################### CREATE THE RIGHT ENVIRONMENT #####################
43 # ImageJ path
44 ij_path=/usr/share/imagej
46 #ImageJ user path
47 ij_user_path=$HOME/.imagej
49 # Documentation URL
50 doc_url='http://rsb.info.nih.gov/ij/'
52 # temp folder
53 ij_tmp='/tmp/imagej'
55 # default behaviour when an ImageJ window is already open
56 newwindow='true'
57 #newwindow='false'
59 # macro argument conjoining character
60 separator=':'
61 # a ' ' may work provided no arguments would contain spaces
62 # use macro functions: args=getArgument(); argArray=split(args, ':');
63 # to recover macro arguments
65 # create plugins,macro,tmp dirs
66 mkdir -p ${ij_user_path}/plugins
67 mkdir -p ${ij_user_path}/macros
68 mkdir -p ${ij_user_path}/luts
70 # makes symbolik links from shared plugins, macros and luts
72 ls ${ij_path}/plugins | while read p ; do
73 if [ ! -e "${ij_user_path}/plugins/$p" ] ; then
74 ln -s ${ij_path}/plugins/$p ${ij_user_path}/plugins/$p
76 done
78 ls ${ij_path}/macros | while read p; do
79 if [ ! -e "${ij_user_path}/macros/$p" ] ; then
80 ln -s ${ij_path}/macros/$p ${ij_user_path}/macros/$p
82 done
84 ls ${ij_path}/luts | while read p ; do
85 if [ ! -e "${ij_user_path}/luts/$p" ] ; then
86 ln -s ${ij_path}/luts/$p ${ij_user_path}/luts/$p
88 done
91 # report errors to this user
92 # ijadmin='paolo.ariano@unito.it'
94 # other variables
95 dir=`pwd`
96 user=`whoami`
97 host=`hostname`
98 if [[ -z "$DISPLAY" ]] ; then
99 echo 'Display variable not set'
100 echo 'If ImageJ fails to load, try '
101 echo '% setenv DISPLAY yourcomputer:0'
102 echo 'if you use the "csh" or for "bash" try'
103 echo '% export DISPLAY=yourcomputer:0'
104 display='default'
105 else
106 display="$DISPLAY"
109 declare -i port=0
110 declare -i verbosity=0
111 images=''
112 macrocmd=''
113 macroargs=''
115 ############ DEFAULT MEMORY SETTINGS #########################
117 declare -i default_mem=768
118 declare -i min_mem=32
119 declare -i max_32bit=1800 # empirical
120 declare -i max_64bit=17000000000 # conservative
122 ############ MEMORY ALLOCATION #########################
124 OS=$(uname)
125 processor=$(uname -m) # -p doesn't work on debian/ubuntu
126 declare -i mem
127 declare -i max_mem
128 declare -i free_mem
130 java_home="${java_home:-$JAVA_HOME}"
132 if [[ "$OS" == 'SunOS' ]] ; then
133 java_arch='-d64'
134 JAVA_HOME="${java_home_SunOS:-$java_home}"
135 max_mem=`vmstat | awk 'BEGIN{maxMem='$max_64bit'} NR == 3 {fmem=int($5 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
136 free_mem="max_mem"
137 mem=${free_mem}/2
138 if (( $mem > $default_mem || $mem < $min_mem )) ; then mem=$default_mem ; fi
139 elif [[ "$OS" == 'Linux' ]] ; then
140 if [[ "$processor" == 'x86_64' ]] ; then
141 java_arch='-d64'
142 JAVA_HOME="${java_home_Linux_x86_64:-$java_home}"
143 max_mem=`free | awk -v maxMem=$max_64bit 'NR == 2 {fmem=int($2 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
144 free_mem=`free | awk -v maxMem=$max_64bit 'NR == 3 {fmem=int($4 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
145 mem=${free_mem}/3*2
146 if (( $mem > $default_mem || $mem < $min_mem )) ; then mem=$default_mem ; fi
147 else
148 java_arch='-d32'
149 JAVA_HOME="${java_home_Linux:-$java_home}"
150 max_mem=`free | awk -v maxMem=$max_32bit 'NR == 2 {fmem=int($2 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
151 free_mem=`free | awk -v maxMem=$max_32bit 'NR == 3 {fmem=int($4 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
152 mem=${free_mem}/3*2
153 if (( $mem > $default_mem || $mem < $min_mem )) ; then mem=$default_mem ; fi
158 ##################### USAGE DESCRIPTION #####################
160 function usage {
161 echo
162 echo 'Image display and analysis program. Opens formats including:'
163 echo 'UNC, Analyze, Dicom, NIFTI, Tiff, Jpeg, Gif, PNG ...'
164 echo
165 echo 'imagej [options] image [ image2 ... image3 ]'
166 echo ' -h print help and more options'
167 echo ' -o open images in an open ImageJ panel'
168 echo ' -p <N> open images in ImageJ panel number <N>'
169 echo " -x <MB> set available memory (default=${mem} max=${max_mem})"
170 echo
173 function fullusage {
174 echo
175 echo 'Image display and analysis program. Opens formats including:'
176 echo 'UNC, Analyze, Dicom, NIFTI, Tiff, Jpeg, Gif, PNG ...'
177 echo
178 echo 'imagej [options] image [ image2 ... image3 ] -> open images'
179 echo
180 echo 'basic options:'
181 echo ' -h print help and more options'
182 echo ' -o open images in existing ImageJ panel if one exists'
183 echo ' -p <N> open images in existing ImageJ panel number <N>'
184 echo " -x <MB> set available memory (default=${mem} max=${max_mem})"
185 echo
186 echo 'advanced options:'
187 echo ' -c enable plugin compilation within imagej'
188 echo ' -d use development version'
189 echo ' -v be verbose (vv or vvv increases verbosity)'
190 echo
191 echo 'options for batch processing:'
192 echo " -e 'Macro Code' execute macro code"
193 echo " -r 'Menu Command' run menu command"
194 echo "Quotation marks '' are required around commands including spaces"
195 echo 'Commands can be sent to open ImageJ panels with the -p option'
196 echo
197 echo 'options for macros:'
198 echo 'imagej [-i image] [-b|-m] [arg1 ... argN] '
199 echo ' -b macro run macro without graphics window'
200 echo ' -m macro run macro'
201 echo '"image" will be opened before macro is run'
202 echo 'all following arguments are passed to macro'
203 echo
204 echo "Documentation - $doc_url "
205 echo "Report problems with this software to $ijadmin"
206 echo
209 function macroCmdError {
210 fullusage
211 echo 'Only one command option (-b -e -m OR -r) may be specified' 1>&2
212 exit 1
215 function getFullPath {
216 # Return full path to file
217 # treats multiple arguments as a single file with spaces
218 if (( $# == 0 )) ; then
219 echo "error getting full path for '${*}'" 1>&2
221 pwd_getFullPath="$PWD"
222 \cd $(dirname "${*}") > /dev/null
223 dir_getFullPath="$PWD"
224 \cd "$pwd_getFullPath" > /dev/null
225 echo "$dir_getFullPath"/$(basename "${*}")
227 function derefln {
228 # Returns the full path of file to which link points
229 # following multiple levels of symbolic links.
230 # NOTE: if you use this function in a script, don't use any
231 # of the variable names used here
232 if (( $# == 0 )) ; then
233 return
235 local the_link="$1"
236 local link_dir
237 local current_dir="$PWD"
238 while file "$the_link" | grep symbolic > /dev/null ; do # resolve links until target is regular file
239 if [[ "$the_link" == */* ]] ; then # path contains /
240 \cd $(dirname "${the_link}") > /dev/null
241 the_link=$(basename "$the_link")
243 link_dir="$PWD"
244 # some versions of 'file' surround the path in `' quotes, hence the tr to remove them
245 the_link=$(file "${the_link}" | awk '/symbolic link/ {print $NF}' | tr -d "\140\047" )
246 if [[ "$the_link" != /* ]] ; then # path is not absolute path - make it one
247 the_link="$link_dir/$the_link"
249 \cd "$current_dir" > /dev/null
250 done
251 echo $the_link
255 # The best way to install .jar libraries required by plugins is to copy them
256 # to the imagej plugins/jars directory
257 # Alternatively, either copy them to ${ij_path}/jre/lib/ext/ or add the .jar
258 # filepath to the modules line below. Paths are separated by a colon
259 # Classpath must follow command line arguments, as ij_path is dependent on the -d option
261 # Resolving ij.jar path. If ij.jar is a symbolic link to ij_<version>.jar
262 # this allows updating ij.jar without crashing running sessions
263 ij_jar_path=$(derefln ${ij_path}/ij.jar)
265 for mod_jar in ${ij_path}/lib/*jar ; do
266 modules="${modules:-}${modules+:}$mod_jar"
267 done
268 modules="-cp ${ij_jar_path}:${modules+:}${modules:-}"
269 #${ij_path}/plugins/jars/dcmie.jar
271 export LD_LIBRARY_PATH="${ij_path}/lib/${OS}_$processor"
272 if (( $verbosity > 0 )) ; then
273 echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
276 # enable plugins to be compiled in imagej
277 tools="$JAVA_HOME/lib/tools.jar"
280 ##################### ARGUMENTS PARSING #####################
282 while getopts b:cde:hi:m:nop:r:vx: options
284 case $options in
285 b) if [[ -n "$macrocmd" ]] ; then macroCmdError ; fi
286 macrocmd="-batch ${OPTARG}"
288 c) modules="${modules:-}${modules+:}${tools}"
290 d) ij_path="$ij_path_dev"
292 e) if [[ -n "$macrocmd" ]] ; then macroCmdError ; fi
293 macrocmd='-eval'
294 macroargs="'${OPTARG}'"
296 h) fullusage
297 exit 0
299 i) images="${images}'${OPTARG}' "
301 m) if [[ -n "$macrocmd" ]] ; then macroCmdError ; fi
302 macrocmd="-macro ${OPTARG}"
304 n) newwindow='true'
306 o) newwindow='false'
308 p) newwindow='false'
309 port="${OPTARG}"
310 if (( "$port" < 1 || "$port" > 99 )) ; then
311 echo "${OPTARG} is not a permissible value for port number (-p)" 1>&2
312 exit 1
315 r) if [[ -n "$macrocmd" ]] ; then macroCmdError ; fi
316 macrocmd='-run'
317 macroargs="'${OPTARG}'"
319 v) verbosity=verbosity+1
320 if (( $verbosity == 2 )) ; then set -x ; fi
321 if (( $verbosity == 3 )) ; then set -v ; fi
323 x) mem="${OPTARG}"
324 newwindow='true'
325 if (( $mem < $min_mem || $mem > $max_mem )) ; then
326 echo "${OPTARG} is not a permissible value for memory (-x)" 1>&2
327 echo "min=${min_mem}, max=${max_mem}" 1>&2
328 exit 1
331 \?) usage
332 exit 1
334 esac
335 done
338 declare -i i=1
339 while (( i < $OPTIND )) ; do
340 shift
341 i=i+1
342 done
344 #if (( "$#" == 0 )) ; then
345 # usage
346 #fi
348 # -b and -m options only:
349 # remaining command line arguments are passed as macro arguments
350 # separated by $separator
351 if [[ -n "$macrocmd" && -z "$macroargs" ]] ; then
352 while (( "$#" > 0 )) ; do
353 if [[ -z "$macroargs" ]] ; then
354 macroargs="${1}"
355 else
356 macroargs="${macroargs}${separator}${1}"
358 shift
359 done
360 macroargs="'$macroargs'"
363 # PROTECT POSSIBLE SPACES IN IMAGE FILENAMES
364 if (( "$#" > 0 )) ; then
365 while (( "$#" > 0 )) ; do
366 filearg="${1}"
367 # full file path required when sending images to running ImageJ panel
368 if [[ "${newwindow}" == 'false' && -f "${filearg}" ]] && ! expr "${filearg}" : '/.*' > /dev/null; then
369 filearg="$(getFullPath ${filearg})"
371 images="${images}'$filearg' "
372 shift
373 done
376 ##################### USING PORT #####################
378 # CREATE IMAGEJ SOCKET-LOCK DIRECTORY IF NON EXISTANT
379 if [[ ! -d "$ij_tmp" ]] ; then
380 mkdir "$ij_tmp"
381 chmod 777 "$ij_tmp"
384 # CREATE IMAGEJ LOG FILE IF NON EXISTANT
385 if [[ -n "$ij_log" && ! -f "$ij_log" ]] ; then
386 touch "$ij_log"
387 chmod 666 "$ij_log"
390 # CREATES A TEMP FILE INDICATING A PORT IS IN USE BY IMAGEJ
391 cd "$ij_tmp"
392 declare -i count=1
393 portopen='false'
394 lockFileCreated='false'
395 declare -a locklist=(`ls | grep '[0-9][0-9]-.*'`)
397 [[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tNew Window = $newwindow" >> "$ij_log" 2> /dev/null
398 [[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tPort = $port" >> "$ij_log" 2> /dev/null
399 [[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tlocklist: \n ${locklist[*]}" >> "$ij_log" 2> /dev/null
400 if (( $verbosity > 0 )) ; then echo -e "locklist: \n ${locklist[*]}" ; fi
402 # PORT SPECIFIED BY USER
403 if (( $port > 0 )) ; then
404 # look for a lock on the port specified
405 for lockname in ${locklist[*]} ; do
406 prefix=`printf '%02u' $port`
407 if [[ "$lockname" == ${prefix}-${user}-${host}* ]] ; then
408 # found lock on the requested port, owned by user on current display
409 portopen='true'
410 if (( $verbosity > 0 )) ; then echo "Using socket lock: $lockname" ; fi
411 count=$port
412 break
413 elif [[ "$lockname" == ${prefix}-* ]] ; then
414 echo "Port $port is in use by some other user or a different host" 1>&2
415 if (( $verbosity > 0 )) ; then echo "Port lock: $lockname" ; fi
416 exit 1
418 done
419 # specified port not in use
420 count=$port
422 # IF EXISTING WINDOW IS REQUESTED, LOOK FOR LISTENING PORT
423 elif [[ "$newwindow" == 'false' && ${#locklist} != 0 ]] ; then
424 # look for a lock on the current display for this user
425 for lockname in ${locklist[*]} ; do
426 if [[ "$lockname" == [0-9][0-9]-${user}-${host}-${display} ]] ; then
427 portopen='true'
428 if (( $verbosity > 0 )) ; then echo "Found socket lock: $lockname" ; fi
429 # if a matching user/display is found, use this one
430 count="${lockname%-*-*-*}"
431 #count=`echo $lockname | sed -e 's/^\([0-9][0-9]\).*/\1/' -e 's/^0//'` # csh?
432 break
434 done
437 # IF A NEW PORT IS TO BE USED
438 if [[ "$portopen" == 'false' ]] ; then
439 # new window requested or no matching port found
440 # if port is not specified, look for first free port
441 if (( "$port" == 0 )) ; then
442 if (( ${#locklist} == 0 )) ; then
443 # no active locks - use first port
444 count=1
445 else
446 # active locks - check each port number so see if it is in use
447 # this is not synchronised!!
448 count=0
449 inuse='true'
450 while [[ "$inuse" == 'true' ]] ; do
451 count=count+1
452 prefix=`printf '%02u' $count`
453 inuse='false'
454 for lockname in ${locklist[*]} ; do
455 if [[ "$lockname" == ${prefix}-* ]] ; then
456 inuse='true'
458 done
459 done
462 # CREATING A NEW PORT LOCK
463 prefix=`printf '%02u' $count`
464 lockname=${prefix}-${user}-${host}-${display}
466 [[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tCreating lock\t$lockname" >> "$ij_log" 2> /dev/null
467 if (( $verbosity > 0 )) ; then echo -n "creating lock $lockname ... " ; fi
468 touch $lockname
469 trap '\rm -f ${ij_tmp}/$lockname >/dev/null ; echo -e "$$\t$(date)\tReleasing lock\t$lockname" >> "$ij_log" 2> /dev/null' EXIT TERM KILL
470 # Quitting ImageJ sends EXIT, as does a kill/kill -9
471 # CTRL+C in terminal sends INT + EXIT
472 # System shutdown sends TERM (+EXIT??)
474 if (( $verbosity > 0 )) ; then echo 'done' ; fi
476 lockFileCreated='true'
477 if [[ -z "$macrocmd" ]] ; then
478 echo 'Open other images in this ImageJ panel as follows:'
479 echo " imagej -p $count <image1> [<image2> ... <imageN>]"
481 [[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tSocket lock:\t$lockname" >> "$ij_log" 2> /dev/null
482 if (( $verbosity > 0 )) ; then echo "Socket lock: $lockname" ; fi
483 echo
486 ##################### FINALLY RUN IMAGEJ #####################
488 #popd > /dev/null
490 #if [ "$JAVA_HOME" ] ; then
491 # if (( $verbosity > 0 )) ; then
492 # echo ${modules}
493 # echo $JAVA_HOME/bin/java ${java_arch} -mx${mem}m ${modules} ij.ImageJ -ijpath ${ij_user_path} -port${count} ${images} ${macrocmd} ${macroargs}
494 # else
495 # eval $JAVA_HOME/bin/java ${java_arch} -mx${mem}m ${modules} ij.ImageJ -ijpath ${ij_user_path} -port${count} ${images} ${macrocmd} ${macroargs}
496 # fi
497 #else
498 # echo "No JVM found to run ImageJ"
499 # echo "Please pacman -S java-runtime a JVM to run ImageJ or "
500 # echo "check JAVA_HOME."
501 # exit 1
504 eval java ${java_arch} -mx${mem}m ${modules} ij.ImageJ -ijpath ${ij_user_path} -port${count} ${images} ${macrocmd} ${macroargs}
506 exit 0