484 lines
16 KiB
Bash
484 lines
16 KiB
Bash
#!/bin/bash
|
|
# A wrapper script to launch imagej from the UNIX command line
|
|
# Images given as arguments will be opened, macros may also be given as arguments
|
|
# Looks for macros in the imagej macro directory
|
|
#
|
|
# This program is free software, but comes with no warrenty or guarantee
|
|
# send bug reports or feedback to jjackson at familyjackson dot net
|
|
# Author: Jon Jackson
|
|
# Last modified date: $Date: 2008-09-17 10:31:27 +0100 (Wed, 17 Sep 2008) $
|
|
# $Revision: 51 $
|
|
#
|
|
# INSTALLATION INSTRUCTIONS
|
|
#
|
|
### WARNING ###########################################################
|
|
# This file must be edited with a program that supports unix new line characters
|
|
# - it won't run if edited in 'Notepad' !
|
|
#######################################################################
|
|
|
|
# Source location: http://rsb.info.nih.gov/ij/download/linux/unix-script.txt
|
|
# 1) Save this script in the ImageJ directory as 'imagej'
|
|
# 2) Modify path variables according to your system
|
|
# 3) Give the new file execute permission
|
|
# 4) Be sure the 'imagej' wrapper is in the 'PATH'
|
|
|
|
### MODIFICATION ###
|
|
# With minor modifications to use with Slackware, by Petar Petrov 2012
|
|
# ppetrov at paju dot oulu dot fi
|
|
####################
|
|
|
|
# setup environment
|
|
set +u # don't give error for unset variables (matters for environment variables)
|
|
shopt -s extglob # allow extended pattern matching
|
|
|
|
############ SITE SPECIFIC VARIABLES #########################
|
|
# Trailing / is not required for path variables
|
|
# IMAGEJ PATH - production installation
|
|
ij_path='/usr/share/ImageJ'
|
|
# Path to ImageJ development installation
|
|
#ij_path_dev='/home/jjackson/ImageJ'
|
|
# JAVA PATH
|
|
# assumes executable is ${java_home}/bin/java
|
|
# set java_home variables ='' to use JAVA_HOME environment variable
|
|
#if [[ -d /usr/java/jdk1.5 ]] ; then
|
|
# java_home='/usr/java/jdk1.5'
|
|
#else
|
|
# # Optionally specify java path for all available OS / architecture combinations
|
|
# java_home_Linux="${ij_path}/jre"
|
|
# java_home_Linux_x86_64="${ij_path}/jre64"
|
|
# java_home_SunOS="${ij_path}/jre64"
|
|
# #
|
|
#fi
|
|
ijadmin=''
|
|
# DOCUMENTATION URL
|
|
doc_url='http://rsb.info.nih.gov/ij/'
|
|
|
|
# TEMP FOLDER
|
|
ij_tmp='/tmp/imagej'
|
|
# LOG FILE
|
|
#ij_log="${ij_tmp}/log.txt"
|
|
# default behaviour when an ImageJ window is already open
|
|
newwindow='true'
|
|
#newwindow='false'
|
|
# macro argument delimiter character
|
|
separator=':'
|
|
# a ' ' may work provided no arguments would contain spaces
|
|
# use macro functions: args=getArgument(); argArray=split(args, ':');
|
|
# to recover macro arguments
|
|
|
|
############ DEFAULT MEMORY SETTINGS #########################
|
|
|
|
declare -i default_mem=768
|
|
declare -i min_mem=32
|
|
declare -i max_32bit=1800 # empirical
|
|
declare -i max_64bit=17000000000 # conservative
|
|
|
|
############ SITE SPECIFIC MODULES #########################
|
|
|
|
# JAR libraries for additional modules may be placed in ${ij_path}/lib
|
|
# jmf.jar jai_codec.jar jai_core.jar mlibwrapper_jai.jar
|
|
|
|
# Native libraries may be placed in ${ij_path}/lib/$OS
|
|
# where OS matches the output of the 'uname' command
|
|
|
|
############ END SITE SPECIFIC VARIABLES #########################
|
|
|
|
OS=$(uname)
|
|
processor=$(uname -m) # -p doesn't work on ubuntu
|
|
declare -i mem
|
|
declare -i max_mem
|
|
declare -i free_mem
|
|
|
|
java_home="${java_home:-$JAVA_HOME}"
|
|
|
|
if [[ "$OS" == 'SunOS' ]] ; then
|
|
java_arch='-d64'
|
|
JAVA_HOME="${java_home_SunOS:-$java_home}"
|
|
max_mem=`vmstat | awk 'BEGIN{maxMem='$max_64bit'} NR == 3 {fmem=int($5 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
|
|
free_mem="max_mem"
|
|
mem=${free_mem}/2
|
|
if (( $mem > $default_mem || $mem < $min_mem )) ; then mem=$default_mem ; fi
|
|
elif [[ "$OS" == 'Linux' ]] ; then
|
|
if [[ "$processor" == 'x86_64' ]] ; then
|
|
java_arch='-d64'
|
|
JAVA_HOME="${java_home_Linux_x86_64:-$java_home}"
|
|
max_mem=`free | awk -v maxMem=$max_64bit 'NR == 2 {fmem=int($2 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
|
|
free_mem=`free | awk -v maxMem=$max_64bit 'NR == 3 {fmem=int($4 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
|
|
mem=${free_mem}/3*2
|
|
if (( $mem > $default_mem || $mem < $min_mem )) ; then mem=$default_mem ; fi
|
|
else
|
|
java_arch='-d32'
|
|
JAVA_HOME="${java_home_Linux:-$java_home}"
|
|
max_mem=`free | awk -v maxMem=$max_32bit 'NR == 2 {fmem=int($2 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
|
|
free_mem=`free | awk -v maxMem=$max_32bit 'NR == 3 {fmem=int($4 / 1024); if (fmem < maxMem) {print fmem} else {print maxMem}}'`
|
|
mem=${free_mem}/3*2
|
|
if (( $mem > $default_mem || $mem < $min_mem )) ; then mem=$default_mem ; fi
|
|
fi
|
|
fi
|
|
|
|
|
|
# if tools.jar is not in ${ij_path}/jre/lib/ext/ edit the 'tools=' line
|
|
# to point to tools.jar. The -compile switch will load tools.jar into the
|
|
# classpath and enable plugins to be compiled in imagej
|
|
|
|
if [[ -f "${ij_path}/tools.jar" ]] ; then
|
|
tools="${ij_path}/tools.jar"
|
|
else
|
|
tools=''
|
|
fi
|
|
|
|
# End Site specific variables ---------------------------------------------------------
|
|
|
|
# other variables
|
|
dir=`pwd`
|
|
user=`whoami`
|
|
host=`hostname`
|
|
if [[ -z "$DISPLAY" ]] ; then
|
|
echo 'Display variable not set'
|
|
echo 'If ImageJ fails to load, try '
|
|
echo '% setenv DISPLAY yourcomputer:0'
|
|
echo 'if you use the "csh" or for "bash" try'
|
|
echo '% export DISPLAY=yourcomputer:0'
|
|
display='default'
|
|
else
|
|
display="$DISPLAY"
|
|
fi
|
|
|
|
declare -i port=0
|
|
declare -i verbosity=0
|
|
images=''
|
|
macrocmd=''
|
|
macroargs=''
|
|
|
|
|
|
function usage {
|
|
echo
|
|
echo 'Image display and analysis program. Opens formats including:'
|
|
echo 'UNC, Analyze, Dicom, NIFTI, Tiff, Jpeg, Gif, PNG ...'
|
|
echo
|
|
echo 'imagej [options] image [ image2 ... image3 ]'
|
|
echo ' -h print help and more options'
|
|
echo ' -o open images in an open ImageJ panel'
|
|
echo ' -p <N> open images in ImageJ panel number <N>'
|
|
echo " -x <MB> set available memory (default=${mem} max=${max_mem})"
|
|
echo
|
|
}
|
|
|
|
function fullusage {
|
|
echo
|
|
echo 'Image display and analysis program. Opens formats including:'
|
|
echo 'UNC, Analyze, Dicom, NIFTI, Tiff, Jpeg, Gif, PNG ...'
|
|
echo
|
|
echo 'imagej [options] image [ image2 ... image3 ] -> open images'
|
|
echo
|
|
echo 'basic options:'
|
|
echo ' -h print help and more options'
|
|
echo ' -o open images in existing ImageJ panel if one exists'
|
|
echo ' -p <N> open images in existing ImageJ panel number <N>'
|
|
echo " -x <MB> set available memory (default=${mem} max=${max_mem})"
|
|
echo
|
|
echo 'advanced options:'
|
|
echo ' -c enable plugin compilation within imagej'
|
|
echo ' -d use development version'
|
|
echo ' -v be verbose (vv or vvv increases verbosity)'
|
|
echo
|
|
echo 'options for batch processing:'
|
|
echo " -e 'Macro Code' execute macro code"
|
|
echo " -r 'Menu Command' run menu command"
|
|
echo "Quotation marks '' are required around commands including spaces"
|
|
echo 'Commands can be sent to open ImageJ panels with the -p option'
|
|
echo
|
|
echo 'options for macros:'
|
|
echo 'imagej [-i image] [-b|-m] [arg1 ... argN] '
|
|
echo ' -b macro run macro without graphics window'
|
|
echo ' -m macro run macro'
|
|
echo '"image" will be opened before macro is run'
|
|
echo 'all following arguments are passed to macro'
|
|
echo
|
|
echo "Documentation - $doc_url "
|
|
echo "Report problems with this software to $ijadmin"
|
|
echo
|
|
}
|
|
|
|
function macroCmdError {
|
|
fullusage
|
|
echo 'Only one command option (-b -e -m OR -r) may be specified' 1>&2
|
|
exit 1
|
|
}
|
|
|
|
function getFullPath {
|
|
# Return full path to file
|
|
# treats multiple arguments as a single file with spaces
|
|
if (( $# == 0 )) ; then
|
|
echo "error getting full path for '${*}'" 1>&2
|
|
fi
|
|
pwd_getFullPath="$PWD"
|
|
\cd $(dirname "${*}") > /dev/null
|
|
dir_getFullPath="$PWD"
|
|
\cd "$pwd_getFullPath" > /dev/null
|
|
echo "$dir_getFullPath"/$(basename "${*}")
|
|
}
|
|
function derefln {
|
|
# Returns the full path of file to which link points
|
|
# following multiple levels of symbolic links.
|
|
# NOTE: if you use this function in a script, don't use any
|
|
# of the variable names used here
|
|
if (( $# == 0 )) ; then
|
|
return
|
|
fi
|
|
local the_link="$1"
|
|
local link_dir
|
|
local current_dir="$PWD"
|
|
while file "$the_link" | grep symbolic > /dev/null ; do # resolve links until target is regular file
|
|
if [[ "$the_link" == */* ]] ; then # path contains /
|
|
\cd $(dirname "${the_link}") > /dev/null
|
|
the_link=$(basename "$the_link")
|
|
fi
|
|
link_dir="$PWD"
|
|
# some versions of 'file' surround the path in `' quotes, hence the tr to remove them
|
|
the_link=$(file "${the_link}" | awk '/symbolic link/ {print $NF}' | tr -d "\140\047" )
|
|
if [[ "$the_link" != /* ]] ; then # path is not absolute path - make it one
|
|
the_link="$link_dir/$the_link"
|
|
fi
|
|
\cd "$current_dir" > /dev/null
|
|
done
|
|
echo $the_link
|
|
}
|
|
|
|
|
|
# parse input arguments
|
|
while getopts b:cde:hi:m:nop:r:vx: options
|
|
do
|
|
case $options in
|
|
b) if [[ -n "$macrocmd" ]] ; then macroCmdError ; fi
|
|
macrocmd="-batch ${OPTARG}"
|
|
;;
|
|
c) modules="${modules:-}${modules+:}${tools}"
|
|
;;
|
|
d) ij_path="$ij_path_dev"
|
|
;;
|
|
e) if [[ -n "$macrocmd" ]] ; then macroCmdError ; fi
|
|
macrocmd='-eval'
|
|
macroargs="'${OPTARG}'"
|
|
;;
|
|
h) fullusage
|
|
exit 0
|
|
;;
|
|
i) images="${images}'${OPTARG}' "
|
|
;;
|
|
m) if [[ -n "$macrocmd" ]] ; then macroCmdError ; fi
|
|
macrocmd="-macro ${OPTARG}"
|
|
;;
|
|
n) newwindow='true'
|
|
;;
|
|
o) newwindow='false'
|
|
;;
|
|
p) newwindow='false'
|
|
port="${OPTARG}"
|
|
if (( "$port" < 1 || "$port" > 99 )) ; then
|
|
echo "${OPTARG} is not a permissible value for port number (-p)" 1>&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
r) if [[ -n "$macrocmd" ]] ; then macroCmdError ; fi
|
|
macrocmd='-run'
|
|
macroargs="'${OPTARG}'"
|
|
;;
|
|
v) verbosity=verbosity+1
|
|
if (( $verbosity == 2 )) ; then set -x ; fi
|
|
if (( $verbosity == 3 )) ; then set -v ; fi
|
|
;;
|
|
x) mem="${OPTARG}"
|
|
newwindow='true'
|
|
if (( $mem < $min_mem || $mem > $max_mem )) ; then
|
|
echo "${OPTARG} is not a permissible value for memory (-x)" 1>&2
|
|
echo "min=${min_mem}, max=${max_mem}" 1>&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
\?) usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
#for ((i=1; i < $OPTIND; i++))
|
|
#do
|
|
# shift
|
|
#done
|
|
## above syntax not supported in bash < 2.05
|
|
declare -i i=1
|
|
while (( i < $OPTIND )) ; do
|
|
shift
|
|
i=i+1
|
|
done
|
|
|
|
if [[ "$#" == 0 && -z "$macrocmd" ]] ; then
|
|
usage
|
|
fi
|
|
|
|
# The best way to install .jar libraries required by plugins is to copy them
|
|
# to the imagej plugins/jars directory
|
|
# Alternatively, either copy them to ${ij_path}/jre/lib/ext/ or add the .jar
|
|
# filepath to the modules line below. Paths are separated by a colon
|
|
# Classpath must follow command line arguments, as ij_path is dependent on the -d option
|
|
|
|
# Resolving ij.jar path. If ij.jar is a symbolic link to ij_<version>.jar
|
|
# this allows updating ij.jar without crashing running sessions
|
|
ij_jar_path=$(derefln ${ij_path}/ij.jar)
|
|
|
|
for mod_jar in ${ij_path}/lib/*jar ; do
|
|
modules="${modules:-}${modules+:}$mod_jar"
|
|
done
|
|
modules="-cp ${ij_jar_path}:${modules+:}${modules:-}"
|
|
#${ij_path}/plugins/jars/dcmie.jar
|
|
|
|
export LD_LIBRARY_PATH="${ij_path}/lib/${OS}_$processor"
|
|
if (( $verbosity > 0 )) ; then
|
|
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
|
|
fi
|
|
|
|
# -b and -m options only:
|
|
# remaining command line arguments are passed as macro arguments
|
|
# separated by $separator
|
|
if [[ -n "$macrocmd" && -z "$macroargs" ]] ; then
|
|
while (( "$#" > 0 )) ; do
|
|
if [[ -z "$macroargs" ]] ; then
|
|
macroargs="${1}"
|
|
else
|
|
macroargs="${macroargs}${separator}${1}"
|
|
fi
|
|
shift
|
|
done
|
|
macroargs="'$macroargs'"
|
|
fi
|
|
|
|
# PROTECT POSSIBLE SPACES IN IMAGE FILENAMES
|
|
if (( "$#" > 0 )) ; then
|
|
while (( "$#" > 0 )) ; do
|
|
filearg="${1}"
|
|
# full file path required when sending images to running ImageJ panel
|
|
if [[ "${newwindow}" == 'false' && -f "${filearg}" ]] && ! expr "${filearg}" : '/.*' > /dev/null; then
|
|
filearg="$(getFullPath ${filearg})"
|
|
fi
|
|
images="${images}'$filearg' "
|
|
shift
|
|
done
|
|
fi
|
|
|
|
# CREATE IMAGEJ SOCKET-LOCK DIRECTORY IF NON EXISTANT
|
|
if [[ ! -d "$ij_tmp" ]] ; then
|
|
mkdir "$ij_tmp"
|
|
chmod 777 "$ij_tmp"
|
|
fi
|
|
|
|
# CREATE IMAGEJ LOG FILE IF NON EXISTANT
|
|
if [[ -n "$ij_log" && ! -f "$ij_log" ]] ; then
|
|
touch "$ij_log"
|
|
chmod 666 "$ij_log"
|
|
fi
|
|
|
|
# CREATES A TEMP FILE INDICATING A PORT IS IN USE BY IMAGEJ
|
|
cd "$ij_tmp"
|
|
declare -i count=1
|
|
portopen='false'
|
|
lockFileCreated='false'
|
|
declare -a locklist=(`ls | grep '[0-9][0-9]-.*'`)
|
|
|
|
[[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tNew Window = $newwindow" >> "$ij_log" 2> /dev/null
|
|
[[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tPort = $port" >> "$ij_log" 2> /dev/null
|
|
[[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tlocklist: \n ${locklist[*]}" >> "$ij_log" 2> /dev/null
|
|
if (( $verbosity > 0 )) ; then echo -e "locklist: \n ${locklist[*]}" ; fi
|
|
|
|
# PORT SPECIFIED BY USER
|
|
if (( $port > 0 )) ; then
|
|
# look for a lock on the port specified
|
|
for lockname in ${locklist[*]} ; do
|
|
prefix=`printf '%02u' $port`
|
|
if [[ "$lockname" == ${prefix}-${user}-${host}* ]] ; then
|
|
# found lock on the requested port, owned by user on current display
|
|
portopen='true'
|
|
if (( $verbosity > 0 )) ; then echo "Using socket lock: $lockname" ; fi
|
|
count=$port
|
|
break
|
|
elif [[ "$lockname" == ${prefix}-* ]] ; then
|
|
echo "Port $port is in use by some other user or a different host" 1>&2
|
|
if (( $verbosity > 0 )) ; then echo "Port lock: $lockname" ; fi
|
|
exit 1
|
|
fi
|
|
done
|
|
# specified port not in use
|
|
count=$port
|
|
|
|
# IF EXISTING WINDOW IS REQUESTED, LOOK FOR LISTENING PORT
|
|
elif [[ "$newwindow" == 'false' && ${#locklist} != 0 ]] ; then
|
|
# look for a lock on the current display for this user
|
|
for lockname in ${locklist[*]} ; do
|
|
if [[ "$lockname" == [0-9][0-9]-${user}-${host}-${display} ]] ; then
|
|
portopen='true'
|
|
if (( $verbosity > 0 )) ; then echo "Found socket lock: $lockname" ; fi
|
|
# if a matching user/display is found, use this one
|
|
count="${lockname%-*-*-*}"
|
|
#count=`echo $lockname | sed -e 's/^\([0-9][0-9]\).*/\1/' -e 's/^0//'` # csh?
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# IF A NEW PORT IS TO BE USED
|
|
if [[ "$portopen" == 'false' ]] ; then
|
|
# new window requested or no matching port found
|
|
# if port is not specified, look for first free port
|
|
if (( "$port" == 0 )) ; then
|
|
if (( ${#locklist} == 0 )) ; then
|
|
# no active locks - use first port
|
|
count=1
|
|
else
|
|
# active locks - check each port number so see if it is in use
|
|
# this is not synchronised!!
|
|
count=0
|
|
inuse='true'
|
|
while [[ "$inuse" == 'true' ]] ; do
|
|
count=count+1
|
|
prefix=`printf '%02u' $count`
|
|
inuse='false'
|
|
for lockname in ${locklist[*]} ; do
|
|
if [[ "$lockname" == ${prefix}-* ]] ; then
|
|
inuse='true'
|
|
fi
|
|
done
|
|
done
|
|
fi
|
|
fi
|
|
# CREATING A NEW PORT LOCK
|
|
prefix=`printf '%02u' $count`
|
|
lockname=${prefix}-${user}-${host}-${display}
|
|
|
|
[[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tCreating lock\t$lockname" >> "$ij_log" 2> /dev/null
|
|
if (( $verbosity > 0 )) ; then echo -n "creating lock $lockname ... " ; fi
|
|
touch $lockname
|
|
trap '\rm -f ${ij_tmp}/$lockname >/dev/null ; [[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tReleasing lock\t$lockname" >> "$ij_log" 2> /dev/null' EXIT TERM KILL
|
|
# Quitting ImageJ sends EXIT, as does a kill/kill -9
|
|
# CTRL+C in terminal sends INT + EXIT
|
|
# System shutdown sends TERM (+EXIT??)
|
|
|
|
if (( $verbosity > 0 )) ; then echo 'done' ; fi
|
|
|
|
lockFileCreated='true'
|
|
if [[ -z "$macrocmd" ]] ; then
|
|
echo 'Open other images in this ImageJ panel as follows:'
|
|
echo " imagej -p $count <image1> [<image2> ... <imageN>]"
|
|
fi
|
|
[[ -n "$ij_log" ]] && echo -e "$$\t$(date)\tSocket lock:\t$lockname" >> "$ij_log" 2> /dev/null
|
|
if (( $verbosity > 0 )) ; then echo "Socket lock: $lockname" ; fi
|
|
echo
|
|
fi
|
|
|
|
if (( $verbosity > 0 )) ; then
|
|
echo ${JAVA_HOME}/bin/java ${java_arch} -mx${mem}m ${modules} ij.ImageJ -ijpath ${ij_path} -port${count} ${images} ${macrocmd} ${macroargs}
|
|
fi
|
|
|
|
cd "$dir"
|
|
eval "${JAVA_HOME}/bin/java ${java_arch} -mx${mem}m ${modules} ij.ImageJ -ijpath ${ij_path} -port${count} ${images} ${macrocmd} ${macroargs} "
|
|
exit 0
|