Repository 'imagej2_bunwarpj_compare_elastic_raw'
hg clone https://toolshed.g2.bx.psu.edu/repos/imgteam/imagej2_bunwarpj_compare_elastic_raw

Changeset 0:1bffabc15695 (2019-09-17)
Next changeset 1:2be338fc671e (2020-09-28)
Commit message:
"planemo upload for repository https://github.com/bgruening/galaxytools/tree/master/tools/image_processing/imagej2 commit b08f0e6d1546caaf627b21f8c94044285d5d5b9c-dirty"
added:
imagej2_adjust_threshold_binary.py
imagej2_adjust_threshold_binary_jython_script.py
imagej2_analyze_particles_binary.py
imagej2_analyze_particles_binary_jython_script.py
imagej2_analyze_skeleton.py
imagej2_analyze_skeleton_jython_script.py
imagej2_base_utils$py.class
imagej2_base_utils.py
imagej2_base_utils.pyc
imagej2_binary_to_edm.py
imagej2_binary_to_edm_jython_script.py
imagej2_bunwarpj_adapt_transform.py
imagej2_bunwarpj_align.py
imagej2_bunwarpj_align_jython_script.py
imagej2_bunwarpj_compare_elastic.py
imagej2_bunwarpj_compare_elastic_raw.py
imagej2_bunwarpj_compare_elastic_raw.xml
imagej2_bunwarpj_compare_raw.py
imagej2_bunwarpj_compose_elastic.py
imagej2_bunwarpj_compose_raw.py
imagej2_bunwarpj_compose_raw_elastic.py
imagej2_bunwarpj_convert_to_raw.py
imagej2_bunwarpj_elastic_transform.py
imagej2_bunwarpj_elastic_transform_jython_script.py
imagej2_bunwarpj_raw_transform.py
imagej2_bunwarpj_raw_transform_jython_script.py
imagej2_create_image.py
imagej2_create_image_jython_script.py
imagej2_enhance_contrast.py
imagej2_enhance_contrast_jython_script.py
imagej2_find_edges.py
imagej2_find_edges_jython_script.py
imagej2_find_maxima.py
imagej2_find_maxima_jython_script.py
imagej2_macros.xml
imagej2_make_binary.py
imagej2_make_binary_jython_script.py
imagej2_math.py
imagej2_math_jython_script.py
imagej2_noise.py
imagej2_noise_jython_script.py
imagej2_shadows.py
imagej2_shadows_jython_script.py
imagej2_sharpen.py
imagej2_sharpen_jython_script.py
imagej2_skeletonize3d.py
imagej2_skeletonize3d_jython_script.py
imagej2_smooth.py
imagej2_smooth_jython_script.py
imagej2_watershed_binary.py
imagej2_watershed_binary_jython_script.py
jython_utils$py.class
jython_utils.py
readme.md
static/images/bunwarpj_scheme.png
test-data/adapted_transformation.txt
test-data/add_specified_noise.gif
test-data/analyze_particles_masks.gif
test-data/analyze_particles_nothing.tabular
test-data/analyze_particles_outlines.gif
test-data/basic.tabular
test-data/blobs.gif
test-data/blobs_black_edm.gif
test-data/blobs_count.tabular
test-data/blobs_direct_transf.txt
test-data/blobs_edm.gif
test-data/blobs_equalize.gif
test-data/blobs_find_edges.gif
test-data/blobs_list.tabular
test-data/blobs_log.gif
test-data/blobs_macro.gif
test-data/blobs_min.gif
test-data/blobs_multiply.gif
test-data/blobs_normalize.gif
test-data/blobs_northwest.gif
test-data/blobs_saturate.gif
test-data/blobs_segmented.gif
test-data/blobs_sharpen.gif
test-data/blobs_single_points.gif
test-data/blobs_smooth.gif
test-data/blobs_square.gif
test-data/blobs_threshold_default.gif
test-data/blobs_threshold_huang_dark.gif
test-data/blobs_threshold_ijiso.gif
test-data/blobs_tolerance.gif
test-data/blobs_watershed_binary.gif
test-data/clown.jpg
test-data/clown_binary.jpg
test-data/composed_raw_elastic_transformation.txt
test-data/composed_raw_transformation.txt
test-data/create_image1.jpg
test-data/despeckle.gif
test-data/detailed.tabular
test-data/dot_blot.jpg
test-data/dot_blot.png
test-data/dot_blot.tiff
test-data/dotblot.jpg
test-data/elastic_trans_registered_source1.png
test-data/largest_shortest_path_basic.tabular
test-data/mask_ramp.gif
test-data/mask_white.png
test-data/raw_trans_registered_source1.png
test-data/raw_transformation.txt
test-data/registered_source1.png
test-data/registered_source2.png
test-data/registered_target1.png
test-data/registered_target2.png
test-data/remove_outliers.gif
test-data/shortest_branch_all_yes.tabular
test-data/shortest_branch_basic.tabular
test-data/skeletonized_blobs.gif
test-data/skeletonized_clown.jpg
test-data/source_elastic_transformation.txt
test-data/source_raw_transformation.txt
test-data/target_elastic_transformation.txt
test-data/target_raw_transformation.txt
test-data/warping_index.txt
test-data/warping_index1.txt
test-data/warping_index2.txt
test-data/warping_index_raw.txt
b
diff -r 000000000000 -r 1bffabc15695 imagej2_adjust_threshold_binary.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_adjust_threshold_binary.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,63 @@
+#!/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( '--threshold_min', dest='threshold_min', type=float, help='Minimum threshold value' )
+parser.add_argument( '--threshold_max', dest='threshold_max', type=float, help='Maximum threshold value' )
+parser.add_argument( '--method', dest='method', help='Threshold method' )
+parser.add_argument( '--display', dest='display', help='Display mode' )
+parser.add_argument( '--black_background', dest='black_background', help='Black background' )
+parser.add_argument( '--stack_histogram', dest='stack_histogram', help='Stack histogram' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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 += ' %.3f' % args.threshold_min
+cmd += ' %.3f' % args.threshold_max
+cmd += ' %s' % args.method
+cmd += ' %s' % args.display
+cmd += ' %s' % args.black_background
+cmd += ' %s' % args.stack_histogram
+cmd += ' %s' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+# 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 )
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_adjust_threshold_binary_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_adjust_threshold_binary_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,49 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -10 ]
+input = sys.argv[ -9 ]
+threshold_min = float( sys.argv[ -8 ] )
+threshold_max = float( sys.argv[ -7 ] )
+method = sys.argv[ -6 ]
+display = sys.argv[ -5 ]
+black_background = jython_utils.asbool( sys.argv[ -4 ] )
+# TODO: this is not being used.
+stack_histogram = jython_utils.asbool( sys.argv[ -3 ] )
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+try:
+    # 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","iterations=1 count=1 edm=Overwrite do=Nothing" )
+    # Set the options.
+    if black_background:
+        method_str = "%s dark" % method
+    else:
+        method_str = method
+    IJ.setAutoThreshold( input_image_plus_copy, method_str )
+    if display == "red":
+        display_mode = "Red"
+    elif display == "bw":
+        display_mode = "Black & White"
+    elif display == "over_under":
+        display_mode = "Over/Under"
+    IJ.setThreshold( input_image_plus_copy, threshold_min, threshold_max, display_mode )
+    # Run the command.
+    IJ.run( input_image_plus_copy, "threshold", "" )
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_analyze_particles_binary.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_analyze_particles_binary.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -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 )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_analyze_particles_binary_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_analyze_particles_binary_jython_script.py Tue Sep 17 16:55:25 2019 -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 ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_analyze_skeleton.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_analyze_skeleton.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,61 @@
+#!/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( '--prune_cycle_method', dest='prune_cycle_method', default='none', help='Prune cycle method' )
+parser.add_argument( '--prune_ends', dest='prune_ends', default='no', help='Prune ends' )
+parser.add_argument( '--calculate_largest_shortest_path', dest='calculate_largest_shortest_path', default='no', help='Calculate largest shortest path' )
+parser.add_argument( '--show_detailed_info', dest='show_detailed_info', default='no', help='Show detailed info' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+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 )
+
+# 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.prune_cycle_method
+cmd += ' %s' % args.prune_ends
+cmd += ' %s' % args.calculate_largest_shortest_path
+cmd += ' %s' % args.show_detailed_info
+cmd += ' %s' % args.output
+
+# 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 )
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_analyze_skeleton_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_analyze_skeleton_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,147 @@
+import jython_utils
+import math
+import sys
+from ij import IJ
+from sc.fiji.analyzeSkeleton import AnalyzeSkeleton_
+
+BASIC_NAMES = [ 'Branches', 'Junctions', 'End-point Voxels',
+                'Junction Voxels', 'Slab Voxels', 'Average branch length',
+                'Triple Points', 'Quadruple Points', 'Maximum Branch Length' ]
+DETAIL_NAMES = [ 'Skeleton ID', 'Branch length', 'V1 x', 'V1 y', 'V1 z', 'V2 x',
+                 'V2 y', 'V2 z', 'Euclidean distance' ]
+
+def get_euclidean_distance( vertex1, vertex2 ):
+    x1, y1, z1 = get_points( vertex1 )
+    x2, y2, z2 = get_points( vertex2 )
+    return math.sqrt( math.pow( ( x2 - x1 ), 2 ) +
+                      math.pow( ( y2 - y1 ), 2 ) +
+                      math.pow( ( z2 - z1 ), 2 ) )
+
+def get_graph_length( graph ):
+    length = 0
+    for edge in graph.getEdges():
+        length = length + edge.getLength()
+    return length
+
+def get_points( vertex ):
+    # An array of Point, which has attributes x,y,z.
+    point = vertex.getPoints()[ 0 ]
+    return point.x, point.y, point.z
+    
+def get_sorted_edge_lengths( graph ):
+    # Return graph edges sorted from longest to shortest.
+    edges = graph.getEdges()
+    edges = sorted( edges, key=lambda edge: edge.getLength(), reverse=True )
+    return edges
+
+def get_sorted_graph_lengths( result ):
+    # Get the separate graphs (skeletons).
+    graphs = result.getGraph()
+    # Sort graphs from longest to shortest.
+    graphs = sorted( graphs, key=lambda g: get_graph_length( g ), reverse=True )
+    return graphs
+
+def save( result, output, show_detailed_info, calculate_largest_shortest_path, sep='\t' ):
+    num_trees = int( result.getNumOfTrees() )
+    outf = open( output, 'wb' )
+    outf.write( '# %s\n' % sep.join( BASIC_NAMES ) )
+    for index in range( num_trees ):
+        outf.write( '%d%s' % ( result.getBranches()[ index ], sep ) )
+        outf.write( '%d%s' % ( result.getJunctions()[ index ], sep ) )
+        outf.write( '%d%s' % ( result.getEndPoints()[ index ], sep ) )
+        outf.write( '%d%s' % ( result.getJunctionVoxels()[ index ], sep ) )
+        outf.write( '%d%s' % ( result.getSlabs()[ index ], sep ) )
+        outf.write( '%.3f%s' % ( result.getAverageBranchLength()[ index ], sep ) )
+        outf.write( '%d%s' % ( result.getTriples()[ index ], sep ) )
+        outf.write( '%d%s' % ( result.getQuadruples()[ index ], sep ) )
+        outf.write( '%.3f' % result.getMaximumBranchLength()[ index ] )
+        if calculate_largest_shortest_path:
+            outf.write( '%s%.3f%s' % ( sep, result.shortestPathList.get( index ), sep ) )
+            outf.write( '%d%s' % ( result.spStartPosition[ index ][ 0 ], sep ) )
+            outf.write( '%d%s' % ( result.spStartPosition[ index ][ 1 ], sep ) )
+            outf.write( '%d\n' % result.spStartPosition[ index ][ 2 ] )
+        else:
+            outf.write( '\n' )
+    if show_detailed_info:
+        outf.write( '# %s\n' % sep.join( DETAIL_NAMES ) )
+        # The following index is a placeholder for the skeleton ID.
+        # The terms "graph" and "skeleton" refer to the same thing.
+        # Also, the SkeletonResult.java code states that the
+        # private Graph[] graph object is an array of graphs (one
+        # per tree).
+        for index, graph in enumerate( get_sorted_graph_lengths( result ) ):
+            for edge in get_sorted_edge_lengths( graph ):
+                vertex1 = edge.getV1()
+                x1, y1, z1 = get_points( vertex1 )
+                vertex2 = edge.getV2()
+                x2, y2, z2 = get_points( vertex2 )
+                outf.write( '%d%s' % ( index+1, sep ) )
+                outf.write( '%.3f%s' % ( edge.getLength(), sep ) )
+                outf.write( '%d%s' % ( x1, sep ) )
+                outf.write( '%d%s' % ( y1, sep ) )
+                outf.write( '%d%s' % ( z1, sep ) )
+                outf.write( '%d%s' % ( x2, sep ) )
+                outf.write( '%d%s' % ( y2, sep ) )
+                outf.write( '%d%s' % ( z2, sep ) )
+                outf.write( '%.3f' % get_euclidean_distance( vertex1, vertex2 ) )
+                if calculate_largest_shortest_path:
+                    # Keep number of separated items the same for each line.
+                    outf.write( '%s %s' % ( sep, sep ) )
+                    outf.write( ' %s' % sep )
+                    outf.write( ' %s' % sep )
+                    outf.write( ' \n' )
+                else:
+                    outf.write( '\n' )
+    outf.close()
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -8 ]
+input = sys.argv[ -7 ]
+black_background = jython_utils.asbool( sys.argv[ -6 ] )
+prune_cycle_method = sys.argv[ -5 ]
+prune_ends = jython_utils.asbool( sys.argv[ -4 ] )
+calculate_largest_shortest_path = jython_utils.asbool( sys.argv[ -3 ] )
+if calculate_largest_shortest_path:
+    BASIC_NAMES.extend( [ 'Longest Shortest Path', 'spx', 'spy', 'spz' ] )
+    DETAIL_NAMES.extend( [ ' ', ' ', ' ', ' ' ] )
+show_detailed_info = jython_utils.asbool( sys.argv[ -2 ] )
+output = 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()
+
+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():
+        IJ.run( input_image_plus_copy, "Make Binary", "" )
+
+    # Run AnalyzeSkeleton
+    analyze_skeleton = AnalyzeSkeleton_()
+    analyze_skeleton.setup( "", input_image_plus_copy )
+    if prune_cycle_method == 'none':
+        prune_index  = analyze_skeleton.NONE
+    elif prune_cycle_method == 'shortest_branch':
+        prune_index  = analyze_skeleton.SHORTEST_BRANCH
+    elif prune_cycle_method == 'lowest_intensity_voxel':
+        prune_index  = analyze_skeleton.LOWEST_INTENSITY_VOXEL
+    elif prune_cycle_method == 'lowest_intensity_branch':
+        prune_index  = analyze_skeleton.LOWEST_INTENSITY_BRANCH
+    result = analyze_skeleton.run( prune_index,
+                                   prune_ends,
+                                   calculate_largest_shortest_path,
+                                   input_image_plus_copy,
+                                   True,
+                                   True )
+    # Save the results.
+    save( result, output, show_detailed_info, calculate_largest_shortest_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_base_utils$py.class
b
Binary file imagej2_base_utils$py.class has changed
b
diff -r 000000000000 -r 1bffabc15695 imagej2_base_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_base_utils.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,169 @@
+import os
+import shutil
+import sys
+import tempfile
+
+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 jvm_memory in [None, 'None']:
+        jvm_memory_str = ''
+    else:
+        jvm_memory_str = '-Xmx%s' % jvm_memory
+    # The following bunwarpj_base_cmd string will look something like this:
+    # "java %s -cp $JAR_DIR/ij-1.49k.jar:$PLUGINS_DIR/bUnwarpJ_-2.6.1.jar \
+    # bunwarpj.bUnwarpJ_" % (jvm_memory_str)
+    # See the bunwarpj.sh script for the fiji 20151222
+    # bioconda recipe in github.
+    bunwarpj_base_cmd = "bunwarpj %s" % jvm_memory_str
+    return bunwarpj_base_cmd
+
+
+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, but our bioconda recipe allows us to do this.
+    """
+    return 'ImageJ'
+
+
+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 ' %.3f' % val
+        elif val_type == 'int':
+            return ' %d' % val
+    return ' %s' % val
+
+
+def stop_err(msg):
+    sys.stderr.write(msg)
+    sys.exit(1)
b
diff -r 000000000000 -r 1bffabc15695 imagej2_base_utils.pyc
b
Binary file imagej2_base_utils.pyc has changed
b
diff -r 000000000000 -r 1bffabc15695 imagej2_binary_to_edm.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_binary_to_edm.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,65 @@
+#!/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( '--iterations', dest='iterations', type=int, help='Iterations' )
+parser.add_argument( '--count', dest='count', type=int, help='Count' )
+parser.add_argument( '--black_background', dest='black_background', help='Black background' )
+parser.add_argument( '--pad_edges_when_eroding', dest='pad_edges_when_eroding', help='Pad edges when eroding' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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 += ' %d' % args.iterations
+cmd += ' %d' % args.count
+cmd += ' %s' % args.black_background
+cmd += ' %s' % args.pad_edges_when_eroding
+cmd += ' %s' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+
+# 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 )
+
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_binary_to_edm_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_binary_to_edm_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,44 @@
+import jython_utils
+import sys
+from ij import IJ
+from ij import ImagePlus
+from ij.plugin.filter import Analyzer
+from ij.plugin.filter import EDM
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -8 ]
+input = sys.argv[ -7 ]
+iterations = int( sys.argv[ -6 ] )
+count = int( sys.argv[ -5 ] )
+black_background = jython_utils.asbool( sys.argv[ -4 ] )
+pad_edges_when_eroding = jython_utils.asbool( sys.argv[ -3 ] )
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+try:
+    # Set binary options.
+    options = jython_utils.get_binary_options( black_background=black_background,
+                                               iterations=iterations,
+                                               count=count,
+                                               pad_edges_when_eroding=pad_edges_when_eroding )
+    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", "" )
+
+    # Run the command.
+    IJ.run( input_image_plus_copy, "Distance Map", "" )
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_adapt_transform.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_adapt_transform.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+import argparse
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--input_elastic_transformation', dest='input_elastic_transformation', help='Input elastic transformation matrix' )
+parser.add_argument( '--image_size_factor', dest='image_size_factor', type=float, help='Image size factor' )
+parser.add_argument( '--output', dest='output', help='Warping index' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+input_elastic_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.input_elastic_transformation, 'txt' )
+
+# 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' )
+
+def is_power2( val ):
+    if val < 0:
+        return False
+    if val < 1:
+        val = 1.0 / val
+    val = int( val )
+    return ( ( val & ( val - 1 ) ) == 0 )
+
+# Build the command line to adapt the transformation.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -adapt_transform'
+
+# Make sure the value of image_size_factor is a power of 2 (positive or negative).
+if is_power2( args.image_size_factor ):
+    image_size_factor = args.image_size_factor
+else:
+    msg = "Image size factor must be a positive or negative power of 2 (0.25, 0.5, 2, 4, 8, etc)."
+    imagej2_base_utils.stop_err( msg )
+
+# Target is sent before source.
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % input_elastic_transformation_path
+cmd += ' %s' % args.output
+cmd += ' %2.f' % image_size_factor
+
+# Adapt the transformation based on the image size factor using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )
+rc = proc.wait()
+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 )
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_align.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_align.py Tue Sep 17 16:55:25 2019 -0400
b
b"@@ -0,0 +1,178 @@\n+#!/usr/bin/env python\n+import argparse\n+import os\n+import shutil\n+import subprocess\n+import tempfile\n+import imagej2_base_utils\n+\n+# Parse Command Line.\n+parser = argparse.ArgumentParser()\n+parser.add_argument( '--source_image', dest='source_image', help='Source image' )\n+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )\n+parser.add_argument( '--source_mask', dest='source_mask', default=None, help='Source mask' )\n+parser.add_argument( '--source_mask_format', dest='source_mask_format', default=None, help='Source mask image format' )\n+parser.add_argument( '--target_image', dest='target_image', help='Target image' )\n+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )\n+parser.add_argument( '--target_mask', dest='target_mask', default=None, help='Target mask' )\n+parser.add_argument( '--target_mask_format', dest='target_mask_format', default=None, help='Target mask image format' )\n+parser.add_argument( '--min_scale_def', dest='min_scale_def', type=int, help='Initial deformation' )\n+parser.add_argument( '--max_scale_def', dest='max_scale_def', type=int, help='Final deformation' )\n+parser.add_argument( '--max_subsamp_fact', dest='max_subsamp_fact', type=int, help='Image sub-sample factor' )\n+parser.add_argument( '--divergence_weight', dest='divergence_weight', type=float, help='Divergence weight' )\n+parser.add_argument( '--curl_weight', dest='curl_weight', type=float, help='Curl weight' )\n+parser.add_argument( '--image_weight', dest='image_weight', type=float, help='Image weight' )\n+parser.add_argument( '--consistency_weight', dest='consistency_weight', type=float, help='Consistency weight' )\n+parser.add_argument( '--landmarks_weight', dest='landmarks_weight', type=float, help='Landmarks weight' )\n+parser.add_argument( '--landmarks_file', dest='landmarks_file', default=None, help='Landmarks file' )\n+parser.add_argument( '--source_affine_file', dest='source_affine_file', default=None, help='Initial source affine matrix transformation' )\n+parser.add_argument( '--target_affine_file', dest='target_affine_file', default=None, help='Initial target affine matrix transformation' )\n+parser.add_argument( '--mono', dest='mono', default=False, help='Unidirectional registration (source to target)' )\n+parser.add_argument( '--source_trans_out', dest='source_trans_out', default=None, help='Direct source transformation matrix' )\n+parser.add_argument( '--target_trans_out', dest='target_trans_out', default=None, help='Inverse target transformation matrix' )\n+parser.add_argument( '--source_out', help='Output source image' )\n+parser.add_argument( '--source_out_datatype', help='Output registered source image format' )\n+parser.add_argument( '--target_out', default=None, help='Output target image' )\n+parser.add_argument( '--target_out_datatype', default=None, help='Output registered target image format' )\n+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )\n+\n+args = parser.parse_args()\n+\n+if args.source_trans_out is not None and args.target_trans_out is not None:\n+    save_transformation = True\n+else:\n+    save_transformation = False\n+\n+tmp_dir = imagej2_base_utils.get_temp_dir()\n+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )\n+tmp_source_out_tiff_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, 'tiff' )\n+tmp_source_out_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, args.source_out_datatype )\n+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )\n+if not args.mono:\n+    tmp_target_out_tiff_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, 'tiff' )\n+    tmp_target_out_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, args.target_out_datatype )\n+if args.source_mask is not None and args.target_mask is not None:\n+    t"..b'max_scale_def\n+cmd += \' %d\' % args.max_subsamp_fact\n+cmd += \' %.1f\' % args.divergence_weight\n+cmd += \' %.1f\' % args.curl_weight\n+cmd += \' %.1f\' % args.image_weight\n+cmd += \' %.1f\' % args.consistency_weight\n+# Source is produced before target.\n+cmd += \' %s\' % tmp_source_out_tiff_path\n+if not args.mono:\n+    cmd += \' %s\' % tmp_target_out_tiff_path\n+if args.landmarks_file is not None:\n+    # We have to create a temporary file with a .txt extension here so that\n+    # bUnwarpJ will not ignore the Galaxy "dataset.dat" file.\n+    tmp_landmarks_file_path = imagej2_base_utils.get_input_image_path( tmp_dir,\n+                                                                       args.landmarks_file,\n+                                                                       \'txt\' )\n+    cmd += \' -landmarks\'\n+    cmd += \' %.1f\' % args.landmarks_weight\n+    cmd += \' %s\' % tmp_landmarks_file_path\n+if args.source_affine_file is not None and args.target_affine_file is not None:\n+    # Target is sent before source.\n+    cmd += \' -affine\'\n+    cmd += \' %s\' % args.target_affine_file\n+    cmd += \' %s\' % args.source_affine_file\n+if args.mono:\n+    cmd += \' -mono\'\n+if save_transformation:\n+    cmd += \' -save_transformation\'\n+\n+# Align the two images using bUnwarpJ.\n+proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )\n+rc = proc.wait()\n+if rc != 0:\n+    error_message = imagej2_base_utils.get_stderr_exception( tmp_err, tmp_stderr, tmp_out, tmp_stdout )\n+    imagej2_base_utils.stop_err( error_message )\n+\n+# bUnwarpJ produces tiff image stacks consisting of 3 slices which can be viewed in ImageJ.\n+# The 3 slices are:: 1) the registered image, 2) the target image and 3) the black/white\n+# warp image.  Galaxy supports only single-layered images, so we\'ll convert the images so they\n+# can be viewed in Galaxy.\n+\n+# Define command response buffers.\n+tmp_out = tempfile.NamedTemporaryFile().name\n+tmp_stdout = open( tmp_out, \'wb\' )\n+tmp_err = tempfile.NamedTemporaryFile().name\n+tmp_stderr = open( tmp_err, \'wb\' )\n+\n+# Build the command line to handle the multi-slice tiff images.\n+cmd = imagej2_base_utils.get_base_command_imagej2( None, jython_script=args.jython_script )\n+if cmd is None:\n+    imagej2_base_utils.stop_err( "ImageJ not found!" )\n+if args.mono:\n+    # bUnwarpJ will produce only a registered source image.\n+    cmd += \' %s %s %s %s\' % ( tmp_source_out_tiff_path,\n+                              args.source_out_datatype,\n+                              tmp_source_out_path,\n+                              args.mono )\n+else:\n+    # bUnwarpJ will produce registered source and target images.\n+    cmd += \' %s %s %s %s %s %s %s\' % ( tmp_source_out_tiff_path,\n+                                       args.source_out_datatype,\n+                                       tmp_source_out_path,\n+                                       tmp_target_out_tiff_path,\n+                                       args.target_out_datatype,\n+                                       tmp_target_out_path,\n+                                       args.mono )\n+\n+# Merge the multi-slice tiff layers into an image that can be viewed in Galaxy.\n+proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )\n+rc = proc.wait()\n+if rc != 0:\n+    error_message = imagej2_base_utils.get_stderr_exception( tmp_err, tmp_stderr, tmp_out, tmp_stdout )\n+    imagej2_base_utils.stop_err( error_message )\n+\n+# Save the Registered Source Image to the output dataset.\n+shutil.move( tmp_source_out_path, args.source_out )\n+if not args.mono:\n+    # Move the Registered Target Image to the output dataset.\n+    shutil.move( tmp_target_out_path, args.target_out )\n+\n+# If requested, save matrix transformations as additional datasets.\n+if save_transformation:\n+    shutil.move( tmp_source_out_transf_path, args.source_trans_out )\n+    if not args.mono:\n+        shutil.move( tmp_target_out_transf_path, args.target_trans_out )\n+\n+imagej2_base_utils.cleanup_before_exit( tmp_dir )\n'
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_align_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_align_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,37 @@
+import sys
+import jython_utils
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+
+if sys.argv[ -1 ].lower() in [ 'true' ]:
+    mono = True
+else:
+    mono = False
+
+if mono:
+    # bUnwarpJ has been called with the -mono param.
+    source_tiff_path = sys.argv[ -4 ]
+    source_datatype = sys.argv[ -3 ]
+    source_path = sys.argv[ -2 ]
+else:
+    source_tiff_path = sys.argv[ -7 ]
+    source_datatype = sys.argv[ -6 ]
+    source_path = sys.argv[ -5 ]
+    target_tiff_path = sys.argv[ -4 ]
+    target_datatype = sys.argv[ -3 ]
+    target_path = sys.argv[ -2 ]
+
+# Save the Registered Source Image.
+registered_source_image = IJ.openImage( source_tiff_path )
+if source_datatype == 'tiff':
+    registered_source_image = jython_utils.convert_before_saving_as_tiff( registered_source_image )
+IJ.saveAs( registered_source_image, source_datatype, source_path )
+
+if not mono:
+    # Save the Registered Target Image.
+    registered_target_image = IJ.openImage( target_tiff_path )
+    if target_datatype == 'tiff':
+        registered_target_image = jython_utils.convert_before_saving_as_tiff( registered_target_image )
+    IJ.saveAs( registered_target_image, target_datatype, target_path )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_compare_elastic.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_compare_elastic.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+import argparse
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--source_transformation', dest='source_transformation', help='Direct source transformation matrix' )
+parser.add_argument( '--target_transformation', dest='target_transformation', help='Inverse target transformation matrix' )
+parser.add_argument( '--output', dest='output', help='Warping index' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+source_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_transformation, 'txt' )
+target_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_transformation, 'txt' )
+# bUnwarpJ produces several lines of output that we need to discard, so
+# we'll use a temporary output file from which we'll read only the last line.
+tmp_output_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.output, 'txt' )
+
+# 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' )
+
+# Build the command line to calculate the warping index.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -compare_elastic'
+# Target is sent before source.
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % target_transformation_path
+cmd += ' %s' % source_transformation_path
+cmd += ' > %s' % tmp_output_path
+
+# Calculate the warping index of two elastic transformations using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )
+rc = proc.wait()
+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 )
+
+# Example contents of tmp_output_path:
+# ['Target image : ~/tmpKAYF1P.jpg\n',
+#  'Source image : ~/tmpgQX0dy.gif\n',
+#  'Target Transformation file : ~/tmpZJC_4B.txt\n',
+#  'Source Transformation file : ~/tmphsSojl.txt\n',
+#  ' Warping index = 14.87777347388348\n']
+results = open( tmp_output_path, 'r' ).readlines()
+warp_index = results[ -1 ].split( ' ' )[ -1 ]
+outf = open( args.output, 'wb' )
+outf.write( '%s' % warp_index )
+outf.close()
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_compare_elastic_raw.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_compare_elastic_raw.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+import argparse
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--target_elastic_transformation', dest='target_elastic_transformation', help='Target elastic transformation matrix' )
+parser.add_argument( '--source_raw_transformation', dest='source_raw_transformation', help='Source raw transformation matrix' )
+parser.add_argument( '--output', dest='output', help='Warping index' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+target_elastic_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_elastic_transformation, 'txt' )
+source_raw_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_raw_transformation, 'txt' )
+# bUnwarpJ produces several lines of output that we need to discard, so
+# we'll use a temporary output file from which we'll read only the last line.
+tmp_output_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.output, 'txt' )
+
+# 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' )
+
+# Build the command line to calculate the warping index.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -compare_elastic_raw'
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % target_elastic_transformation_path
+cmd += ' %s' % source_raw_transformation_path
+cmd += ' > %s' % tmp_output_path
+
+# Calculate the warping index of elastic and raw transformations using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )
+rc = proc.wait()
+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 )
+
+# Example contents of tmp_output_path:
+# ['Target image : ~/tmpHdt9Cs.jpg\n',
+#  'Source image : ~/tmpu6kyfc.gif\n',
+#  'Elastic Transformation file   : ~/tmp4vZurG.txt\n',
+#  'Raw Transformation file : ~/tmp2PNQcT.txt\n',
+#  ' Warping index = 25.007467512204983\n']
+results = open( tmp_output_path, 'r' ).readlines()
+warp_index = results[ -1 ].split( ' ' )[ -1 ]
+outf = open( args.output, 'wb' )
+outf.write( '%s' % warp_index )
+outf.close()
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_compare_elastic_raw.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_compare_elastic_raw.xml Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,52 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<tool id="imagej2_bunwarpj_compare_elastic_raw" name="Compare elastic and raw deformation" version="@WRAPPER_VERSION@.0">
+    <description>by warping index with bUnwarpJ</description>
+    <macros>
+        <import>imagej2_macros.xml</import>
+    </macros>
+    <expand macro="fiji_requirements" />
+    <command>
+<![CDATA[
+    python $__tool_directory__/imagej2_bunwarpj_compare_elastic_raw.py
+    --target_image "$target_image"
+    --target_image_format $target_image.ext
+    --source_image "$source_image"
+    --source_image_format $source_image.ext
+    --target_elastic_transformation "$target_elastic_transformation"
+    --source_raw_transformation "$source_raw_transformation"
+    --output "$output"
+]]>
+    </command>
+    <inputs>
+        <param format="bmp,eps,gif,jpg,pcx,pgm,png,psd,tiff" name="target_image" type="data" label="Target image"/>
+        <param format="bmp,eps,gif,jpg,pcx,pgm,png,psd,tiff" name="source_image" type="data" label="Source image"/>
+        <param format="txt" name="target_elastic_transformation" type="data" label="Elastic transformation file"/>
+        <param format="txt" name="source_raw_transformation" type="data" label="Raw transformation file"/>
+    </inputs>
+    <outputs>
+        <data name="output" format="txt" label="${tool.name} (same direction) on ${on_string}: Warping index" />
+    </outputs>
+    <tests>
+        <test>
+            <param name="target_image" value="dotblot.jpg" />
+            <param name="source_image" value="blobs.gif" />
+            <param name="target_elastic_transformation" value="target_elastic_transformation.txt" />
+            <param name="source_raw_transformation" value="source_raw_transformation.txt" />
+            <output name="output" file="warping_index_raw.txt" compare="contains" />
+        </test>
+    </tests>
+    <help>
+**What it does**
+
+<![CDATA[
+Calculates the warping index of an elastic transformation and a raw transformation. The elastic
+transformation file must be in the same format as the files created with the **Save transformation**
+option of the **Align two images with bUnwarpJ** tool, while the raw transformation file must be
+in the same format as the file produced by the **Convert elastic transformation to raw with bUnwarpJ**
+tool.
+
+]]>
+
+    </help>
+    <expand macro="bunwarpj_citations" />
+</tool>
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_compare_raw.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_compare_raw.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+import argparse
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--target_raw_transformation', dest='target_raw_transformation', help='First raw transformation matrix' )
+parser.add_argument( '--source_raw_transformation', dest='source_raw_transformation', help='Second raw transformation matrix' )
+parser.add_argument( '--output', dest='output', help='Warping index' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+target_raw_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_raw_transformation, 'txt' )
+source_raw_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_raw_transformation, 'txt' )
+# bUnwarpJ produces several lines of output that we need to discard, so
+# we'll use a temporary output file from which we'll read only the last line.
+tmp_output_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.output, 'txt' )
+
+# 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' )
+
+# Build the command line to calculate the warping index.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -compare_raw'
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % target_raw_transformation_path
+cmd += ' %s' % source_raw_transformation_path
+cmd += ' > %s' % tmp_output_path
+
+# Calculate the warping index of two raw transformations using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )
+rc = proc.wait()
+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 )
+
+# Example contents of tmp_output_path:
+# ['Target image : ~/tmp5WmDku.jpg\n',
+#  'Source image : ~/tmps74U40.gif\n',
+#  'Target Transformation file : ~/tmpXofC1x.txt\n',
+#  'Source Transformation file : ~/tmpFqNYe4.txt\n',
+#  ' Warping index = 24.111209027033937\n']
+results = open( tmp_output_path, 'r' ).readlines()
+warp_index = results[ -1 ].split( ' ' )[ -1 ]
+outf = open( args.output, 'wb' )
+outf.write( '%s' % warp_index )
+outf.close()
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_compose_elastic.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_compose_elastic.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+import argparse
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--source_elastic_transformation', dest='source_elastic_transformation', help='Direct source transformation matrix' )
+parser.add_argument( '--target_elastic_transformation', dest='target_elastic_transformation', help='Inverse target transformation matrix' )
+parser.add_argument( '--output', dest='output', help='Warping index' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+source_elastic_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_elastic_transformation, 'txt' )
+target_elastic_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_elastic_transformation, 'txt' )
+
+# 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' )
+
+# Build the command line to compose the transformations.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -compose_elastic'
+# Target is sent before source.
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % target_elastic_transformation_path
+cmd += ' %s' % source_elastic_transformation_path
+cmd += ' %s' % args.output
+
+# Compose the two elastic transformations into a raw transformation using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )
+rc = proc.wait()
+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 )
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_compose_raw.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_compose_raw.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+import argparse
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--source_raw_transformation', dest='source_raw_transformation', help='Direct source transformation matrix' )
+parser.add_argument( '--target_raw_transformation', dest='target_raw_transformation', help='Inverse target transformation matrix' )
+parser.add_argument( '--output', dest='output', help='Warping index' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+source_raw_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_raw_transformation, 'txt' )
+target_raw_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_raw_transformation, 'txt' )
+
+# 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' )
+
+# Build the command line to compose the two raw transformations.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -compose_raw'
+# Target is sent before source.
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % target_raw_transformation_path
+cmd += ' %s' % source_raw_transformation_path
+cmd += ' %s' % args.output
+
+# Compose the two raw transformations into another raw transformation using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )
+rc = proc.wait()
+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 )
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_compose_raw_elastic.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_compose_raw_elastic.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+import argparse
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--source_elastic_transformation', dest='source_elastic_transformation', help='Direct source transformation matrix' )
+parser.add_argument( '--target_raw_transformation', dest='target_raw_transformation', help='Inverse target transformation matrix' )
+parser.add_argument( '--output', dest='output', help='Warping index' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+source_elastic_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_elastic_transformation, 'txt' )
+target_raw_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_raw_transformation, 'txt' )
+
+# 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' )
+
+# Build the command line to compose the raw and elastic transformations.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -compose_raw_elastic'
+# Target is sent before source.
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % target_raw_transformation_path
+cmd += ' %s' % source_elastic_transformation_path
+cmd += ' %s' % args.output
+
+# Compose the raw and elastic transformations into another raw transformation using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )
+rc = proc.wait()
+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 )
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_convert_to_raw.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_convert_to_raw.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+import argparse
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--elastic_transformation', dest='elastic_transformation', help='Elastic transformation as saved by bUnwarpJ in elastic format' )
+parser.add_argument( '--raw_transformation', dest='raw_transformation', help='Raw transformation' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+elastic_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.elastic_transformation, 'txt' )
+
+# 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' )
+
+# Build the command line to convert the B-spline (i.e., elastic) transformation to raw.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -convert_to_raw'
+# Target is sent before source.
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % elastic_transformation_path
+cmd += ' %s' % args.raw_transformation
+
+# Convert the elastic transformation to raw using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )
+rc = proc.wait()
+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 )
+
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_elastic_transform.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_elastic_transform.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+import argparse
+import shutil
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--elastic_transformation', dest='elastic_transformation', help='Elastic transformation as saved by bUnwarpJ in elastic format' )
+parser.add_argument( '--source_out', help='Output source image' )
+parser.add_argument( '--source_out_datatype', help='Output registered source image format' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+tmp_source_out_tiff_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, 'tiff' )
+tmp_source_out_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, args.source_out_datatype )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+elastic_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.elastic_transformation, 'txt' )
+
+# 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' )
+
+# Build the command line to apply the transformation.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -elastic_transform'
+# Target is sent before source.
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % elastic_transformation_path
+cmd += ' %s' % tmp_source_out_tiff_path
+
+# Apply the elastic transformation using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )
+rc = proc.wait()
+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 )
+
+# Convert the registered image to the specified output format.
+tmp_out = tempfile.NamedTemporaryFile().name
+tmp_stdout = open( tmp_out, 'wb' )
+tmp_err = tempfile.NamedTemporaryFile().name
+tmp_stderr = open( tmp_err, 'wb' )
+
+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 %s %s' % ( tmp_source_out_tiff_path,
+                       args.source_out_datatype,
+                       tmp_source_out_path )
+
+proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )
+rc = proc.wait()
+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 )
+
+# Save the Registered Source Image to the defined output.
+shutil.move( tmp_source_out_path, args.source_out )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_elastic_transform_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_elastic_transform_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,16 @@
+import sys
+import jython_utils
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+
+source_tiff_path = sys.argv[ -3 ]
+source_datatype = sys.argv[ -2 ]
+source_path = sys.argv[ -1 ]
+
+# Save the Registered Source Image.
+registered_source_image = IJ.openImage( source_tiff_path )
+if source_datatype == 'tiff':
+    registered_source_image = jython_utils.convert_before_saving_as_tiff( registered_source_image )
+IJ.saveAs( registered_source_image, source_datatype, source_path )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_raw_transform.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_raw_transform.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+import argparse
+import shutil
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+# Parse Command Line.
+parser = argparse.ArgumentParser()
+parser.add_argument( '--source_image', dest='source_image', help='Source image' )
+parser.add_argument( '--source_image_format', dest='source_image_format', help='Source image format' )
+parser.add_argument( '--target_image', dest='target_image', help='Target image' )
+parser.add_argument( '--target_image_format', dest='target_image_format', help='Target image format' )
+parser.add_argument( '--raw_transformation', dest='raw_transformation', help='Raw transformation as saved by bUnwarpJ' )
+parser.add_argument( '--source_out', help='Output source image' )
+parser.add_argument( '--source_out_datatype', help='Output registered source image format' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+
+args = parser.parse_args()
+
+tmp_dir = imagej2_base_utils.get_temp_dir()
+source_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.source_image, args.source_image_format )
+tmp_source_out_tiff_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, 'tiff' )
+tmp_source_out_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, args.source_out_datatype )
+target_image_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.target_image, args.target_image_format )
+raw_transformation_path = imagej2_base_utils.get_input_image_path( tmp_dir, args.raw_transformation, 'txt' )
+
+# 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' )
+
+# Build the command line to apply the raw transformation.
+cmd = imagej2_base_utils.get_base_cmd_bunwarpj( None )
+if cmd is None:
+    imagej2_base_utils.stop_err( "bUnwarpJ not found!" )
+cmd += ' -raw_transform'
+# Target is sent before source.
+cmd += ' %s' % target_image_path
+cmd += ' %s' % source_image_path
+cmd += ' %s' % raw_transformation_path
+cmd += ' %s' % tmp_source_out_tiff_path
+
+# Apply the raw transformation using bUnwarpJ.
+proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )
+rc = proc.wait()
+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 )
+
+# Convert the registered image to the specified output format.
+tmp_out = tempfile.NamedTemporaryFile().name
+tmp_stdout = open( tmp_out, 'wb' )
+tmp_err = tempfile.NamedTemporaryFile().name
+tmp_stderr = open( tmp_err, 'wb' )
+
+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 %s %s' % ( tmp_source_out_tiff_path,
+                       args.source_out_datatype,
+                       tmp_source_out_path )
+
+proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )
+rc = proc.wait()
+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 )
+
+# Save the Registered Source Image to the defined output.
+shutil.move( tmp_source_out_path, args.source_out )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_bunwarpj_raw_transform_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_bunwarpj_raw_transform_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,16 @@
+import sys
+import jython_utils
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+
+source_tiff_path = sys.argv[ -3 ]
+source_datatype = sys.argv[ -2 ]
+source_path = sys.argv[ -1 ]
+
+# Save the Registered Source Image.
+registered_source_image = IJ.openImage( source_tiff_path )
+if source_datatype == 'tiff':
+    registered_source_image = jython_utils.convert_before_saving_as_tiff( registered_source_image )
+IJ.saveAs( registered_source_image, source_datatype, source_path )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_create_image.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_create_image.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+import argparse
+import shutil
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+if __name__=="__main__":
+    # Parse Command Line.
+    parser = argparse.ArgumentParser()
+    parser.add_argument( '--width', dest='width', type=int, help='Image width in pixels' )
+    parser.add_argument( '--height', dest='height', type=int, help='Image height in pixels' )
+    parser.add_argument( '--depth', dest='depth', type=int, help='Image depth (specifies the number of stack slices)' )
+    parser.add_argument( '--image_type', dest='image_type', help='Image type' )
+    parser.add_argument( '--image_title', dest='image_title', default='', help='Image title' )
+    parser.add_argument( '--output_datatype', dest='output_datatype', help='Output image format' )
+    parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+    parser.add_argument( '--out_fname', help='Path to the output file' )
+    args = parser.parse_args()
+
+    tmp_dir = imagej2_base_utils.get_temp_dir()
+    tmp_image_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' )
+    # 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 %d %d %d %s %s' % ( args.image_title, args.width, args.height, args.depth, args.image_type, tmp_image_path )
+    proc = subprocess.Popen( args=cmd, stderr=tmp_stderr, stdout=tmp_stdout, shell=True )
+    rc = proc.wait()
+    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 )
+    shutil.move( tmp_image_path, args.out_fname )
+    imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_create_image_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_create_image_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,14 @@
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+title = sys.argv[ -6 ]
+width = int( sys.argv[ -5 ] )
+height = int( sys.argv[ -4 ] )
+depth = int( sys.argv[ -3 ] )
+type = sys.argv[ -2 ].replace( '_', ' ' )
+tmp_image_path = sys.argv[ -1 ]
+
+imp = IJ.newImage( title, type, width, height, depth )
+IJ.save( imp, "%s" % tmp_image_path )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_enhance_contrast.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_enhance_contrast.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,63 @@
+#!/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( '--equalize_histogram', dest='equalize_histogram', help='Equalize_histogram' )
+parser.add_argument( '--saturated_pixels', dest='saturated_pixels', type=float, default=None, help='Saturated pixel pct' )
+parser.add_argument( '--normalize', dest='normalize', help='Normalize' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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.equalize_histogram
+cmd += imagej2_base_utils.handle_none_type( args.saturated_pixels )
+cmd += ' %s' % args.normalize
+cmd += ' %s' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+
+# 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 )
+
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_enhance_contrast_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_enhance_contrast_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,42 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -7 ]
+input = sys.argv[ -6 ]
+equalize_histogram = jython_utils.asbool( sys.argv[ -5 ] )
+saturated_pixels = sys.argv[ -4 ]
+normalize = jython_utils.asbool( sys.argv[ -3 ] )
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+bit_depth = image_processor_copy.getBitDepth()
+
+# Set the options
+options = []
+# If equalize_histogram, saturated_pixels and normalize are ignored.
+if equalize_histogram:
+    options.append( 'equalize' )
+else:
+    if saturated_pixels not in [ None, 'None' ]:
+        # Fiji allows only a single decimal place for this value.
+        options.append( 'saturated=%.3f' % float( saturated_pixels ) )
+    # Normalization of RGB images is not supported.
+    if bit_depth != 24 and normalize:
+        options.append( 'normalize' )
+try:
+    # Run the command.
+    options = "%s" % ' '.join( options )
+    IJ.run( input_image_plus_copy, "Enhance Contrast...", options )
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_find_edges.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_find_edges.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,57 @@
+#!/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( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+
+# 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 )
+
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_find_edges_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_find_edges_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,25 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -4 ]
+input = sys.argv[ -3 ]
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+try:
+    # Run the command.
+    IJ.run( input_image_plus_copy, "Find Edges", "" )
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_find_maxima.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_find_maxima.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,69 @@
+#!/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( '--scale_when_converting', dest='scale_when_converting', help='Scale when converting RGB image' )
+parser.add_argument( '--weighted_rgb_conversions', dest='weighted_rgb_conversions', help='Weighted RGB conversions for RGB image' )
+parser.add_argument( '--noise_tolerance', dest='noise_tolerance', type=int, help='Noise tolerance' )
+parser.add_argument( '--output_type', dest='output_type', help='Output type' )
+parser.add_argument( '--exclude_edge_maxima', dest='exclude_edge_maxima', help='Exclude edge maxima' )
+parser.add_argument( '--light_background', dest='light_background', help='Light background' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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.scale_when_converting
+cmd += ' %s' % args.weighted_rgb_conversions
+cmd += ' %d' % args.noise_tolerance
+cmd += ' %s' % args.output_type
+cmd += ' %s' % args.exclude_edge_maxima
+cmd += ' %s' % args.light_background
+cmd += ' %s' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+
+# 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 )
+
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_find_maxima_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_find_maxima_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,94 @@
+import sys
+import jython_utils
+from ij import ImagePlus, IJ
+from ij.plugin.filter import Analyzer, MaximumFinder
+from ij.process import ImageProcessor
+from jarray import array
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -10 ]
+input = sys.argv[ -9 ]
+scale_when_converting = jython_utils.asbool( sys.argv[ -8 ] )
+weighted_rgb_conversions = jython_utils.asbool( sys.argv[ -7 ] )
+noise_tolerance = int( sys.argv[ -6 ] )
+output_type = sys.argv[ -5 ]
+exclude_edge_maxima = jython_utils.asbool( sys.argv[ -4 ] )
+light_background = jython_utils.asbool( sys.argv[ -3 ] )
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+bit_depth = image_processor_copy.getBitDepth()
+analyzer = Analyzer( input_image_plus_copy )
+
+try:
+    # Set the conversion options.
+    options = []
+    # The following 2 options are applicable only to RGB images.
+    if bit_depth == 24:
+        if scale_when_converting:
+            option.append( "scale" )
+        if weighted_rgb_conversions:
+            options.append( "weighted" )
+    # Perform conversion - must happen even if no options are set.
+    IJ.run( input_image_plus_copy, "Conversions...", "%s" % " ".join( options ) )
+    if output_type in [ 'List', 'Count' ]:
+        # W're  generating a tabular file for the output.
+        # Set the Find Maxima options.
+        options = [ 'noise=%d' % noise_tolerance ]
+        if output_type.find( '_' ) > 0:
+            output_type_str = 'output=[%s]' % output_type.replace( '_', ' ' )
+        else:
+            output_type_str = 'output=%s' % output_type
+        options.append( output_type_str )
+        if exclude_edge_maxima:
+            options.append( 'exclude' )
+        if light_background:
+            options.append( 'light' )
+        # Run the command.
+        IJ.run( input_image_plus_copy, "Find Maxima...", "%s" % " ".join( options ) )
+        results_table = analyzer.getResultsTable()
+        results_table.saveAs( tmp_output_path )
+    else:
+        # Find the maxima of an image (does not find minima).
+        # LIMITATIONS: With output_type=Segmented_Particles
+        # (watershed segmentation), some segmentation lines
+        # may be improperly placed if local maxima are suppressed
+        # by the tolerance.
+        mf = MaximumFinder()
+        if output_type == 'Single_Points':
+            output_type_param = mf.SINGLE_POINTS
+        elif output_type == 'Maxima_Within_Tolerance':
+            output_type_param = mf.IN_TOLERANCE
+        elif output_type == 'Segmented_Particles':
+            output_type_param = mf.SEGMENTED
+        elif output_type == 'List':
+            output_type_param = mf.LIST
+        elif output_type == 'Count':
+            output_type_param = mf.COUNT
+        # Get a new byteProcessor with a normal (uninverted) LUT where
+        # the marked points are set to 255 (Background 0). Pixels outside
+        # of the roi of the input image_processor_copy are not set. No
+        # output image is created for output types POINT_SELECTION, LIST
+        # and COUNT.  In these cases findMaxima returns null.
+        byte_processor = mf.findMaxima( image_processor_copy,
+                                        noise_tolerance,
+                                        ImageProcessor.NO_THRESHOLD,
+                                        output_type_param,
+                                        exclude_edge_maxima,
+                                        False )
+        # Invert the image or ROI.
+        byte_processor.invert()
+        if output_type == 'Segmented_Particles' and not light_background:
+            # Invert the values in this image's LUT (indexed color model).
+            byte_processor.invertLut()
+        image_plus = ImagePlus( "output", byte_processor )
+        IJ.saveAs( image_plus, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_macros.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_macros.xml Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,106 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<macros>
+    <token name="@WRAPPER_VERSION@">3.0</token>
+    <xml name="fiji_requirements">
+        <requirements>
+            <requirement type="package" version="20170530">fiji</requirement>
+        </requirements>
+    </xml>
+    <xml name="stdio">
+        <stdio>
+            <exit_code range="1:"/>
+            <exit_code range=":-1"/>
+            <regex match="Error:"/>
+            <regex match="Exception:"/>
+        </stdio>
+    </xml>
+    <xml name="image_type">
+        <param name="image_type" type="select" label="Image type">
+            <option value="8-bit_white" selected="True">8-bit white</option>
+            <option value="8-bit_black">8-bit black</option>
+            <option value="8-bit_random">8-bit random</option>
+            <option value="8-bit_ramp">8-bit ramp</option>
+            <option value="16-bit_white">16-bit white</option>
+            <option value="16-bit_black">16-bit black</option>
+            <option value="16-bit_random">16-bit random</option>
+            <option value="16-bit_ramp">16-bit ramp</option>
+            <option value="32-bit_white">32-bit white</option>
+            <option value="32-bit_black">32-bit black</option>
+            <option value="32-bit_random">32-bit random</option>
+            <option value="32-bit_ramp">32-bit ramp</option>
+            <option value="RGB_white">RGB white</option>
+            <option value="RGB_black">RGB black</option>
+            <option value="RGB_random">RGB random</option>
+            <option value="RGB_ramp">RGB ramp</option>
+        </param>
+    </xml>
+    <xml name="make_binary_params">
+        <param name="iterations" type="integer" value="1" min="1" max="100" label="Iterations" help="The number of times (1-100) erosion, dilation, opening, and closing are performed."/>
+        <param name="count" type="integer" value="1" min="1" max="8" label="Count" help="The number of adjacent background pixels necessary (1-8) for erosion or dilation."/>
+        <param name="black_background" type="select" label="Black background" help="If Yes, the background is black and the foreground is white (no implies the opposite).">
+            <option value="no" selected="True">No</option>
+            <option value="yes">Yes</option>
+        </param>
+        <param name="pad_edges_when_eroding" type="select" label="Pad edges when eroding" help="If Yes, eroding does not erode from the edges of the image.">
+            <option value="no" selected="True">No</option>
+            <option value="yes">Yes</option>
+        </param>
+    </xml>
+    <xml name="black_background_param">
+        <param name="black_background" type="select" label="Black background" help="If Yes, the background is black and the foreground is white (no implies the opposite).">
+            <option value="no" selected="True">No</option>
+            <option value="yes">Yes</option>
+        </param>
+    </xml>
+    <token name="@make_binary_args@">
+        --iterations $iterations
+        --count $count
+        --black_background $black_background
+        --pad_edges_when_eroding $pad_edges_when_eroding
+    </token>
+    <token name="@requires_binary_input@">
+.. 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)**
+tool, which allows you to change them.
+    </token>
+    <xml name="image_datatypes">
+        <option value="bmp">bmp</option>
+        <option value="gif">gif</option>
+        <option value="jpg">jpg</option>
+        <option value="png" selected="true">png</option>
+        <option value="tiff">tiff</option>
+    </xml>
+    <xml name="bunwarpj_citations">
+        <citations>
+            <citation type="bibtex">
+                @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")
+            </citation>
+            <citation type="doi">10.1038/nmeth.2019</citation>
+        </citations>
+    </xml>
+    <xml name="fiji_headless_citations">
+        <citations>
+            <citation type="doi">10.1038/nmeth.2102</citation>
+        </citations>
+    </xml>
+</macros>
b
diff -r 000000000000 -r 1bffabc15695 imagej2_make_binary.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_make_binary.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,59 @@
+#!/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( '--iterations', dest='iterations', type=int, help='Iterations' )
+parser.add_argument( '--count', dest='count', type=int, help='Count' )
+parser.add_argument( '--black_background', dest='black_background', help='Black background' )
+parser.add_argument( '--pad_edges_when_eroding', dest='pad_edges_when_eroding', help='Pad edges when eroding' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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 += ' %d' % args.iterations
+cmd += ' %d' % args.count
+cmd += ' %s' % args.black_background
+cmd += ' %s' % args.pad_edges_when_eroding
+cmd += ' %s' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+# 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 )
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_make_binary_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_make_binary_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,37 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -8 ]
+input = sys.argv[ -7 ]
+iterations = int( sys.argv[ -6 ] )
+count = int( sys.argv[ -5 ] )
+black_background = jython_utils.asbool( sys.argv[ -4 ] )
+pad_edges_when_eroding = jython_utils.asbool( sys.argv[ -3 ] )
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+try:
+    # Set binary options.
+    options = jython_utils.get_binary_options( black_background=black_background,
+                                               iterations=iterations,
+                                               count=count,
+                                               pad_edges_when_eroding=pad_edges_when_eroding )
+    IJ.run( input_image_plus_copy, "Options...", options )
+
+    # Run the command.
+    IJ.run( input_image_plus_copy, "Make Binary", "" )
+
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_math.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_math.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,69 @@
+#!/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( '--operation', dest='operation', help='Operation' )
+parser.add_argument( '--expression', dest='expression', default=None, help='Expression' )
+parser.add_argument( '--bin_constant', dest='bin_constant', type=int, default=None, help='Constant of type binary integer' )
+parser.add_argument( '--float_constant', dest='float_constant', type=float, default=None, help='Constant of type float' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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.operation
+# Handle the expression, which must be enclosed in " if not None.
+if args.expression in [ None, 'None' ]:
+    cmd += ' None'
+else:
+    cmd += ' "%s"' % args.expression
+cmd += imagej2_base_utils.handle_none_type( args.bin_constant, val_type='int' )
+cmd += imagej2_base_utils.handle_none_type( args.float_constant )
+cmd += ' %s' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+
+# 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 )
+
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_math_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_math_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,78 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -8 ]
+input = sys.argv[ -7 ]
+operation = sys.argv[ -6 ]
+expression = sys.argv[ -5 ]
+if sys.argv[ -4 ] in [ None, 'None' ]:
+    bin_constant = None
+else:
+    bin_constant = int( sys.argv[ -4 ] )
+if sys.argv[ -3 ] in [ None, 'None' ]:
+    float_constant = None
+else:
+    float_constant = float( sys.argv[ -3 ] )
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+bit_depth = image_processor_copy.getBitDepth()
+
+try:
+    if operation.find( '_' ) > 0:
+        # Square_Root.
+        new_operation = operation.replace( '_', ' ' )
+    elif operation in [ 'Square', 'Log', 'Exp', 'Abs', 'Reciprocal' ]:
+        # Unfortunately some ImageJ commands require a "..." ending
+        # while others do not.  There seems to be no pattern.
+        new_operation = '%s' % operation
+    else:
+        new_operation = '%s...' % operation
+
+    if operation == 'Macro':
+        # Apply the macro code to the image via a call to it's
+        # ImageProcessor since this option does not work using
+        # the IJ.run() method.
+        new_expression = expression.lstrip( '"' ).rstrip( '"' )
+        options = 'code=%s' % new_expression
+        image_processor_copy.applyMacro( new_expression )
+    elif operation == 'Min':
+        # Min does not work without using the ImageProcessor.
+        image_processor_copy.min( float_constant )
+    elif operation == 'Max':
+        # Max does not work without using the ImageProcessor.
+        image_processor_copy.max( float_constant )
+    elif operation == 'Abs':
+        if bit_depth not in [ 16, 32 ]:
+            # Convert the image to 32-bit.
+            IJ.run( input_image_plus_copy, "32-bit", "" )
+            IJ.run( input_image_plus_copy, new_operation, "" )
+    elif operation == 'Reciprocal':
+        if bit_depth != 32:
+            # Convert the image to 32 bit.
+            IJ.run( input_image_plus_copy, "32-bit", "" )
+            IJ.run( input_image_plus_copy, new_operation, "" )
+    else:
+        if operation in [ 'AND', 'OR', 'XOR' ]:
+            # Value is a binary number.
+            options = 'value=%d' % bin_constant
+        elif operation in [ 'Log', 'Exp', 'Square', 'Square_Root' ]:
+            # No constant value.
+            options = ''
+        else:
+            # Value is a floating point number.
+            options = 'value=%.3f' % float_constant
+        IJ.run( input_image_plus_copy, "%s" % new_operation, "%s" % options )
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_noise.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_noise.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+import argparse
+import os
+import shutil
+import subprocess
+import tempfile
+import imagej2_base_utils
+
+if __name__=="__main__":
+    # Parse Command Line.
+    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( '--noise', dest='noise', help='Specified noise to add to or remove from the image' )
+    parser.add_argument( '--standard_deviation', dest='standard_deviation', type=float, default=None, help='Standard deviation' )
+    parser.add_argument( '--radius', dest='radius', type=float, default=None, help='Radius' )
+    parser.add_argument( '--threshold', dest='threshold', type=float, default=None, help='Threshold' )
+    parser.add_argument( '--which_outliers', dest='which_outliers', default=None, help='Which outliers' )
+    parser.add_argument( '--randomj', dest='randomj', default=None, help='RandomJ' )
+    parser.add_argument( '--trials', dest='trials', type=float, default=None, help='Trials' )
+    parser.add_argument( '--probability', dest='probability', type=float, default=None, help='Probability' )
+    parser.add_argument( '--lammbda', dest='lammbda', type=float, default=None, help='Lambda' )
+    parser.add_argument( '--order', dest='order', type=int, default=None, help='Order' )
+    parser.add_argument( '--mean', dest='mean', type=float, default=None, help='Mean' )
+    parser.add_argument( '--sigma', dest='sigma', type=float, default=None, help='Sigma' )
+    parser.add_argument( '--min', dest='min', type=float, default=None, help='Min' )
+    parser.add_argument( '--max', dest='max', type=float, default=None, help='Max' )
+    parser.add_argument( '--insertion', dest='insertion', default=None, help='Insertion' )
+    parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+    parser.add_argument( '--output', dest='output', help='Path to the output file' )
+    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 )
+    tmp_output_path = imagej2_base_utils.get_temporary_image_path( tmp_dir, args.input_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.input_datatype
+    cmd += ' %s ' % args.noise
+    cmd += imagej2_base_utils.handle_none_type( args.standard_deviation )
+    cmd += imagej2_base_utils.handle_none_type( args.radius )
+    cmd += imagej2_base_utils.handle_none_type( args.threshold )
+    cmd += ' %s' % args.which_outliers
+    cmd += ' %s' % args.randomj
+    cmd += imagej2_base_utils.handle_none_type( args.trials )
+    cmd += imagej2_base_utils.handle_none_type( args.probability )
+    cmd += imagej2_base_utils.handle_none_type( args.lammbda )
+    cmd += imagej2_base_utils.handle_none_type( args.order, val_type='int' )
+    cmd += imagej2_base_utils.handle_none_type( args.mean )
+    cmd += imagej2_base_utils.handle_none_type( args.sigma )
+    cmd += imagej2_base_utils.handle_none_type( args.min )
+    cmd += imagej2_base_utils.handle_none_type( args.max )
+    cmd += ' %s' % args.insertion
+    cmd += ' %s' % tmp_output_path
+
+    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 )
+    # Save the output image.
+    shutil.move( tmp_output_path, args.output )
+    imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_noise_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_noise_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,84 @@
+import sys
+from ij import IJ
+from ij import ImagePlus
+import jython_utils
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -19 ]
+input = sys.argv[ -18 ]
+image_datatype = sys.argv[ -17 ]
+noise = sys.argv[ -16 ]
+standard_deviation = sys.argv[ -15 ]
+radius = sys.argv[ -14 ]
+threshold = sys.argv[ -13 ]
+which_outliers = sys.argv[ -12 ]
+randomj = sys.argv[ -11 ]
+trials = sys.argv[ -10 ]
+probability = sys.argv[ -9 ]
+# Note the spelling - so things don't get confused due to Python lambda function.
+lammbda = sys.argv[ -8 ]
+order = sys.argv[ -7 ]
+mean = sys.argv[ -6 ]
+sigma = sys.argv[ -5 ]
+min = sys.argv[ -4 ]
+max = sys.argv[ -3 ]
+insertion = sys.argv[ -2 ]
+tmp_output_path = sys.argv[ -1 ]
+
+error = False
+
+# Open the input image file.
+image_plus = IJ.openImage( input )
+bit_depth = image_plus.getBitDepth()
+image_type = image_plus.getType()
+# Create an ImagePlus object for the image.
+image_plus_copy = image_plus.duplicate()
+# Make a copy of the image.
+image_processor_copy = image_plus_copy.getProcessor()
+
+# Perform the analysis on the ImagePlus object.
+if noise == 'add_noise':
+    IJ.run( image_plus_copy, "Add Noise", "" )
+elif noise == 'add_specified_noise':
+    IJ.run( image_plus_copy, "Add Specified Noise", "standard=&standard_deviation" )
+elif noise == 'salt_and_pepper':
+    IJ.run( image_plus_copy, "Salt and Pepper", "" )
+elif noise == 'despeckle':
+    IJ.run( image_plus_copy, "Despeckle", "" )
+elif noise == 'remove_outliers':
+    IJ.run( image_plus_copy, "Remove Outliers", "radius=&radius threshold=&threshold which=&which_outliers" )
+elif noise == 'remove_nans':
+    if bit_depth == 32:
+        IJ.run( image_plus_copy, "Remove NaNs", "" )
+    else:
+        # When Galaxy metadata for images is enhanced to include information like this,
+        # we'll be able to write tool validators rather than having to stop the job in
+        # an error state.
+        msg = "Remove NaNs requires a 32-bit image, the selected image is %d-bit" % bit_depth
+        jython_utils.handle_error( error_log, msg )
+        error = True
+elif noise == 'rof_denoise':
+    if image_type == ImagePlus.GRAY32:
+        IJ.run( image_plus_copy, "ROF Denoise", "" )
+    else:
+        msg = "ROF Denoise requires an image of type 32-bit grayscale, the selected image is %d-bit" % ( bit_depth )
+        jython_utils.handle_error( error_log, msg )
+        error = True
+elif noise == 'randomj':
+    if randomj == 'randomj_binomial':
+        IJ.run( image_plus_copy, "RandomJ Binomial", "trials=&trials probability=&probability insertion=&insertion" )
+    elif randomj == 'randomj_exponential':
+        IJ.run( image_plus_copy, "RandomJ Exponential", "lambda=&lammbda insertion=&insertion" )
+    elif randomj == 'randomj_gamma':
+        IJ.run( image_plus_copy, "RandomJ Gamma", "order=&order insertion=&insertion" )
+    elif randomj == 'randomj_gaussian':
+        IJ.run( image_plus_copy, "RandomJ Gaussian", "mean=&mean sigma=&sigma insertion=&insertion" )
+    elif randomj == 'randomj_poisson':
+        IJ.run( image_plus_copy, "RandomJ Poisson", "mean=&mean insertion=&insertion" )
+    elif randomj == 'randomj_uniform':
+        IJ.run( image_plus_copy, "RandomJ Uniform", "min=&min max=&max insertion=&insertion" )
+
+if not error:
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( image_plus_copy, image_datatype, tmp_output_path )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_shadows.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_shadows.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,59 @@
+#!/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( '--direction', dest='direction', help='Direction' )
+parser.add_argument( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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.direction
+cmd += ' %s' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+
+# 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 )
+
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_shadows_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_shadows_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,26 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -5 ]
+input = sys.argv[ -4 ]
+direction = sys.argv[ -3 ]
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+try:
+    # Run the command.
+    IJ.run( input_image_plus_copy, direction, "" )
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_sharpen.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_sharpen.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,57 @@
+#!/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( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+
+# 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 )
+
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_sharpen_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_sharpen_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,25 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -4 ]
+input = sys.argv[ -3 ]
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+try:
+    # Run the command.
+    IJ.run( input_image_plus_copy, "Sharpen", "" )
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_skeletonize3d.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_skeletonize3d.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,53 @@
+#!/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( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+# 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 )
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_skeletonize3d_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_skeletonize3d_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,36 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -5 ]
+input = sys.argv[ -4 ]
+black_background = jython_utils.asbool( sys.argv[ -3 ] )
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+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", "" )
+
+    # Run the command.
+    IJ.run( input_image_plus_copy, "Skeletonize (2D/3D)", "" )
+
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_smooth.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_smooth.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,57 @@
+#!/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( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+
+# 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 )
+
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_smooth_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_smooth_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,25 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -4 ]
+input = sys.argv[ -3 ]
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+try:
+    # Run the command.
+    IJ.run( input_image_plus_copy, "Smooth", "" )
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_watershed_binary.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_watershed_binary.py Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,53 @@
+#!/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( '--jython_script', dest='jython_script', help='Path to the Jython script' )
+parser.add_argument( '--output', dest='output', help='Path to the output file' )
+parser.add_argument( '--output_datatype', dest='output_datatype', 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 )
+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' % tmp_output_path
+cmd += ' %s' % args.output_datatype
+# 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 )
+# Save the output image.
+shutil.move( tmp_output_path, args.output )
+imagej2_base_utils.cleanup_before_exit( tmp_dir )
b
diff -r 000000000000 -r 1bffabc15695 imagej2_watershed_binary_jython_script.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagej2_watershed_binary_jython_script.py Tue Sep 17 16:55:25 2019 -0400
[
@@ -0,0 +1,36 @@
+import jython_utils
+import sys
+from ij import IJ
+
+# Fiji Jython interpreter implements Python 2.5 which does not
+# provide support for argparse.
+error_log = sys.argv[ -5 ]
+input = sys.argv[ -4 ]
+black_background = jython_utils.asbool( sys.argv[ -3 ] )
+tmp_output_path = sys.argv[ -2 ]
+output_datatype = 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()
+
+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", "" )
+
+    # Run the command.
+    IJ.run( input_image_plus_copy, "Watershed", "" )
+
+    # Save the ImagePlus object as a new image.
+    IJ.saveAs( input_image_plus_copy, output_datatype, tmp_output_path )
+except Exception, e:
+    jython_utils.handle_error( error_log, str( e ) )
b
diff -r 000000000000 -r 1bffabc15695 jython_utils$py.class
b
Binary file jython_utils$py.class has changed
b
diff -r 000000000000 -r 1bffabc15695 jython_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jython_utils.py Tue Sep 17 16:55:25 2019 -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()
b
diff -r 000000000000 -r 1bffabc15695 readme.md
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/readme.md Tue Sep 17 16:55:25 2019 -0400
[
b'@@ -0,0 +1,120 @@\n+Galaxy wrappers for ImageJ2 tools\n+==================================\n+\n+ImageJ2 is a new version of ImageJ for the next generation of multidimensional image data, with a focus on scientific imaging. Its central goal is to broaden the paradigm of ImageJ beyond the limitations of ImageJ 1.x, to support the next generation of multidimensional scientific imaging.\n+\n+Fiji is an image processing package. It can be described as a "batteries-included" distribution of ImageJ (and ImageJ2), bundling Java, Java3D and a lot of plugins organized into a coherent menu structure. Fiji compares to ImageJ as Ubuntu compares to Linux.\n+\n+More informations is available at:\n+\n+* [http://fiji.sc/ImageJ2](http://fiji.sc/ImageJ2)\n+* [http://fiji.sc/Fiji](http://fiji.sc/Fiji)\n+\n+\n+Installation\n+============\n+\n+Galaxy tool wrappers use specified Fiji Lifeline versions available from [http://fiji.sc/Downloads](http://fiji.sc/Downloads).  Galaxy should be able to automatically install this package.\n+\n+The wrappers are available at [https://github.com/bgruening/galaxytools/tree/master/tools/image_processing/imagej2](https://github.com/bgruening/galaxytools/tree/master/tools/image_processing/imagej2).\n+\n+\n+Use Docker\n+==========\n+\n+A docker image that installs Galaxy with these imaging tools is available at [https://github.com/bgruening/galaxy-imaging](https://github.com/bgruening/galaxy-imaging).\n+\n+\n+Using Fiji with Galaxy tools\n+============================\n+\n+Galaxy ImageJ2 tool wrappers generate a command line that calls a Python script, passing it a series of arguments including a Jython script named jython_script.py that resides in the same directory as the tool wrapper.  During tool execution, the Python script will call ImageJ2 with the --headless argument to run without the ImageJ2 GUI.  The Jython script is also passed to ImageJ2 along with all command line arguments that it expects.  ImageJ2 will execute the Jython script, passing the expected arguments.  The command line to run ImageJ2 from a Galaxy tool wrapper looks something like this:\n+\n+`ImageJ2 --ij2 --headless --jython ~jython_script.py arg1, arg2, ...`\n+\n+Each tool execution starts the ImageJ2 application within a Java virtual machine (JVM).  When ImageJ2 is finished processing the Jython script, the results are either written to a file or returned to the calling Galaxy process.  The JVM is shut down, and the Galaxy job terminates.  This approach provides the ability to run ImageJ2 tools from Galaxy on any supported HPC environment.\n+\n+Of course, eliminating the ImageJ2 GUI restricts us to wrapping only those ImageJ2 plugins that do not require any GUI components (i.e., the ImageJ2 window manager).  Plugins are written by an open community, so not all of them are written in such a way that they can be executed from the command line and produce useful results.  For example, some plugins create one or more images that can only be accessed via calls to the ImageJ2 window manager, and running in headless mode eliminates the window manager as well as other GUI components.\n+\n+Those familiar with ImageJ2 will find differences with this general pattern for executing ImageJ2 tools within Galaxy.  ImageJ2 accounts for user defined global preferences which are available to tools throughout the session, and an image can be uploaded and run through any number of available tools, saving only the final image.  While Galaxy currently does not account for user preferences defined in ImageJ2, enhancements to the Galaxy framework are planned that will accomodate these kinds of settings (e.g., binary image options).  Also, since Galaxy initiates a new ImageJ2 session with each tool execution, initial images are uploaded to ImageJ2 and resulting images are saved for each tool execution.\n+\n+The Galaxy ImageJ2 tools currently fall into the following categories.  Additional tools will be added at a steady pace.\n+\n+Working with Pixels\n+===================\n+These Galaxy tools wrap the Image'..b'+* **Convert binary image to EDM** - Converts a binary image into a 8-bit grayscale Euclidean Distance Map (EDM). Each foreground (nonzero) pixel in the binary image is assigned a value equal to its distance from the nearest background (zero) pixel.\n+\n+**Interpreting binary Images in ImageJ2**\n+\n+Binary images are thresholded to only two values, typically 0 and 1, but often \xe2\x80\x94 as with ImageJ \xe2\x80\x94 0 and 255, that represent black and white on an 8-bit scale.\n+\n+The interpretation of binary images is not universal. While some software packages will always perform binary operations on 255 values (or 1, or any non-zero value), ImageJ takes into account the foreground and background colors of the binary image.\n+\n+In ImageJ, the **Black background** global preference setting defines not only how new binary images will be created, but also how previously created images are interpreted. This means objects will be inferred on a image-per-image basis.  As such, inverting the LUT (i.e., pixels with a value of zero are white and pixels with a value 255 are black) of a binary image without updating the black background option may lead to unexpected results.  This issue can currently be avoided by properly selecting the **Black background** option available on all Galaxy binary image tools.\n+\n+BunwarpJ Plugin Tools\n+=====================\n+These Galaxy tools wrap the bUnwarpJ plugin [http://fiji.sc/BUnwarpJ](http://fiji.sc/BUnwarpJ).\n+\n+* **Adapt an elastic transformation** - Adapts an elastic transformation to a new image size by transforming the\n+coefficients of a specified elastic transformation according to a real image factor.\n+* **Align two images** - Performs a simultaneous registration of two images, A and B. Image A is elastically deformed\n+in order to look as similar as possible to image B, and, at the same time, the "inverse"\n+transformation (from B to A) is also calculated so a pseudo-invertibility of the final deformation\n+could be guaranteed.  Two images are produced: the deformed versions of A and B images.\n+* **Compare opposite elastic deformations** - Calculates the warping index of two opposite elast transformations, i.e. the average of the geometrical distance between every pixel and its version after applying both transformations (direct and inverse).\n+* **Compare elastic and raw deformation** - Calculates the warping index of an elastic transformation and a raw transformation.\n+* **Compare two raw deformations** - Calculates the warping index of two raw transformations (same direction).\n+* **Compose two elastic transformations** - Composes two elastic transformations into a raw transformation.\n+* **Compose two raw transformations** - Composes two raw transformations into another raw transformation.\n+* **Compose a raw and an elastic transformation** - Composes a raw transformation and an elastic transformation\n+into a raw transformation.\n+* **Convert elastic transformation to raw** - Converts an elastic (i.e., B-spline ) transformation file into a raw transformation file.\n+* **Apply elastic transformation** - Applies an elastic transformation to an image, producing another image which is elastically\n+deformed according to the transformation.\n+* **Apply raw transformation** - Applies a raw transformation to an image, producing another image which is deformed according\n+to the transformation.\n+\n+Other Tools\n+===========\n+* **Create new image** - Creates a new image of a selected type, size, depth and format.\n+* **Convert image format** - Converts the format of an input image file, producing an output image.\n+\n+Licence\n+=======\n+\n+Fiji is released as open source under the GNU General Public License: [http://www.gnu.org/licenses/gpl.html](http://www.gnu.org/licenses/gpl.html)\n+\n+Fiji builds on top of the ImageJ2 core, which is licensed under the permissive BSD 2-Clause license: [http://opensource.org/licenses/BSD-2-Clause](http://opensource.org/licenses/BSD-2-Clause)\n+\n+Plugins and other components have their own licenses.\n+\n'
b
diff -r 000000000000 -r 1bffabc15695 static/images/bunwarpj_scheme.png
b
Binary file static/images/bunwarpj_scheme.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/adapted_transformation.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/adapted_transformation.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,19 @@
+Intervals=4
+
+X Coeffs -----------------------------------
+   -71.22261496228916  -0.35442767924191093     70.55477101478836    141.48046330114607    212.39813136117553    283.36374640208885    354.43327963109795 
+   -71.28352256238495   -37.226230944094716     76.34084941944606    160.02208968373813       273.55343187174    254.79291915021662     354.2799811586804 
+    -71.2426429370489    -32.71748193741429     177.9000599691838    128.29850224500663    140.92089517714993    258.80790676143397    354.12912297861186 
+   -71.16592771634139   -5.2361603551610765     200.1952417342254    250.67440518610016     175.9632721236523     269.8182348834141    354.05647262505533 
+   -71.11932853032275   -11.878550966054844    225.55781625788134    230.48529336480044     258.5284090366016     303.9164005876728    354.13779763217406 
+   -71.08970622730098    20.302646615516533     74.38994929885534    150.94855292599084    233.92703879457446    303.27842533983653     354.2944484209131 
+   -71.06392165558401   -0.1475022444872089     70.71553999200232    141.56589696490104    212.44426058522552     283.3913227639922    354.44777541221777 
+
+Y Coeffs -----------------------------------
+                -71.0    -70.97352968109173    -70.89411872436696    -70.84117808655046    -70.89411872436696    -70.97352968109173                 -71.0 
+                  0.0    0.0397054783623835    14.202191039012094    119.43281261970162     -64.7898912338142    -78.07610697398358                   0.0 
+                 71.0     41.99965358343721    48.801650399807585     -4.96831542657184     65.92550026202618    52.529005249001116                  71.0 
+                142.0     42.71037318260199    -10.45958071265268     137.6637735153788    13.689619340755756    126.62467245361297     142.0004344305075 
+   212.99999999999997    214.58667057999367    290.49952942694233    211.47733987307876    213.00310018836666     242.7605654138609    213.00173772203004 
+                284.0     284.0005109248762     324.2670965032303    296.04807329727873    307.46661221661003     309.9351077964876    284.00260658304506 
+   354.99999999999994     355.0003406165841    355.00136246633656     355.0024781300123    353.49851662901756     355.0029471996293       355.00173772203 
b
diff -r 000000000000 -r 1bffabc15695 test-data/add_specified_noise.gif
b
Binary file test-data/add_specified_noise.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/analyze_particles_masks.gif
b
Binary file test-data/analyze_particles_masks.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/analyze_particles_nothing.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/analyze_particles_nothing.tabular Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,66 @@
+  Area Mean Min Max
+1 136 255 255 255
+2 60 255 255 255
+3 206 255 255 255
+4 139 255 255 255
+5 152 255 255 255
+6 86 255 255 255
+7 72 255 255 255
+8 25 255 255 255
+9 85 255 255 255
+10 9 255 255 255
+11 157 255 255 255
+12 207 255 255 255
+13 29 255 255 255
+14 73 255 255 255
+15 143 255 255 255
+16 125 255 255 255
+17 159 255 255 255
+18 133 255 255 255
+19 85 255 255 255
+20 109 255 255 255
+21 51 255 255 255
+22 133 255 255 255
+23 133 255 255 255
+24 81 255 255 255
+25 162 255 255 255
+26 88 255 255 255
+27 212 255 255 255
+28 55 255 255 255
+29 116 255 255 255
+30 172 255 255 255
+31 103 255 255 255
+32 4 255 255 255
+33 60 255 255 255
+34 198 255 255 255
+35 187 255 255 255
+36 7 255 255 255
+37 85 255 255 255
+38 80 255 255 255
+39 75 255 255 255
+40 103 255 255 255
+41 151 255 255 255
+42 52 255 255 255
+43 122 255 255 255
+44 129 255 255 255
+45 77 255 255 255
+46 171 255 255 255
+47 117 255 255 255
+48 207 255 255 255
+49 119 255 255 255
+50 181 255 255 255
+51 22 255 255 255
+52 49 255 255 255
+53 150 255 255 255
+54 191 255 255 255
+55 170 255 255 255
+56 64 255 255 255
+57 174 255 255 255
+58 270 255 255 255
+59 87 255 255 255
+60 69 255 255 255
+61 1 255 255 255
+62 29 255 255 255
+63 25 255 255 255
+64 16 255 255 255
+65 15 255 255 255
b
diff -r 000000000000 -r 1bffabc15695 test-data/analyze_particles_outlines.gif
b
Binary file test-data/analyze_particles_outlines.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/basic.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/basic.tabular Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,2 @@
+# Branches Junctions End-point Voxels Junction Voxels Slab Voxels Average branch length Triple Points Quadruple Points Maximum Branch Length
+96 60 7 120 1246 17.344 56 3 70.882
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs.gif
b
Binary file test-data/blobs.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_black_edm.gif
b
Binary file test-data/blobs_black_edm.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_count.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/blobs_count.tabular Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,2 @@
+  Count
+1 112
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_direct_transf.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/blobs_direct_transf.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,19 @@
+Intervals=4
+
+X Coeffs -----------------------------------
+   -34.14981674286569     3.144052189417975     44.74398427283767     72.62900018057132     111.3348086331012    134.27021754923854    171.74048996962574 
+  -46.475609806523806    -28.37507243951631     71.19906566193379     30.10778479539863    122.71885776990422     109.9563576074076    171.94005579124322 
+   -57.04494430952696    1.8032931596380026    61.404945193416715     42.75919945626539     148.2715738833391    126.39195563069309     116.8758739961032 
+   -26.50696765072751    24.133275156317662     45.18779137671111     49.91727740928712     130.5425749032711    160.35055773949284     186.2385413131219 
+    30.36695633747302    -3.333376652604397    35.957597759623795      86.8060703274396     102.5208634329241      126.298277744805     243.1342175649626 
+   -2.831201175463878    -4.836159041803193    36.263197544298954     77.65977608215381     98.47306066697166    149.98143182373533    193.72941653859635 
+   -33.88117649278133    7.9003473752729985    41.603347919804314     72.11109321021485    111.05849721622616    148.16049042863358    181.51669289966162 
+
+Y Coeffs -----------------------------------
+   -32.99874935645494   -10.853014366833959    -18.11337422707787    120.45933796140201   -11.717505555260894    -42.65980408275417    -41.34878020779432 
+   11.306632136922623     42.01572254879719   -18.137465736571315     41.67904406737918       -9.059457409112    -63.14804168936847    -7.646807909694754 
+   20.638424092275454    35.302620259132304    1.8587715711200654     2.065183621887666     13.47064662534885     8.966817348422527     65.74329336525717 
+    79.92027086396175    117.61262084713007      78.2409336472003     102.3526144171297     97.29273111510625     48.80095761073018     89.32772899111102 
+    121.0699654326738    114.38154300759474     23.57251043213103    101.87328690674049    115.94282218472065    106.18526585145909    111.14979545782822 
+   140.58687592247674    130.54971240393465    177.05271414686374    150.48052118800214    150.41722526235608     156.3116913517668    146.21075369002716 
+   175.51191703543347     174.9228152249439    173.31675176966468    181.87538254503764    170.81399893021742    186.14994867024973    185.85560874061068 
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_edm.gif
b
Binary file test-data/blobs_edm.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_equalize.gif
b
Binary file test-data/blobs_equalize.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_find_edges.gif
b
Binary file test-data/blobs_find_edges.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_list.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/blobs_list.tabular Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,113 @@
+  X Y
+1 95 8
+2 107 24
+3 10 25
+4 34 16
+5 2 20
+6 118 11
+7 19 10
+8 132 0
+9 124 143
+10 130 139
+11 142 126
+12 140 108
+13 125 99
+14 133 80
+15 30 65
+16 46 52
+17 42 41
+18 116 34
+19 24 36
+20 136 33
+21 50 29
+22 86 29
+23 125 23
+24 143 23
+25 71 10
+26 39 8
+27 105 5
+28 5 3
+29 23 0
+30 2 0
+31 114 141
+32 31 140
+33 112 136
+34 20 133
+35 125 122
+36 28 116
+37 110 109
+38 54 105
+39 15 101
+40 142 95
+41 96 93
+42 4 88
+43 112 91
+44 86 91
+45 58 90
+46 42 90
+47 76 77
+48 102 84
+49 44 81
+50 29 75
+51 41 73
+52 57 73
+53 0 72
+54 118 66
+55 44 68
+56 16 60
+57 67 64
+58 125 63
+59 85 63
+60 108 62
+61 88 49
+62 122 47
+63 97 48
+64 64 43
+65 143 47
+66 28 44
+67 85 46
+68 1 44
+69 14 42
+70 127 40
+71 63 36
+72 93 28
+73 60 28
+74 23 26
+75 73 23
+76 62 24
+77 142 18
+78 49 15
+79 77 3
+80 101 1
+81 95 1
+82 95 140
+83 83 138
+84 69 139
+85 68 126
+86 6 133
+87 70 135
+88 52 135
+89 90 124
+90 88 116
+91 1 114
+92 51 112
+93 8 113
+94 83 112
+95 62 109
+96 31 105
+97 81 99
+98 33 99
+99 31 92
+100 59 85
+101 51 70
+102 79 57
+103 109 54
+104 112 50
+105 104 48
+106 12 48
+107 94 64
+108 43 24
+109 98 22
+110 67 78
+111 143 7
+112 143 0
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_log.gif
b
Binary file test-data/blobs_log.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_macro.gif
b
Binary file test-data/blobs_macro.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_min.gif
b
Binary file test-data/blobs_min.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_multiply.gif
b
Binary file test-data/blobs_multiply.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_normalize.gif
b
Binary file test-data/blobs_normalize.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_northwest.gif
b
Binary file test-data/blobs_northwest.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_saturate.gif
b
Binary file test-data/blobs_saturate.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_segmented.gif
b
Binary file test-data/blobs_segmented.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_sharpen.gif
b
Binary file test-data/blobs_sharpen.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_single_points.gif
b
Binary file test-data/blobs_single_points.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_smooth.gif
b
Binary file test-data/blobs_smooth.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_square.gif
b
Binary file test-data/blobs_square.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_threshold_default.gif
b
Binary file test-data/blobs_threshold_default.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_threshold_huang_dark.gif
b
Binary file test-data/blobs_threshold_huang_dark.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_threshold_ijiso.gif
b
Binary file test-data/blobs_threshold_ijiso.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_tolerance.gif
b
Binary file test-data/blobs_tolerance.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/blobs_watershed_binary.gif
b
Binary file test-data/blobs_watershed_binary.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/clown.jpg
b
Binary file test-data/clown.jpg has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/clown_binary.jpg
b
Binary file test-data/clown_binary.jpg has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/composed_raw_elastic_transformation.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/composed_raw_elastic_transformation.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,5 @@
+Width=144
+Height=144
+
+X Trans -----------------------------------
+   -8.356784649818302    -7.197224454983437    -6.007291128456463     -4.78857035976083    -3.542648755368276     -2.27111292175059   -0.9755494653795207   0.34245500727314293    1.6813138897356357    3.0394405755361955     4.415248458203067     5.807150931264452      7.21356138824859     6.722616523231703     7.982832965851492     9.241901922762699    10.500157904929564    11.755439850906992    13.007881998138114    14.257818796273467    15.503597042436024      16.7441831444607    17.979203521782882    19.209729191621175    20.434924351265607    21.653927817871562    22.868018271403987    24.077212618583225     25.28220858222662    26.482822213238034     27.68108269563495    28.876976885081163    30.071735843481154    31.267312088467172    32.461884574486334      33.6540253250871     34.84451070010306    36.032159052340404     37.21731193936262     38.40098887470948     39.58514301848773      40.7697991777691     41.95621659878733     43.14336916337468    44.332762755666245     45.52368427263207     46.71616063628192      47.9102587132078     49.10447011578231     50.29945996745416     51.49280946178481     52.68452392595436     53.87243480117253      55.0558589967881     56.23259866253449     57.40168688627666    58.560586048253406     59.70814582308569    60.842020356312204     61.96028478681958     63.06129999594824     64.14282865164152     65.20294849643733     66.23977708520655       67.251514074432      68.2364787499741     69.19379132689076     70.12368273237351     71.02688237947935     71.90443109666018     72.75759402782955     73.58797464576547     74.39754123580246     75.18880500856693     75.96371546546276      76.7252296396663     77.47583769656181     78.21957975177521     78.95905016293707     79.69712587468834      80.4370485162662     81.18210364892593     81.93429837927215     82.69597230924478      83.4691472921311     84.25544962565074     85.05614376573314     85.87215879473054     86.70392313153135     87.55146827026859     88.41445157658053     89.29218897542948     90.18369572122522     91.08773317913175    102.68235537543303     103.7042131782845    104.71196201385267    105.70449758967617    106.68071561329351    107.63951179224333    108.57978183406415    109.50042144629455    110.40032633647319     111.2783922121385    112.13351478082917    112.96458975008372    113.77051282744074    114.55017972043879    115.30267699164074    116.02873972512184    116.72995672023089    117.40792272643284     118.0642324931926    118.70048076997512    119.31826230624539    119.91917185146836    120.50480415510899    121.07675396663221    121.63661603550297    122.18598511118623    122.72645594314696     123.2596232808501    123.78708187376054    124.31042647134338    124.83125182306345    125.35115267838574    125.87172378677525    126.39455989769684    126.92125576061551    127.45340612499622    127.99260574030393    128.54044935600356     129.0985317215601    129.66844758643848    130.25179170010364    130.85015881202057     131.4651436716542     132.0983410284695    132.75134563193137    133.42575223150482    134.12315557665482    134.84515041684625     135.5933315015441    136.36929118355562 
b
diff -r 000000000000 -r 1bffabc15695 test-data/composed_raw_transformation.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/composed_raw_transformation.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,5 @@
+Width=144
+Height=144
+
+X Trans -----------------------------------
+   -8.356784649818302    -7.197224454983437    -6.007291128456463     -4.78857035976083    -3.542648755368276     -2.27111292175059   -0.9755494653795207   0.34245500727314293    1.6813138897356357    3.0394405755361955     4.415248458203067     5.807150931264452      7.21356138824859     6.722616523231703     7.982832965851492     9.241901922762699    10.500157904929564    11.755439850906992    13.007881998138114    14.257818796273467    15.503597042436024      16.7441831444607    17.979203521782882    19.209729191621175    20.434924351265607    21.653927817871562    22.868018271403987    24.077212618583225     25.28220858222662    26.482822213238034     27.68108269563495    28.876976885081163    30.071735843481154    31.267312088467172    32.461884574486334      33.6540253250871     34.84451070010306    36.032159052340404     37.21731193936262     38.40098887470948     39.58514301848773      40.7697991777691     41.95621659878733     43.14336916337468    44.332762755666245     45.52368427263207     46.71616063628192      47.9102587132078     49.10447011578231     50.29945996745416     51.49280946178481     52.68452392595436     53.87243480117253      55.0558589967881     56.23259866253449     57.40168688627666    58.560586048253406     59.70814582308569    60.842020356312204     61.96028478681958     63.06129999594824     64.14282865164152     65.20294849643733     66.23977708520655       67.251514074432      68.2364787499741     69.19379132689076     70.12368273237351     71.02688237947935     71.90443109666018     72.75759402782955     73.58797464576547     74.39754123580246     75.18880500856693     75.96371546546276      76.7252296396663     77.47583769656181     78.21957975177521     78.95905016293707     79.69712587468834      80.4370485162662     81.18210364892593     81.93429837927215     82.69597230924478      83.4691472921311     84.25544962565074     85.05614376573314     85.87215879473054     86.70392313153135     87.55146827026859     88.41445157658053     89.29218897542948     90.18369572122522     91.08773317913175    102.68235537543303     103.7042131782845    104.71196201385267    105.70449758967617    106.68071561329351    107.63951179224333    108.57978183406415    109.50042144629455    110.40032633647319     111.2783922121385    112.13351478082917    112.96458975008372    113.77051282744074    114.55017972043879    115.30267699164074    116.02873972512184    116.72995672023089    117.40792272643284     118.0642324931926    118.70048076997512    119.31826230624539    119.91917185146836    120.50480415510899    121.07675396663221    121.63661603550297    122.18598511118623    122.72645594314696     123.2596232808501    123.78708187376054    124.31042647134338    124.83125182306345    125.35115267838574    125.87172378677525    126.39455989769684    126.92125576061551    127.45340612499622    127.99260574030393    128.54044935600356     129.0985317215601    129.66844758643848    130.25179170010364    130.85015881202057     131.4651436716542     132.0983410284695    132.75134563193137    133.42575223150482    134.12315557665482    134.84515041684625     135.5933315015441    136.36929118355562 
b
diff -r 000000000000 -r 1bffabc15695 test-data/create_image1.jpg
b
Binary file test-data/create_image1.jpg has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/despeckle.gif
b
Binary file test-data/despeckle.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/detailed.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/detailed.tabular Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,2 @@
+# Branches Junctions End-point Voxels Junction Voxels Slab Voxels Average branch length Triple Points Quadruple Points Maximum Branch Length
+96 60 7 120 1246 17.344 56 3 70.882
b
diff -r 000000000000 -r 1bffabc15695 test-data/dot_blot.jpg
b
Binary file test-data/dot_blot.jpg has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/dot_blot.png
b
Binary file test-data/dot_blot.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/dot_blot.tiff
b
Binary file test-data/dot_blot.tiff has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/dotblot.jpg
b
Binary file test-data/dotblot.jpg has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/elastic_trans_registered_source1.png
b
Binary file test-data/elastic_trans_registered_source1.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/largest_shortest_path_basic.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/largest_shortest_path_basic.tabular Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,2 @@
+# Branches Junctions End-point Voxels Junction Voxels Slab Voxels Average branch length Triple Points Quadruple Points Maximum Branch Length Longest Shortest Path spx spy spz
+96 60 7 120 1246 17.344 56 3 70.882 207.380 135 137 0
b
diff -r 000000000000 -r 1bffabc15695 test-data/mask_ramp.gif
b
Binary file test-data/mask_ramp.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/mask_white.png
b
Binary file test-data/mask_white.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/raw_trans_registered_source1.png
b
Binary file test-data/raw_trans_registered_source1.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/raw_transformation.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/raw_transformation.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,5 @@
+Width=144
+Height=144
+
+X Trans -----------------------------------
+    4.176715938136983     5.028059425766952     5.848163112344083     6.625286081420434     7.346949869450837     7.999993504600507     8.570638908853306     9.044622789513964     9.413506255387968     9.681218421492703     9.854312101993061     9.940614113498254     9.949133680349874     9.889960336823316     9.774150445497835     9.613603978540679     9.420928827203937     9.209297594621251      8.99229520815497     8.783758029488393     8.597605040212112     8.447661785513965     8.347477892926463     8.310139148227263     8.348075306899938     8.472865046334638     8.695039719264653      9.02388784955587     9.467262612735961    10.031394859423866    10.720714562420634    11.537683888429232    12.482635931423559    13.548553680644847    14.713909933407903    15.955437681044362    17.250615997032845     18.57910317041673    19.924588848162042    21.273131961240793     22.61287165006273    23.933978509626925    25.228599373795102     26.49079330268239      27.7164571781934     28.90324005022652    30.050446065539795     31.15892642005994     32.23096128077027     33.27013301056534     34.28119229030748    35.269918863348025     36.24297862912084     37.20777868670669    38.172321680760554     39.14506043617836    40.134753390327724     41.15032074914446     42.20070061327572     43.29470355140843     44.44086325080732     45.64727996412613    46.921452516062644     48.27009365995084     49.69892261951472     51.21242468486518     52.81308002996115      54.5006890705208     56.27295866194047     58.12547164246331     60.05155284704986    62.042126167374654      64.0853963435782     66.16300087019144     68.25096023630147     70.32434810515224     72.35799991286407     74.32708587789452     76.20772360258024     77.97761366869307     79.61667819048832     81.10767966466686     82.43679584207585     83.59412588149885     84.57410381192264     85.37579734320398      86.0030732794589     86.46461509691974     86.77378348443933     86.94831659732299     87.00987319114694     86.98342840026854     86.89653840770765     86.77849631690853     86.65940540750502     86.56678652831073     86.51894680093264     86.52962234401939      86.6091568313555     86.76444343256262     86.99795950541491     87.30767458029689      87.6887773859162      88.1343150744824     88.63573469192004     89.18339795340363     89.76705660855026     90.37627810648544     91.00098259921862     91.63313750582321     92.26649727091988     92.89592945322954     93.51736271382487     94.12771798912087     94.72482575123138     95.30733544608778     95.87462173881887     96.42669102951422      96.9640907767786     97.48782343666693     97.99926625358638     98.50009769694455     98.99223099750193     99.47775497987517     99.95888219552717    100.43790422009906    100.91715387889398    101.39897409567641     101.8856930154123    102.37960502529904    102.88295728576551    103.39794138037603    103.92668969786209    104.47127616862906    105.03372099039578    105.61599899198129     106.2200512999695    106.84779998979062    107.50116542083198     108.1820859751434    108.89253994223978    109.63456932007529    110.41030533674008    111.22199287092927 
b
diff -r 000000000000 -r 1bffabc15695 test-data/registered_source1.png
b
Binary file test-data/registered_source1.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/registered_source2.png
b
Binary file test-data/registered_source2.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/registered_target1.png
b
Binary file test-data/registered_target1.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/registered_target2.png
b
Binary file test-data/registered_target2.png has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/remove_outliers.gif
b
Binary file test-data/remove_outliers.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/shortest_branch_all_yes.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/shortest_branch_all_yes.tabular Tue Sep 17 16:55:25 2019 -0400
b
b'@@ -0,0 +1,205 @@\n+# Branches\tJunctions\tEnd-point Voxels\tJunction Voxels\tSlab Voxels\tAverage branch length\tTriple Points\tQuadruple Points\tMaximum Branch Length\tLongest Shortest Path\tspx\tspy\tspz\n+1\t0\t2\t0\t1\t2.414\t0\t0\t2.414\t2.414\t1\t59\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t4\t91\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t5\t43\t0\n+143\t75\t40\t144\t918\t9.176\t61\t9\t96.113\t277.930\t161\t0\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t5\t80\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t6\t53\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t6\t67\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t8\t64\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t7\t75\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t9\t66\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t9\t76\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t11\t81\t0\n+1\t0\t2\t0\t0\t1.414\t0\t0\t1.414\t1.414\t15\t65\t0\n+1\t0\t2\t0\t3\t4.000\t0\t0\t4.000\t4.000\t27\t84\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t27\t93\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t26\t99\t0\n+1\t0\t2\t0\t3\t4.414\t0\t0\t4.414\t4.414\t38\t91\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t39\t88\t0\n+1\t0\t2\t0\t3\t5.657\t0\t0\t5.657\t5.657\t49\t111\t0\n+5\t2\t4\t2\t97\t23.182\t2\t0\t58.385\t100.770\t92\t174\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t65\t31\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t66\t175\t0\n+1\t0\t2\t0\t4\t5.828\t0\t0\t5.828\t5.828\t88\t42\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t89\t177\t0\n+1\t0\t2\t0\t4\t5.828\t0\t0\t5.828\t5.828\t97\t51\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t95\t44\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t105\t14\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t104\t20\t0\n+262\t117\t105\t266\t957\t5.803\t65\t37\t34.142\t352.779\t279\t50\t0\n+96\t43\t31\t104\t373\t6.437\t25\t11\t34.142\t212.675\t192\t110\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t121\t35\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t132\t54\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t135\t53\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t138\t116\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t138\t124\t0\n+22\t11\t10\t24\t151\t9.834\t10\t1\t20.728\t116.633\t207\t123\t0\n+5\t2\t4\t2\t44\t12.285\t2\t0\t26.799\t52.184\t176\t174\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t156\t54\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t162\t61\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t163\t56\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t163\t59\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t166\t58\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t168\t59\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t168\t154\t0\n+1\t0\t2\t0\t0\t1.414\t0\t0\t1.414\t1.414\t173\t183\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t175\t0\t0\n+1\t0\t2\t0\t0\t1.414\t0\t0\t1.414\t1.414\t176\t170\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t176\t182\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t177\t172\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t179\t0\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t179\t175\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t178\t179\t0\n+4\t1\t4\t4\t6\t4.282\t0\t1\t5.650\t10.479\t182\t195\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t179\t183\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t180\t2\t0\n+1\t0\t2\t0\t2\t3.000\t0\t0\t3.000\t3.000\t184\t0\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t186\t53\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t190\t53\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t189\t71\t0\n+1\t0\t2\t0\t1\t2.414\t0\t0\t2.414\t2.414\t192\t3\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t190\t50\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t193\t64\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t192\t66\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t195\t102\t0\n+1\t0\t2\t0\t1\t2.414\t0\t0\t2.414\t2.414\t196\t68\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t196\t66\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t199\t102\t0\n+1\t0\t2\t0\t0\t1.414\t0\t0\t1.414\t1.414\t205\t71\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t206\t129\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t208\t6\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t210\t72\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t210\t80\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t211\t83\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t211\t63\t0\n+1\t0\t2\t0\t6\t8.657\t0\t0\t8.657\t8.657\t216\t74\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t212\t65\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t212\t99\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t215\t65\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t214\t67\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t214\t69\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t214\t86\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t214\t97\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t216\t9\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t218\t91\t0\n+1\t0\t2\t0\t2\t3.414\t0\t0\t3.414\t3.414\t222\t8\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t224\t94\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t225\t55\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t225\t7\t0\n+3\t1\t3\t1\t8\t4.219\t1\t0\t6.414\t9.828\t234\t11\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000'..b'0\t1.000\t1.000\t253\t31\t0\n+1\t0\t2\t0\t2\t3.000\t0\t0\t3.000\t3.000\t253\t36\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t253\t63\t0\n+1\t0\t2\t0\t0\t1.414\t0\t0\t1.414\t1.414\t254\t67\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t254\t71\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t255\t57\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t257\t45\t0\n+1\t0\t2\t0\t6\t7.414\t0\t0\t7.414\t7.414\t265\t70\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t260\t61\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t262\t67\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t263\t60\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t267\t48\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t268\t60\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t271\t70\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t273\t64\t0\n+1\t0\t2\t0\t11\t13.243\t0\t0\t13.243\t13.243\t277\t7\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t277\t47\t0\n+1\t0\t2\t0\t3\t4.828\t0\t0\t4.828\t4.828\t277\t58\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t279\t52\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t279\t15\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t281\t63\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t280\t11\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t280\t31\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t280\t60\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t282\t52\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t281\t67\t0\n+1\t0\t2\t0\t2\t3.000\t0\t0\t3.000\t3.000\t285\t47\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t283\t54\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t283\t77\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t283\t11\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t285\t66\t0\n+3\t1\t3\t3\t12\t6.495\t1\t0\t7.828\t14.657\t297\t56\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t284\t64\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t286\t17\t0\n+1\t0\t2\t0\t1\t2.414\t0\t0\t2.414\t2.414\t287\t28\t0\n+1\t0\t2\t0\t2\t3.414\t0\t0\t3.414\t3.414\t286\t110\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t286\t57\t0\n+1\t0\t2\t0\t3\t4.414\t0\t0\t4.414\t4.414\t289\t86\t0\n+1\t0\t2\t0\t1\t2.414\t0\t0\t2.414\t2.414\t288\t36\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t287\t108\t0\n+1\t0\t2\t0\t1\t2.414\t0\t0\t2.414\t2.414\t289\t122\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t287\t134\t0\n+13\t6\t8\t10\t55\t5.956\t6\t0\t20.899\t68.184\t309\t78\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t288\t69\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t288\t75\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t288\t92\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t293\t46\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t291\t78\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t292\t71\t0\n+1\t0\t2\t0\t7\t8.828\t0\t0\t8.828\t8.828\t300\t119\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t293\t135\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t296\t22\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t296\t30\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t296\t145\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t298\t27\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t297\t75\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t298\t157\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t298\t24\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t301\t88\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t301\t98\t0\n+5\t1\t5\t3\t15\t5.994\t0\t0\t12.243\t18.899\t313\t82\t0\n+1\t0\t2\t0\t1\t2.414\t0\t0\t2.414\t2.414\t303\t35\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t303\t104\t0\n+1\t0\t2\t0\t2\t3.000\t0\t0\t3.000\t3.000\t306\t75\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t303\t118\t0\n+1\t0\t2\t0\t1\t2.414\t0\t0\t2.414\t2.414\t305\t123\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t304\t52\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t305\t73\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t304\t115\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t306\t32\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t306\t87\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t306\t94\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t306\t127\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t308\t89\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t309\t39\t0\n+1\t0\t2\t0\t5\t6.000\t0\t0\t6.000\t6.000\t315\t94\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t309\t99\t0\n+1\t0\t2\t0\t4\t6.243\t0\t0\t6.243\t6.243\t315\t48\t0\n+1\t0\t2\t0\t8\t10.657\t0\t0\t10.657\t10.657\t312\t50\t0\n+1\t0\t2\t0\t4\t5.000\t0\t0\t5.000\t5.000\t315\t57\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t311\t141\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t312\t4\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t313\t27\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t313\t55\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t313\t84\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t314\t75\t0\n+1\t0\t2\t0\t0\t1.414\t0\t0\t1.414\t1.414\t316\t9\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t316\t30\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t316\t79\t0\n+1\t0\t2\t0\t2\t3.000\t0\t0\t3.000\t3.000\t319\t27\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t317\t55\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t318\t63\t0\n+0\t0\t1\t0\t0\t0.000\t0\t0\t0.000\t0.000\t317\t23\t0\n+1\t0\t2\t0\t1\t2.000\t0\t0\t2.000\t2.000\t319\t83\t0\n+1\t0\t2\t0\t0\t1.000\t0\t0\t1.000\t1.000\t319\t58\t0\n'
b
diff -r 000000000000 -r 1bffabc15695 test-data/shortest_branch_basic.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/shortest_branch_basic.tabular Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,205 @@
+# Branches Junctions End-point Voxels Junction Voxels Slab Voxels Average branch length Triple Points Quadruple Points Maximum Branch Length
+1 0 2 0 1 2.414 0 0 2.414
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+143 75 40 144 918 9.176 61 9 96.113
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.414 0 0 1.414
+1 0 2 0 3 4.000 0 0 4.000
+1 0 2 0 1 2.000 0 0 2.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 3 4.414 0 0 4.414
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 3 5.657 0 0 5.657
+5 2 4 2 97 23.182 2 0 58.385
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 4 5.828 0 0 5.828
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 4 5.828 0 0 5.828
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+262 117 105 266 957 5.803 65 37 34.142
+96 43 31 104 373 6.437 25 11 34.142
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+22 11 10 24 151 9.834 10 1 20.728
+5 2 4 2 44 12.285 2 0 26.799
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.414 0 0 1.414
+1 0 2 0 1 2.000 0 0 2.000
+1 0 2 0 0 1.414 0 0 1.414
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+4 1 4 4 6 4.282 0 1 5.650
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 2 3.000 0 0 3.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 1 2.414 0 0 2.414
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 1 2.000 0 0 2.000
+1 0 2 0 1 2.414 0 0 2.414
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.414 0 0 1.414
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 6 8.657 0 0 8.657
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 2 3.414 0 0 3.414
+1 0 2 0 1 2.000 0 0 2.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+3 1 3 1 8 4.219 1 0 6.414
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+3 1 3 1 3 3.162 1 0 4.243
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 1 2.000 0 0 2.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 1 2.000 0 0 2.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 1 2.414 0 0 2.414
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 2 3.000 0 0 3.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.414 0 0 1.414
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 6 7.414 0 0 7.414
+1 0 2 0 1 2.000 0 0 2.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 11 13.243 0 0 13.243
+1 0 2 0 1 2.000 0 0 2.000
+1 0 2 0 3 4.828 0 0 4.828
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 1 2.000 0 0 2.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 2 3.000 0 0 3.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 1 2.000 0 0 2.000
+3 1 3 3 12 6.495 1 0 7.828
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 1 2.414 0 0 2.414
+1 0 2 0 2 3.414 0 0 3.414
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 3 4.414 0 0 4.414
+1 0 2 0 1 2.414 0 0 2.414
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 1 2.414 0 0 2.414
+0 0 1 0 0 0.000 0 0 0.000
+13 6 8 10 55 5.956 6 0 20.899
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 1 2.000 0 0 2.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 7 8.828 0 0 8.828
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 1 2.000 0 0 2.000
+1 0 2 0 1 2.000 0 0 2.000
+5 1 5 3 15 5.994 0 0 12.243
+1 0 2 0 1 2.414 0 0 2.414
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 2 3.000 0 0 3.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 1 2.414 0 0 2.414
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 5 6.000 0 0 6.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 4 6.243 0 0 6.243
+1 0 2 0 8 10.657 0 0 10.657
+1 0 2 0 4 5.000 0 0 5.000
+0 0 1 0 0 0.000 0 0 0.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 0 1.414 0 0 1.414
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 2 3.000 0 0 3.000
+1 0 2 0 0 1.000 0 0 1.000
+1 0 2 0 1 2.000 0 0 2.000
+0 0 1 0 0 0.000 0 0 0.000
+1 0 2 0 1 2.000 0 0 2.000
+1 0 2 0 0 1.000 0 0 1.000
b
diff -r 000000000000 -r 1bffabc15695 test-data/skeletonized_blobs.gif
b
Binary file test-data/skeletonized_blobs.gif has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/skeletonized_clown.jpg
b
Binary file test-data/skeletonized_clown.jpg has changed
b
diff -r 000000000000 -r 1bffabc15695 test-data/source_elastic_transformation.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/source_elastic_transformation.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,19 @@
+Intervals=4
+
+X Coeffs -----------------------------------
+   -35.61130748114458  -0.17721383962095547     35.27738550739418     70.74023165057304    106.19906568058776    141.68187320104443    177.21663981554897 
+   -35.64176128119247   -18.613115472047358     38.17042470972303     80.01104484186907       136.77671593587    127.39645957510831     177.1399905793402 
+   -35.62132146852445   -16.358740968707146      88.9500299845919     64.14925112250332     70.46044758857497    129.40395338071698    177.06456148930593 
+   -35.58296385817069   -2.6180801775805382     100.0976208671127    125.33720259305008     87.98163606182615    134.90911744170705    177.02823631252767 
+   -35.55966426516137    -5.939275483027422    112.77890812894067    115.24264668240022     129.2642045183008     151.9582002938364    177.06889881608703 
+   -35.54485311365049    10.151323307758267     37.19497464942767     75.47427646299542    116.96351939728723    151.63921266991827    177.14722421045656 
+  -35.531960827792005  -0.07375112224360444     35.35776999600116     70.78294848245052    106.22213029261276     141.6956613819961    177.22388770610888 
+
+Y Coeffs -----------------------------------
+                -35.5    -35.48676484054587    -35.44705936218348    -35.42058904327523    -35.44705936218348    -35.48676484054587                 -35.5 
+                  0.0   0.01985273918119175     7.101095519506047     59.71640630985081     -32.3949456169071    -39.03805348699179                   0.0 
+                 35.5    20.999826791718604    24.400825199903792     -2.48415771328592     32.96275013101309    26.264502624500558                  35.5 
+                 71.0    21.355186591300996     -5.22979035632634      68.8318867576894     6.844809670377878     63.31233622680649     71.00021721525376 
+   106.49999999999999    107.29333528999683    145.24976471347117    105.73866993653938    106.50155009418333    121.38028270693044    106.50086886101502 
+                142.0     142.0002554624381    162.13354825161514    148.02403664863937    153.73330610830502     154.9675538982438    142.00130329152253 
+   177.49999999999997    177.50017030829204    177.50068123316828    177.50123906500616    176.74925831450878    177.50147359981466      177.500868861015 
b
diff -r 000000000000 -r 1bffabc15695 test-data/source_raw_transformation.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/source_raw_transformation.txt Tue Sep 17 16:55:25 2019 -0400
b
b'@@ -0,0 +1,294 @@\n+Width=144\n+Height=144\n+\n+X Trans -----------------------------------\n+   -8.356784649818302    -7.197224454983437    -6.007291128456463     -4.78857035976083    -3.542648755368276     -2.27111292175059   -0.9755494653795207   0.34245500727314293    1.6813138897356357    3.0394405755361955     4.415248458203067     5.807150931264452      7.21356138824859     8.632893222683734    10.063559828098088    11.503974598019894    12.952550925977388    14.407702205498786    15.867841830112352    17.331383193346277    18.796739688728827    20.262324709788203    21.726551650052656    23.187833903050404     24.64458486230968     26.09521792135873     27.53814647372579    28.971783912939053     30.39454363252679     31.80483902601722     33.20108348693856     34.58169040881904     35.94507318518693     37.28964520957042    38.613819875497754     39.91601057649718     41.19463931189525     42.44894522166797     43.67977041049533      44.8881387226239     46.07507400230021     47.24160009377076     48.38874084128215     49.51752008908086     50.62896168141348    51.724089462526514    52.803927276666506        53.86949896808     54.92182838101353    55.961939359713675    56.990855748426895    58.009601391399784     59.01920013287888     60.02067581711069    61.015052288341764     62.00335339081867     62.98660296878793     63.96582486649604     64.94204292818961     65.91628099811513     66.88956292051915     67.86291253964822     68.83735369974886     69.81391024506763     70.79360601985103     71.77746486834566     72.76651063479801     73.76176716345464     74.76425829856204      75.7750078843668     76.79503976511549     77.82537778505457     78.86700293195861     79.91987202230135     80.98292657951217     82.05506231112969     83.13517492469245     84.22216012773899     85.31491362780798     86.41233113243788     87.51330834916736     88.61674098553493     89.72152474907921     90.82655534733871     91.93072848785208     93.03293987815786     94.13208522579464     95.22706023830095      96.3167606232154     97.40008208807656     98.47592034042299     99.54317108779328    100.60073003772601    101.64749289775975    102.68235537543303     103.7042131782845    104.71196201385267    105.70449758967617    106.68071561329351    107.63951179224333    108.57978183406415    109.50042144629455    110.40032633647319     111.2783922121385    112.13351478082917    112.96458975008372    113.77051282744074    114.55017972043879    115.30267699164074    116.02873972512184    116.72995672023089    117.40792272643284     118.0642324931926    118.70048076997512    119.31826230624539    119.91917185146836    120.50480415510899    121.07675396663221    121.63661603550297    122.18598511118623    122.72645594314696     123.2596232808501    123.78708187376054    124.31042647134338    124.83125182306345    125.35115267838574    125.87172378677525    126.39455989769684    126.92125576061551    127.45340612499622    127.99260574030393    128.54044935600356     129.0985317215601    129.66844758643848    130.25179170010364    130.85015881202057     131.4651436716542     132.0983410284695    132.75134563193137    133.42575223150482    134.12315557665482    134.84515041684625     135.5933315015441    136.36929118355562 \n+   -8.374127336215409    -7.203348638731092   -6.0013206733761475   -4.7696961635913855   -3.5101287650461663   -2.2242721334099076   -0.9137799243519846   0.41969420645818767    1.7744966033512157    3.1489736106577126     4.541471572708295     5.950336833833539     7.373915738364056     8.810554630630472    10.258599854963366    11.716397755693352    13.182294677151042    14.654636963667025     16.13177095957193    17.612043009196334     19.09379945687087    20.575386646926102     22.05515092369267     23.53143863150116    25.002596114682184    26.466969717566347     27.92290578448427     29.36875065976652    30.802850687743735    32.223552212746505     33.62920157910542     35.01814513115111     36.38872921321416      37.739300'..b'4268085129334     148.6469194029473    148.75112793673117    148.85494266869821    148.95804026817186    149.06009758700367    149.16079147704525    149.25979879014827    149.35679637816423    149.45146109294487    149.54346978634177     149.6324993102064    149.71822651639053    149.80032825674573    149.87848138312359     149.9523627473757     150.0216492013537     150.0860175969092    150.14514478589376    150.19870762015907    150.24638295155668    150.28784763193826    150.32277851315536    150.35085244705957     150.3717462855025    150.38513688033586     150.3907010834112     150.3881157465801    150.37705772169414    150.35720386060504     150.3282310151643    150.28981603722363    150.24163577863453    150.18336709124873    150.11468682691773    150.03527183749316    149.94479897482674    149.84294213626143 \n+    145.4017522591916    145.68728041991523    145.98694201220394    146.29952872192806    146.62382901867576    146.95863137203523    147.30272425159467     147.6548961269422    148.01393546766607    148.37863074335445    148.74777042359548    149.12014297797742    149.49453687608838     149.8697405875166    150.24454258185023    150.61773132867748    150.98809529758645    151.35442295816546     151.7155027800026     152.0701232326861    152.41707278580407    152.75513990894476    153.08311307169637    153.39978074364703    153.70393139438494    153.99435349349835    154.26983551057532    154.52916591520406    154.77113317697285     154.9945257654698     155.1981321502831    155.38074080100097    155.54114018721157    155.67811877850303     155.7904650444636    155.87696745468145    155.93642087390077    155.96838472497006    155.97390397514764    155.95419417089084    155.91047085865708    155.84394958490358     155.7558458960878    155.64737533866708    155.51975345909875    155.37419580384014    155.21191791934865    155.03413535208156    154.84206364849632    154.63691835505023    154.41991501820058     154.1922691844048    153.95519640012026    153.70991221180424     153.4576321659141    153.19957180890725      152.936946687241    152.67097234737275    152.40286433575972     152.1338381988594    151.86510948312906     151.5978937350261    151.33340650100786    151.07286332753165    150.81747976105487    150.56847134803485    150.32705363492894    150.09444216819452    149.87185249428887    149.66050015966943    149.46160071079348    149.27636969411842    149.10598788905725    148.95084272664363    148.81052683715328    148.68459856794385    148.57261626637296    148.47413827979818    148.38872295557715    148.31592864106744    148.25531368362664    148.20643643061246     148.1688552293824    148.14212842729404    148.12581437170508    148.11947140997316    148.12265788945575    148.13493215751055    148.15585256149515     148.1849774487671     148.2218651666841    148.26607406260374    148.31716248388352    148.37468877788112     148.4382112919542    148.50728837346028      148.581478369757    148.66033962820197    148.74343049615283    148.83030932096707     148.9205344500024     149.0136642306164    149.10925701016671     149.2068711360109    149.30606495550654     149.4063968160113    149.50742506488274     149.6087080494785     149.7098135053973    149.81038919811107    149.91012475333372      150.008709995401     150.1058347486486    150.20118883741236    150.29446208602795    150.38534431883116    150.47352536015774    150.55869503434337     150.6405431657239    150.71875957863497     150.7930340974124    150.86305654639193     150.9285167499093    150.98910453230025     151.0445097179005    151.09442213104586    151.13853159607203    151.17652793731477    151.20810097910982    151.23294054579296    151.25073646169986    151.26117855116632    151.26395663852813      151.258760548121    151.24528010428062     151.2232051313428    151.19222545364326    151.15203089551784    151.10231128130212    151.04275643533197     150.9730561819431    150.89290034547125    150.80197875025215     150.6999782464026 \n'
b
diff -r 000000000000 -r 1bffabc15695 test-data/target_elastic_transformation.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/target_elastic_transformation.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,19 @@
+Intervals=4
+
+X Coeffs -----------------------------------
+  -36.117111387825766    -5.385082876408411     29.45328994432716     69.52713740463037    104.86444345420553    140.38588675017897    176.15810397808303 
+    -36.2264937297932     32.74325846227494   -23.191917392170573    114.86951887066796     57.81410506673627     93.56163377395188    175.07587514376843 
+   0.8001972037270695    12.384298514696155     18.96171978376125    -9.054176385210205    169.21498785601005      94.5062179325982       133.72979056309 
+     37.4575728168268     6.705478803782103    16.339916785568008     5.562964841921719     65.90677629039934     122.5348986039493     141.4180288611356 
+    5.496315162772514     8.984072369276337    19.160018686442353   -3.7679568417648954     43.56505263435343    117.04632483917443     169.8089818139191 
+  -30.985076022709965     30.48234563028456     -4.57185947623744      39.9368298981367     73.31325150981691     133.0187666782411     176.1637707773676 
+  -35.824759556202444  -0.21353961425912088      30.2488566576995     69.96729226623545    105.30466899887463    140.78641175637736    176.45425772333607 
+
+Y Coeffs -----------------------------------
+  -33.457457947943325    -32.95237416015525    -32.61732073835082    -32.48427183266622    -32.58520159323763    -32.90603931346188    -33.43271428673581 
+    2.474884239673922     6.153086829496797     2.176031929152565    -46.73739868123545    -6.641482787072329     31.63483537910857     2.439245655742275 
+   38.282600013666176    115.10962128034645     99.44890686454225    106.09291532187778     85.86380388606122    120.14511724076014    38.219638319719145 
+    76.76990361540554     95.85872248257112     91.75200358207188       96.626066210422     91.19160682525583     78.03096008955086     75.31885003707583 
+   109.49947623795049     79.13551534555077     86.11217821438672     82.74394547366322     87.45682442725105     84.10531604274911    107.04136479340134 
+    144.8490318765146     131.9043794552622    128.01742994365395     132.9301726951304     130.2019758552892    126.07871666147047    144.55505941286611 
+    179.9547514779979    183.11538557329476    195.11844341969527     177.9158356900086    178.83724202056163     180.2225249725144     179.6371932718197 
b
diff -r 000000000000 -r 1bffabc15695 test-data/target_raw_transformation.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/target_raw_transformation.txt Tue Sep 17 16:55:25 2019 -0400
b
b'@@ -0,0 +1,294 @@\n+Width=144\n+Height=144\n+\n+X Trans -----------------------------------\n+  -0.9471327820908413 -0.036947364843447794    0.8665129887435837    1.7635773766466396     2.654574326398728     3.539832365532834     4.419680021581961     5.294445822079093     6.164458294557222     7.030045966549346    7.8915373655884675      8.74926101920756     9.603545454939628     10.45471920031767    11.303110782874665    12.149048730143617    12.992861569657515    13.834877828949354    14.675426035552135    15.514834716998834    16.353432400822467       17.191547614556    18.029508885732444    18.867644741884785    19.706283710546025    20.545754319249152     21.38638509552716    22.228504566913045     23.07244126093979      23.9185237051404    24.767080427047865    25.618439954195168    26.472930814115326    27.330881534341312    28.192620642406126    29.058476665842765     29.92877814392578    30.803701529270146    31.683138826385786     32.56694769384605     33.45498579022433     34.34711077409394      35.2431803040283     36.14305203860072     37.04658363638463     37.95363275595335    38.864057055880245     39.77771419473869     40.69446183110206     41.61415762354373       42.536659230637     43.46182431095532       44.389510523072     45.31957552556042     46.25187697699394    47.186272535945946    48.122619860989786     49.06077661069881     50.00060044364642     50.94194901840596     51.88467999355079     52.82865102765428     53.77371977928979     54.71974390703071    55.666581069450366     56.61408892512216    57.562125132619435     58.51054735051555    59.459213237383885    60.407980451797826      61.3567066523307     62.30524949755586    63.253470346980464     64.20128065895713     65.14865007282945     66.09554923482635     67.04194879117674     67.98781938810946     68.93313167185342     69.87785628863749      70.8219638846906     71.76542510624161     72.70821059951939     73.65029101075284     74.59163698617084      75.5322191720023     76.47200821447609     77.41097475982112     78.34908945426622     79.28632294404034     80.22264587537234     81.15802889449108     82.09244264762548     83.02585778100443     83.95824494085682     84.88957477341152     85.81981792489742     86.74894504154342     87.67692676957836      88.6037337552312     89.52933664473078     90.45370608430598     91.37681272018574     92.29862719859885     93.21912016577431     94.13826226794093     95.05602415132762     95.97237646216327     96.88731539347678     97.80104427266286     98.71387898837273     99.62613502705707    100.53812787516655    101.45017301915183    102.36258594546365    103.27568214055273    104.18977709086971    105.10518628286525    106.02222520299009    106.94120933769487    107.86245417343034    108.78627519664715    109.71298789379597    110.64290775132753    111.57635025569252    112.51363089334161    113.45506515072555    114.40096851429487    115.35165647050039    116.30744450579282    117.26864810662275    118.23558275944092    119.20856395069801     120.1879071668447    121.17392789433173    122.16694161960973     123.1672638291294    124.17521000934141    125.19109564669654     126.2152362276454    127.24794723863872     128.2895441661271     129.3403424965613     130.4006557989244 \n+  -0.7313664673060771   0.17667588201022702    1.0774047290529172    1.9711849351854833     2.858380793629345     3.739356597605901     4.614476640336566     5.484105215042738      6.34860661494582     7.208345133267221     8.063685063228359      8.91499069805062     9.762626330955415    10.606956255164164    11.448344763898254    12.287156150379097    13.123754707828105    13.958504729466675    14.791770508516228    15.623916338198146     16.45530651173386     17.28630532234475     18.11727706325224    18.948586027677724    19.780596508842624    20.613672799968334    21.448179194276264    22.284479984987808    23.122939465324393    23.963921928507407    24.807791667758266    25.654912976298355     26.50565014734912    27.36036747'..b'5577995234032      135.419784220157    135.28859216070194    135.16424341640416    135.04657099130387    134.93540653694066    134.83058170485415    134.73192814658395    134.63927751366964    134.55246145765085    134.47131163006716     134.3956596824582    134.32533726636353    134.26017603332275    134.20000763487548    134.14466372256135     134.0939759479199    134.04777596249085    134.00589541781363    133.96816596542797    133.93441925687344    133.90448694368965    133.87820067741615     133.8553921095926     133.8358928917586     133.8195346754537    133.80614911221755    133.79556785358974    133.78762255110988    133.78214485631753    133.77896642075234     133.7779188959539     133.7788339334618    133.78154318481566    133.78587830155507    133.79167093521957     133.7987527373489    133.80695269909975 \n+   143.57341840948715    143.52409221274127    143.47689934583906    143.43181660411574    143.38881794786036    143.34787733736184     143.3089687329091    143.27206609479126    143.23714338329714    143.20417455871575    143.17313358133606    143.14399441144707    143.11673100933774      143.091317335297    143.06772734961382    143.04593501257722    143.02591428447613    143.00763912559952    142.99108349623637    142.97622135667564    142.96302666720635    142.95147338811736    142.94153547969773    142.93318690223637    142.92640161602228    142.92115358134447     142.9174167584918    142.91516510775332    142.91437258941798    142.91501316377477    142.91706079111262     142.9204894317205    142.92527304588742     142.9313855939023    142.93880103605412     142.9474933326319    142.95743588921954     142.9685331860426    142.98055596858387    142.99325959747262    143.00639943333812    143.01973083680969    143.03300916851657    143.04598978908805     143.0584280591534    143.07007933934196     143.0806989902829     143.0900423726056    143.09786484693927    143.10392177391319     143.1079685141567      143.109760428299    143.10905287696943    143.10560122079724     143.0991608204117    143.08948703644214    143.07633522951772    143.05946076026785    143.03861898932178    143.01356527730871      142.984054984858    142.94984347259887    142.91068610116065     142.8663382311726    142.81655522326398    142.76109243806414    142.69970523620222    142.63214897830764    142.55817902500954    142.47755073693736    142.39001947472025    142.29534059898756     142.1932821314333    142.08390706786426     141.9675725082867      141.844648503743    141.71550510527527    141.58051236392572     141.4400403307365    141.29445905674982     141.1441385930079     140.9894489905529      140.830760300427    140.66844257367245    140.50286586133137      140.334400214446    140.16341568405852    139.99028232121105     139.8153701769459     139.6390493023052     139.4616897483311     139.2836615660659    139.10533480655164     138.9270795208307    138.74926575994508    138.57226357493707    138.39644301684885    138.22217413672263    138.04982698560056    137.87977161452483    137.71237807453767    137.54801641668126    137.38705669199777    137.22986895152937     137.0768232463183    136.92828962740674    136.78463814583685    136.64623885265084    136.51342820465817    136.38625249617593    136.26460775208992    136.14838895080575     136.0374910707289    135.93180909026484    135.83123798781915    135.73567274179732     135.6450083306049    135.55913973264737    135.47796192633024    135.40136989005907    135.32925860223935    135.26152304127663    135.19805818557637     135.1387590135442     135.0835205035855    135.03223763410588     134.9848053835108    134.94111873020586    134.90107265259647    134.86456212908826    134.83148213808664    134.80172765799722    134.77519366722547    134.75177514417692    134.73136706725708    134.71386441487147    134.69916216542566     134.6871552973251     134.6777387889753    134.67080761878185    134.66625676515022     134.6639812064859     134.6638759211945     134.6658331976206 \n'
b
diff -r 000000000000 -r 1bffabc15695 test-data/warping_index.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/warping_index.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,1 @@
+22.224744070209738
b
diff -r 000000000000 -r 1bffabc15695 test-data/warping_index1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/warping_index1.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,1 @@
+33.6
b
diff -r 000000000000 -r 1bffabc15695 test-data/warping_index2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/warping_index2.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,1 @@
+0.0
b
diff -r 000000000000 -r 1bffabc15695 test-data/warping_index_raw.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/warping_index_raw.txt Tue Sep 17 16:55:25 2019 -0400
b
@@ -0,0 +1,1 @@
+66.4