Class PersistenceAnalyzer

java.lang.Object
sc.fiji.snt.analysis.PersistenceAnalyzer

public class PersistenceAnalyzer extends Object
Performs persistent homology analysis on neuronal Trees.

This class implements the algorithm described in Kanari, L. et al. "A Topological Representation of Branching Neuronal Morphologies" (Neuroinformatics 16, 3–13, 2018) to extract topological features from neuronal morphologies.

Core Concepts

Filter Functions: Mathematical functions that assign scalar values to each node in the tree based on various morphological properties (distance from root, branch order, spatial coordinates, etc.).

Persistence Diagram: A collection of 2D points (birth, death) representing when topological features (branches) appear and disappear during a filtration process. Each point corresponds to a branch in the neuronal tree.

Persistence: The "lifespan" of a topological feature, calculated as death - birth. High persistence indicates morphologically significant branches, while low persistence may represent noise or minor branches.

Supported Filter Functions
  • Geodesic: Path distance from node to root along the tree structure
  • Radial: Euclidean (straight-line) distance from node to root
  • Centrifugal: Reverse Strahler number (branch order from tips)
  • Path Order: SNT path order hierarchy
  • X, Y, Z: Spatial coordinates for directional analysis
Usage Example

 // Create analyzer for a neuronal tree
 PersistenceAnalyzer analyzer = new PersistenceAnalyzer(tree);
 
 // Get persistence diagram using geodesic distance
 List<List<Double>> diagram = analyzer.getDiagram("geodesic");
 
 // Each inner list contains [birth, death] values
 for (List<Double> pair : diagram) {
     double birth = pair.get(0);
     double death = pair.get(1);
     double persistence = death - birth;
     System.out.println("Branch: birth=" + birth + ", death=" + death + ", persistence=" + persistence);
 }
 
 // Get persistence landscape
 double[] landscape = analyzer.getLandscape("geodesic", 5, 100);
 
Author:
Cameron Arshadi, Tiago Ferreira
See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected static final int
    The geodesic (i.e., "path") distance from a node to the tree root.
    protected static final int
    The Euclidean (i.e., "straight line") distance between a node and the tree root.
    protected static final int
    The centrifugal branch order of a node (reverse Strahler number).
    protected static final int
    The Path order of a node as defined by SNT's path hierarchy.
    protected static final int
    The X coordinate of a node in the spatial coordinate system.
    protected static final int
    The Y coordinate of a node in the spatial coordinate system.
    protected static final int
    The Z coordinate of a node in the spatial coordinate system.
    protected static final int
     
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates a new PersistenceAnalyzer for the specified neuronal tree.
  • Method Summary

    Modifier and Type
    Method
    Description
    getBarcode(String descriptor)
    Gets the persistence barcode for the specified filter function.
    static List<String>
    Gets a list of supported descriptor functions for persistence analysis.
    getDiagram(String descriptor)
    Gets the persistence diagram for the specified filter function.
    getDiagramNodes(String descriptor)
    Gets the tree nodes associated with each point in the persistence diagram.
    double[]
    getLandscape(String descriptor, int numLandscapes, int resolution)
    Gets the persistence landscape as a vectorized representation.
    static void
    main(String[] args)
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • FUNC_UNKNOWN

      protected static final int FUNC_UNKNOWN
      See Also:
    • FUNC_0_GEODESIC

      protected static final int FUNC_0_GEODESIC
      The geodesic (i.e., "path") distance from a node to the tree root.

      This filter function computes the cumulative distance along the tree structure from each node to the root. For trees with edge weights representing physical distances, this gives the actual cable length from root to node.High persistence indicates branches that extend far from their branching point along the tree structure.

      See Also:
    • FUNC_1_RADIAL

      protected static final int FUNC_1_RADIAL
      The Euclidean (i.e., "straight line") distance between a node and the tree root.

      This filter function computes the direct 3D Euclidean distance from each node to the root, ignoring the tree structure. This can reveal spatial organization patterns that differ from the branching structure. High persistence indicates branches that extend far from the root in straight-line distance, regardless of the path taken through the tree.

      See Also:
    • FUNC_2_CENTRIFUGAL

      protected static final int FUNC_2_CENTRIFUGAL
      The centrifugal branch order of a node (reverse Strahler number).

      This filter function assigns branch order values starting from the tips (order 1) and increasing toward the root. This is the reverse of the traditional Strahler ordering and emphasizes the branching complexity from the perspective of terminal branches. High persistence indicates branches with complex sub-branching patterns.

      See Also:
    • FUNC_3_PATH_ORDER

      protected static final int FUNC_3_PATH_ORDER
      The Path order of a node as defined by SNT's path hierarchy.

      This filter function uses SNT's internal path ordering system, where primary paths have order 1, their immediate children have order 2, and so on. This reflects the reconstruction order and hierarchical organization of the traced paths. High persistence indicates branches that are far from primary paths in the reconstruction hierarchy.

      See Also:
    • FUNC_4_X

      protected static final int FUNC_4_X
      The X coordinate of a node in the spatial coordinate system.

      This filter function uses the X spatial coordinate directly as the filter value. This can reveal directional growth patterns and spatial organization along the X-axis. High persistence indicates branches that extend significantly in the positive X direction from their branching points.

      See Also:
    • FUNC_5_Y

      protected static final int FUNC_5_Y
      The Y coordinate of a node in the spatial coordinate system.

      This filter function uses the Y spatial coordinate directly as the filter value. This can reveal directional growth patterns and spatial organization along the Y-axis. High persistence indicates branches that extend significantly in the positive Y direction from their branching points.

      See Also:
    • FUNC_6_Z

      protected static final int FUNC_6_Z
      The Z coordinate of a node in the spatial coordinate system.

      This filter function uses the Z spatial coordinate directly as the filter value. This can reveal directional growth patterns and spatial organization along the Z-axis (depth). High persistence indicates branches that extend significantly in the positive Z direction from their branching points.

      See Also:
  • Constructor Details

    • PersistenceAnalyzer

      public PersistenceAnalyzer(Tree tree)
      Creates a new PersistenceAnalyzer for the specified neuronal tree.

      The analyzer will perform topological data analysis on the tree structure to extract persistence diagrams, barcodes, and landscape representations. The tree must have a valid graph structure with a single root for the analysis to succeed.

      >
      Parameters:
      tree - the neuronal tree to analyze. Must be a valid Tree object with proper structure (no cycles, proper parent-child relationships, at least one tip, and a single root).
      Throws:
      NullPointerException - if tree is null
      See Also:
  • Method Details

    • getDescriptors

      public static List<String> getDescriptors()
      Gets a list of supported descriptor functions for persistence analysis.

      Returns the string identifiers for all available filter functions that can be used with getDiagram(String), getBarcode(String), and other analysis methods. These descriptors are case-insensitive when used in method calls.

      Returns:
      the list of available descriptors: ["geodesic", "radial", "centrifugal", "path order", "x", "y", "z"]
      See Also:
    • getDiagram

      public List<List<Double>> getDiagram(String descriptor) throws UnknownMetricException, IllegalArgumentException
      Gets the persistence diagram for the specified filter function.

      The persistence diagram is the core output of the analysis, consisting of birth-death pairs that represent the "lifespan" of topological features (branches) during the filtration process. Each point in the diagram corresponds to a branch in the neuronal tree.

      Structure: Returns a list where each inner list contains exactly two values:
      • Birth [0]: The filter value where the branch appears (branch point)
      • Death [1]: The filter value where the branch disappears (tip)
      Properties:
      • Number of points = Number of tips in the tree
      • All values are non-negative
      • For geodesic descriptor: sum of all (death-birth) = total cable length
      • High persistence (death-birth) indicates morphologically significant branches
      Example usage:
      
       List<List<Double>> diagram = analyzer.getDiagram("geodesic");
       for (List<Double> point : diagram) {
           double birth = point.get(0);
           double death = point.get(1);
           double persistence = death - birth;
           System.out.println("Branch: persistence = " + persistence);
       }
       
      Parameters:
      descriptor - A descriptor for the filter function as per getDescriptors() (case-insensitive). Supported values: "geodesic", "radial", "centrifugal", "path order", "x", "y", "z". Alternative names like "reverse strahler" for "centrifugal" are also accepted.
      Returns:
      the persistence diagram as a list of [birth, death] pairs. Each inner list contains exactly two Double values representing the birth and death of a topological feature.
      Throws:
      UnknownMetricException - If descriptor is not recognized as a valid filter function
      IllegalArgumentException - If the tree's graph could not be obtained (e.g., tree has multiple roots or is empty)
      See Also:
    • getBarcode

      public List<Double> getBarcode(String descriptor) throws UnknownMetricException, IllegalArgumentException
      Gets the persistence barcode for the specified filter function.

      The barcode is a simplified representation of the persistence diagram that contains only the persistence values (death - birth) for each topological feature, akin to a one-dimensional summary of branch significance.

      Interpretation:
      • High values: Morphologically significant branches
      • Low values: Minor branches or potential noise
      • Distribution: The spread of values indicates branching complexity
      Special Properties:
      • All values are non-negative (|death - birth|)
      • For geodesic descriptor: sum of all values equals total cable length
      • Number of values equals number of tips in the tree
      Example Usage:
      
       List<Double> barcode = analyzer.getBarcode("geodesic");
       
       // Find most significant branches
       barcode.sort(Collections.reverseOrder());
       System.out.println("Top 5 most persistent branches:");
       for (int i = 0; i < Math.min(5, barcode.size()); i++) {
           System.out.println("Branch " + (i+1) + ": " + barcode.get(i));
       }
       
      Parameters:
      descriptor - A descriptor for the filter function as per getDescriptors() (case-insensitive). Supported values: "geodesic", "radial", "centrifugal", "path order", "x", "y", "z".
      Returns:
      the barcode as a list of persistence values (death - birth). Each value represents the "lifespan" or significance of a topological feature (branch).
      Throws:
      UnknownMetricException - If descriptor is not recognized as a valid filter function
      IllegalArgumentException - If the tree's graph could not be obtained (e.g., tree has multiple roots or is empty)
      See Also:
    • getDiagramNodes

      public List<List<SWCPoint>> getDiagramNodes(String descriptor)
      Gets the tree nodes associated with each point in the persistence diagram.

      This method returns the actual SWCPoint nodes from the neuronal tree that correspond to each birth-death pair in the persistence diagram. This allows you to map topological features back to specific locations in the original morphology.

      Structure: Returns a list where each inner list contains exactly two nodes:
      • Birth Node [0]: The branch point where the topological feature appears
      • Death Node [1]: The tip node where the topological feature disappears
      Correspondence: The order of node pairs matches the order of birth-death pairs returned by getDiagram(String), allowing direct correlation between topological features and their spatial locations.

      Example Usage:

      
       List<List<Double>> diagram = analyzer.getDiagram("geodesic");
       List<List<SWCPoint>> nodes = analyzer.getDiagramNodes("geodesic");
       
       for (int i = 0; i < diagram.size(); i++) {
           List<Double> birthDeath = diagram.get(i);
           List<SWCPoint> nodesPair = nodes.get(i);
           
           double persistence = birthDeath.get(1) - birthDeath.get(0);
           SWCPoint branchPoint = nodesPair.get(0);
           SWCPoint tipPoint = nodesPair.get(1);
           
           System.out.printf("Branch with persistence %.2f: from (%.1f,%.1f,%.1f) to (%.1f,%.1f,%.1f)%n",
                             persistence, 
                             branchPoint.getX(), branchPoint.getY(), branchPoint.getZ(),
                             tipPoint.getX(), tipPoint.getY(), tipPoint.getZ());
       }
       
      Parameters:
      descriptor - A descriptor for the filter function as per getDescriptors() (case-insensitive). Supported values: "geodesic", "radial", "centrifugal", "path order", "x", "y", "z".
      Returns:
      the persistence diagram nodes as a list of [birth_node, death_node] pairs. Each inner list contains exactly two SWCPoint objects representing the spatial locations of the topological feature.
      Throws:
      UnknownMetricException - If descriptor is not recognized as a valid filter function
      IllegalArgumentException - If the tree's graph could not be obtained (e.g., tree has multiple roots or is empty)
      See Also:
    • getLandscape

      public double[] getLandscape(String descriptor, int numLandscapes, int resolution)
      Gets the persistence landscape as a vectorized representation.

      Persistence landscapes transform persistence diagrams into a vector space representation that The landscape is a collection of piecewise-linear functions that capture the "shape" of the persistence diagram in a stable, vectorized format.

      Mathematical Background: Each point (birth, death) in the persistence diagram contributes a "tent" function to the landscape. The k-th landscape function at any point is the k-th largest value among all tent functions at that point. This creates a stable, multi-resolution representation of the topological features.

      Output Structure: Returns a 1D array of length numLandscapes × resolution where the first resolution values represent the first landscape function, the next resolution values represent the second landscape function, and so on.

      Parameters:
      descriptor - A descriptor for the filter function as per getDescriptors() (case-insensitive). Supported values: "geodesic", "radial", "centrifugal", "path order", "x", "y", "z".
      numLandscapes - the number of piecewise-linear landscape functions to compute. Higher values capture more detailed topological information but increase computational cost. Typical range: 3-10. Higher values increase computational cost and vector dimensionality.
      resolution - the number of sample points for each landscape function. Higher values provide more precision but increase vector dimensionality. Typical range: 50-200. Higher values increase computational cost and vector dimensionality.
      Returns:
      the persistence landscape as a 1D array of length numLandscapes × resolution. All values are non-negative and scaled by √2 for proper L² normalization.
      Throws:
      UnknownMetricException - If descriptor is not recognized as a valid filter function
      IllegalArgumentException - If the tree's graph could not be obtained, or if numLandscapes or resolution are non-positive
      See Also:
    • main

      public static void main(String[] args)