Commit 1afbbeac authored by rhaase's avatar rhaase
Browse files

initial test classes, also containing academic examples for how to work with graphs/edges/vertices

parent 4caff6fa
package de.mpicbg.scf.skeletonanalysis;
import ij.IJ;
import ij.ImageJ;
import ij.ImagePlus;
import ij.gui.WaitForUserDialog;
import org.junit.Test;
import sc.fiji.analyzeSkeleton.*;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Author: Robert Haase, Scientific Computing Facility, MPI-CBG Dresden, rhaase@mpi-cbg.de
* Date: September 2016
*/
public class BuildSkeletonTest {
@Test
public void buildSkeletonTest()
{
System.out.println("hello 1");
ImageJ.main( new String[1] );
System.out.println("hello 2");
ImagePlus imp = IJ.openImage(
AnalyzeSkeleton_.class.getResource(
"/skelRaw.tif" ).getFile() );
System.out.println("hello 3");
imp.show();
AnalyzeSkeleton_ skel = new AnalyzeSkeleton_();
System.out.println("hello 4");
skel.setup("", imp);
System.out.println("hello 5");
SkeletonResult sr = skel.run(AnalyzeSkeleton_.SHORTEST_BRANCH, false, false, imp, false, false);
int[] numberOfEndPoints = sr.getEndPoints();
System.out.println("numberOfEndPoints " + Arrays.toString(numberOfEndPoints));
int[] numberOfJunctions = sr.getJunctions();
System.out.println("numberOfJunctions " + Arrays.toString(numberOfJunctions));
ArrayList<Point> listStartPoints = sr.getListOfStartingSlabVoxels();
System.out.print("Start points: ");
printListOfPoints(listStartPoints);
ArrayList<Point> listJunctionPoints = sr.getListOfJunctionVoxels();
System.out.print("Junction points: ");
printListOfPoints(listJunctionPoints);
// -----------------
Graph firstGraph = sr.getGraph()[0];
Edge firstEdge = firstGraph.getEdges().get(0);
System.out.println(firstEdge);
GraphDrawer gd = new GraphDrawer(sr.getGraph()[0], imp);
gd.draw();
//drawEdge(firstEdge);
new WaitForUserDialog("bla").show();
}
public void buildRealDataSkeletonTest()
{
// "/Users/rhaase/Projects/Nereo_Huttner_neuron structure_1984/data/Cell 4 AP"
}
private void printListOfPoints(ArrayList<Point> list)
{
System.out.println("number of points: " + list.size());
for (Point point : list)
{
System.out.println("" + point.x + "/" + point.y + "/" + point.z);
}
}
}
package de.mpicbg.scf.skeletonanalysis;
import ij.IJ;
import ij.ImageJ;
import ij.ImagePlus;
import ij.gui.Overlay;
import ij.gui.PointRoi;
import org.junit.Before;
import org.junit.Test;
import sc.fiji.analyzeSkeleton.*;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Author: Robert Haase, Scientific Computing Facility, MPI-CBG Dresden, rhaase@mpi-cbg.de
* Date: September 2016
*/
public class SkeletonAnalyserTest {
@Test
public void academicTestExample()
{
ImageJ.main( new String[1] );
// ---------------------------------
// load images
ImagePlus skeletonImage = IJ.openImage(
AnalyzeSkeleton_.class.getResource(
"/skelRaw.tif" ).getFile() );
skeletonImage.show();
ImagePlus greyValueImage = IJ.openImage(
AnalyzeSkeleton_.class.getResource(
"/greyValueImage.tif" ).getFile() );
greyValueImage.show();
if (greyValueImage.getOverlay() == null) {
greyValueImage.setOverlay(new Overlay());
}
// ---------------------------------
// derive skeleton
AnalyzeSkeleton_ skel = new AnalyzeSkeleton_();
skel.setup("", skeletonImage);
  • @lombardo here you see how to create a Skeleton (from the binary image) and 4 lines below, how to initialise our API, namely the SkeletonAnalyser

Please register or sign in to reply
simpleSkeletonResult = skel.run(AnalyzeSkeleton_.SHORTEST_BRANCH, false, false, greyValueImage, false, false);
// ---------------------------------
// run the skeleton Analyser
skeletonAnalyser = new SkeletonAnalyser(simpleSkeletonResult);
// ---------------------------------
// get largest junction and its position
Please register or sign in to reply
Vertex soma = skeletonAnalyser.getLargestJunction();
Point somaCenter = SkeletonAnalyser.getCenterOfJunction(soma);
System.out.println("Some at: " + somaCenter);
assertTrue(somaCenter.x == 44);
assertTrue(somaCenter.y == 1031);
assertTrue(somaCenter.z == 0);
// ---------------------------------
// get number of processes
ArrayList<Edge> edgesStartingAtSoma = skeletonAnalyser.getEdgesStartingAtJunction(soma);
System.out.println("Numbe of processes (edges starting at soma) " + edgesStartingAtSoma.size());
assertTrue(edgesStartingAtSoma.size() == 2);
  • @lombardo this is how to navigate through edges starting at the soma. This example could be extended to browse through the graph deeply

Please register or sign in to reply
// ---------------------------------
// navigate in edges starting at soma
for (Edge edge : edgesStartingAtSoma)
{
assertTrue(SkeletonAnalyser.junctionsEqual(edge.getV1(), soma));
// check if the edges end is a leaf
Vertex otherJunction = edge.getV2();
ArrayList<Edge> edgesStartingAtJunction = skeletonAnalyser.getEdgesStartingAtJunction(otherJunction);
System.out.println("Number of edges starting at junction " + edgesStartingAtJunction.size());
if (edgesStartingAtJunction.size() == 1)
{
// leaf
System.out.println("Found leaf directly connected to soma.");
}
else
{
// it's not a leaf so go through following edges
for (Edge deeperEdge : edgesStartingAtJunction)
{
// don't go back in tree
if (SkeletonAnalyser.edgesEqual(edge, deeperEdge))
{
System.out.println("Deeper in tree");
// continue recursively
}
}
}
}
// ---------------------------------
// get all leafs
ArrayList<Vertex> leafs = skeletonAnalyser.getLeafs();
System.out.println("number of leafs: " + leafs.size());
assertTrue(leafs.size() == 2);
  • @lombardo An alternative to navigate in the graph is to get a list of paths, each going from a leaf to the soma.

Please register or sign in to reply
// ---------------------------------
// get shortest paths from leafs to
// soma and analyse their straightness
for (Vertex leaf : leafs)
{
ArrayList<Edge> path = skeletonAnalyser.getShortestPath(leaf, soma);
// measure from junction center to junction center
double pathLength = SkeletonAnalyser.getLengthAlongPath(path);
System.out.println("path length " + pathLength);
// last edge ends at soma
Edge edgeAtSoma = path.get(path.size() - 1);
assertTrue(SkeletonAnalyser.junctionsEqual(soma, edgeAtSoma.getV2()));
// but it neads to be flipped, because its second vertex is the soma
Edge edgeStartingAtSoma = SkeletonAnalyser.flipEdge(edgeAtSoma);
assertTrue(SkeletonAnalyser.junctionsEqual(soma, edgeStartingAtSoma.getV1()));
// determine length along path from starting point (at the border of soma) to leaf
double distanceBetweenStartingPointAndSomaCenter = SkeletonAnalyser.getDistanceBetweenStartingPointAndJunctionCenter(edgeStartingAtSoma);
double actualLength = pathLength - distanceBetweenStartingPointAndSomaCenter;
// get starting and ending point
Point startingPoint = edgeStartingAtSoma.getSlabs().get(0);
Point leafCenter = SkeletonAnalyser.getCenterOfJunction(leaf);
// calculate euclidean distance between both points and the actual straightness
double euclideanDistance = SkeletonAnalyser.getPointDistance(startingPoint, leafCenter);
double actualStraightness = euclideanDistance / actualLength;
System.out.println("Straightness (startpoint to leaf center) " + actualStraightness);
System.out.println("Straightness (soma center to leaf center) " + SkeletonAnalyser.getStraightness(path));
}
// ---------------------------------
// draw paths from soma to leaf
for (Vertex leaf : leafs) {
ArrayList<Edge> path = skeletonAnalyser.getShortestPath(leaf, soma);
ArrayList<Point> polygon = SkeletonAnalyser.getPointsAlongPath(path);
for (Point point : polygon)
{
greyValueImage.getOverlay().add(new PointRoi(point.x, point.y));
}
}
  • @lombardo Here you see how to group paths by their process. All paths belonging to a process contain all the same edge: the first edge starting at the soma

Please register or sign in to reply
// ---------------------------------
// determine longest path per process
for (Edge edge : edgesStartingAtSoma) {
double maximumLength = Double.POSITIVE_INFINITY;
for (Vertex leaf : leafs) {
ArrayList<Edge> path = skeletonAnalyser.getShortestPath(soma, leaf);
// check if the leaf is part of the current process
if (SkeletonAnalyser.pathContainsEdge(path, edge)) {
double length = SkeletonAnalyser.getLengthAlongPath(path);
if (maximumLength < length) {
maximumLength = length;
}
}
}
System.out.println("Longest path of process " + (maximumLength - SkeletonAnalyser.getDistanceBetweenStartingPointAndJunctionCenter(edge)));
}
// ---------------------------------
}
SkeletonResult simpleSkeletonResult;
double tolerance = 1;
SkeletonAnalyser skeletonAnalyser;
@Before
public void initialize()
{
ImageJ.main( new String[1] );
ImagePlus target = IJ.openImage(
AnalyzeSkeleton_.class.getResource(
"/verysimple.tif" ).getFile() );
target.show();
AnalyzeSkeleton_ skel = new AnalyzeSkeleton_();
skel.setup("", target);
//skel.run( null );
simpleSkeletonResult = skel.run(AnalyzeSkeleton_.SHORTEST_BRANCH, false, false, target, false, false);
// = skel.assembleResults();
skeletonAnalyser = new SkeletonAnalyser(simpleSkeletonResult);
}
@Test
public void testIfGettingLargestJunctionWorks()
{
// from one particular graph
Vertex v1 = skeletonAnalyser.getLargestJunction();
assertTrue(v1.getPoints().size() == 2);
}
@Test
public void testIfNumberOfStartingEdgesIsCorrect()
{
Vertex v1 = skeletonAnalyser.getLargestJunction();
ArrayList<Edge> edges = skeletonAnalyser.getEdgesStartingAtJunction(v1);
assertTrue(edges.size() == 4);
}
@Test
public void testIfNumberOfLeafsIsCorrect()
{
ArrayList<Vertex> leafs = skeletonAnalyser.getLeafs();
assertTrue(leafs.size() == 4);
}
@Test
public void testIfEdgeCountIsCorrect()
{
assertEquals(simpleSkeletonResult.getGraph()[0].getEdges().size(), 4);
}
@Test
public void testIfAllEdgesHaveSameLength()
{
double length = -1;
for (Edge edge : simpleSkeletonResult.getGraph()[0].getEdges())
{
System.out.println(edge.toString());
System.out.println("V1: " + SkeletonAnalyser.getCenterOfJunction(edge.getV1()));
System.out.println("V1raw: " + edge.getV1());
System.out.println("V2: " + SkeletonAnalyser.getCenterOfJunction(edge.getV2()));
System.out.println("V2raw: " + edge.getV2());
System.out.println("len: " + SkeletonAnalyser.getLengthOfEdge(edge));
if (length < 0)
{
length = SkeletonAnalyser.getLengthOfEdge(edge);
}
else
{
assertEquals(length, SkeletonAnalyser.getLengthOfEdge(edge), tolerance);
}
}
}
// 1,1
// 8,1
@Test
public void testIfShortestPathWorks()
{
Vertex v1 = skeletonAnalyser.getVertexAtPosition(1,1,0);
Vertex v2 = skeletonAnalyser.getVertexAtPosition(8,1,0);
ArrayList<Edge> shortPath = skeletonAnalyser.getShortestPath(v1, v2);
assertTrue(shortPath.size() == 2);
Vertex vCenter = shortPath.get(0).getV2();
Vertex soma = skeletonAnalyser.getLargestJunction();
assertTrue(SkeletonAnalyser.junctionsEqual(vCenter, soma));
}
}
package de.mpicbg.scf.skeletonanalysis;
import ij.IJ;
import ij.ImageJ;
import ij.ImagePlus;
import ij.gui.*;
import org.junit.Test;
import sc.fiji.analyzeSkeleton.AnalyzeSkeleton_;
import sc.fiji.analyzeSkeleton.Edge;
import sc.fiji.analyzeSkeleton.Point;
import sc.fiji.analyzeSkeleton.SkeletonResult;
import java.util.ArrayList;
/**
* Author: Robert Haase, Scientific Computing Facility, MPI-CBG Dresden, rhaase@mpi-cbg.de
* Date: September 2016
*/
public class VerySimpleTest {
ImagePlus target;
@Test
public void verySimpleSkeletonTest()
{
ImageJ.main( new String[1] );
target = IJ.openImage(
AnalyzeSkeleton_.class.getResource(
"/verysimple.tif" ).getFile() );
target.show();
AnalyzeSkeleton_ skel = new AnalyzeSkeleton_();
skel.setup("", target);
SkeletonResult sr = skel.run(AnalyzeSkeleton_.SHORTEST_BRANCH, false, false, target, false, false);
for (Edge edge : sr.getGraph()[0].getEdges()){
drawEdge(edge);
//System.out.println("length: " + edge.getLength());
}
new WaitForUserDialog("bla").show();
}
private void drawEdge(Edge edge)
{
ArrayList<Point> list = edge.getSlabs();
Point predecessor = null;
int sumX = 0;
int sumY = 0;
for (Point point : list)
{
if (predecessor != null)
{
sumX += point.x;
sumY += point.y;
Roi roi = new Line(point.x+0.5, point.y+0.5, predecessor.x+0.5, predecessor.y+0.5);
//()Roi(point.x, point.y, 2, 2);
//roi.setStrokeColor(color);
fixRoiInOverlay(roi);
}
predecessor = point;
}
System.out.println("Edge " + list.get(0).x + "/" + list.get(0).y + " len " + edge.getLength());
//Roi roi = new TextRoi(sumX / list.size(), sumY / list.size(), "Len: " + edge.getLength());
//fixRoiInOverlay(roi);
}
private void fixRoiInOverlay(Roi roi) {
if (target.getOverlay() == null) {
target.setOverlay(new Overlay());
}
target.getOverlay().add(roi);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment