Belle II Software  release-08-01-10
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 
21 using namespace Belle2;
22 using namespace TrackFindingCDC;
23 
24 #if 0
25 namespace {
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 
149 void 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 
190 std::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  // Expaning 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 curv points from discrete overlap specifications.
Definition: CurvRep.h:23
DiscreteCurv::Array constructArray() const
Constuct the array of discrete curv 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
Constuct 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 parmeter list.