Belle II Software  release-05-01-25
AxialTrackMerger.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Viktor Trusov, Nils Braun, Oliver Frost *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #include <tracking/trackFindingCDC/findlets/minimal/AxialTrackMerger.h>
11 
12 #include <tracking/trackFindingCDC/processing/AxialTrackUtil.h>
13 
14 #include <tracking/trackFindingCDC/fitting/CDCKarimakiFitter.h>
15 
16 #include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
17 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
18 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
19 
20 #include <tracking/trackFindingCDC/numerics/WeightComperator.h>
21 
22 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
23 
24 #include <framework/core/ModuleParamList.templateDetails.h>
25 
26 using namespace Belle2;
27 using namespace TrackFindingCDC;
28 
30 {
31  return "Merges axial tracks found in the legendre search";
32 }
33 
34 void AxialTrackMerger::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
35 {
36  moduleParamList->addParameter(prefixed(prefix, "minFitProb"),
38  "Minimal fit probability of the common fit "
39  "of two tracks to be eligible for merging",
41 }
42 
43 void AxialTrackMerger::apply(std::vector<CDCTrack>& axialTracks,
44  const std::vector<const CDCWireHit*>& allAxialWireHits)
45 {
46  // Check quality of the track basing on holes on the trajectory;
47  // if holes exist then track is splitted
48  for (CDCTrack& track : axialTracks) {
49  if (track.size() < 5) continue;
52  }
53 
54  // Update tracks before storing to DataStore
55  for (CDCTrack& track : axialTracks) {
57  }
58 
59  // Remove bad tracks
62 
63  // Perform tracks merging
64  this->doTracksMerging(axialTracks, allAxialWireHits);
65 
66  // Remove the consumed, now empty tracks.
67  AxialTrackUtil::deleteShortTracks(axialTracks, 0);
68 }
69 
70 void AxialTrackMerger::doTracksMerging(std::vector<CDCTrack>& axialTracks,
71  const std::vector<const CDCWireHit*>& allAxialWireHits)
72 {
73  // Search for best matches - cannot use range for here :(.
74  for (auto itTrack = axialTracks.begin(); itTrack != axialTracks.end(); ++itTrack) {
75  CDCTrack& track = *itTrack;
76  auto followingTracks = asRange(std::next(itTrack), axialTracks.end());
77 
78  WithWeight<MayBePtr<CDCTrack> > bestTrack = calculateBestTrackToMerge(track, followingTracks);
79  double fitProb = bestTrack.getWeight();
80 
81  if (bestTrack != nullptr and fitProb > m_param_minFitProb) {
82  mergeTracks(track, *bestTrack, allAxialWireHits);
83  }
84  }
85 
87 }
88 
90 template <class ACDCTracks>
92 {
93  std::vector<WithWeight<CDCTrack*>> weightedTracks;
94  for (CDCTrack& track2 : tracks) {
95  if (&track == &track2) continue;
96  if (track2.size() < 3) continue;
97 
98  double fitProb = doTracksFitTogether(track, track2);
99  if (std::isnan(fitProb)) continue;
100 
101  weightedTracks.emplace_back(&track2, fitProb);
102  }
103 
104  auto bestMatch = std::max_element(weightedTracks.begin(), weightedTracks.end(), LessWeight());
105  if (bestMatch == weightedTracks.end()) return {nullptr, 0};
106  else return *bestMatch;
107 }
108 
110 {
111  // First check whether most of the hits from the tracks lie in the backward direction
112  // even if though track is not curling -> tracks should not be merged
113  const CDCTrajectory3D& trajectory3D1 = track1.getStartTrajectory3D();
114  const CDCTrajectory3D& trajectory3D2 = track2.getStartTrajectory3D();
115 
116  const Vector2D& phi0Vec1 = trajectory3D1.getFlightDirection3DAtSupport().xy();
117  const Vector2D& phi0Vec2 = trajectory3D2.getFlightDirection3DAtSupport().xy();
118 
119  int fbVote12 = 0;
120  int fbVote21 = 0;
121 
122  for (const CDCRecoHit3D& recoHit3D : track1) {
123  EForwardBackward fbInfo = phi0Vec2.isForwardOrBackwardOf(recoHit3D.getRecoPos2D());
124  if (not isValid(fbInfo)) continue;
125  fbVote12 += fbInfo;
126  }
127 
128  for (const CDCRecoHit3D& recoHit3D : track2) {
129  EForwardBackward fbInfo = phi0Vec1.isForwardOrBackwardOf(recoHit3D.getRecoPos2D());
130  if (not isValid(fbInfo)) continue;
131  fbVote21 += fbInfo;
132  }
133 
134  if (not trajectory3D1.isCurler() and fbVote12 < 0) return NAN;
135  if (not trajectory3D2.isCurler() and fbVote21 < 0) return NAN;
136 
137  // Build common hit list by copying the wire hits into one large list
138  // We use the wire hits here as we do not want them to bring
139  // their "old" reconstructed position when fitting.
140  std::vector<const CDCWireHit*> combinedWireHits;
141  combinedWireHits.reserve(track1.size() + track2.size());
142  for (const CDCRecoHit3D& hit : track1) {
143  // cppcheck-suppress useStlAlgorithm
144  combinedWireHits.push_back(&(hit.getWireHit()));
145  }
146  for (const CDCRecoHit3D& hit : track2) {
147  // cppcheck-suppress useStlAlgorithm
148  combinedWireHits.push_back(&(hit.getWireHit()));
149  }
150 
151  // Sorting is done via pointer addresses (!!).
152  // This is not very stable and also not very meaningful (in terms of ordering in the track),
153  // but it does the job for unique.
154  // (the ordering is still outwards though since the wire hits are ordered like that in continuous memory)
155  std::sort(combinedWireHits.begin(), combinedWireHits.end());
156  erase_unique(combinedWireHits);
157 
158  // Calculate track parameters
159  CDCTrajectory2D commonTrajectory2D;
161 
162  // Approach the best fit
163  commonTrajectory2D = fitter.fit(combinedWireHits);
164  removeStrangeHits(5, combinedWireHits, commonTrajectory2D);
165  commonTrajectory2D = fitter.fit(combinedWireHits);
166  removeStrangeHits(3, combinedWireHits, commonTrajectory2D);
167  commonTrajectory2D = fitter.fit(combinedWireHits);
168  removeStrangeHits(1, combinedWireHits, commonTrajectory2D);
169  commonTrajectory2D = fitter.fit(combinedWireHits);
170  removeStrangeHits(1, combinedWireHits, commonTrajectory2D);
171  commonTrajectory2D = fitter.fit(combinedWireHits);
172 
173  // Dismiss this possibility if the hit list size after all the removing of hits is even smaller
174  // than the two lists before or if the list is too small
175  if (combinedWireHits.size() <= std::max(track1.size(), track2.size())
176  or combinedWireHits.size() < 15) {
177  return NAN;
178  }
179 
180  return commonTrajectory2D.getPValue();
181 }
182 
184  std::vector<const CDCWireHit*>& wireHits,
185  CDCTrajectory2D& trajectory2D)
186 {
187  auto farFromTrajectory = [&trajectory2D, &factor](const CDCWireHit * wireHit) {
188  Vector2D pos2D = wireHit->getRefPos2D();
189  double driftLength = wireHit->getRefDriftLength();
190  double dist = std::fabs(trajectory2D.getDist2D(pos2D)) - driftLength;
191  return std::fabs(dist) > driftLength * factor;
192  };
193  erase_remove_if(wireHits, farFromTrajectory);
194 }
195 
197  CDCTrack& track2,
198  const std::vector<const CDCWireHit*>& allAxialWireHits)
199 {
200  if (&track1 == &track2) return;
201 
202  CDCTrajectory2D trajectory2D = track1.getStartTrajectory3D().getTrajectory2D();
203  for (const CDCRecoHit3D& orgRecoHit3D : track2) {
204  CDCRecoHit3D recoHit3D = CDCRecoHit3D::reconstruct(orgRecoHit3D.getRLWireHit(), trajectory2D);
205  track1.push_back(std::move(recoHit3D));
206  }
207  track2.clear();
208 
210 
212 
214 
215  for (CDCRecoHit3D& recoHit3D : track2) {
216  recoHit3D.setRecoPos3D({recoHit3D.getRefPos2D(), 0});
217  recoHit3D.setRLInfo(ERightLeft::c_Unknown);
218  }
219 
221  bool success = AxialTrackUtil::postprocessTrack(track2, allAxialWireHits);
222  if (not success) {
223  for (const CDCRecoHit3D& recoHit3D : track2) {
224  recoHit3D.getWireHit()->setTakenFlag(false);
225  }
226  track2.clear();
227  }
228 }
Belle2::TrackFindingCDC::AxialTrackMerger::doTracksMerging
void doTracksMerging(std::vector< CDCTrack > &axialTracks, const std::vector< const CDCWireHit * > &allAxialWireHits)
The track finding often finds two curling tracks, originating from the same particle.
Definition: AxialTrackMerger.cc:70
Belle2::TrackFindingCDC::CDCTrajectory2D::getPValue
double getPValue() const
Getter for p-value.
Definition: CDCTrajectory2D.h:472
Belle2::TrackFindingCDC::CDCRecoHit3D
Class representing a three dimensional reconstructed hit.
Definition: CDCRecoHit3D.h:62
Belle2::TrackFindingCDC::CDCTrack
Class representing a sequence of three dimensional reconstructed hits.
Definition: CDCTrack.h:51
Belle2::TrackFindingCDC::BinaryJoin
Functor factory turning a binary functor and two functors into a new functor which executes the binar...
Definition: Functional.h:137
Belle2::TrackFindingCDC::Vector2D
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:37
Belle2::TrackFindingCDC::AxialTrackUtil::splitBack2BackTrack
static std::vector< CDCRecoHit3D > splitBack2BackTrack(CDCTrack &track)
Tries to split back-to-back tracks into two different tracks.
Definition: AxialTrackUtil.cc:211
Belle2::TrackFindingCDC::AxialTrackMerger::mergeTracks
static void mergeTracks(CDCTrack &track1, CDCTrack &track2, const std::vector< const CDCWireHit * > &allAxialWireHits)
Function to merge two track candidates.
Definition: AxialTrackMerger.cc:196
Belle2::TrackFindingCDC::AxialTrackUtil::deleteTracksWithLowFitProbability
static void deleteTracksWithLowFitProbability(std::vector< CDCTrack > &axialTracks, double minimal_probability_for_good_fit=0.4)
Check an (improper) p-values of the tracks. If they are below the given value, delete the track from ...
Definition: AxialTrackUtil.cc:159
Belle2::TrackFindingCDC::AxialTrackMerger::exposeParameters
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
Definition: AxialTrackMerger.cc:34
Belle2::TrackFindingCDC::CDCKarimakiFitter
Class implementing the fitter using Karimakis method.
Definition: CDCKarimakiFitter.h:33
Belle2::TrackFindingCDC::AxialTrackMerger::calculateBestTrackToMerge
static WithWeight< MayBePtr< CDCTrack > > calculateBestTrackToMerge(CDCTrack &track, ACDCTracks &tracks)
Searches for the best candidate to merge this track to.
Belle2::TrackFindingCDC::NForwardBackward::EForwardBackward
EForwardBackward
Enumeration to represent the distinct possibilities of the right left passage information.
Definition: EForwardBackward.h:35
Belle2::TrackFindingCDC::AxialTrackUtil::removeHitsAfterSuperLayerBreak
static void removeHitsAfterSuperLayerBreak(CDCTrack &track)
Searches for a break in the super layer chain and remove all hits that come after that.
Definition: AxialTrackUtil.cc:288
Belle2::TrackFindingCDC::AxialTrackUtil::postprocessTrack
static bool postprocessTrack(CDCTrack &track, const std::vector< const CDCWireHit * > &allAxialWireHits)
Perform all track postprocessing - return whether the track is considered good after the postprocessi...
Definition: AxialTrackUtil.cc:69
Belle2::TrackFindingCDC::CDCTrajectory2D
Particle trajectory as it is seen in xy projection represented as a circle.
Definition: CDCTrajectory2D.h:46
Belle2::TrackFindingCDC::AxialTrackMerger::getDescription
std::string getDescription() final
Short description of the findlet.
Definition: AxialTrackMerger.cc:29
Belle2::ModuleParamList::addParameter
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
Definition: ModuleParamList.templateDetails.h:38
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TrackFindingCDC::AxialTrackMerger::doTracksFitTogether
static double doTracksFitTogether(CDCTrack &track1, CDCTrack &track2)
Fits the hit content of both tracks in a common fit repeated with an annealing schedule removing far ...
Definition: AxialTrackMerger.cc:109
Belle2::TrackFindingCDC::CDCTrajectory3D::isCurler
bool isCurler(double factor=1) const
Checks if the trajectory leaves the outer radius of the CDC times the given tolerance factor.
Definition: CDCTrajectory3D.cc:299
Belle2::TrackFindingCDC::Vector3D::xy
const Vector2D & xy() const
Getter for the xy projected vector ( reference ! )
Definition: Vector3D.h:500
Belle2::TrackFindingCDC::WithWeight
A mixin class to attach a weight to an object.
Definition: WithWeight.h:34
Belle2::TrackFindingCDC::WithWeight::getWeight
Weight getWeight() const
Getter for the weight.
Definition: WithWeight.h:66
Belle2::TrackFindingCDC::CDCTrajectory3D::getFlightDirection3DAtSupport
Vector3D getFlightDirection3DAtSupport() const
Get the unit momentum at the start point of the trajectory.
Definition: CDCTrajectory3D.h:222
Belle2::TrackFindingCDC::CDCKarimakiFitter::getNoDriftVarianceFitter
static const CDCKarimakiFitter & getNoDriftVarianceFitter()
Static getter for a general fitter that does not use the drift length variances.
Definition: CDCKarimakiFitter.cc:35
Belle2::TrackFindingCDC::CDCTrajectory2D::getDist2D
double getDist2D(const Vector2D &point) const
Calculates the distance from the point to the trajectory as seen from the xy projection.
Definition: CDCTrajectory2D.h:419
Belle2::TrackFindingCDC::Vector2D::isForwardOrBackwardOf
EForwardBackward isForwardOrBackwardOf(const Vector2D &rhs) const
Indicates if the given vector is more coaligned or reverse if you looked in the direction of this vec...
Definition: Vector2D.h:507
Belle2::TrackFindingCDC::AxialTrackMerger::m_param_minFitProb
double m_param_minFitProb
Parameter : Minimal fit probability of the common fit of two tracks to be eligible for merging.
Definition: AxialTrackMerger.h:103
Belle2::TrackFindingCDC::CDCWireHit
Class representing a hit wire in the central drift chamber.
Definition: CDCWireHit.h:65
Belle2::TrackFindingCDC::CDCRecoHit3D::reconstruct
static CDCRecoHit3D reconstruct(const CDCRecoHit2D &recoHit2D, const CDCTrajectory2D &trajectory2D)
Reconstructs the three dimensional hit from the two dimensional and the two dimensional trajectory.
Definition: CDCRecoHit3D.cc:58
Belle2::ModuleParamList
The Module parameter list class.
Definition: ModuleParamList.h:46
Belle2::TrackFindingCDC::AxialTrackUtil::deleteShortTracks
static void deleteShortTracks(std::vector< CDCTrack > &axialTracks, double minimal_size=5)
Remove tracks that are shorter than the given number of hits.
Definition: AxialTrackUtil.cc:198
Belle2::TrackFindingCDC::AxialTrackMerger::removeStrangeHits
static void removeStrangeHits(double factor, std::vector< const CDCWireHit * > &wireHits, CDCTrajectory2D &trajectory)
Remove all hits that are further than factor * driftlength waay from the trajectory.
Definition: AxialTrackMerger.cc:183
Belle2::TrackFindingCDC::AxialTrackUtil::normalizeTrack
static void normalizeTrack(CDCTrack &track)
Refit and resort the track. Unmask all hits.
Definition: AxialTrackUtil.cc:95
Belle2::TrackFindingCDC::AxialTrackMerger::apply
void apply(std::vector< CDCTrack > &axialTracks, const std::vector< const CDCWireHit * > &axialWireHits) final
Merge tracks together. Allows for axial hits to be added as it may see fit.
Definition: AxialTrackMerger.cc:43
Belle2::TrackFindingCDC::CDCTrajectory3D
Particle full three dimensional trajectory.
Definition: CDCTrajectory3D.h:47