Belle II Software development
CellularPathFollower.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <tracking/trackingUtilities/ca/Path.h>
11#include <tracking/trackingUtilities/ca/AutomatonCell.h>
12
13#include <tracking/trackingUtilities/utilities/WeightedRelation.h>
14
15#include <cmath>
16#include <vector>
17
18namespace Belle2 {
23
24 namespace TrackingUtilities {
25
36 template<class ACellHolder>
38
39 public:
41 static std::vector<Path<ACellHolder>> followAll(
42 const std::vector<ACellHolder*>& cellHolders,
43 const std::vector<WeightedRelation<ACellHolder>>& cellHolderRelations,
44 Weight minStateToFollow = -INFINITY)
45 {
46 B2ASSERT("Expected the relations to be sorted",
47 std::is_sorted(cellHolderRelations.begin(), cellHolderRelations.end()));
48
49 // Result
50 std::vector<Path<ACellHolder> > paths;
51
52 // Stack for back tracking
53 Path<ACellHolder> path;
54
55 for (ACellHolder* cellHolder : cellHolders) {
56 const AutomatonCell& automatonCell = cellHolder->getAutomatonCell();
57
58 if (validStartCell(automatonCell, minStateToFollow)) {
59 // Cell marks a start point of a path
60
61 // Start new path
62 path.clear();
63
64 // Insert a pointer to the cell into the path
65 path.push_back(cellHolder);
66
67 // Recursively grow the path
68 growAllPaths(path, cellHolderRelations, paths);
69 path.pop_back();
70 }
71 }
72 return paths;
73 }
74
80 static Path<ACellHolder> followSingle(ACellHolder* startCellHolder,
81 const std::vector<WeightedRelation<ACellHolder>>& cellHolderRelations,
82 Weight minStateToFollow = -INFINITY)
83 {
84 Path<ACellHolder> path;
85 if (not startCellHolder) return path;
86 const AutomatonCell& startCell = startCellHolder->getAutomatonCell();
87 if (not validStartCell(startCell, minStateToFollow)) return path;
88
89 // Start new path
90 path.reserve(20); // Just a guess
91
92 // Insert a pointer to the cell into the path
93 path.push_back(startCellHolder);
94 bool grew = true;
95 while (grew) {
96 grew = false;
97 ACellHolder* cellHolder = path.back();
98
99 auto continuations = asRange(std::equal_range(cellHolderRelations.begin(),
100 cellHolderRelations.end(),
101 cellHolder));
102
103 for (const WeightedRelation<ACellHolder>& relation : continuations) {
104 // cppcheck-suppress useStlAlgorithm
105 if (isHighestContinuation(relation)) {
106 ACellHolder* neighbor = relation.getTo();
107 path.push_back(neighbor);
108 grew = true;
109 break;
110 }
111 }
112 }
113 return path;
114 }
115
116 private:
123 static void growAllPaths(Path<ACellHolder>& path,
124 const std::vector<WeightedRelation<ACellHolder>>& cellHolderRelations,
125 std::vector<Path<ACellHolder> >& paths)
126 {
127 auto growPathByRelation = [&](const WeightedRelation<ACellHolder>& neighborRelation) {
128 if (!isHighestContinuation(neighborRelation)) return false;
129 ACellHolder* neighbor(neighborRelation.getTo());
130 path.push_back(neighbor);
131 growAllPaths(path, cellHolderRelations, paths);
132 path.pop_back();
133 return true;
134 };
135
136 ACellHolder* lastCellHolder = path.back();
137
138 auto continuations = asRange(std::equal_range(cellHolderRelations.begin(),
139 cellHolderRelations.end(),
140 lastCellHolder));
141 int nRelationsUsed = std::count_if(continuations.begin(),
142 continuations.end(),
143 growPathByRelation);
144
145 if (nRelationsUsed == 0) {
146 // end point of the recursion copy maximal path to the vector.
147 paths.push_back(path);
148 }
149 }
150
155 static bool validStartCell(const AutomatonCell& automatonCell,
156 Weight minStateToFollow)
157 {
158 return
159 automatonCell.hasStartFlag() and
160 not automatonCell.hasMaskedFlag() and
161 not automatonCell.hasCycleFlag() and
162 minStateToFollow <= automatonCell.getCellState();
163 }
164
170 {
171 const ACellHolder* cellHolderPtr(relation.getFrom());
172 const ACellHolder* neighborCellHolderPtr(relation.getTo());
173
174 if (not cellHolderPtr or not neighborCellHolderPtr) return false;
175
176 const ACellHolder& cellHolder = *cellHolderPtr;
177 Weight relationWeight = relation.getWeight();
178 const ACellHolder& neighborCellHolder = *neighborCellHolderPtr;
179
180 return isHighestContinuation(cellHolder, relationWeight, neighborCellHolder);
181 }
182
187 static bool isHighestContinuation(const ACellHolder& cellHolder,
188 Weight relationWeight,
189 const ACellHolder& neighborCellHolder)
190 {
191 const AutomatonCell& automatonCell = cellHolder.getAutomatonCell();
192 const AutomatonCell& neighborAutomatonCell = neighborCellHolder.getAutomatonCell();
193
194 return not neighborAutomatonCell.hasCycleFlag() and not neighborAutomatonCell.hasMaskedFlag() and
195 (automatonCell.getCellState() ==
196 (neighborAutomatonCell.getCellState() + relationWeight + automatonCell.getCellWeight()));
197 }
198 };
199 }
201}
Cell used by the cellular automata.
bool hasCycleFlag() const
Gets the current state of the cycle marker flag.
bool hasStartFlag() const
Gets the current state of the start marker flag.
bool hasMaskedFlag() const
Gets the current state of the masked marker flag.
Weight getCellWeight() const
Getter for the cell weight.
Weight getCellState() const
Getter for the cell state.
Implements to pick up of the highest value path in neighborhood Following high value paths can be don...
static Path< ACellHolder > followSingle(ACellHolder *startCellHolder, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations, Weight minStateToFollow=-INFINITY)
Follows a single maximal path starting with the given start cell.
static void growAllPaths(Path< ACellHolder > &path, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations, std::vector< Path< ACellHolder > > &paths)
Helper function for recursively growing paths.
static bool isHighestContinuation(const WeightedRelation< ACellHolder > &relation)
Helper function determining if the given neighbor is one of the best to be followed.
static bool isHighestContinuation(const ACellHolder &cellHolder, Weight relationWeight, const ACellHolder &neighborCellHolder)
Helper function determining if the given neighbor is one of the best to be followed.
static std::vector< Path< ACellHolder > > followAll(const std::vector< ACellHolder * > &cellHolders, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations, Weight minStateToFollow=-INFINITY)
Follow paths from all start cells marked with the start flag.
static bool validStartCell(const AutomatonCell &automatonCell, Weight minStateToFollow)
Helper function to determine, if the cell has all flags indicating to be a start cell and that its st...
Type for two related objects with a weight.
Weight getWeight() const
Getter for the weight.
From * getFrom() const
Getter for the pointer to the from side object.
To * getTo() const
Getter for the pointer to the to side object.
Abstract base class for different kinds of events.