Belle II Software development
AxialLegendreLeafProcessor.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#include <tracking/trackFindingCDC/hough/perigee/AxialLegendreLeafProcessor.h>
10
11#include <tracking/trackFindingCDC/processing/AxialTrackUtil.h>
12
13#include <tracking/trackFindingCDC/hough/perigee/StereoHitContained.h>
14#include <tracking/trackFindingCDC/hough/perigee/OffOrigin.h>
15#include <tracking/trackFindingCDC/hough/algorithms/InPhi0ImpactCurvBox.h>
16#include <tracking/trackFindingCDC/hough/baseelements/WithSharedMark.h>
17
18#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory2D.h>
19#include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
20#include <tracking/trackFindingCDC/fitting/CDCKarimakiFitter.h>
21#include <tracking/trackingUtilities/geometry/PerigeeCircle.h>
22#include <tracking/trackingUtilities/geometry/VectorUtil.h>
23
24#include <tracking/trackFindingCDC/legendre/precisionFunctions/PrecisionUtil.h>
25
26#include <tracking/trackingUtilities/utilities/StringManipulation.h>
27
28#include <framework/core/ModuleParamList.templateDetails.h>
29
30#include <Math/Vector2D.h>
31
32namespace Belle2 {
37 namespace TrackFindingCDC {
38
39 template <class ANode>
41 {
42 // Special post processing looking for more hits
43 // Start off by fitting the items of the leaf with a general trajectory
44 // that may have a distinct impact != 0
46 auto fitPos = EFitPos::c_RecoPos;
47 auto fitVariance = EFitVariance::c_DriftLength;
48 // Other combinations of fit information
49 // EFitPos::c_RLDriftCircle x EFitVariance::(c_Nominal, c_Pseudo, c_Proper)
50 // have been tried, but found to be worse, which is
51 // not intuitive. Probably the perfect circle trajectory
52 // is not as good of a model on the full CDC volume.
53 CDCObservations2D observations2D(fitPos, fitVariance);
54
55 CDCKarimakiFitter fitter;
56 // Tested alternative CDCRiemannFitter with only marginal differences;
57
58 std::vector<WithSharedMark<TrackingUtilities::CDCRLWireHit>> hits(leaf->begin(), leaf->end());
59 std::sort(hits.begin(), hits.end()); // Hits should be naturally sorted
60 observations2D.appendRange(hits);
61 TrackingUtilities::CDCTrajectory2D trajectory2D = fitter.fit(observations2D);
62 {
63 const double curv = trajectory2D.getCurvature();
64 std::array<DiscreteCurv, 2> curvs = leaf->template getBounds<DiscreteCurv>();
65
66 float lowerCurv = *(curvs[0]);
67 float upperCurv = *(curvs[1]);
68 if (static_cast<double>(TrackingUtilities::ESignUtil::common(lowerCurv, upperCurv)) * curv < 0) {
69 trajectory2D.reverse();
70 }
71 }
72 trajectory2D.setLocalOrigin(ROOT::Math::XYVector(0, 0));
73
74 // Look for more hits near the found trajectory
76 if (m_param_nRoadSearches > 0) {
77 // Acquire all available items in some parent node for the road search
78 // Somewhat bypasses the logic of the tree walk - Must handle with care!
79 ANode* roadNode = leaf;
80 while (roadNode->getParent() and roadNode->getLevel() > m_param_roadLevel) {
81 roadNode = roadNode->getParent();
82 }
83
84 for (int iRoadSearch = 0; iRoadSearch < m_param_nRoadSearches; ++iRoadSearch) {
85 // Use a road search to find new hits from the trajectory
86 // hits = this->searchRoad(*roadNode, trajectory2D); // In case you only want the road hits
87 // if (hits.size() < 5) return;
88
89 // Second version always holding on to the originally found hits
90 int nHitsBefore = hits.size();
91 std::vector<WithSharedMark<TrackingUtilities::CDCRLWireHit>> roadHits = this->searchRoad(*roadNode, trajectory2D);
92 std::sort(roadHits.begin(), roadHits.end());
93 hits.insert(hits.end(), roadHits.begin(), roadHits.end());
94 std::inplace_merge(hits.begin(), hits.begin() + nHitsBefore, hits.end());
95 hits.erase(std::unique(hits.begin(), hits.end()), hits.end());
96
97 // Update the current fit
98 observations2D.clear();
99 observations2D.appendRange(hits);
100 trajectory2D = fitter.fit(observations2D);
101 trajectory2D.setLocalOrigin(ROOT::Math::XYVector(0.0, 0.0));
102 }
103 }
104
105 // Mark found hit as used and safe them with the trajectory
107 std::vector<const TrackingUtilities::CDCWireHit*> foundWireHits;
108 for (TrackingUtilities::CDCRLWireHit& rlWireHit : hits) {
109 foundWireHits.push_back(&rlWireHit.getWireHit());
110 }
111
113
114 // Sync up the marks with the used hits
115 for (WithSharedMark<TrackingUtilities::CDCRLWireHit>& markableRLWireHit : leaf->getTree()->getTopNode()) {
116 const TrackingUtilities::AutomatonCell& automatonCell = markableRLWireHit.getWireHit().getAutomatonCell();
117 if (automatonCell.hasTakenFlag() or automatonCell.hasMaskedFlag()) {
118 markableRLWireHit.mark();
119 } else {
120 markableRLWireHit.unmark();
121 }
122 }
123 }
124
125 template <class ANode>
126 std::vector<WithSharedMark<TrackingUtilities::CDCRLWireHit> >
128 {
129 const TrackingUtilities::PerigeeCircle& circle = trajectory2D.getGlobalCircle();
130 const ROOT::Math::XYVector& support = trajectory2D.getGlobalPerigee();
131 const float curv = circle.curvature();
132 const float phi0 = circle.phi0();
133
135 hitInPhi0CurvBox.setLocalOrigin(support);
136 using RoadHoughBox = StereoHitContained<OffOrigin<InPhi0ImpactCurvBox> >::HoughBox;
137
138 // Determine a precision that we expect to achieve at the fitted momentum
139 // There certainly is some optimizsation potential here.
140 // Spread in the impact parameter is made available here but is not activated yet.
141 const float levelPrecision = 9.0;
142 // Earlier version
143 // const float levelPrecision = 10.5 - 0.24 * exp(-4.13118 * PrecisionUtil::convertRhoToPt(curv) + 2.74);
144 const float phi0Precision = M_PI / std::pow(2.0, levelPrecision + 1.0);
145 const float impactPrecision = 0.0 * std::sqrt(TrackingUtilities::CDCWireHit::c_simpleDriftLengthVariance);
146 const float curvPrecision = 0.15 / std::pow(2.0, levelPrecision);
147
148 DiscreteCurv::Array curvBounds{{curv - curvPrecision, curv + curvPrecision}};
149 ContinuousImpact::Array impactBounds{{ -impactPrecision, impactPrecision}};
150 DiscretePhi0::Array phi0Bounds{{VectorUtil::Phi(phi0 - phi0Precision), VectorUtil::Phi(phi0 + phi0Precision)}};
151 RoadHoughBox precisionPhi0CurvBox(DiscretePhi0::getRange(phi0Bounds),
152 ContinuousImpact::getRange(impactBounds),
153 DiscreteCurv::getRange(curvBounds));
154
155 std::vector<WithSharedMark<TrackingUtilities::CDCRLWireHit>> hitsInPrecisionBox;
156
157 // Explicitly making a copy here to ensure that we do not change the node content
158 for (WithSharedMark<TrackingUtilities::CDCRLWireHit> markableRLWireHit : node) {
159 // Skip marked hits
160 if (markableRLWireHit.isMarked()) continue;
161 TrackingUtilities::Weight weight = hitInPhi0CurvBox(markableRLWireHit, &precisionPhi0CurvBox);
162 if (not std::isnan(weight)) hitsInPrecisionBox.push_back(markableRLWireHit);
163 }
164
165 return hitsInPrecisionBox;
166 }
167 }
169}
170
171namespace Belle2 {
176 namespace TrackFindingCDC {
177 template <class ANode>
178 std::vector<typename AxialLegendreLeafProcessor<ANode>::Candidate>
180 {
181 std::vector<Candidate> result;
182 for (const TrackingUtilities::CDCTrack& track : m_tracks) {
183 std::vector<TrackingUtilities::CDCRLWireHit> rlWireHits;
184 for (const TrackingUtilities::CDCRecoHit3D& recoHit3D : track) {
185 rlWireHits.push_back(recoHit3D.getRLWireHit());
186 }
187 TrackingUtilities::CDCTrajectory2D trajectory2D = track.getStartTrajectory3D().getTrajectory2D();
188 result.emplace_back(std::move(trajectory2D), std::move(rlWireHits));
189 }
190 return result;
191 }
192
193 template <class ANode>
195 const std::string& prefix)
196 {
197 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "maxLevel"),
199 "Level of divisions in the hough space at which a leaf is reached",
201
202 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "minWeight"),
204 "Minimal exceptable weight of a leaf to be considered",
206
207 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "maxCurv"),
209 "Maximal curvature of a leaf to be considered",
211
212 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "curlCurv"),
214 "Curvature below which hits on both arms of the trajectory are allowed",
216
217 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "nRoadSearches"),
219 "How often the road search should be performed to find new hits",
221
222 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "roadLevel"),
224 "Level of the read from which additional hits in the road search can be taken",
226
227 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "curvResolution"),
229 "The name of the resolution function to be used. "
230 "Valid values are 'none', 'const', 'basic', 'origin', 'nonOrigin'",
232 }
233
234 template <class ANode>
236 {
237 // Setup the requested precision function
238 if (m_param_curvResolution == "none") {
239 m_curvResolution = [](double curv __attribute__((unused))) { return NAN; };
240 } else if (m_param_curvResolution == "const") {
241 m_curvResolution = [](double curv __attribute__((unused))) { return 0.0008; };
242 } else if (m_param_curvResolution == "basic") {
244 } else if (m_param_curvResolution == "origin") {
246 } else if (m_param_curvResolution == "nonOrigin") {
248 } else {
249 B2WARNING("Unknown curvature resolution function " << m_param_curvResolution);
250 m_curvResolution = [](double curv __attribute__((unused))) { return NAN; };
251 }
252 }
253 }
255}
The Module parameter list class.
std::vector< Candidate > getCandidates() const
Getter for the candidates structure still used in some tests.
std::vector< TrackingUtilities::CDCTrack > m_tracks
Memory for found trajectories.
std::string m_param_curvResolution
Memory for the name of the resolution function to be used. Valid values are 'none',...
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix)
Expose the parameters as a module parameter list.
void processLeaf(ANode *leaf)
A valuable leaf has been found in the hough tree walk.
void beginWalk()
Function to notify the leaf processor about changes in parameters before a new walk.
std::function< double(double)> m_curvResolution
Memory for the freely defined curvature resolution function.
int m_param_roadLevel
Memory for the tree node level which should be the source of hits for the road searches....
std::vector< const TrackingUtilities::CDCWireHit * > m_axialWireHits
Memory for the pool of axial wire hits to can be used in the post processing.
double m_param_curlCurv
Memory for the curvature of a curler in the CDC.
std::vector< WithSharedMark< TrackingUtilities::CDCRLWireHit > > searchRoad(const ANode &node, const TrackingUtilities::CDCTrajectory2D &trajectory2D)
Look for more hits near a ftted trajectory from hits available in the give node.
int m_param_maxLevel
Memory for the maximal level of the tree.
double m_param_maxCurv
Memory for the maximal curvature that should be searched in the current walk.
double m_param_minWeight
Memory for the minimal weight threshold for following the children of a node.
int m_param_nRoadSearches
Memory for the number of repeated road searches.
Class implementing the fitter using Karimakis method.
Class serving as a storage of observed drift circles to present to the Riemann fitter.
std::size_t appendRange(const TrackingUtilities::CDCSegment2D &segment2D)
Appends all reconstructed hits from the two dimensional segment.
void clear()
Removes all observations stored.
static std::array< This, 2 > getRange(const Array &bounds)
static double getOriginCurvPrecision(double curv)
Function which estimates desired curvature resolution of quadtree node in the given pt region paramet...
static double getNonOriginCurvPrecision(double curv)
Function which estimates desired curvature resolution of quadtree node in the given pt region paramet...
static double getBasicCurvPrecision(double curv)
Basic function to estimate the curvature precision Takes a curvature value and returns a width that.
Predicate class to check for the containment of axial and stereo hits in some hough space part.
Mixin class to attach a mark that is shared among many instances.
Cell used by the cellular automata.
bool hasMaskedFlag() const
Gets the current state of the masked marker flag.
bool hasTakenFlag() const
Gets the current state of the taken marker flag.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Class representing a three dimensional reconstructed hit.
Class representing a sequence of three dimensional reconstructed hits.
Definition CDCTrack.h:37
Particle trajectory as it is seen in xy projection represented as a circle.
PerigeeCircle getGlobalCircle() const
Getter for the circle in global coordinates.
void reverse()
Reverses the trajectory in place.
double setLocalOrigin(const ROOT::Math::XYVector &localOrigin)
Setter for the origin of the local coordinate system.
ROOT::Math::XYVector getGlobalPerigee() const
Getter for the closest approach on the trajectory to the global origin.
double getCurvature() const
Getter for the curvature as seen from the xy projection.
static constexpr const double c_simpleDriftLengthVariance
A default value for the drift length variance if no variance from the drift length translation is ava...
Definition CDCWireHit.h:65
Extension of the generalized circle also caching the perigee coordinates.
double phi0() const
Getter for the azimuth angle of the direction of flight at the perigee.
double curvature() const
Getter for the signed curvature.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
static ESign common(ESign n1, ESign n2)
Check if two values have a common sign.
Definition ESign.h:57
Abstract base class for different kinds of events.
static void addCandidateFromHits(const std::vector< const TrackingUtilities::CDCWireHit * > &foundAxialWireHits, const std::vector< const TrackingUtilities::CDCWireHit * > &allAxialWireHits, std::vector< TrackingUtilities::CDCTrack > &axialTracks, bool withPostprocessing=true)
Create CDCTrack using CDCWireHit hits and store it in the list. Then call the postprocessing on it.