TreeCC est une structure de données qui représente l'organisation hiérarchique des composantes connectées (CC) dans le système racinaire. Elle permet de naviguer facilement dans l'arborescence des racines primaires, secondaires, tertiaires, etc.
La classe TreeCC est automatiquement construite dans la fonction buildStep5PruneOutliersFirstPhase() :
List<TreeCC> treeRoots = buildStep5PruneOutliersFirstPhase(graph, pph);Cette fonction retourne une liste de racines TreeCC, une pour chaque plante identifiée.
List<TreeCC> children = node.getChildren();TreeCC parent = node.getParent();boolean isRoot = node.isRoot();
boolean isLeaf = node.isLeaf();TreeCC root = node.getRoot();
List<TreeCC> pathToRoot = node.getPathToRoot();List<TreeCC> allDescendants = node.getAllDescendants();List<TreeCC> leaves = node.getAllLeaves();// Retourne TOUS les organes latéraux, y compris les tertiaires, quaternaires, etc.
List<List<TreeCC>> allLateralOrgans = node.getAllLateralOrgans();// Retourne UNIQUEMENT les organes branchés directement sur le chemin principal
// Par exemple, pour une racine primaire (ordre 1) : seulement les secondaires (ordre 2)
List<List<TreeCC>> directLateralOrgans = node.getAllLateralOrgansEmergingDirectlyFromThisOrganPath();Différence importante :
getAllLateralOrgans(): RÉCURSIF - retourne TOUS les organes latéraux de tous niveaux- Exemple : pour une primaire, retourne les secondaires (ordre 2) + tertiaires (ordre 3) + ...
getAllLateralOrgansEmergingDirectlyFromThisOrganPath(): NON RÉCURSIF - retourne uniquement les organes directement branchés- Exemple : pour une primaire, retourne SEULEMENT les secondaires (ordre 2)
Chaque TreeCC contient :
cc: le Connected Component (CC) correspondantplantIndex: l'index de la planteorder: l'ordre de la racine (1=primaire, 2=secondaire, etc.)indexInOrgan: position dans l'organe (0=début)isOrganStart: indique si c'est le début d'un organeisTrunkNode: indique si c'est sur le chemin principal (trunk)
int nodeCount = tree.getNodeCount();
int totalPixels = tree.getTotalPixelCount();
int height = tree.getHeight();
int depth = node.getDepth();List<TreeCC> treeRoots = buildStep5PruneOutliersFirstPhase(graph, pph);
for (int i = 0; i < treeRoots.size(); i++) {
TreeCC root = treeRoots.get(i);
System.out.println("Plante " + i + ":");
TreeCC current = root;
while (current != null) {
System.out.println(" Position " + current.getIndexInOrgan() +
": " + current.getCc());
// Chercher le prochain nœud du trunk (ordre 1)
TreeCC next = null;
for (TreeCC child : current.getChildren()) {
if (child.getOrder() == 1) {
next = child;
break;
}
}
current = next;
}
}for (TreeCC root : treeRoots) {
// Méthode 1 : Récupérer TOUTES les latérales (récursif)
List<List<TreeCC>> allLaterals = root.getAllLateralOrgans();
System.out.println("Total latérales (tous ordres) : " + allLaterals.size());
// Méthode 2 : Récupérer SEULEMENT les latérales directes (non récursif)
List<List<TreeCC>> directLaterals = root.getAllLateralOrgansEmergingDirectlyFromThisOrganPath();
System.out.println("Latérales directes (ordre 2 uniquement) : " + directLaterals.size());
// Exemple : si la primaire a 5 secondaires, et ces secondaires ont 20 tertiaires au total
// allLaterals.size() = 25 (5 secondaires + 20 tertiaires)
// directLaterals.size() = 5 (seulement les secondaires)
for (List<TreeCC> organ : directLaterals) {
TreeCC organStart = organ.get(0);
TreeCC attachmentPoint = organStart.getParent();
System.out.println(" Ordre " + organStart.getOrder() +
", attachée au segment " + attachmentPoint.getIndexInOrgan() +
", longueur : " + organ.size() + " segments");
}
}// Dans buildStep9RefinePlongement, on peut maintenant utiliser TreeCC :
List<TreeCC> treeRoots = buildStep5PruneOutliersFirstPhase(graph, pph);
for (int plantIndex = 0; plantIndex < treeRoots.size(); plantIndex++) {
TreeCC root = treeRoots.get(plantIndex);
// 1. Créer la racine primaire (trunk)
Root primaryRoot = createRootFromTreePath(getMainTrunkPath(root));
rm.addRoot(primaryRoot);
// 2. Créer les racines latérales et les attacher
List<List<TreeCC>> lateralOrgans = root.getAllLateralOrgans();
for (List<TreeCC> lateralPath : lateralOrgans) {
TreeCC lateralStart = lateralPath.get(0);
TreeCC attachmentPoint = lateralStart.getParent();
Root lateralRoot = createRootFromTreePath(lateralPath);
// Attacher au bon parent selon l'ordre
Root parentRoot = findParentRoot(attachmentPoint, primaryRoot);
parentRoot.addLateralRoot(lateralRoot, attachmentPoint.getIndexInOrgan());
}
}// Afficher toute la structure de l'arbre
root.printTree();
// Ou avec plus de contrôle
root.printTree("", true);=== Tree Structure ===
└── TreeCC[Plant=0, Order=1, IndexInOrgan=0, CC=..., Children=3]
├── TreeCC[Plant=0, Order=1, IndexInOrgan=1, CC=..., Children=2]
│ ├── TreeCC[Plant=0, Order=1, IndexInOrgan=2, CC=..., Children=1]
│ └── TreeCC[Plant=0, Order=2, IndexInOrgan=0, CC=..., Children=0]
└── TreeCC[Plant=0, Order=2, IndexInOrgan=0, CC=..., Children=0]
La structure TreeCC est construite automatiquement pendant buildStep5PruneOutliersFirstPhase() et peut être utilisée dans les étapes suivantes, notamment buildStep9RefinePlongement() pour simplifier la construction du RootModel.
- Navigation facile : Plus besoin de parcourir manuellement le graphe pour trouver les parents/enfants
- Structure claire : L'arborescence reflète exactement l'organisation des racines
- Réutilisable : Peut servir pour d'autres analyses (statistiques, visualisation, etc.)
- Performances : La Map interne permet un accès O(1) depuis un CC vers son TreeCC
TreeCC.java: Classe principaleTreeCCExample.java: Exemples d'utilisationRegionAdjacencyGraphPipelineV2.java: Construction dansbuildStep5PruneOutliersFirstPhase()
Consultez TreeCCExample.java pour des exemples complets et détaillés d'utilisation.