summaryrefslogtreecommitdiff
path: root/academic/ImageJ/imagej
blob: 44922f4fd73bea8ff3bccebd2a7e4fe2867f8882 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
#!/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