Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-23 03:13:38

0001 #ifndef CkfPattern_TempTrajectory_H
0002 #define CkfPattern_TempTrajectory_H
0003 
0004 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
0005 #include "DataFormats/TrackCandidate/interface/TrajectoryStopReasons.h"
0006 #include "DataFormats/TrajectorySeed/interface/PropagationDirection.h"
0007 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
0008 #include "DataFormats/Common/interface/OwnVector.h"
0009 #include "FWCore/Utilities/interface/Visibility.h"
0010 
0011 #include <vector>
0012 #include <algorithm>
0013 #include <limits>
0014 #include "TrackingTools/PatternTools/interface/bqueue.h"
0015 
0016 #include "TrackingTools/PatternTools/interface/Trajectory.h"
0017 
0018 /** A class for detailed particle trajectory representation.
0019  *  It is used during trajectory building to "grow" a trajectory.
0020  *  The trajectory is represented as an ordered sequence of 
0021  *  TrajectoryMeasurement objects with a stack-like interface.
0022  *  The measurements are added to the Trajectory in the order of
0023  *  increasing precision: each new TrajectoryMeasurement is assumed to improve
0024  *  the precision of the last one, normally by adding a constraint from 
0025  *  a new RecHit.
0026  *     However the Trajectory class does not have the means to verify
0027  *  that measurements are added in the correct order, and thus cannot
0028  *  guarantee the order, which is the responsibility of the 
0029  *  TrajectoryBuilder. The Trajectory provides some security by
0030  *  allowing to add or remove measurements only on one of it's ends,
0031  *  with push(TM) and pop() methods. The last measurement in a Trajectory
0032  *  can thus be either the innermost (closest to the interaction point)
0033  *  or the outermost, depending on the way the Trajectory was built.
0034  *  The direction of building is represented as a PropagationDirection,
0035  *  which has two possible values: alongMomentum (outwards) and
0036  *  oppositeToMomentum (inwards), and is accessed with the direction()
0037  *  method.
0038  */
0039 
0040 class TempTrajectory {
0041 public:
0042   typedef cmsutils::bqueue<TrajectoryMeasurement> DataContainer;
0043   typedef TrackingRecHit::ConstRecHitContainer ConstRecHitContainer;
0044   typedef ConstRecHitContainer RecHitContainer;
0045 
0046   struct Payload {
0047     float theChiSquared = 0;
0048     float theDPhiCache = 0;
0049     float theCCCThreshold_ = std::numeric_limits<float>::max();
0050 
0051     uint8_t theNumberOfFoundHits = 0;
0052     uint8_t theNumberOfFoundPixelHits = 0;
0053     uint8_t theNumberOfLostHits = 0;
0054     uint8_t theNumberOfTrailingFoundHits = 0;
0055     uint8_t theNumberOfCCCBadHits_ = 0;
0056 
0057     // PropagationDirection
0058     int8_t theDirection = anyDirection;
0059 
0060     uint8_t theNHseed = 0;
0061     uint8_t theNLoops = 0;
0062     StopReason stopReason_ = StopReason::UNINITIALIZED;
0063   };
0064 
0065   /** Default constructor of an empty trajectory with undefined seed and 
0066    * undefined direction. This constructor is necessary in order to transiently
0067    * copy vector<Trajectory> in the edm::Event
0068    */
0069 
0070   TempTrajectory() {}
0071 
0072   /** Constructor of an empty trajectory with defined direction.
0073    *  No check is made in the push method that measurements are
0074    *  added in the correct direction.
0075    */
0076   TempTrajectory(PropagationDirection dir, unsigned char nhseed) : thePayload(std::make_unique<Payload>()) {
0077     thePayload->theDirection = dir;
0078     thePayload->theNHseed = nhseed;
0079   }
0080 
0081   TempTrajectory(TempTrajectory const& rh)
0082       : theData(rh.theData), thePayload(rh.thePayload ? std::make_unique<Payload>(*rh.thePayload) : nullptr) {}
0083 
0084   TempTrajectory& operator=(TempTrajectory const& rh) {
0085     theData = rh.theData;
0086     thePayload = rh.thePayload ? std::make_unique<Payload>(*rh.thePayload) : nullptr;
0087     return *this;
0088   }
0089 
0090   TempTrajectory(TempTrajectory&& rh) noexcept : theData(std::move(rh.theData)), thePayload(std::move(rh.thePayload)) {}
0091 
0092   TempTrajectory& operator=(TempTrajectory&& rh) noexcept {
0093     using std::swap;
0094     swap(theData, rh.theData);
0095     swap(thePayload, rh.thePayload);
0096     return *this;
0097   }
0098 
0099   void swap(TempTrajectory& rh) noexcept {
0100     using std::swap;
0101     swap(theData, rh.theData);
0102     swap(thePayload, rh.thePayload);
0103   }
0104 
0105   /// construct TempTrajectory from standard Trajectory
0106   explicit TempTrajectory(Trajectory&& traj);
0107 
0108   /// destruct a TempTrajectory
0109   ~TempTrajectory() = default;
0110 
0111   /** Add a new measurement to a Trajectory.
0112    *  The Chi2 of the trajectory is incremented by the value
0113    *  of tm.estimate() . 
0114    */
0115   void push(const TrajectoryMeasurement& tm) { push(tm, tm.estimate()); }
0116 
0117   void push(TrajectoryMeasurement&& tm) { push(std::forward<TrajectoryMeasurement>(tm), tm.estimate()); }
0118 
0119   template <typename... Args>
0120   void emplace(Args&&... args) {
0121     theData.emplace_back(std::forward<Args>(args)...);
0122     pushAux(theData.back().estimate());
0123   }
0124 
0125   /** Add a new sets of measurements to a Trajectory
0126    *  The sorting of hits in the other trajectory must match the one
0127    *  inside this trajectory (that is, both along or both opposite to momentum)
0128    *  (the input segment will be reset to an empty one)
0129    */
0130   void push(TempTrajectory const& segment);
0131 
0132   /** Add a new sets of measurements to a Trajectory
0133    *  Exactly like push(TempTrajectory), but it doesn't copy the data
0134    *  (the input segment will be reset to an empty one)
0135    */
0136   void join(TempTrajectory& segment);
0137 
0138   /** same as the one-argument push, but the trajectory Chi2 is incremented 
0139    *  by chi2Increment. Useful e.g. in trajectory smoothing.
0140    */
0141   void push(const TrajectoryMeasurement& tm, double chi2Increment) {
0142     theData.push_back(tm);
0143     pushAux(chi2Increment);
0144   }
0145 
0146   void push(TrajectoryMeasurement&& tm, double chi2Increment) {
0147     theData.push_back(std::move(tm));
0148     pushAux(chi2Increment);
0149   }
0150 
0151   template <typename... Args>
0152   void emplace(double chi2Increment, Args&&... args) {  // works only because the first Arg is never a double!
0153     theData.emplace_back(std::forward<Args>(args)...);
0154     pushAux(chi2Increment);
0155   }
0156 
0157   /** Remove the last measurement from the trajectory.
0158    */
0159   void pop();
0160 
0161   /** Access to the last measurement.
0162    *  It's the most precise one in a trajectory before smoothing.
0163    *  It's the outermost measurement if direction() == alongMomentum,
0164    *  the innermost one if direction() == oppositeToMomentum.
0165    */
0166   const TrajectoryMeasurement& lastMeasurement() const {
0167     check();
0168     return theData.back();
0169   }
0170 
0171   /** Access to the first measurement.
0172    *  It is the least precise one in a trajectory before smoothing.
0173    *  It is precise in a smoothed trajectory. 
0174    *  It's the innermost measurement if direction() == alongMomentum,
0175    *  the outermost one if direction() == oppositeToMomentum.
0176    */
0177   const TrajectoryMeasurement& firstMeasurement() const {
0178     check();
0179     return theData.front();
0180   }
0181 
0182   /** Return all measurements in a container.
0183    */
0184   const DataContainer& measurements() const { return theData; }
0185 
0186   /** Number of valid RecHits used to determine the trajectory.
0187    *  Can be less than the number of measurements in data() since
0188    *  detector layers crossed without using RecHits from them are also 
0189    *  stored as measurements.
0190    */
0191   int foundHits() const { return thePayload->theNumberOfFoundHits; }
0192 
0193   /** Number of valid pixel RecHits used to determine the trajectory.
0194    */
0195   int foundPixelHits() const { return thePayload->theNumberOfFoundPixelHits; }
0196 
0197   /** Number of detector layers crossed without valid RecHits.
0198    *  Used mainly as a criteria for abandoning a trajectory candidate
0199    *  during trajectory building.
0200    */
0201   int lostHits() const { return thePayload->theNumberOfLostHits; }
0202 
0203   /** Number of valid RecHits at the end of the trajectory after last lost hit.
0204    */
0205   int trailingFoundHits() const { return thePayload->theNumberOfTrailingFoundHits; }
0206 
0207   /** Number of hits that are not compatible with the CCC used during
0208    *  patter recognition. Used mainly as a criteria for abandoning a
0209    *  trajectory candidate during trajectory building.
0210    */
0211   int cccBadHits() const { return thePayload->theNumberOfCCCBadHits_; }
0212 
0213   //number of hits in seed
0214   unsigned int seedNHits() const { return thePayload->theNHseed; }
0215 
0216   /// True if trajectory has no measurements.
0217   bool empty() const { return theData.empty(); }
0218 
0219   /// Value of the raw Chi2 of the trajectory, not normalised to the N.D.F.
0220   float chiSquared() const { return thePayload->theChiSquared; }
0221 
0222   /** Direction of "growing" of the trajectory. 
0223    *  Possible values are alongMomentum (outwards) and 
0224    *  oppositeToMomentum (inwards).
0225    */
0226   PropagationDirection direction() const;
0227 
0228   /** Returns true if the Trajectory is valid.
0229    *  Trajectories are invalidated e.g. during ambiguity resolution.
0230    */
0231   bool isValid() const { return bool(thePayload); }
0232 
0233   /// Method to invalidate a trajectory. Useful during ambiguity resolution.
0234   void invalidate() { thePayload.reset(); }
0235 
0236   /** Definition of inactive Det from the Trajectory point of view.
0237    */
0238   static bool inactive(  //const Det& det
0239   ) {
0240     return false;
0241   }  //FIXME
0242 
0243   /// Redundant method, returns the layer of lastMeasurement() .
0244   const DetLayer* lastLayer() const {
0245     check();
0246     return theData.back().layer();
0247   }
0248 
0249   /// Convert to a standard Trajectory
0250   Trajectory toTrajectory() const;
0251 
0252   /// Pops out all the invalid hits on the tail
0253   void popInvalidTail();
0254 
0255   /// accessor to the delta phi angle betweem the directions of the two measurements on the last
0256   /// two layers crossed by the trajectory
0257   float dPhiCacheForLoopersReconstruction() const { return thePayload->theDPhiCache; }
0258 
0259   /// method to set the delta phi angle betweem the directions of the two measurements on the last
0260   /// two layers crossed by the trajectory
0261   void setDPhiCacheForLoopersReconstruction(float dphi) { thePayload->theDPhiCache = dphi; }
0262 
0263   bool isLooper() const { return (thePayload->theNLoops > 0); }
0264   signed char nLoops() const { return thePayload->theNLoops; }
0265 
0266   void setNLoops(int8_t value) { thePayload->theNLoops = value; }
0267   void incrementLoops() { thePayload->theNLoops++; }
0268 
0269   StopReason stopReason() const { return thePayload->stopReason_; }
0270   void setStopReason(StopReason s) { thePayload->stopReason_ = s; }
0271 
0272   int numberOfCCCBadHits(float ccc_threshold);
0273 
0274   static bool lost(const TrackingRecHit& hit) dso_internal;
0275 
0276 private:
0277   /** Definition of what it means for a hit to be "lost".
0278    *  This definition is also used by the TrajectoryBuilder.
0279    */
0280   bool badForCCC(const TrajectoryMeasurement& tm) dso_internal;
0281   void updateBadForCCC(float ccc_threshold) dso_internal;
0282 
0283   void pushAux(double chi2Increment);
0284 
0285 private:
0286   DataContainer theData;
0287   std::unique_ptr<Payload> thePayload;
0288 
0289   void check() const;
0290 };
0291 
0292 #endif