@Test public void testAngleResults() throws Exception { final Predicate<Double> nonEmpty = Objects::nonNull; final URL resource = getClass().getClassLoader().getResource( "test-skelly.zip"); assert resource != null; final ImagePlus skelly = IJ.openImage(resource.getFile()); final CommandModule module = command().run( IntertrabecularAngleWrapper.class, true, "inputImage", skelly, "minimumValence", 3, "maximumValence", 50, "minimumTrabecularLength", 2, "marginCutOff", 0, "useClusters", true, "iteratePruning", false).get(); @SuppressWarnings("unchecked") final List<DefaultColumn<Double>> table = (List<DefaultColumn<Double>>) module.getOutput("resultsTable"); assertNotNull(table); assertEquals(2, table.size()); final DefaultColumn<Double> threeColumn = table.get(0); assertEquals("3", threeColumn.getHeader()); assertEquals(10, threeColumn.size()); assertEquals(3, threeColumn.stream().filter(nonEmpty).count()); assertEquals(2, threeColumn.stream().filter(nonEmpty).distinct().count()); final DefaultColumn<Double> fiveColumn = table.get(1); assertEquals("5", fiveColumn.getHeader()); assertEquals(10, fiveColumn.size()); assertEquals(10, fiveColumn.stream().filter(nonEmpty).count()); assertEquals(6, fiveColumn.stream().filter(nonEmpty).distinct().count()); assertEquals(1, fiveColumn.stream().filter(nonEmpty) .filter(d -> d == Math.PI).count()); assertEquals(2, fiveColumn.stream().filter(nonEmpty) .filter(d -> d == Math.PI / 2).count()); }
@Override public void run() { statusService.showStatus("Intertrabecular angles: Initialising..."); statusService.showStatus("Intertrabecular angles: skeletonising"); final ImagePlus skeleton = skeletonise(); statusService.showStatus("Intertrabecular angles: analysing skeletons"); statusService.showProgress(0, PROGRESS_STEPS); final Graph[] graphs = analyzeSkeleton(skeleton); if (graphs == null || graphs.length == 0) { cancelMacroSafe(this, NO_SKELETONS); return; } warnMultipleGraphs(graphs); final Graph largestGraph = Arrays.stream(graphs).max(Comparator .comparingInt(a -> a.getVertices().size())).orElse(new Graph()); statusService.showStatus("Intertrabecular angles: pruning graph"); statusService.showProgress(1, PROGRESS_STEPS); final ValuePair<Graph, double[]> pruningResult = GraphPruning .pruneShortEdges(largestGraph, minimumTrabecularLength, iteratePruning, useClusters, coefficients); final Graph cleanGraph = pruningResult.a; statusService.showStatus( "Intertrabecular angles: valence sorting trabeculae"); statusService.showProgress(3, PROGRESS_STEPS); final Map<Integer, List<Vertex>> valenceMap = VertexUtils.groupByValence( cleanGraph.getVertices(), minimumValence, maximumValence); if (valenceMap.isEmpty()) { cancelMacroSafe(this, NO_RESULTS_MSG); } statusService.showStatus("Intertrabecular angles: calculating angles"); statusService.showProgress(4, PROGRESS_STEPS); final Map<Integer, DoubleStream> radianMap = createRadianMap(valenceMap); addResults(radianMap); printEdgeCentroids(cleanGraph.getEdges()); printCulledEdgePercentages(pruningResult.b); reportUsage(); }
IntertrabecularAngleWrapper extends BoneJCommand { @Override public void run() { statusService.showStatus("Intertrabecular angles: Initialising..."); statusService.showStatus("Intertrabecular angles: skeletonising"); final ImagePlus skeleton = skeletonise(); statusService.showStatus("Intertrabecular angles: analysing skeletons"); statusService.showProgress(0, PROGRESS_STEPS); final Graph[] graphs = analyzeSkeleton(skeleton); if (graphs == null || graphs.length == 0) { cancelMacroSafe(this, NO_SKELETONS); return; } warnMultipleGraphs(graphs); final Graph largestGraph = Arrays.stream(graphs).max(Comparator .comparingInt(a -> a.getVertices().size())).orElse(new Graph()); statusService.showStatus("Intertrabecular angles: pruning graph"); statusService.showProgress(1, PROGRESS_STEPS); final ValuePair<Graph, double[]> pruningResult = GraphPruning .pruneShortEdges(largestGraph, minimumTrabecularLength, iteratePruning, useClusters, coefficients); final Graph cleanGraph = pruningResult.a; statusService.showStatus( "Intertrabecular angles: valence sorting trabeculae"); statusService.showProgress(3, PROGRESS_STEPS); final Map<Integer, List<Vertex>> valenceMap = VertexUtils.groupByValence( cleanGraph.getVertices(), minimumValence, maximumValence); if (valenceMap.isEmpty()) { cancelMacroSafe(this, NO_RESULTS_MSG); } statusService.showStatus("Intertrabecular angles: calculating angles"); statusService.showProgress(4, PROGRESS_STEPS); final Map<Integer, DoubleStream> radianMap = createRadianMap(valenceMap); addResults(radianMap); printEdgeCentroids(cleanGraph.getEdges()); printCulledEdgePercentages(pruningResult.b); reportUsage(); } }
IntertrabecularAngleWrapper extends BoneJCommand { @Override public void run() { statusService.showStatus("Intertrabecular angles: Initialising..."); statusService.showStatus("Intertrabecular angles: skeletonising"); final ImagePlus skeleton = skeletonise(); statusService.showStatus("Intertrabecular angles: analysing skeletons"); statusService.showProgress(0, PROGRESS_STEPS); final Graph[] graphs = analyzeSkeleton(skeleton); if (graphs == null || graphs.length == 0) { cancelMacroSafe(this, NO_SKELETONS); return; } warnMultipleGraphs(graphs); final Graph largestGraph = Arrays.stream(graphs).max(Comparator .comparingInt(a -> a.getVertices().size())).orElse(new Graph()); statusService.showStatus("Intertrabecular angles: pruning graph"); statusService.showProgress(1, PROGRESS_STEPS); final ValuePair<Graph, double[]> pruningResult = GraphPruning .pruneShortEdges(largestGraph, minimumTrabecularLength, iteratePruning, useClusters, coefficients); final Graph cleanGraph = pruningResult.a; statusService.showStatus( "Intertrabecular angles: valence sorting trabeculae"); statusService.showProgress(3, PROGRESS_STEPS); final Map<Integer, List<Vertex>> valenceMap = VertexUtils.groupByValence( cleanGraph.getVertices(), minimumValence, maximumValence); if (valenceMap.isEmpty()) { cancelMacroSafe(this, NO_RESULTS_MSG); } statusService.showStatus("Intertrabecular angles: calculating angles"); statusService.showProgress(4, PROGRESS_STEPS); final Map<Integer, DoubleStream> radianMap = createRadianMap(valenceMap); addResults(radianMap); printEdgeCentroids(cleanGraph.getEdges()); printCulledEdgePercentages(pruningResult.b); reportUsage(); }  }
IntertrabecularAngleWrapper extends BoneJCommand { @Override public void run() { statusService.showStatus("Intertrabecular angles: Initialising..."); statusService.showStatus("Intertrabecular angles: skeletonising"); final ImagePlus skeleton = skeletonise(); statusService.showStatus("Intertrabecular angles: analysing skeletons"); statusService.showProgress(0, PROGRESS_STEPS); final Graph[] graphs = analyzeSkeleton(skeleton); if (graphs == null || graphs.length == 0) { cancelMacroSafe(this, NO_SKELETONS); return; } warnMultipleGraphs(graphs); final Graph largestGraph = Arrays.stream(graphs).max(Comparator .comparingInt(a -> a.getVertices().size())).orElse(new Graph()); statusService.showStatus("Intertrabecular angles: pruning graph"); statusService.showProgress(1, PROGRESS_STEPS); final ValuePair<Graph, double[]> pruningResult = GraphPruning .pruneShortEdges(largestGraph, minimumTrabecularLength, iteratePruning, useClusters, coefficients); final Graph cleanGraph = pruningResult.a; statusService.showStatus( "Intertrabecular angles: valence sorting trabeculae"); statusService.showProgress(3, PROGRESS_STEPS); final Map<Integer, List<Vertex>> valenceMap = VertexUtils.groupByValence( cleanGraph.getVertices(), minimumValence, maximumValence); if (valenceMap.isEmpty()) { cancelMacroSafe(this, NO_RESULTS_MSG); } statusService.showStatus("Intertrabecular angles: calculating angles"); statusService.showProgress(4, PROGRESS_STEPS); final Map<Integer, DoubleStream> radianMap = createRadianMap(valenceMap); addResults(radianMap); printEdgeCentroids(cleanGraph.getEdges()); printCulledEdgePercentages(pruningResult.b); reportUsage(); }  @Override void run(); }
IntertrabecularAngleWrapper extends BoneJCommand { @Override public void run() { statusService.showStatus("Intertrabecular angles: Initialising..."); statusService.showStatus("Intertrabecular angles: skeletonising"); final ImagePlus skeleton = skeletonise(); statusService.showStatus("Intertrabecular angles: analysing skeletons"); statusService.showProgress(0, PROGRESS_STEPS); final Graph[] graphs = analyzeSkeleton(skeleton); if (graphs == null || graphs.length == 0) { cancelMacroSafe(this, NO_SKELETONS); return; } warnMultipleGraphs(graphs); final Graph largestGraph = Arrays.stream(graphs).max(Comparator .comparingInt(a -> a.getVertices().size())).orElse(new Graph()); statusService.showStatus("Intertrabecular angles: pruning graph"); statusService.showProgress(1, PROGRESS_STEPS); final ValuePair<Graph, double[]> pruningResult = GraphPruning .pruneShortEdges(largestGraph, minimumTrabecularLength, iteratePruning, useClusters, coefficients); final Graph cleanGraph = pruningResult.a; statusService.showStatus( "Intertrabecular angles: valence sorting trabeculae"); statusService.showProgress(3, PROGRESS_STEPS); final Map<Integer, List<Vertex>> valenceMap = VertexUtils.groupByValence( cleanGraph.getVertices(), minimumValence, maximumValence); if (valenceMap.isEmpty()) { cancelMacroSafe(this, NO_RESULTS_MSG); } statusService.showStatus("Intertrabecular angles: calculating angles"); statusService.showProgress(4, PROGRESS_STEPS); final Map<Integer, DoubleStream> radianMap = createRadianMap(valenceMap); addResults(radianMap); printEdgeCentroids(cleanGraph.getEdges()); printCulledEdgePercentages(pruningResult.b); reportUsage(); }  @Override void run(); static final String NO_RESULTS_MSG; }