Belle II Software  release-08-01-10
SegmentTrackAdderWithNormalization.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/SegmentTrackAdderWithNormalization.h>
9 
10 #include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
11 #include <tracking/trackFindingCDC/eventdata/segments/CDCSegment2D.h>
12 
13 #include <framework/core/ModuleParamList.templateDetails.h>
14 
15 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
16 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
17 #include <vector>
18 
19 using namespace Belle2;
20 using namespace TrackFindingCDC;
21 
23  : Super()
24 {
27 }
28 
29 void SegmentTrackAdderWithNormalization::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
30 {
31  m_singleHitSelector.exposeParameters(moduleParamList, prefixed(prefix, "hitSelector"));
32  moduleParamList->addParameter(prefixed(prefix, "removeUnmatchedSegments"),
34  "Swtich to remove hits in segments that have no matching track from all tracks",
36 
37 }
38 
40 {
41  return "Add the matched segments to the tracks and normalize the tracks afterwards. Also deletes all "
42  "hits from tracks, that are now part in another track (or should not be part in any).";
43 }
44 
46  std::vector<CDCTrack>& tracks, const std::vector<CDCSegment2D>& segments)
47 {
48  // Storage space for the hits
49  // Important to reserve enough space as otherwise references to the elements used by the
50  // `WeightedRelations` in the vector `trackHitRelations` are not valid anymore
51  // !!! We cannot use a deque or list as these do not guarantee valid pointer comparisons as
52  // used by `std::sort` below !!!
53  std::vector<CDCRecoHit3D> recoHits3D;
54  int hit_size = 0;
55  for (const auto& relation : relations) {
56  hit_size += relation.getTo()->size();
57  }
58  for (const CDCSegment2D& segment : segments) {
59  hit_size += segment.size();
60  }
61  for (CDCTrack& track : tracks) {
62  hit_size += track.size();
63  }
64  recoHits3D.reserve(hit_size);
65 
66  // Relations for the matching tracks
67  std::vector<WeightedRelation<CDCTrack, const CDCRecoHit3D>> trackHitRelations;
68  trackHitRelations.reserve(2500);
69 
70  // We construct track hit relations denoting to which track each hit should belong from 3 sources
71  // 1. From the given track segment matches with the weight of the match
72  // 2. From the unmatch, untaken segments schedule the hits for removal with lower weight
73  // 3. From the original track content with lowest weight
74  // Hence if a hit is mentioned in source 1. it takes precedence over 2. and 3. to so on.
75 
76  // 1. Add the relations for the matched segments with the match weight
77  for (const auto& relation : relations) {
78  CDCTrack* track = relation.getFrom();
79  const CDCSegment2D& segment = *(relation.getTo());
80  const Weight weight = relation.getWeight();
81  const CDCTrajectory3D& trajectory3D = track->getStartTrajectory3D();
82 
83  for (const CDCRecoHit2D& recoHit : segment) {
84 
85  // In case the hit is already in the matched track - keep its reconstructed position
86  MayBePtr<const CDCRecoHit3D> ptrRecoHit3D = track->find(recoHit.getWireHit());
87  if (ptrRecoHit3D != nullptr) {
88  recoHits3D.push_back(*ptrRecoHit3D);
89  trackHitRelations.push_back({track, weight, &recoHits3D.back()});
90  continue;
91  }
92 
93  // Otherwise reconstruct the position into the third dimension
94  CDCRecoHit3D recoHit3D = CDCRecoHit3D::reconstruct(recoHit, trajectory3D);
95  if (std::isnan(recoHit3D.getArcLength2D())) {
96  B2DEBUG(25, "Had to skip a NAN hit");
97  continue;
98  }
99  recoHits3D.push_back(recoHit3D);
100  trackHitRelations.push_back({track, weight, &recoHits3D.back()});
101  }
102  segment->setTakenFlag();
103  }
104 
105  // 2. Add also those segments, that have no track-partner and schedule them for removal
107  for (const CDCSegment2D& segment : segments) {
108 
109  // Skip segment already used in the steps before or marked outside as already taken.
110  if (segment->hasTakenFlag()) continue;
111 
112  // Add hit with destination track nullptr
113  for (const CDCRecoHit2D& recoHit : segment) {
114  recoHits3D.push_back({recoHit.getRLWireHit(), Vector3D(recoHit.getRecoPos2D()), 0});
115  trackHitRelations.push_back({nullptr, 0, &recoHits3D.back()});
116  }
117  }
118  }
119 
120  // 3. Add the original hit content of the track with lowest priority
121  for (CDCTrack& track : tracks) {
122  for (const CDCRecoHit3D& recoHit3D : track) {
123  recoHits3D.push_back(recoHit3D);
124  // cppcheck-suppress invalidContainer
125  trackHitRelations.push_back({&track, -INFINITY, &recoHits3D.back()});
126  }
127  }
128 
129  // Thin out the weighted relations by selecting only the best matching track for each hit.
130  std::sort(trackHitRelations.begin(), trackHitRelations.end());
131  m_singleHitSelector.apply(trackHitRelations);
132 
133  // Remove all hits from the tracks in order to rebuild them completely
134  for (CDCTrack& track : tracks) {
135  for (const CDCRecoHit3D& recoHit3D : track) {
136  recoHit3D.getWireHit()->unsetTakenFlag();
137  }
138  track.clear();
139  }
140 
141  // Now add the hits to their destination tracks
142  for (const auto& trackHitRelation : trackHitRelations) {
143  CDCTrack* track = trackHitRelation.getFrom();
144  const CDCRecoHit3D* recoHit3D = trackHitRelation.getTo();
145 
146  if (track == nullptr) continue;
147 
148  track->push_back(*recoHit3D);
149  recoHit3D->getWireHit()->setTakenFlag();
150  }
151 
152  // Drop tracks which have no hits
153  TrackFindingCDC::erase_remove_if(tracks, [](const CDCTrack & track) { return track.empty(); });
154 
155  // Establish the ordering
156  for (CDCTrack& track : tracks) {
157  track.sortByArcLength2D();
158  CDCTrajectory3D startTrajectory = track.getStartTrajectory3D();
159  startTrajectory.setLocalOrigin(track.front().getRecoPos3D());
160  track.setStartTrajectory3D(startTrajectory);
161 
162  CDCTrajectory3D endTrajectory = track.getEndTrajectory3D();
163  endTrajectory.setLocalOrigin(track.back().getRecoPos3D());
164  track.setEndTrajectory3D(endTrajectory);
165  }
166 
167  // Normalize the trajectory and hit contents of the tracks
168  m_trackNormalizer.apply(tracks);
169 }
The Module parameter list class.
void setTakenFlag(bool setTo=true)
Sets the taken flag to the given value. Default value true.
Class representing a two dimensional reconstructed hit in the central drift chamber.
Definition: CDCRecoHit2D.h:47
Class representing a three dimensional reconstructed hit.
Definition: CDCRecoHit3D.h:52
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:56
double getArcLength2D() const
Getter for the travel distance in the xy projection.
Definition: CDCRecoHit3D.h:370
const CDCWireHit & getWireHit() const
Getter for the wire hit.
Definition: CDCRecoHit3D.h:238
A reconstructed sequence of two dimensional hits in one super layer.
Definition: CDCSegment2D.h:39
Class representing a sequence of three dimensional reconstructed hits.
Definition: CDCTrack.h:41
Particle full three dimensional trajectory.
double setLocalOrigin(const Vector3D &localOrigin)
Setter for the origin of the local coordinate system.
void addProcessingSignalListener(ProcessingSignalListener *psl)
Register a processing signal listener to be notified.
std::string getDescription() override
Short description of the findlet.
TrackNormalizer m_trackNormalizer
Findlet for performing the normalization of the tracks afterwards.
SingleMatchSelector< CDCTrack, CDCRecoHit3D, HitComperator > m_singleHitSelector
The selector for finding the track each hit should belong to.
bool m_param_removeUnmatchedSegments
Parameter : Swtich to remove hits in segments that have no matching track from all tracks.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) override
Expose the parameters of the sub-findlets.
SegmentTrackAdderWithNormalization()
Constructor for registering the sub-findlets.
void apply(std::vector< WeightedRelation< CDCTrack, const CDCSegment2D >> &relations, std::vector< CDCTrack > &tracks, const std::vector< CDCSegment2D > &segment) override
Apply the findlet.
void apply(std::vector< CDCTrack > &tracks) final
Fit the tracks.
Type for two related objects with a weight.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
HepGeom::Vector3D< double > Vector3D
3D Vector
Definition: Cell.h:34
Abstract base class for different kinds of events.