Belle II Software development
AxialTrackCreatorHitHough.cc
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#include <tracking/trackFindingCDC/findlets/minimal/AxialTrackCreatorHitHough.h>
9
10#include <tracking/trackFindingCDC/hough/perigee/AxialLegendreLeafProcessor.h>
11#include <tracking/trackFindingCDC/hough/perigee/AxialLegendreLeafProcessor.icc.h>
12#include <tracking/trackFindingCDC/hough/perigee/StandardBinSpec.h>
13
14#include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
15#include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
16
17#include <tracking/trackFindingCDC/utilities/StringManipulation.h>
18
19#include <framework/core/ModuleParamList.templateDetails.h>
20
21using namespace Belle2;
22using namespace TrackFindingCDC;
23
24#if 0
25namespace {
26 void saveBounds(std::vector<float> bounds, const std::string& fileName)
27 {
28 std::ofstream boundsFile;
29 boundsFile.open(fileName);
30 for (float bound : bounds) {
31 boundsFile << bound;
32 boundsFile << "\n";
33 }
34 boundsFile.close();
35 }
36
37 std::vector<float> loadBounds(const std::string& fileName)
38 {
39 std::vector<float> bounds;
40 std::ifstream boundsFile;
41 std::string boundLine;
42 boundsFile.open(fileName);
43 if (boundsFile.is_open()) {
44 while (std::getline(boundsFile, boundLine)) {
45 float bound = stof(boundLine);
46 bounds.push_back(bound);
47 }
48 boundsFile.close();
49 } else {
50 B2ERROR("Could not read bounds file");
51 }
52 return bounds;
53 }
54}
55#endif
56
58{
59 return "Generates axial tracks from hits using several increasingly relaxed hough space search over phi0 and curvature.";
60}
61
63 const std::string& prefix)
64{
65 // Parameters for the hough space
66 moduleParamList->addParameter(prefixed(prefix, "granularityLevel"),
68 "Level of divisions in the hough space.",
70
71 moduleParamList->addParameter(prefixed(prefix, "sectorLevelSkip"),
73 "Number of levels to be skipped in the hough "
74 "space on the first level to form sectors",
76
77 moduleParamList->addParameter(prefixed(prefix, "curvBounds"),
79 "Curvature bounds of the hough space. Either 2 or all discrete bounds",
81
82 moduleParamList->addParameter(prefixed(prefix, "discretePhi0Width"),
84 "Width of the phi0 bins at the lowest level of the hough space.",
86
87 moduleParamList->addParameter(prefixed(prefix, "discretePhi0Overlap"),
89 "Overlap of the phi0 bins at the lowest level of the hough space.",
91
92 moduleParamList->addParameter(prefixed(prefix, "discreteCurvWidth"),
94 "Width of the curvature bins at the lowest level of the hough space.",
96
97 moduleParamList->addParameter(prefixed(prefix, "discreteCurvOverlap"),
99 "Overlap of the curvature bins at the lowest level of the hough space.",
101
102 // Relaxation schedule
103 moduleParamList->addParameter(prefixed(prefix, "relaxationSchedule"),
105 "Relaxation schedule for the leaf processor in the hough tree. "
106 "For content of the individual parameter maps consider the parameters of the "
107 "AxialLegendreLeafProcessor",
109
110}
111
113{
115
116 // Construct the hough space
117 const long nPhi0Bins = std::pow(c_phi0Divisions, m_param_granularityLevel);
118 const Phi0BinsSpec phi0BinsSpec(nPhi0Bins,
121
122 if (m_param_curvBounds.size() == 2) {
123 // If parameters are unchanged use the legendre default binning
124 if (m_param_discreteCurvOverlap == -1) {
126 std::array<float, 2> curvSpan({m_param_curvBounds[0], m_param_curvBounds[1]});
128 } else {
129 std::array<double, 2> curvBounds{{m_param_curvBounds.front(), m_param_curvBounds.back()}};
130 const long nCurvBins = std::pow(c_curvDivisions, m_param_granularityLevel);
131 const CurvBinsSpec curvBinsSpec(curvBounds.front(),
132 curvBounds.back(),
133 nCurvBins,
136 m_param_curvBounds = curvBinsSpec.constructArray();
137 }
138 }
139
140 // Construct hough tree
142 m_houghTree = std::make_unique<SimpleRLTaggedWireHitPhi0CurvHough>(maxTreeLevel, m_curlCurv);
143 m_houghTree->setSectorLevelSkip(m_param_sectorLevelSkip);
144 m_houghTree->assignArray<DiscretePhi0>(phi0BinsSpec.constructArray(), phi0BinsSpec.getNOverlap());
146 m_houghTree->initialize();
147}
148
149void AxialTrackCreatorHitHough::apply(const std::vector<const CDCWireHit*>& axialWireHits,
150 std::vector<CDCTrack>& tracks)
151{
152 // Reset the mask flag and select only the untaken hits
153 std::vector<const CDCWireHit*> unusedAxialWireHits;
154 for (const CDCWireHit* wireHit : axialWireHits) {
155 (*wireHit)->setMaskedFlag(false);
156 if ((*wireHit)->hasTakenFlag()) continue;
157 unusedAxialWireHits.push_back(wireHit);
158 }
159
160 // Setup the level processor and obtain its parameter list to be set.
161 using Node = typename SimpleRLTaggedWireHitPhi0CurvHough::Node;
163 AxialLegendreLeafProcessor<Node> leafProcessor(maxTreeLevel);
164 leafProcessor.setAxialWireHits(axialWireHits);
165 ModuleParamList moduleParamList;
166 const std::string prefix = "";
167 leafProcessor.exposeParameters(&moduleParamList, prefix);
168
169 // Find tracks with increasingly relaxed conditions in the hough grid
170 m_houghTree->seed(std::move(unusedAxialWireHits));
171 for (const ParameterVariantMap& passParameters : m_param_relaxationSchedule) {
172 AssignParameterVisitor::update(&moduleParamList, passParameters);
173 leafProcessor.beginWalk();
174 m_houghTree->findUsing(leafProcessor);
175 }
176 m_houghTree->fell();
177
178 // Write out tracks as return value
179 const std::vector<CDCTrack>& foundTracks = leafProcessor.getTracks();
180 tracks.insert(tracks.end(), foundTracks.begin(), foundTracks.end());
181}
182
184{
185 m_houghTree->raze();
186 m_houghTree.reset();
188}
189
190std::vector<float> AxialTrackCreatorHitHough::getDefaultCurvBounds(std::array<float, 2> curvSpan, int granularityLevel)
191{
192 using BinSpan = std::array<float, 2>;
193 using BinSpans = std::vector<BinSpan>;
194 std::vector<BinSpans> binSpansByLevel(granularityLevel + 1);
195 binSpansByLevel[0].push_back(BinSpan({curvSpan[0], curvSpan[1]}));
196
197 for (int level = 1; level <= granularityLevel; ++level) {
198 for (const BinSpan& binSpan : binSpansByLevel[level - 1]) {
199 const float subBinWidth = std::fabs(binSpan[1] - binSpan[0]) / 2;
200 const float middle = binSpan[0] + (binSpan[1] - binSpan[0]) / 2.0;
201
202 // Expanding bins somewhat to have a overlap
203 // Assuming granularity level = 12
204 // For level 6 to 7 only expand 1 / 4, for higher levels expand 1 / 8.
205 // Never expand for curvatures lower than 0.005
206 // (copied from the Legendre method. Works well, but some experimentation
207 // needs to be made to know why)
208 const float extension = [&]() {
209 if ((level + 7 <= granularityLevel)
210 // or (std::fabs(middle) <= 0.007)
211 or (std::fabs(middle) <= 0.005)) {
212 return 0.0;
213 } else if (level + 5 < granularityLevel) {
214 return subBinWidth / 4.0;
215 } else {
216 return subBinWidth / 8.0;
217 }
218 }();
219
220 const float lower1 = binSpan[0] - extension;
221 const float upper1 = middle + extension;
222
223 const float lower2 = middle - extension;
224 const float upper2 = binSpan[1] + extension;
225
226 binSpansByLevel[level].push_back({lower1, upper1});
227 binSpansByLevel[level].push_back({lower2, upper2});
228 }
229 }
230
231 // Return highest level as prepared bin bounds.
232 std::vector<float> result;
233
234 for (BinSpan& binSpan : binSpansByLevel[granularityLevel]) {
235 result.push_back(binSpan[0]);
236 result.push_back(binSpan[1]);
237 }
238 return result;
239}
The Module parameter list class.
Predicate class that is feed the nodes in a WeightedHoughTree walk It decides if a node should be fur...
void setAxialWireHits(std::vector< const CDCWireHit * > axialWireHits)
Set the pool of all axial wire hits to be used in the postprocessing.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix)
Expose the parameters as a module parameter list.
void beginWalk()
Function to notify the leaf processor about changes in parameters before a new walk.
const std::vector< CDCTrack > & getTracks() const
Getter for the tracks.
const double m_curlCurv
Curvature below which particles from IP do not leave the CDC.
static const int c_curvDivisions
Fixed parameter: Number of divisions in the curv direction.
void apply(const std::vector< const CDCWireHit * > &axialWireHits, std::vector< CDCTrack > &tracks) final
Generates the tracks from the given segments into the output argument.
std::unique_ptr< SimpleRLTaggedWireHitPhi0CurvHough > m_houghTree
The hough space tree search.
void initialize() final
Initialize the findlet before event processing.
std::vector< ParameterVariantMap > m_param_relaxationSchedule
Parameter: Relaxation schedule for the leaf processor in the hough tree.
int m_param_sectorLevelSkip
Parameter: Number of levels to be skipped in the hough space on the first level to form sectors.
std::string getDescription() final
Short description of the findlet.
int m_param_granularityLevel
Parameter: Level of divisions in the hough space.
int m_param_discretePhi0Width
Parameter: Width of the phi0 bins at the highest level of the hough space.
static std::vector< float > getDefaultCurvBounds(std::array< float, 2 > curvSpan, int granularityLevel)
Get a series of parameters to be set for each pass over the rough hough space.
std::vector< float > m_param_curvBounds
Parameter: hough bounds.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
int m_param_discreteCurvOverlap
Parameter: Overlap of the curvature bins at the highest level of the hough space.
static const int c_phi0Divisions
Fixed parameter: Number of divisions in the phi0 direction.
void terminate() final
Cleanup the findlet after event processing.
int m_param_discreteCurvWidth
Parameter: Width of the curvature bins at the highest level of the hough space.
int m_param_discretePhi0Overlap
Parameter: Overlap of the phi0 bins at the highest level of the hough space.
Class representing a hit wire in the central drift chamber.
Definition: CDCWireHit.h:55
void initialize() override
Receive and dispatch signal before the start of the event processing.
void terminate() override
Receive and dispatch Signal for termination of the event processing.
Strategy to construct discrete curve points from discrete overlap specifications.
Definition: CurvRep.h:23
DiscreteCurv::Array constructArray() const
Construct the array of discrete curve positions.
Definition: CurvRep.h:40
Representation for a discrete position in an array of discrete positions.
Definition: DiscreteValue.h:23
Strategy to construct discrete phi0 points from discrete overlap specifications.
Definition: Phi0Rep.h:20
DiscretePhi0::Array constructArray() const
Construct the array of discrete phi0 positions.
Definition: Phi0Rep.cc:23
int getNOverlap() const
Getter for the overlap in discrete number of positions.
Definition: Phi0Rep.h:47
typename Super::Node Node
Type of the node in the hough tree.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
Abstract base class for different kinds of events.
static void update(ModuleParamList *moduleParamList, const std::map< std::string, boost::variant< T... > > &valuesByName)
Transfer all the parameters from the map boost:variant values to the module parameter list.