Belle II Software development
CellularAutomaton< ACellHolder > Class Template Reference

Implements the weighted cellular automaton algorithm. More...

#include <CellularAutomaton.h>

Classes

class  CycleException
 Type for the very basic exception signal used in the detection of cycles. More...
 

Public Member Functions

ACellHolder * applyTo (const std::vector< ACellHolder * > &cellHolders, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations) const
 Applies the cellular automaton to the collection of cells and its neighborhood.
 

Private Member Functions

Weight getFinalCellState (ACellHolder *cellHolder, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations) const
 Gets the cell state of the cell holder.
 
Weight updateState (ACellHolder *cellHolder, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations) const
 Updates the state of a cell considering all continuations recursively.
 
void prepareCellFlags (const std::vector< ACellHolder * > &cellHolders) const
 Helper function to prepare the stats.
 

Detailed Description

template<class ACellHolder>
class Belle2::TrackFindingCDC::CellularAutomaton< ACellHolder >

Implements the weighted cellular automaton algorithm.

Definition at line 30 of file CellularAutomaton.h.

Member Function Documentation

◆ applyTo()

ACellHolder * applyTo ( const std::vector< ACellHolder * > &  cellHolders,
const std::vector< WeightedRelation< ACellHolder > > &  cellHolderRelations 
) const
inline

Applies the cellular automaton to the collection of cells and its neighborhood.

Parameters
cellHoldersThe range based iterable containing the cells.
cellHolderRelationsThe weighted relations between the cells.
Returns
The cell holder with the highest cell state found.

Definition at line 43 of file CellularAutomaton.h.

45 {
46 B2ASSERT("Expected the relations to be sorted",
47 std::is_sorted(cellHolderRelations.begin(), cellHolderRelations.end()));
48
49 // Set all cell states to -inf and the non permanent flags to unset.
50 prepareCellFlags(cellHolders);
51
52 for (ACellHolder* cellHolder : cellHolders) {
53 AutomatonCell& cell = cellHolder->getAutomatonCell();
54 if (cell.hasMaskedFlag()) continue;
55 if (cell.hasCycleFlag()) continue;
56
57 if (not cell.hasAssignedFlag()) {
58 // Mark this cell as a start point of a long path since we encountered it in
59 // at the top level of the recursion.
60 cell.setStartFlag();
61 // The flag will be unset when it appears on the _to_ side of a relation.
62 }
63
64 try {
65 // Assigns flags and the cell state
66 getFinalCellState(cellHolder, cellHolderRelations);
67 } catch (CycleException) {
68 // TODO: Come up with some handling for cycles.
69 // For now we continue to look for long paths in the graph
70 // hoping to find a part that does not enter the cycle.
71
72 // Thoughts:
73 // If there is a single cycle in the graph we might be able to break it at some point.
74 // However, if there are multiple cycles intertwined things get very tricky.
75 // But can we actually distinguish the two situations?
76 }
77 }
78
79 auto lessStartCellState = [](ACellHolder * lhs, ACellHolder * rhs) {
80 const AutomatonCell& lhsCell = lhs->getAutomatonCell();
81 const AutomatonCell& rhsCell = rhs->getAutomatonCell();
82 return (std::make_pair(lhsCell.hasStartFlag(), lhsCell.getCellState()) <
83 std::make_pair(rhsCell.hasStartFlag(), rhsCell.getCellState()));
84 };
85
86 auto itStartCellHolder =
87 std::max_element(cellHolders.begin(), cellHolders.end(), lessStartCellState);
88 if (itStartCellHolder == cellHolders.end()) return nullptr;
89 if (not(*itStartCellHolder)->getAutomatonCell().hasStartFlag()) return nullptr;
90 return *itStartCellHolder;
91 }
Weight getFinalCellState(ACellHolder *cellHolder, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations) const
Gets the cell state of the cell holder.
void prepareCellFlags(const std::vector< ACellHolder * > &cellHolders) const
Helper function to prepare the stats.

◆ getFinalCellState()

Weight getFinalCellState ( ACellHolder *  cellHolder,
const std::vector< WeightedRelation< ACellHolder > > &  cellHolderRelations 
) const
inlineprivate

Gets the cell state of the cell holder.

Determines it if necessary traversing the graph. Throws CycleException if it encounters a cycle in the graph.

Definition at line 99 of file CellularAutomaton.h.

101 {
102 AutomatonCell& cell = cellHolder->getAutomatonCell();
103
104 // Throw if this cell has already been traversed in this recursion cycle
105 if (cell.hasCycleFlag()) {
106 B2DEBUG(25, "Cycle detected");
107 throw (CycleException());
108 }
109
110 if (cell.hasAssignedFlag()) {
111 return cell.getCellState();
112
113 } else {
114 // Mark cell in order to detect if it was already traversed in this recursion cycle
115 cell.setCycleFlag();
116
117 Weight finalCellState = updateState(cellHolder, cellHolderRelations);
118
119 // Unmark the cell
120 cell.unsetCycleFlag();
121 return finalCellState;
122 }
123 }
Weight updateState(ACellHolder *cellHolder, const std::vector< WeightedRelation< ACellHolder > > &cellHolderRelations) const
Updates the state of a cell considering all continuations recursively.

◆ prepareCellFlags()

void prepareCellFlags ( const std::vector< ACellHolder * > &  cellHolders) const
inlineprivate

Helper function to prepare the stats.

Clears all temporary cell flags and sets the cell state to minus infinity.

Definition at line 201 of file CellularAutomaton.h.

202 {
203 for (ACellHolder* cellHolder : cellHolders) {
204 AutomatonCell& cell = cellHolder->getAutomatonCell();
205 cell.unsetTemporaryFlags();
206 if (cell.hasMaskedFlag()) continue;
207 cell.setCellState(NAN);
208 }
209 }

◆ updateState()

Weight updateState ( ACellHolder *  cellHolder,
const std::vector< WeightedRelation< ACellHolder > > &  cellHolderRelations 
) const
inlineprivate

Updates the state of a cell considering all continuations recursively.

Definition at line 126 of file CellularAutomaton.h.

128 {
129 AutomatonCell& cell = cellHolder->getAutomatonCell();
130
131 // --- blocked cells do not contribute a continuation ---
132 // Redundant check.
133 if (cell.hasMaskedFlag()) {
134 cell.setAssignedFlag();
135 return NAN;
136 }
137
138 //--- Search for neighbors ---
139 Weight maxStateWithContinuation = NAN;
140
141 // Flag to keep track whether the best continuation lies on a prioriy path
142 bool isPriorityPath = false;
143
144 auto continuations = asRange(
145 std::equal_range(cellHolderRelations.begin(), cellHolderRelations.end(), cellHolder));
146
147 // Check neighbors now
148 for (const WeightedRelation<ACellHolder>& relation : continuations) {
149 // Advance to valid neighbor
150 ACellHolder* neighborCellHolder = relation.getTo();
151
152 // Skip dead ends (should not happen)
153 if (not neighborCellHolder) continue;
154
155 AutomatonCell& neighborCell = neighborCellHolder->getAutomatonCell();
156 // Skip masked continuations
157 if (neighborCell.hasMaskedFlag()) continue;
158
159 // Invalidate a possible start flag since the neighbor has an ancestors
160 neighborCell.unsetStartFlag();
161
162 // Get the value of the neighbor
163 Weight neighborCellState = getFinalCellState(neighborCellHolder, cellHolderRelations);
164
165 // Add the value of the connection to the gain value
166 Weight stateWithContinuation = neighborCellState + relation.getWeight();
167
168 // Remember only the maximum value of all neighbors
169 if (std::isnan(maxStateWithContinuation) or maxStateWithContinuation < stateWithContinuation) {
170 maxStateWithContinuation = stateWithContinuation;
171 // Remember whether the best continuation marks a priority path
172 // construction ensures that priority paths have at least two elements
173 isPriorityPath = neighborCell.hasPriorityFlag() or neighborCell.hasPriorityPathFlag();
174 }
175 } // end for relations
176
177 if (std::isnan(maxStateWithContinuation)) {
178 // No valid neighbor contributed a connection to the cell
179 maxStateWithContinuation = 0;
180 }
181
182 // The value of this cell is only its own weight
183 maxStateWithContinuation += cell.getCellWeight();
184
185 // Set the value
186 cell.setCellState(maxStateWithContinuation);
187 cell.setPriorityPathFlag(isPriorityPath);
188
189 // Mark this cell as having its final value
190 cell.setAssignedFlag();
191
192 // Return the just determined value
193 return cell.getCellState();
194 }

The documentation for this class was generated from the following file: