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