Package sc.fiji.snt.tracing.auto
Class TuftDetector
java.lang.Object
sc.fiji.snt.tracing.auto.TuftDetector
Detects tufts (clusters of nearby terminal structure) in a
Tree and reports them as ranked SeedPoints.
Four node populations can be scanned, selected via TuftDetector.Type:
TuftDetector.Type.TIPS: the tree's end points (DirectedWeightedGraph.getTips())TuftDetector.Type.BRANCH_POINTS: the tree's branch points (DirectedWeightedGraph.getBPs())TuftDetector.Type.TERMINAL_BRANCH_POINTS: branch points that are the immediate parent of at least one terminal branch, i.e., forks where twigs actually converge, as opposed to internal forks anywhere in the tree. More specific (and topologically more robust) thanTuftDetector.Type.BRANCH_POINTSfor tuft detectionTuftDetector.Type.TERMINAL_BRANCHES: the centroid of each terminal branch (aTreeStatistics.getBranches()segment with no children), i.e., the last unbranched run of nodes leading to a tip. Useful when tufts are formed by several short terminal twigs converging in one spot rather than by a single prominent tip/fork node. Because a discontiguous/beaded neurite can fragment into several short, spatially-close but topologically-unrelated terminal branches (mimicking a genuine tuft), short branches are down-weighted by default (seesetPenalizeShortBranches(boolean))TuftDetector.Type.BRANCH_DENSITY: every node of every branch, weighted by the arc length it locally represents. Measures the 'amount of neurite' in a neighborhood rather than a count of discrete tip/branch-point nodes, so it degrades gracefully under a discontiguous/beaded neurite instead of spiking (extra spurious tips) or dropping out (a lost branch point). Scans the whole tree, so a dense non-terminal trunk/shaft can also score as a hotspotTuftDetector.Type.TERMINAL_BRANCH_DENSITY: asTuftDetector.Type.BRANCH_DENSITY, but restricted to terminal branches only keeping the measure focused on terminal structure like the otherTypes
A node's score is the (weighted) number of other nodes found within radius of it, optionally further
weighted by thickness and/or intensity. Nodes belonging to the same tuft mutually reinforce each other's score,
while isolated nodes score low. Candidates are then greedily suppressed by distance (highest score first) so that
each tuft is reported once, at the location of its highest-scoring node.
- Author:
- Tiago Ferreira
- See Also:
-
Nested Class Summary
Nested Classes -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptiondetect(Tree tree, List<TuftDetector.Type> types) Detects tufts across several node populations intreein a single pooled pass: candidates from every requestedTuftDetector.Typeare merged into one KDTree/scoring/suppression run, so a tuft that happens to show up in more than one (e.g. a fork sitting right next to a tip) is still reported once, rather than once per type.detect(Tree tree, TuftDetector.Type type) Detects tufts of the given type intree.voidsetPenalizeShortBranches(boolean penalizeShortBranches) Sets whether short terminal branches have their contribution to the density score down-weighted, forTuftDetector.Type.TERMINAL_BRANCHESonly.voidsetPercentileClip(double percentileClip) Sets the robustness margin (0-45) for confidence normalization; seeSeedConfidence.percentileClipNormalize(double[], double).voidsetRadius(double radius) Sets the tuft radius (physical units)voidsetWeightByIntensity(boolean weightByIntensity) Sets whether each node's sampled intensity (PointInImage.v, min-max normalized across the scanned population) is added to its neighbor count when scoring, in addition to (or instead of) thickness.voidsetWeightByThickness(boolean weightByThickness) Sets whether each node's thickness (PointInImage.radius, or its per-branch average forTuftDetector.Type.TERMINAL_BRANCHES) is added to its neighbor count when scoring.
-
Constructor Details
-
TuftDetector
public TuftDetector(double radius) Creates a detector with the given tuft radius.- Parameters:
radius- neighborhood radius (physical units) defining a tuft. Nodes within this distance of each other are treated as candidates for the same tuft
-
-
Method Details
-
setRadius
public void setRadius(double radius) Sets the tuft radius (physical units) -
setWeightByThickness
public void setWeightByThickness(boolean weightByThickness) Sets whether each node's thickness (PointInImage.radius, or its per-branch average forTuftDetector.Type.TERMINAL_BRANCHES) is added to its neighbor count when scoring. Default: true -
setWeightByIntensity
public void setWeightByIntensity(boolean weightByIntensity) Sets whether each node's sampled intensity (PointInImage.v, min-max normalized across the scanned population) is added to its neighbor count when scoring, in addition to (or instead of) thickness. Nodes with unassigned/NaNvalues contribute0. Requires the tree to have been profiled beforehand (e.g. viaPathProfiler#assignValues()); otherwise every node contributes0and this has no effect. Default: false -
setPenalizeShortBranches
public void setPenalizeShortBranches(boolean penalizeShortBranches) Sets whether short terminal branches have their contribution to the density score down-weighted, forTuftDetector.Type.TERMINAL_BRANCHESonly. A discontiguous (e.g. beaded) neurite can fragment into several short, spatially-close but topologically-unrelated terminal branches, which would otherwise look like a genuine dense tuft. Weight ismin(1, branchLength / radius), so branches at least as long asradiusare unaffected. Default: true -
setPercentileClip
public void setPercentileClip(double percentileClip) Sets the robustness margin (0-45) for confidence normalization; seeSeedConfidence.percentileClipNormalize(double[], double). Default: 10 -
detect
Detects tufts of the given type intree.- Parameters:
tree- the tree to scantype- which node population to scan (seeTuftDetector.Type)- Returns:
- one
SeedPointper detected tuft, sorted by descending confidence. Empty iftreehas no matching nodes
-
detect
Detects tufts across several node populations intreein a single pooled pass: candidates from every requestedTuftDetector.Typeare merged into one KDTree/scoring/suppression run, so a tuft that happens to show up in more than one (e.g. a fork sitting right next to a tip) is still reported once, rather than once per type.- Parameters:
tree- the tree to scantypes- which node population(s) to scan (seeTuftDetector.Type)- Returns:
- one
SeedPointper detected tuft, sorted by descending confidence. Empty iftreehas no matching nodes
-