Belle II Software  release-08-01-10
TreeSearcher.icc.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/ckf/general/findlets/TreeSearcher.dcl.h>
11 
12 #include <framework/logging/Logger.h>
13 
14 #include <tracking/trackFindingCDC/utilities/Range.h>
15 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
16 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
17 
18 #include <framework/core/ModuleParamList.templateDetails.h>
19 
20 namespace Belle2 {
25  template <class AState, class AStateRejecter, class AResult>
27  {
29  };
30 
31  template <class AState, class AStateRejecter, class AResult>
32  void TreeSearcher<AState, AStateRejecter, AResult>::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
33  {
34  m_stateRejecter.exposeParameters(moduleParamList, prefix);
35 
36  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "endEarly"), m_param_endEarly,
37  "Make it possible to have all subresults in the end result vector.",
38  m_param_endEarly);
39  }
40 
41  template <class AState, class AStateRejecter, class AResult>
42  void TreeSearcher<AState, AStateRejecter, AResult>::apply(const std::vector<AState>& seededStates,
43  std::vector<AState>& hitStates,
44  const std::vector<TrackFindingCDC::WeightedRelation<AState>>& relations,
45  std::vector<AResult>& results)
46  {
47  B2ASSERT("Expected relation to be sorted",
48  std::is_sorted(relations.begin(), relations.end()));
49 
50  // TODO: May be better to just do this for each seed separately
51  const std::vector<AState*>& statePointers = TrackFindingCDC::as_pointers<AState>(hitStates);
52  m_automaton.applyTo(statePointers, relations);
53 
54  std::vector<TrackFindingCDC::WithWeight<const AState*>> path;
55  for (const AState& state : seededStates) {
56  B2DEBUG(29, "Starting with new seed...");
57 
58  path.emplace_back(&state, 0);
59  traverseTree(path, relations, results);
60  path.pop_back();
61  B2ASSERT("Something went wrong during the path traversal", path.empty());
62 
63  B2DEBUG(29, "... finished with seed");
64  }
65  }
66 
67  template <class AState, class AStateRejecter, class AResult>
69  const std::vector<TrackFindingCDC::WeightedRelation<AState>>& relations,
70  std::vector<AResult>& results)
71  {
72  if (m_param_endEarly) {
73  // Make it possible to end earlier (with less hits)
74  results.emplace_back(path);
75  }
76 
77  // Implement only graph traversal logic and leave the extrapolation and selection to the
78  // rejecter.
79  const AState* currentState = path.back();
80  auto continuations =
81  TrackFindingCDC::asRange(std::equal_range(relations.begin(), relations.end(), currentState));
82 
83  std::vector<TrackFindingCDC::WithWeight<AState*>> childStates;
84  for (const TrackFindingCDC::WeightedRelation<AState>& continuation : continuations) {
85  AState* childState = continuation.getTo();
86  TrackFindingCDC::Weight weight = continuation.getWeight();
87  // the state may still include information from an other round of processing, so lets set it back
88 
89  if (std::count(path.begin(), path.end(), childState)) {
90  // Cycle detected -- is this the best handling?
91  // Other options: Raise an exception and bail out of this seed
92  B2FATAL("Cycle detected!");
93  }
94 
95  childState->reset();
96  childStates.emplace_back(childState, weight);
97  }
98 
99  // Do everything with child states, linking, extrapolation, teaching, discarding, what have
100  // you.
101  const std::vector<TrackFindingCDC::WithWeight<const AState*>>& constPath = path;
102  m_stateRejecter.apply(constPath, childStates);
103 
104  if (childStates.empty()) {
105  B2DEBUG(29, "Terminating this route, as there are no possible child states.");
106  if (not m_param_endEarly) {
107  results.emplace_back(path);
108  }
109  return;
110  }
111 
112  // Traverse the tree from each new state on
113  const auto stateLess = [](const auto & lhs, const auto & rhs) {
114  return lhs->getAutomatonCell().getCellState() < rhs->getAutomatonCell().getCellState();
115  };
116  std::sort(childStates.begin(), childStates.end(), stateLess);
117 
118  B2DEBUG(29, "Having found " << childStates.size() << " child states.");
119  for (const TrackFindingCDC::WithWeight<AState*>& childState : childStates) {
120  path.emplace_back(childState, childState.getWeight());
121  traverseTree(path, relations, results);
122  path.pop_back();
123  }
124  }
126 }
The Module parameter list class.
void addProcessingSignalListener(ProcessingSignalListener *psl)
Register a processing signal listener to be notified.
Type for two related objects with a weight.
A mixin class to attach a weight to an object.
Definition: WithWeight.h:24
AStateRejecter m_stateRejecter
State rejecter to decide which available continuations should be traversed next.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
void apply(const std::vector< AState > &seededStates, std::vector< AState > &hitStates, const std::vector< TrackFindingCDC::WeightedRelation< AState >> &relations, std::vector< AResult > &results) final
Main function of this findlet: traverse a tree starting from a given seed states.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters of the subfindlet.
TreeSearcher()
Construct this findlet and add the subfindlet as listener.
void traverseTree(std::vector< TrackFindingCDC::WithWeight< const AState * >> &path, const std::vector< TrackFindingCDC::WeightedRelation< AState >> &relations, std::vector< AResult > &results)
Implementation of the traverseTree function.
Abstract base class for different kinds of events.