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/trackFindingCDC/ca/Path.h>
11#include <tracking/trackFindingCDC/ca/AutomatonCell.h>
12
13#include <tracking/trackFindingCDC/utilities/WeightedRelation.h>
14
15#include <cassert>
16#include <cmath>
17#include <vector>
18
19namespace Belle2 {
25 namespace TrackFindingCDC {
26
37 template<class ACellHolder>
39
40 public:
42 std::vector<Path<ACellHolder>> followAll(
43 const std::vector<ACellHolder*>& cellHolders,
44 const std::vector<WeightedRelation<ACellHolder>>& cellHolderRelations,
45 Weight minStateToFollow = -INFINITY) const
46 {
47 B2ASSERT("Expected the relations to be sorted",
48 std::is_sorted(cellHolderRelations.begin(), cellHolderRelations.end()));
49
50 // Result
51 std::vector<Path<ACellHolder> > paths;
52
53 // Stack for back tracking
54 Path<ACellHolder> path;
55
56 for (ACellHolder* cellHolder : cellHolders) {
57 const AutomatonCell& automatonCell = cellHolder->getAutomatonCell();
58
59 if (validStartCell(automatonCell, minStateToFollow)) {
60 // Cell marks a start point of a path
61
62 // Start new path
63 path.clear();
64
65 // Insert a pointer to the cell into the path
66 path.push_back(cellHolder);
67
68 // Recursively grow the path
69 growAllPaths(path, cellHolderRelations, paths);
70 path.pop_back();
71 }
72 }
73 return paths;
74 }
75
81 Path<ACellHolder> followSingle(ACellHolder* startCellHolder,
82 const std::vector<WeightedRelation<ACellHolder>>& cellHolderRelations,
83 Weight minStateToFollow = -INFINITY) const
84 {
85 assert(std::is_sorted(cellHolderRelations.begin(), cellHolderRelations.end()));
86
87 Path<ACellHolder> path;
88 if (not startCellHolder) return path;
89 const AutomatonCell& startCell = startCellHolder->getAutomatonCell();
90 if (not validStartCell(startCell, minStateToFollow)) return path;
91
92 // Start new path
93 path.reserve(20); // Just a guess
94
95 // Insert a pointer to the cell into the path
96 path.push_back(startCellHolder);
97 bool grew = true;
98 while (grew) {
99 grew = false;
100 ACellHolder* cellHolder = path.back();
101
102 auto continuations = asRange(std::equal_range(cellHolderRelations.begin(),
103 cellHolderRelations.end(),
104 cellHolder));
105
106 for (const WeightedRelation<ACellHolder>& relation : continuations) {
107 // cppcheck-suppress useStlAlgorithm
108 if (isHighestContinuation(relation)) {
109 ACellHolder* neighbor = relation.getTo();
110 path.push_back(neighbor);
111 grew = true;
112 break;
113 }
114 }
115 }
116 return path;
117 }
118
119 private:
126 void growAllPaths(Path<ACellHolder>& path,
127 const std::vector<WeightedRelation<ACellHolder>>& cellHolderRelations,
128 std::vector<Path<ACellHolder> >& paths) const
129 {
130 auto growPathByRelation = [&](const WeightedRelation<ACellHolder>& neighborRelation) {
131 if (not this->isHighestContinuation(neighborRelation)) return false;
132 ACellHolder* neighbor(neighborRelation.getTo());
133 path.push_back(neighbor);
134 this->growAllPaths(path, cellHolderRelations, paths);
135 path.pop_back();
136 return true;
137 };
138
139 ACellHolder* lastCellHolder = path.back();
140
141 auto continuations = asRange(std::equal_range(cellHolderRelations.begin(),
142 cellHolderRelations.end(),
143 lastCellHolder));
144 int nRelationsUsed = std::count_if(continuations.begin(),
145 continuations.end(),
146 growPathByRelation);
147
148 if (nRelationsUsed == 0) {
149 // end point of the recursion copy maximal path to the vector.
150 paths.push_back(path);
151 }
152 }
153
158 static bool validStartCell(const AutomatonCell& automatonCell,
159 Weight minStateToFollow)
160 {
161 return
162 automatonCell.hasStartFlag() and
163 not automatonCell.hasMaskedFlag() and
164 not automatonCell.hasCycleFlag() and
165 minStateToFollow <= automatonCell.getCellState();
166 }
167
173 {
174 ACellHolder* cellHolderPtr(relation.getFrom());
175 ACellHolder* neighborCellHolderPtr(relation.getTo());
176
177 if (not cellHolderPtr or not neighborCellHolderPtr) return false;
178
179 ACellHolder& cellHolder = *cellHolderPtr;
180 Weight relationWeight = relation.getWeight();
181 ACellHolder& neighborCellHolder = *neighborCellHolderPtr;
182
183 return isHighestContinuation(cellHolder, relationWeight, neighborCellHolder);
184 }
185
190 static bool isHighestContinuation(ACellHolder& cellHolder,
191 Weight relationWeight,
192 ACellHolder& neighborCellHolder)
193 {
194 const AutomatonCell& automatonCell = cellHolder.getAutomatonCell();
195 const AutomatonCell& neighborAutomatonCell = neighborCellHolder.getAutomatonCell();
196
197 return not neighborAutomatonCell.hasCycleFlag() and not neighborAutomatonCell.hasMaskedFlag() and
198 (automatonCell.getCellState() ==
199 (neighborAutomatonCell.getCellState() + relationWeight + automatonCell.getCellWeight()));
200 }
201 };
202 }
204}
Cell used by the cellular automata.
Definition: AutomatonCell.h:29
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.
Definition: AutomatonCell.h:96
Implements to pick up of the highest value path in neighborhood Following high value paths can be don...
std::vector< Path< ACellHolder > > followAll(const std::vector< ACellHolder * > &cellHolders, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations, Weight minStateToFollow=-INFINITY) const
Follow paths from all start cells marked with the start flag.
void growAllPaths(Path< ACellHolder > &path, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations, std::vector< Path< ACellHolder > > &paths) const
Helper function for recursively growing paths.
static bool isHighestContinuation(ACellHolder &cellHolder, Weight relationWeight, ACellHolder &neighborCellHolder)
Helper function determining if the given neighbor is one of the best to be followed.
static bool isHighestContinuation(const WeightedRelation< ACellHolder > &relation)
Helper function determining if the given neighbor is one of the best to be followed.
Path< ACellHolder > followSingle(ACellHolder *startCellHolder, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations, Weight minStateToFollow=-INFINITY) const
Follows a single maximal path starting with the given start cell.
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.