Belle II Software development
CDCTrack.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/eventdata/tracks/CDCTrack.h>
9
10#include <tracking/trackFindingCDC/eventdata/tracks/CDCSegmentTriple.h>
11#include <tracking/trackFindingCDC/eventdata/tracks/CDCSegmentPair.h>
12#include <tracking/trackFindingCDC/eventdata/segments/CDCSegment3D.h>
13#include <tracking/trackFindingCDC/eventdata/segments/CDCSegment2D.h>
14
15#include <tracking/trackFindingCDC/eventdata/hits/CDCRecoHit3D.h>
16#include <tracking/trackFindingCDC/eventdata/hits/CDCRecoHit2D.h>
17#include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
18
19#include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory3D.h>
20#include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
21
22#include <tracking/trackFindingCDC/topology/ISuperLayer.h>
23
24#include <tracking/trackFindingCDC/geometry/PerigeeCircle.h>
25#include <tracking/trackFindingCDC/geometry/UncertainPerigeeCircle.h>
26#include <tracking/trackFindingCDC/geometry/Vector3D.h>
27
28#include <tracking/trackFindingCDC/ca/AutomatonCell.h>
29
30#include <tracking/trackFindingCDC/numerics/FloatComparing.h>
31
32#include <tracking/trackFindingCDC/utilities/MayBePtr.h>
33
34#include <framework/logging/Logger.h>
35
36#include <algorithm>
37#include <utility>
38#include <cmath>
39
40namespace Belle2 {
45 namespace TrackFindingCDC {
46 class CDCRLWireHit;
47 }
49}
50
51using namespace Belle2;
52using namespace TrackFindingCDC;
53
54namespace {
56 void appendReconstructed(const CDCSegment2D* segment,
57 const CDCTrajectory3D& trajectory3D,
58 double perpSOffset,
59 CDCTrack& track)
60 {
61 B2ASSERT("Did not expect segment == nullptr", segment);
62
63 for (const CDCRecoHit2D& recohit2D : *segment) {
64 track.push_back(CDCRecoHit3D::reconstruct(recohit2D,
65 trajectory3D));
66 track.back().shiftArcLength2D(perpSOffset);
67 }
68 }
69
70
83 double appendReconstructedAverage(const CDCSegment2D* segment,
84 const CDCTrajectory3D& trajectory3D,
85 double perpSOffset,
86 const CDCTrajectory3D& parallelTrajectory3D,
87 CDCTrack& track)
88 {
89 B2ASSERT("Did not expect segment == nullptr", segment);
90
91 const CDCRecoHit2D& firstRecoHit2D = segment->front();
92
93 CDCRecoHit3D firstRecoHit3D =
94 CDCRecoHit3D::reconstruct(firstRecoHit2D, trajectory3D);
95
96 double firstPerpS = firstRecoHit3D.getArcLength2D();
97
98 CDCRecoHit3D parallelFirstRecoHit3D =
99 CDCRecoHit3D::reconstruct(firstRecoHit2D, parallelTrajectory3D);
100
101 double parallelFirstPerpS = parallelFirstRecoHit3D.getArcLength2D();
102
103 double parallelPerpSOffSet = firstPerpS + perpSOffset - parallelFirstPerpS;
104
105 for (const CDCRecoHit2D& recoHit2D : *segment) {
106
107 CDCRecoHit3D recoHit3D =
108 CDCRecoHit3D::reconstruct(recoHit2D, trajectory3D);
109
110 recoHit3D.shiftArcLength2D(perpSOffset);
111
112
113 CDCRecoHit3D parallelRecoHit3D =
114 CDCRecoHit3D::reconstruct(recoHit2D, parallelTrajectory3D);
115
116 parallelRecoHit3D.shiftArcLength2D(parallelPerpSOffSet);
117
118 track.push_back(CDCRecoHit3D::average(recoHit3D, parallelRecoHit3D));
119
120 }
121
122 const CDCRecoHit2D& lastRecoHit2D = segment->back() ;
123
124 CDCRecoHit3D parallelLastRecoHit3D =
125 CDCRecoHit3D::reconstruct(lastRecoHit2D, parallelTrajectory3D);
126
127 double newPrepSOffset = track.back().getArcLength2D() - parallelLastRecoHit3D.getArcLength2D();
128
129 return newPrepSOffset;
130 }
131}
132
133CDCTrack::CDCTrack(const std::vector<CDCRecoHit3D>& recoHits3D)
134 : std::vector<CDCRecoHit3D>(recoHits3D)
135{
136}
137
139 m_startTrajectory3D(segment.getTrajectory2D()),
140 m_endTrajectory3D(segment.getTrajectory2D())
141{
142 if (segment.empty()) return;
143
144 // Adjust the start point
145 const CDCRecoHit2D& startRecoHit2D = segment.front();
146 const CDCRecoHit2D& endRecoHit2D = segment.back();
147
148 Vector3D startPos3D(startRecoHit2D.getRecoPos2D(), 0.0);
149 Vector3D endPos3D(endRecoHit2D.getRecoPos2D(), 0.0);
150
153
154 for (const CDCRecoHit2D& recoHit2D : segment) {
155 const CDCRLWireHit& rlWireHit = recoHit2D.getRLWireHit();
156 Vector3D recoPos3D(recoHit2D.getRecoPos2D(), 0.0);
157 double perpS = m_startTrajectory3D.calcArcLength2D(recoPos3D);
158 push_back(CDCRecoHit3D(rlWireHit, recoPos3D, perpS));
159 }
160
161 // TODO: Maybe enhance the estimation of the z coordinate with the superlayer slopes.
162}
163
164CDCTrack CDCTrack::condense(const Path<const CDCTrack>& trackPath)
165{
166 if (trackPath.empty()) {
167 return CDCTrack();
168 } else if (trackPath.size() == 1) {
169 return CDCTrack(*(trackPath[0]));
170 } else {
171 CDCTrack result;
172 for (const CDCTrack* track : trackPath) {
173 for (const CDCRecoHit3D& recoHit3D : *track) {
174 result.push_back(recoHit3D);
176 }
177 }
178
179 CDCTrajectory3D startTrajectory3D = trackPath.front()->getStartTrajectory3D();
180 CDCTrajectory3D endTrajectory3D = trackPath.back()->getStartTrajectory3D();
181
182 double resetPerpSOffset =
183 startTrajectory3D.setLocalOrigin(result.front().getRecoPos3D());
184 result.setStartTrajectory3D(startTrajectory3D);
185
186 endTrajectory3D.setLocalOrigin(result.back().getRecoPos3D());
187 result.setEndTrajectory3D(endTrajectory3D);
188
189 for (CDCRecoHit3D& recoHit3D : result) {
190 recoHit3D.shiftArcLength2D(-resetPerpSOffset);
191 }
192
193 return result;
194 }
195}
196
197CDCTrack CDCTrack::condense(const Path<const CDCSegmentTriple>& segmentTriplePath)
198{
199 CDCTrack track;
200 // B2DEBUG(200,"Length of segmentTripleTrack is " << segmentTripleTrack.size() );
201 if (segmentTriplePath.empty()) return track;
202
203 Path<const CDCSegmentTriple>::const_iterator itSegmentTriple = segmentTriplePath.begin();
204 const CDCSegmentTriple* firstSegmentTriple = *itSegmentTriple++;
205
206 // Set the start fits of the track to the ones of the first segment
207 CDCTrajectory3D startTrajectory3D = firstSegmentTriple->getTrajectory3D();
208
209
210 double perpSOffset = 0.0;
211 appendReconstructed(firstSegmentTriple->getStartSegment(),
212 firstSegmentTriple->getTrajectory3D(),
213 perpSOffset,
214 track);
215
216 appendReconstructed(firstSegmentTriple->getMiddleSegment(),
217 firstSegmentTriple->getTrajectory3D(),
218 perpSOffset, track);
219
220 while (itSegmentTriple != segmentTriplePath.end()) {
221
222 const CDCSegmentTriple* secondSegmentTriple = *itSegmentTriple++;
223 B2ASSERT("Two segment triples do not overlap in their axial segments",
224 firstSegmentTriple->getEndSegment() == secondSegmentTriple->getStartSegment());
225
226 perpSOffset = appendReconstructedAverage(firstSegmentTriple->getEndSegment(),
227 firstSegmentTriple->getTrajectory3D(),
228 perpSOffset,
229 secondSegmentTriple->getTrajectory3D(),
230 track);
231
232 appendReconstructed(secondSegmentTriple->getMiddleSegment(),
233 secondSegmentTriple->getTrajectory3D(),
234 perpSOffset, track);
235
236 firstSegmentTriple = secondSegmentTriple;
237
238 }
239
240 const CDCSegmentTriple* lastSegmentTriple = firstSegmentTriple;
241
242 appendReconstructed(lastSegmentTriple->getEndSegment(),
243 lastSegmentTriple->getTrajectory3D(),
244 perpSOffset, track);
245
246 // Set the end fits of the track to the ones of the last segment
247 CDCTrajectory3D endTrajectory3D = lastSegmentTriple->getTrajectory3D();
248
249 // Set the reference point on the trajectories to the last reconstructed hit
250 double resetPerpSOffset = startTrajectory3D.setLocalOrigin(track.front().getRecoPos3D());
251 track.setStartTrajectory3D(startTrajectory3D);
252
253 endTrajectory3D.setLocalOrigin(track.back().getRecoPos3D());
254 track.setEndTrajectory3D(endTrajectory3D);
255
256 for (CDCRecoHit3D& recoHit3D : track) {
257 recoHit3D.shiftArcLength2D(-resetPerpSOffset);
258 }
259
260 return track;
261}
262
263CDCTrack CDCTrack::condense(const Path<const CDCSegmentPair>& segmentPairPath)
264{
265 CDCTrack track;
266
267 //B2DEBUG(200,"Length of segmentTripleTrack is " << segmentTripleTrack.size() );
268 if (segmentPairPath.empty()) return track;
269
270 Path<const CDCSegmentPair>::const_iterator itSegmentPair = segmentPairPath.begin();
271 const CDCSegmentPair* firstSegmentPair = *itSegmentPair++;
272
273
274 // Keep the fit of the first segment pair to set it as the fit at the start of the track
275 CDCTrajectory3D startTrajectory3D = firstSegmentPair->getTrajectory3D();
276
277 double perpSOffset = 0.0;
278 appendReconstructed(firstSegmentPair->getFromSegment(),
279 firstSegmentPair->getTrajectory3D(),
280 perpSOffset, track);
281
282 while (itSegmentPair != segmentPairPath.end()) {
283
284 const CDCSegmentPair* secondSegmentPair = *itSegmentPair++;
285
286 B2ASSERT("Two segment pairs do not overlap in their segments",
287 firstSegmentPair->getToSegment() == secondSegmentPair->getFromSegment());
288
289 perpSOffset = appendReconstructedAverage(firstSegmentPair->getToSegment(),
290 firstSegmentPair->getTrajectory3D(),
291 perpSOffset,
292 secondSegmentPair->getTrajectory3D(),
293 track);
294
295 firstSegmentPair = secondSegmentPair;
296 }
297
298 const CDCSegmentPair* lastSegmentPair = firstSegmentPair;
299 appendReconstructed(lastSegmentPair->getToSegment(),
300 lastSegmentPair->getTrajectory3D(),
301 perpSOffset, track);
302
303 // Keep the fit of the last segment pair to set it as the fit at the end of the track
304 CDCTrajectory3D endTrajectory3D = lastSegmentPair->getTrajectory3D();
305
306 // Move the reference point of the start fit to the first observed position
307 double resetPerpSOffset = startTrajectory3D.setLocalOrigin(track.front().getRecoPos3D());
308 track.setStartTrajectory3D(startTrajectory3D);
309
310 // Move the reference point of the end fit to the last observed position
311 endTrajectory3D.setLocalOrigin(track.back().getRecoPos3D());
312 track.setEndTrajectory3D(endTrajectory3D);
313
314 for (CDCRecoHit3D& recoHit3D : track) {
315 recoHit3D.shiftArcLength2D(-resetPerpSOffset);
316 }
317
318 return track;
319}
320
321std::vector<CDCSegment3D> CDCTrack::splitIntoSegments() const
322{
323 vector<CDCSegment3D> result;
324 ISuperLayer lastISuperLayer = -1;
325 for (const CDCRecoHit3D& recoHit3D : *this) {
326 ISuperLayer iSuperLayer = recoHit3D.getISuperLayer();
327 if (result.empty() or lastISuperLayer != iSuperLayer) {
328 result.emplace_back();
329 }
330 result.back().push_back(recoHit3D);
331 lastISuperLayer = iSuperLayer;
332 }
333 return result;
334}
335
337{
338 if (empty()) return;
339
340 // Exchange the forward and backward trajectory and reverse them
344
345 const CDCRecoHit3D& lastRecoHit3D = back();
346 double lastPerpS = lastRecoHit3D.getArcLength2D();
347 double newLastPerpS = m_startTrajectory3D.calcArcLength2D(lastRecoHit3D.getRecoPos3D());
348
349 // Reverse the left right passage hypotheses and reverse the measured travel distance
350 for (CDCRecoHit3D& recoHit3D : *this) {
351 recoHit3D.reverse();
352 double perpS = recoHit3D.getArcLength2D();
353 recoHit3D.setArcLength2D(newLastPerpS + lastPerpS - perpS);
354 }
355
356 // Reverse the arrangement of hits.
357 std::reverse(begin(), end());
358}
359
361{
362 CDCTrack reversedTrack(*this);
363 reversedTrack.reverse();
364 return reversedTrack;
365}
366
367MayBePtr<const CDCRecoHit3D> CDCTrack::find(const CDCWireHit& wireHit) const
368{
369 auto hasWireHit = [&wireHit](const CDCRecoHit3D & recoHit3D) {
370 return recoHit3D.hasWireHit(wireHit);
371 };
372 auto itRecoHit3D = std::find_if(this->begin(), this->end(), hasWireHit);
373 return itRecoHit3D == this->end() ? nullptr : &*itRecoHit3D;
374}
375
377{
379 for (const CDCRecoHit3D& recoHit3D : *this) {
380 const CDCWireHit& wireHit = recoHit3D.getWireHit();
382 }
383}
384
386{
388 for (const CDCRecoHit3D& recoHit3D : *this) {
389 const CDCWireHit& wireHit = recoHit3D.getWireHit();
391 }
392}
393
395{
396 for (const CDCRecoHit3D& recoHit3D : *this) {
397 const CDCWireHit& wireHit = recoHit3D.getWireHit();
398 if (wireHit.getAutomatonCell().hasMaskedFlag()) {
400 return;
401 }
402 }
403}
404
405void CDCTrack::forwardTakenFlag(bool takenFlag) const
406{
407 for (const CDCRecoHit3D& recoHit3D : *this) {
408 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(takenFlag);
409 }
410}
411
413{
414 std::stable_sort(begin(),
415 end(),
416 [](const CDCRecoHit3D & recoHit, const CDCRecoHit3D & otherRecoHit) {
417 double arcLength = recoHit.getArcLength2D();
418 double otherArcLength = otherRecoHit.getArcLength2D();
419 return lessFloatHighNaN(arcLength, otherArcLength);
420 });
421}
422
424{
425 const CDCTrajectory2D& startTrajectory2D = getStartTrajectory3D().getTrajectory2D();
426 if (doForAllTracks or startTrajectory2D.isCurler(1.1)) {
427 const double shiftValue = startTrajectory2D.getLocalCircle()->arcLengthPeriod();
428 if (std::isfinite(shiftValue)) {
429 for (CDCRecoHit3D& recoHit : *this) {
430 if (recoHit.getArcLength2D() < 0) {
431 recoHit.shiftArcLength2D(shiftValue);
432 }
433 }
434 }
435 }
436}
void setTakenFlag(bool setTo=true)
Sets the taken flag to the given value. Default value true.
void setMaskedFlag(bool setTo=true)
Sets the masked flag to the given value. Default value true.
void unsetMaskedFlag()
Resets the masked flag to false.
bool hasMaskedFlag() const
Gets the current state of the masked marker flag.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Definition: CDCRLWireHit.h:41
Class representing a two dimensional reconstructed hit in the central drift chamber.
Definition: CDCRecoHit2D.h:47
Vector2D getRecoPos2D() const
Getter for the position in the reference plane.
Definition: CDCRecoHit2D.h:238
Class representing a three dimensional reconstructed hit.
Definition: CDCRecoHit3D.h:52
static CDCRecoHit3D average(const CDCRecoHit3D &first, const CDCRecoHit3D &second)
Constructs the average of two reconstructed hit positions.
const CDCWireHit & getWireHit() const
Getter for the wire hit.
Definition: CDCRecoHit3D.h:238
const Vector3D & getRecoPos3D() const
Getter for the 3d position of the hit.
Definition: CDCRecoHit3D.h:285
ISuperLayer getISuperLayer() const
Getter for the superlayer id.
Definition: CDCRecoHit3D.h:220
void shiftArcLength2D(double arcLength2DOffSet)
Adjust the travel distance by the given value.
Definition: CDCRecoHit3D.h:364
void reverse()
Turns the orientation in place.
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
bool hasWireHit(const CDCWireHit &wireHit) const
Checks if the reconstructed hit is associated with the give wire hit.
Definition: CDCRecoHit3D.h:244
void setArcLength2D(const double arcLength2D)
Setter for the travel distance in the xy projection.
Definition: CDCRecoHit3D.h:376
A reconstructed sequence of two dimensional hits in one super layer.
Definition: CDCSegment2D.h:39
Class representing a pair of one reconstructed axial segment and one stereo segment in adjacent super...
const CDCSegment2D * getToSegment() const
Getter for the to segment.
CDCTrajectory3D & getTrajectory3D() const
Getter for the three dimensional trajectory.
const CDCSegment2D * getFromSegment() const
Getter for the from segment.
Class representing a triple of reconstructed segments in adjacent superlayer.
const CDCStereoSegment2D * getMiddleSegment() const
Getter for the middle stereo segment.
const CDCAxialSegment2D * getEndSegment() const
Getter for the end axial segment.
const CDCTrajectory3D & getTrajectory3D() const
Getter for the three dimensional helix trajectory.
const CDCAxialSegment2D * getStartSegment() const
Getter for the start axial segment.
Class representing a sequence of three dimensional reconstructed hits.
Definition: CDCTrack.h:41
std::vector< CDCSegment3D > splitIntoSegments() const
Splits the track into segments.
Definition: CDCTrack.cc:321
CDCTrack reversed() const
Return a reversed copy of the track.
Definition: CDCTrack.cc:360
void reverse()
Reverse the track inplace.
Definition: CDCTrack.cc:336
const CDCTrajectory3D & getStartTrajectory3D() const
Getter for the two dimensional trajectory.
Definition: CDCTrack.h:112
void forwardTakenFlag(bool takenFlag=true) const
Set the taken flag of all hits belonging to this track to the given value (default true),...
Definition: CDCTrack.cc:405
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
Definition: CDCTrack.h:125
void sortByArcLength2D()
Sort the recoHits according to their perpS information.
Definition: CDCTrack.cc:412
void shiftToPositiveArcLengths2D(bool doForAllTracks=false)
Set all arcLengths to have positive values by shifting them by pi*radius if they are negative.
Definition: CDCTrack.cc:423
void setAndForwardMaskedFlag() const
Set the masked flag of the automaton cell of this segment and forward the masked flag to all containe...
Definition: CDCTrack.cc:385
CDCTrajectory3D m_startTrajectory3D
Memory for the three dimensional trajectory at the start of the track.
Definition: CDCTrack.h:204
void unsetAndForwardMaskedFlag() const
Unset the masked flag of the automaton cell of this segment and of all contained wire hits.
Definition: CDCTrack.cc:376
MayBePtr< const CDCRecoHit3D > find(const CDCWireHit &wireHit) const
Finds the first CDCRecoHit3D that is based on the given wire hit - nullptr if none.
Definition: CDCTrack.cc:367
static CDCTrack condense(const Path< const CDCTrack > &trackPath)
concatenates several tracks from a path
Definition: CDCTrack.cc:164
CDCTrajectory3D m_endTrajectory3D
Memory for the three dimensional trajectory at the end of the track.
Definition: CDCTrack.h:207
void receiveMaskedFlag() const
Check all contained wire hits if one has the masked flag.
Definition: CDCTrack.cc:394
CDCTrack()=default
Default constructor for ROOT compatibility.
Particle trajectory as it is seen in xy projection represented as a circle.
bool isCurler(double factor=1) const
Checks if the trajectory leaves the outer radius of the CDC times the given tolerance factor.
const UncertainPerigeeCircle & getLocalCircle() const
Getter for the circle in local coordinates.
Particle full three dimensional trajectory.
double calcArcLength2D(const Vector3D &point) const
Calculate the travel distance from the start position of the trajectory.
void reverse()
Reverses the trajectory in place.
CDCTrajectory2D getTrajectory2D() const
Getter for the two dimensional trajectory.
double setLocalOrigin(const Vector3D &localOrigin)
Setter for the origin of the local coordinate system.
Class representing a hit wire in the central drift chamber.
Definition: CDCWireHit.h:55
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
Definition: CDCWireHit.h:286
double arcLengthPeriod() const
Getter for the arc length for a full round of the circle.
A three dimensional vector.
Definition: Vector3D.h:33
Abstract base class for different kinds of events.
STL namespace.