Mercurial > repos > bgruening > imagej2_crop
diff imagej2_analyze_skeleton_jython_script.py @ 0:018144807556 draft default tip
planemo upload for repository https://github.com/bgruening/galaxytools/tree/master/tools/image_processing/imagej2 commit 8f49f3c66b5a1de99ec15e65c2519a56792f1d56
author | bgruening |
---|---|
date | Tue, 24 Sep 2024 17:12:52 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imagej2_analyze_skeleton_jython_script.py Tue Sep 24 17:12:52 2024 +0000 @@ -0,0 +1,173 @@ +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", +] +OPTIONS = ["edm=Overwrite", "iterations=1", "count=1"] + + +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. +input = sys.argv[-7] +black_background = sys.argv[-6] == "yes" +prune_cycle_method = sys.argv[-5] +prune_ends = sys.argv[-4] == "yes" +calculate_largest_shortest_path = sys.argv[-3] == "yes" +if calculate_largest_shortest_path: + BASIC_NAMES.extend(["Longest Shortest Path", "spx", "spy", "spz"]) + DETAIL_NAMES.extend([" ", " ", " ", " "]) +show_detailed_info = sys.argv[-2] == "yes" +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() + +# Set binary options. +options_list = OPTIONS +if black_background: + options_list.append("black") +options = " ".join(options_list) +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)