Belle II Software development
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
20namespace Belle2 {
25 template <class AState, class AStateRejecter, class AResult>
27 {
29 };
30
31 template <class AState, class AStateRejecter, class AResult>
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 if (childStates.empty()) {
100 B2DEBUG(29, "Terminating this route, as there are no possible child states.");
101 if (not m_param_endEarly) {
102 results.emplace_back(path);
103 }
104 return;
105 }
106
107 // Do everything with child states, linking, extrapolation, teaching, discarding, what have
108 // you.
109 const std::vector<TrackFindingCDC::WithWeight<const AState*>>& constPath = path;
110 m_stateRejecter.apply(constPath, childStates);
111
112 if (childStates.empty()) {
113 B2DEBUG(29, "Terminating this route, as there are no possible child states.");
114 if (not m_param_endEarly) {
115 results.emplace_back(path);
116 }
117 return;
118 }
119
120 // Traverse the tree from each new state on
121 const auto stateLess = [](const auto & lhs, const auto & rhs) {
122 return lhs->getAutomatonCell().getCellState() < rhs->getAutomatonCell().getCellState();
123 };
124 std::sort(childStates.begin(), childStates.end(), stateLess);
125
126 B2DEBUG(29, "Having found " << childStates.size() << " child states.");
127 for (const TrackFindingCDC::WithWeight<AState*>& childState : childStates) {
128 path.emplace_back(childState, childState.getWeight());
129 traverseTree(path, relations, results);
130 path.pop_back();
131 }
132 }
134}
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 traverseTree(std::vector< TrackFindingCDC::WithWeight< const AState * > > &path, const std::vector< TrackFindingCDC::WeightedRelation< AState > > &relations, std::vector< AResult > &results)
Implementation of the traverseTree function.
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.
Abstract base class for different kinds of events.