# HG changeset patch
# User iuc
# Date 1440614177 14400
# Node ID d065ec177dcdba018f33d246a9ebfd1223cb6de5
planemo upload commit 18df9e67efd4adafcde4eb9b62cd815e4afe9733-dirty
diff -r 000000000000 -r d065ec177dcd imagej2_analyze_particles_binary.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_analyze_particles_binary.py Wed Aug 26 14:36:17 2015 -0400
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+import argparse
+import os
+import shutil
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+parser = argparse.ArgumentParser()
+parser.add_argument( '--input', dest='input', help='Path to the input file' )
+parser.add_argument( '--input_datatype', dest='input_datatype', help='Datatype of the input image' )
+parser.add_argument( '--black_background', dest='black_background', help='Black background' )
+parser.add_argument( '--size', dest='size', help='Size (pixel^2)' )
+parser.add_argument( '--circularity_min', dest='circularity_min', type=float, help='Circularity minimum' )
+parser.add_argument( '--circularity_max', dest='circularity_max', type=float, help='Circularity maximum' )
+parser.add_argument( '--show', dest='show', help='Show' )
+parser.add_argument( '--display_results', dest='display_results', help='Display results' )
+parser.add_argument( '--all_results', dest='all_results', help='All results' )
+parser.add_argument( '--exclude_edges', dest='exclude_edges', help='Exclude edges' )
+parser.add_argument( '--include_holes', dest='include_holes', help='Include holes' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--results', dest='results', default=None, help='Path to the output results file' )
+parser.add_argument( '--output', dest='output', default=None, help='Path to the output image file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', default='data', help='Datatype of the output image' )
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+# ImageJ expects valid image file extensions, so the Galaxy .dat extension does not
+# work for some features. The following creates a symlink with an appropriate file
+# extension that points to the Galaxy dataset. This symlink is used by ImageJ.
+tmp_input_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.input, args.input_datatype )
+if args.output is None:
+ tmp_output_path = None
+else:
+ tmp_output_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, args.output_datatype )
+
+# Define command response buffers.
+tmp_out = tempfile.NamedTemporaryFile().name
+tmp_stdout = open( tmp_out, 'wb' )
+tmp_err = tempfile.NamedTemporaryFile().name
+tmp_stderr = open( tmp_err, 'wb' )
+# Java writes a lot of stuff to stderr, so we'll specify a file for handling actual errors.
+error_log = tempfile.NamedTemporaryFile( delete=False ).name
+
+# Build the command line.
+cmd = imagej2_base_utils.get_base_command_imagej2( None, jython_script=args.jython_script )
+if cmd is None:
+ imagej2_base_utils.stop_err( "ImageJ not found!" )
+cmd += ' %s' % error_log
+cmd += ' %s' % tmp_input_path
+cmd += ' %s' % args.black_background
+cmd += ' %s' % args.size
+cmd += ' %.3f' % args.circularity_min
+cmd += ' %.3f' % args.circularity_max
+cmd += ' %s' % args.show
+cmd += ' %s' % args.display_results
+cmd += '%s' % imagej2_base_utils.handle_none_type( args.all_results, val_type='str' )
+cmd += ' %s' % args.exclude_edges
+cmd += ' %s' % args.include_holes
+cmd += '%s' % imagej2_base_utils.handle_none_type( tmp_output_path, val_type='str' )
+cmd += ' %s' % args.output_datatype
+cmd += '%s' % imagej2_base_utils.handle_none_type( args.results, val_type='str' )
+
+# Run the command.
+proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )
+rc = proc.wait()
+
+# Handle execution errors.
+if rc != 0:
+ error_message = imagej2_base_utils.get_stderr_exception( tmp_err, tmp_stderr, tmp_out, tmp_stdout )
+ imagej2_base_utils.stop_err( error_message )
+
+# Handle processing errors.
+if os.path.getsize( error_log ) > 0:
+ error_message = open( error_log, 'r' ).read()
+ imagej2_base_utils.stop_err( error_message )
+
+if tmp_output_path is not None:
+ # Save the output image.
+ shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
diff -r 000000000000 -r d065ec177dcd imagej2_analyze_particles_binary.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_analyze_particles_binary.xml Wed Aug 26 14:36:17 2015 -0400
@@ -0,0 +1,132 @@
+
+
+ of binary image with ImageJ2
+
+ imagej2_macros.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ show != "Nothing"
+
+
+ show == "Nothing" or display_results_cond['display_results'] == "yes"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.. class:: warningmark
+
+@requires_binary_input@
+
+**What it does**
+
+
+
+
+
+
diff -r 000000000000 -r d065ec177dcd imagej2_base_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_base_utils.py Wed Aug 26 14:36:17 2015 -0400
@@ -0,0 +1,164 @@
+import os
+import shutil
+import sys
+import tempfile
+
+FIJI_JAR_DIR = os.environ.get( 'FIJI_JAR_DIR', None )
+FIJI_OSX_JAVA3D_DIR = os.environ.get( 'FIJI_OSX_JAVA3D_DIR', None )
+FIJI_PLUGIN_DIR = os.environ.get( 'FIJI_PLUGIN_DIR', None )
+FIJI_ROOT_DIR = os.environ.get( 'FIJI_ROOT_DIR', None )
+
+BUFF_SIZE = 1048576
+
+def cleanup_before_exit( tmp_dir ):
+ """
+ Remove temporary files and directories prior to tool exit.
+ """
+ if tmp_dir and os.path.exists( tmp_dir ):
+ shutil.rmtree( tmp_dir )
+
+def get_base_cmd_bunwarpj( jvm_memory ):
+ if FIJI_JAR_DIR is not None and FIJI_PLUGIN_DIR is not None:
+ if jvm_memory in [ None, 'None' ]:
+ jvm_memory_str = ''
+ else:
+ jvm_memory_str = '-Xmx%s' % jvm_memory
+ bunwarpj_base_cmd = "java %s -cp %s/ij-1.49k.jar:%s/bUnwarpJ_-2.6.1.jar bunwarpj.bUnwarpJ_" % \
+ ( jvm_memory_str, FIJI_JAR_DIR, FIJI_PLUGIN_DIR )
+ return bunwarpj_base_cmd
+ return None
+
+def get_base_command_imagej2( memory_size=None, macro=None, jython_script=None ):
+ imagej2_executable = get_imagej2_executable()
+ if imagej2_executable is None:
+ return None
+ cmd = '%s --ij2 --headless --debug' % imagej2_executable
+ if memory_size is not None:
+ memory_size_cmd = ' -DXms=%s -DXmx=%s' % ( memory_size, memory_size )
+ cmd += memory_size_cmd
+ if macro is not None:
+ cmd += ' --macro %s' % os.path.abspath( macro )
+ if jython_script is not None:
+ cmd += ' --jython %s' % os.path.abspath( jython_script )
+ return cmd
+
+def get_file_extension( image_format ):
+ """
+ Return a valid bioformats file extension based on the received
+ value of image_format( e.g., "gif" is returned as ".gif".
+ """
+ return '.%s' % image_format
+
+def get_file_name_without_extension( file_path ):
+ """
+ Eliminate the .ext from the received file name, assuming that
+ the file name consists of only a single '.'.
+ """
+ if os.path.exists( file_path ):
+ path, name = os.path.split( file_path )
+ name_items = name.split( '.' )
+ return name_items[ 0 ]
+ return None
+
+def get_imagej2_executable():
+ """
+ Fiji names the ImageJ executable different names for different
+ architectures, so figure out which name we need.
+ """
+ platform_dict = get_platform_info_dict()
+ if platform_dict.get( 'architecture', None ) in [ 'x86_64' ]:
+ if platform_dict.get( 'os', None ) in [ 'darwin' ]:
+ return 'ImageJ-macosx'
+ if platform_dict.get( 'os', None ) in [ 'linux' ]:
+ return 'ImageJ-linux64'
+ return None
+
+def get_input_image_path( tmp_dir, input_file, image_format ):
+ """
+ Bioformats uses file extensions (e.g., .job, .gif, etc)
+ when reading and writing image files, so the Galaxy dataset
+ naming convention of setting all file extensions as .dat
+ must be handled.
+ """
+ image_path = get_temporary_image_path( tmp_dir, image_format )
+ # Remove the file so we can create a symlink.
+ os.remove( image_path )
+ os.symlink( input_file, image_path )
+ return image_path
+
+def get_platform_info_dict():
+ '''Return a dict with information about the current platform.'''
+ platform_dict = {}
+ sysname, nodename, release, version, machine = os.uname()
+ platform_dict[ 'os' ] = sysname.lower()
+ platform_dict[ 'architecture' ] = machine.lower()
+ return platform_dict
+
+def get_stderr_exception( tmp_err, tmp_stderr, tmp_out, tmp_stdout, include_stdout=False ):
+ tmp_stderr.close()
+ """
+ Return a stderr string of reasonable size.
+ """
+ # Get stderr, allowing for case where it's very large.
+ tmp_stderr = open( tmp_err, 'rb' )
+ stderr_str = ''
+ buffsize = BUFF_SIZE
+ try:
+ while True:
+ stderr_str += tmp_stderr.read( buffsize )
+ if not stderr_str or len( stderr_str ) % buffsize != 0:
+ break
+ except OverflowError:
+ pass
+ tmp_stderr.close()
+ if include_stdout:
+ tmp_stdout = open( tmp_out, 'rb' )
+ stdout_str = ''
+ buffsize = BUFF_SIZE
+ try:
+ while True:
+ stdout_str += tmp_stdout.read( buffsize )
+ if not stdout_str or len( stdout_str ) % buffsize != 0:
+ break
+ except OverflowError:
+ pass
+ tmp_stdout.close()
+ if include_stdout:
+ return 'STDOUT\n%s\n\nSTDERR\n%s\n' % ( stdout_str, stderr_str )
+ return stderr_str
+
+def get_temp_dir( prefix='tmp-imagej-', dir=None ):
+ """
+ Return a temporary directory.
+ """
+ return tempfile.mkdtemp( prefix=prefix, dir=dir )
+
+def get_tempfilename( dir=None, suffix=None ):
+ """
+ Return a temporary file name.
+ """
+ fd, name = tempfile.mkstemp( suffix=suffix, dir=dir )
+ os.close( fd )
+ return name
+
+def get_temporary_image_path( tmp_dir, image_format ):
+ """
+ Return the path to a temporary file with a valid image format
+ file extension that can be used with bioformats.
+ """
+ file_extension = get_file_extension( image_format )
+ return get_tempfilename( tmp_dir, file_extension )
+
+def handle_none_type( val, val_type='float' ):
+ if val is None:
+ return ' None'
+ else:
+ if val_type == 'float':
+ return ' %.1f' % val
+ elif val_type == 'int':
+ return ' %d' % val
+ return ' %s' % val
+
+def stop_err( msg ):
+ sys.stderr.write( msg )
+ sys.exit( 1 )
diff -r 000000000000 -r d065ec177dcd imagej2_macros.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_macros.xml Wed Aug 26 14:36:17 2015 -0400
@@ -0,0 +1,121 @@
+
+
+ 1.0
+
+
+ fiji
+
+
+
+
+ fiji
+ javabridge
+ numpy
+ python_bioformats
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ --iterations $iterations
+ --count $count
+ --black_background $black_background
+ --pad_edges_when_eroding $pad_edges_when_eroding
+
+
+.. class:: warningmark
+
+This tool works on binary images, so other image types will automatically be converted to binary
+before they are analyzed. This step is performed using the ImageJ2 **Make Binary** command with
+the following settings: **Iterations:** 1, **Count:** 1, **Pad edges when eroding:** No. The tool
+allows you to choose the **Black background** setting. If these settings are not appropriate,
+first manually convert the image to binary using the **Convert to binary (black and white) with ImageJ2**
+tool, which allows you to change them.
+
+
+
+
+
+
+
+
+
+
+
+ @InProceedings(Arganda-Carreras2006,
+ author = "Ignacio Arganda-Carreras and
+ Carlos Oscar S{\'a}nchez Sorzano and
+ Roberto Marabini and
+ Jos{\'e} Mar\'{\i}a Carazo and
+ Carlos Ortiz-de-Solorzano and
+ Jan Kybic",
+ title = "Consistent and Elastic Registration of Histological Sections Using Vector-Spline Regularization",
+ publisher = "Springer Berlin / Heidelberg",
+ booktitle = "Computer Vision Approaches to Medical Image Analysis",
+ series = "Lecture Notes in Computer Science",
+ year = "2006",
+ volume = "4241",
+ pages = "85-95",
+ month = "May",
+ city = "Graz, Austria")
+
+ 10.1038/nmeth.2019
+
+
+
+
+ 10.1038/nmeth.2102
+
+
+
+
+ 10.1038/nmeth.2102
+ 10.1038/nmeth.2019
+ 10.1083/jcb.201004104
+
+
+
diff -r 000000000000 -r d065ec177dcd jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jython_script.py Wed Aug 26 14:36:17 2015 -0400
@@ -0,0 +1,72 @@
+import jython_utils
+import sys
+from ij import IJ
+from ij.plugin.filter import Analyzer
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -14 ]
+input = sys.argv[ -13 ]
+black_background = jython_utils.asbool( sys.argv[ -12 ] )
+size = sys.argv[ -11 ]
+circularity_min = float( sys.argv[ -10 ] )
+circularity_max = float( sys.argv[ -9 ] )
+show = sys.argv[ -8 ]
+display_results = jython_utils.asbool( sys.argv[ -7 ] )
+all_results = jython_utils.asbool( sys.argv[ -6 ] )
+exclude_edges = jython_utils.asbool( sys.argv[ -5 ] )
+include_holes = jython_utils.asbool( sys.argv[ -4 ] )
+tmp_output_path = sys.argv[ -3 ]
+output_datatype = sys.argv[ -2 ]
+results_path = sys.argv[ -1 ]
+
+# Open the input image file.
+input_image_plus = IJ.openImage( input )
+
+# Create a copy of the image.
+input_image_plus_copy = input_image_plus.duplicate()
+image_processor_copy = input_image_plus_copy.getProcessor()
+analyzer = Analyzer( input_image_plus_copy )
+
+try:
+ # Set binary options.
+ options = jython_utils.get_binary_options( black_background=black_background )
+ IJ.run( input_image_plus_copy, "Options...", options )
+
+ # Convert image to binary if necessary.
+ if not image_processor_copy.isBinary():
+ # Convert the image to binary grayscale.
+ IJ.run( input_image_plus_copy, "Make Binary", "" )
+
+ # Set the options.
+ options = [ 'size=%s' % size ]
+ circularity_str = '%.3f-%.3f' % ( circularity_min, circularity_max )
+ options.append( 'circularity=%s' % circularity_str )
+ if show.find( '_' ) >= 0:
+ show_str = '[%s]' % show.replace( '_', ' ' )
+ else:
+ show_str = show
+ options.append( 'show=%s' % show_str )
+ if display_results:
+ options.append( 'display' )
+ if not all_results:
+ options.append( 'summarize' )
+ if exclude_edges:
+ options.append( 'exclude' )
+ if include_holes:
+ options.append( 'include' )
+ # Always run "in_situ".
+ options.append( 'in_situ' )
+
+ # Run the command.
+ IJ.run( input_image_plus_copy, "Analyze Particles...", " ".join( options ) )
+
+ # Save outputs.
+ if tmp_output_path not in [ None, 'None' ]:
+ # Save the ImagePlus object as a new image.
+ IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+ if display_results and results_path not in [ None, 'None' ]:
+ results_table = analyzer.getResultsTable()
+ results_table.saveAs( results_path )
+except Exception, e:
+ jython_utils.handle_error( error_log, str( e ) )
diff -r 000000000000 -r d065ec177dcd jython_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jython_utils.py Wed Aug 26 14:36:17 2015 -0400
@@ -0,0 +1,48 @@
+import imagej2_base_utils
+from ij import IJ
+
+IMAGE_PLUS_IMAGE_TYPE_FIELD_VALUES = { '0':'GRAY8', '1':'GRAY16', '2':'GRAY32',
+ '3':'COLOR_256', '4':'COLOR_RGB' }
+
+def asbool( val ):
+ return str( val ).lower() in [ 'yes', 'true' ]
+
+def convert_before_saving_as_tiff( image_plus ):
+ # The bUnwarpJ plug-in produces TIFF image stacks consisting of 3
+ # slices which can be viewed in ImageJ. The 3 slices are: 1) the
+ # registered image, 2) the target image and 3) the black/white warp
+ # image. When running bUnwarpJ from the command line (as these
+ # Galaxy wrappers do) the initial call to IJ.openImage() (to open the
+ # registered source and target images produced by bUnwarpJ) in the
+ # tool's jython_script.py returns an ImagePlus object with a single
+ # slice which is the "generally undesired" slice 3 discussed above.
+ # However, a call to IJ.saveAs() will convert the single-slice TIFF
+ # into a 3-slice TIFF image stack (as described above) if the selected
+ # format for saving is TIFF. Galaxy supports only single-layered
+ # images, so to work around this behavior, we have to convert the
+ # image to something other than TIFF so that slices are eliminated.
+ # We can then convert back to TIFF for saving. There might be a way
+ # to do this without converting twice, but I spent a lot of time looking
+ # and I have yet to discover it.
+ tmp_dir = imagej2_base_utils.get_temp_dir()
+ tmp_out_png_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, 'png' )
+ IJ.saveAs( image_plus, 'png', tmp_out_png_path )
+ return IJ.openImage( tmp_out_png_path )
+
+def get_binary_options( black_background, iterations=1, count=1, pad_edges_when_eroding='no' ):
+ options = [ 'edm=Overwrite', 'iterations=%d' % iterations, 'count=%d' % count ]
+ if asbool( pad_edges_when_eroding ):
+ options.append( 'pad' )
+ if asbool( black_background ):
+ options.append( "black" )
+ return " ".join( options )
+
+def get_display_image_type( image_type ):
+ return IMAGE_PLUS_IMAGE_TYPE_FIELD_VALUES.get( str( image_type ), None )
+
+def handle_error( error_log, msg ):
+ # Java writes a lot of stuff to stderr, so the received error_log
+ # will log actual errors.
+ elh = open( error_log, 'wb' )
+ elh.write( msg )
+ elh.close()
diff -r 000000000000 -r d065ec177dcd test-data/analyze_particles_masks.gif
Binary file test-data/analyze_particles_masks.gif has changed
diff -r 000000000000 -r d065ec177dcd test-data/analyze_particles_nothing.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/analyze_particles_nothing.tabular Wed Aug 26 14:36:17 2015 -0400
@@ -0,0 +1,48 @@
+ Area Mean Min Max
+1 86 0 0 0
+2 72 0 0 0
+3 25 0 0 0
+4 85 0 0 0
+5 157 0 0 0
+6 207 0 0 0
+7 29 0 0 0
+8 73 0 0 0
+9 143 0 0 0
+10 125 0 0 0
+11 159 0 0 0
+12 133 0 0 0
+13 85 0 0 0
+14 51 0 0 0
+15 133 0 0 0
+16 133 0 0 0
+17 81 0 0 0
+18 88 0 0 0
+19 212 0 0 0
+20 116 0 0 0
+21 172 0 0 0
+22 103 0 0 0
+23 4 0 0 0
+24 60 0 0 0
+25 198 0 0 0
+26 187 0 0 0
+27 80 0 0 0
+28 75 0 0 0
+29 103 0 0 0
+30 52 0 0 0
+31 122 0 0 0
+32 129 0 0 0
+33 77 0 0 0
+34 171 0 0 0
+35 117 0 0 0
+36 207 0 0 0
+37 119 0 0 0
+38 181 0 0 0
+39 49 0 0 0
+40 150 0 0 0
+41 191 0 0 0
+42 170 0 0 0
+43 174 0 0 0
+44 270 0 0 0
+45 87 0 0 0
+46 69 0 0 0
+47 1 0 0 0
diff -r 000000000000 -r d065ec177dcd test-data/analyze_particles_outlines.gif
Binary file test-data/analyze_particles_outlines.gif has changed
diff -r 000000000000 -r d065ec177dcd test-data/blobs_watershed_binary.gif
Binary file test-data/blobs_watershed_binary.gif has changed
diff -r 000000000000 -r d065ec177dcd tool_dependencies.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool_dependencies.xml Wed Aug 26 14:36:17 2015 -0400
@@ -0,0 +1,6 @@
+
+
+
+
+
+