8#include <tracking/trackingUtilities/eventdata/tracks/CDCTrack.h>
10#include <tracking/trackingUtilities/eventdata/tracks/CDCSegmentTriple.h>
11#include <tracking/trackingUtilities/eventdata/tracks/CDCSegmentPair.h>
12#include <tracking/trackingUtilities/eventdata/segments/CDCSegment3D.h>
13#include <tracking/trackingUtilities/eventdata/segments/CDCSegment2D.h>
15#include <tracking/trackingUtilities/eventdata/hits/CDCRecoHit2D.h>
16#include <tracking/trackingUtilities/eventdata/hits/CDCWireHit.h>
18#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory3D.h>
19#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory2D.h>
21#include <cdc/topology/ISuperLayer.h>
23#include <tracking/trackingUtilities/geometry/PerigeeCircle.h>
24#include <tracking/trackingUtilities/geometry/UncertainPerigeeCircle.h>
26#include <tracking/trackingUtilities/ca/AutomatonCell.h>
28#include <tracking/trackingUtilities/numerics/FloatComparing.h>
30#include <tracking/trackingUtilities/utilities/MayBePtr.h>
32#include <framework/logging/Logger.h>
43 namespace TrackingUtilities {
51using namespace TrackingUtilities;
55 void appendReconstructed(
const CDCSegment2D* segment,
56 const CDCTrajectory3D& trajectory3D,
60 B2ASSERT(
"Did not expect segment == nullptr", segment);
62 for (
const CDCRecoHit2D& recohit2D : *segment) {
65 track.back().shiftArcLength2D(perpSOffset);
82 double appendReconstructedAverage(
const CDCSegment2D* segment,
83 const CDCTrajectory3D& trajectory3D,
85 const CDCTrajectory3D& parallelTrajectory3D,
88 B2ASSERT(
"Did not expect segment == nullptr", segment);
90 const CDCRecoHit2D& firstRecoHit2D = segment->front();
92 CDCRecoHit3D firstRecoHit3D =
97 CDCRecoHit3D parallelFirstRecoHit3D =
100 double parallelFirstPerpS = parallelFirstRecoHit3D.
getArcLength2D();
102 double parallelPerpSOffSet = firstPerpS + perpSOffset - parallelFirstPerpS;
104 for (
const CDCRecoHit2D& recoHit2D : *segment) {
106 CDCRecoHit3D recoHit3D =
112 CDCRecoHit3D parallelRecoHit3D =
121 const CDCRecoHit2D& lastRecoHit2D = segment->back() ;
123 CDCRecoHit3D parallelLastRecoHit3D =
126 double newPrepSOffset = track.back().getArcLength2D() - parallelLastRecoHit3D.
getArcLength2D();
128 return newPrepSOffset;
141 if (segment.empty())
return;
147 const auto& tmpStart = startRecoHit2D.getRecoPos2D();
148 const auto& tmpEnd = endRecoHit2D.getRecoPos2D();
149 ROOT::Math::XYZVector startPos3D(tmpStart.X(), tmpStart.Y(), 0.0);
150 ROOT::Math::XYZVector endPos3D(tmpEnd.X(), tmpEnd.Y(), 0.0);
156 const CDCRLWireHit& rlWireHit = recoHit2D.getRLWireHit();
157 const auto& tmp = recoHit2D.getRecoPos2D();
158 ROOT::Math::XYZVector recoPos3D(tmp.X(), tmp.Y(), 0.0);
168 if (trackPath.empty()) {
170 }
else if (trackPath.size() == 1) {
174 for (
const CDCTrack* track : trackPath) {
176 result.push_back(recoHit3D);
181 CDCTrajectory3D startTrajectory3D = trackPath.front()->getStartTrajectory3D();
182 CDCTrajectory3D endTrajectory3D = trackPath.back()->getStartTrajectory3D();
184 double resetPerpSOffset =
186 result.setStartTrajectory3D(startTrajectory3D);
189 result.setEndTrajectory3D(endTrajectory3D);
203 if (segmentTriplePath.empty())
return track;
205 Path<const CDCSegmentTriple>::const_iterator itSegmentTriple = segmentTriplePath.begin();
212 double perpSOffset = 0.0;
222 while (itSegmentTriple != segmentTriplePath.end()) {
225 B2ASSERT(
"Two segment triples do not overlap in their axial segments",
228 perpSOffset = appendReconstructedAverage(firstSegmentTriple->
getEndSegment(),
238 firstSegmentTriple = secondSegmentTriple;
252 double resetPerpSOffset = startTrajectory3D.
setLocalOrigin(track.front().getRecoPos3D());
253 track.setStartTrajectory3D(startTrajectory3D);
256 track.setEndTrajectory3D(endTrajectory3D);
270 if (segmentPairPath.empty())
return track;
272 Path<const CDCSegmentPair>::const_iterator itSegmentPair = segmentPairPath.begin();
279 double perpSOffset = 0.0;
284 while (itSegmentPair != segmentPairPath.end()) {
288 B2ASSERT(
"Two segment pairs do not overlap in their segments",
291 perpSOffset = appendReconstructedAverage(firstSegmentPair->
getToSegment(),
297 firstSegmentPair = secondSegmentPair;
309 double resetPerpSOffset = startTrajectory3D.
setLocalOrigin(track.front().getRecoPos3D());
310 track.setStartTrajectory3D(startTrajectory3D);
314 track.setEndTrajectory3D(endTrajectory3D);
325 vector<CDCSegment3D> result;
329 if (result.empty() or lastISuperLayer != iSuperLayer) {
330 result.emplace_back();
332 result.back().push_back(recoHit3D);
333 lastISuperLayer = iSuperLayer;
359 std::reverse(begin(), end());
366 return reversedTrack;
371 auto hasWireHit = [&wireHit](
const CDCRecoHit3D & recoHit3D) {
374 auto itRecoHit3D = std::find_if(this->begin(), this->end(), hasWireHit);
375 return itRecoHit3D == this->end() ? nullptr : &*itRecoHit3D;
416 std::stable_sort(begin(),
421 return lessFloatHighNaN(arcLength, otherArcLength);
428 if (doForAllTracks or startTrajectory2D.
isCurler(1.1)) {
430 if (std::isfinite(shiftValue)) {
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 ...
Class representing a two dimensional reconstructed hit in the central drift chamber.
Class representing a three dimensional reconstructed hit.
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.
const ROOT::Math::XYZVector & getRecoPos3D() const
Getter for the 3d position of the hit.
void shiftArcLength2D(double arcLength2DOffSet)
Adjust the travel distance by the given value.
void reverse()
Turns the orientation in place.
CDC::ISuperLayer getISuperLayer() const
Getter for the superlayer id.
static CDCRecoHit3D reconstruct(const CDCRecoHit2D &recoHit2D, const CDCTrajectory2D &trajectory2D)
Reconstructs the three dimensional hit from the two dimensional and the two dimensional trajectory.
double getArcLength2D() const
Getter for the travel distance in the xy projection.
bool hasWireHit(const CDCWireHit &wireHit) const
Checks if the reconstructed hit is associated with the give wire hit.
void setArcLength2D(const double arcLength2D)
Setter for the travel distance in the xy projection.
A reconstructed sequence of two dimensional hits in one super layer.
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.
std::vector< CDCSegment3D > splitIntoSegments() const
Splits the track into segments.
CDCTrack reversed() const
Return a reversed copy of the track.
void reverse()
Reverse the track inplace.
const CDCTrajectory3D & getStartTrajectory3D() const
Getter for the two dimensional trajectory.
void forwardTakenFlag(bool takenFlag=true) const
Set the taken flag of all hits belonging to this track to the given value (default true),...
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
void sortByArcLength2D()
Sort the recoHits according to their perpS information.
void shiftToPositiveArcLengths2D(bool doForAllTracks=false)
Set all arcLengths to have positive values by shifting them by pi*radius if they are negative.
void setAndForwardMaskedFlag() const
Set the masked flag of the automaton cell of this segment and forward the masked flag to all containe...
CDCTrajectory3D m_startTrajectory3D
Memory for the three dimensional trajectory at the start of the track.
void unsetAndForwardMaskedFlag() const
Unset the masked flag of the automaton cell of this segment and of all contained wire hits.
MayBePtr< const CDCRecoHit3D > find(const CDCWireHit &wireHit) const
Finds the first CDCRecoHit3D that is based on the given wire hit - nullptr if none.
static CDCTrack condense(const Path< const CDCTrack > &trackPath)
concatenates several tracks from a path
CDCTrajectory3D m_endTrajectory3D
Memory for the three dimensional trajectory at the end of the track.
void receiveMaskedFlag() const
Check all contained wire hits if one has the masked flag.
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 setLocalOrigin(const ROOT::Math::XYZVector &localOrigin)
Setter for the origin of the local coordinate system.
CDCTrajectory2D getTrajectory2D() const
Getter for the two dimensional trajectory.
Class representing a hit wire in the central drift chamber.
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
double arcLengthPeriod() const
Getter for the arc length for a full round of the circle.
signed short ISuperLayer
The type of the layer and superlayer ids.
Abstract base class for different kinds of events.