Belle II Software  release-08-01-10
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 
19 namespace 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  // Recursivly 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...
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.
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.
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.
To * getTo() const
Getter for the pointer to the to side object.
From * getFrom() const
Getter for the pointer to the from side object.
Abstract base class for different kinds of events.