Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:29:01

0001 #ifndef Traj2TrackHits_H
0002 #define Traj2TrackHits_H
0003 
0004 #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
0005 #include "TrackingTools/PatternTools/interface/Trajectory.h"
0006 
0007 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
0008 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
0009 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit1D.h"
0010 
0011 #include "RecoTracker/TransientTrackingRecHit/interface/TkTransientTrackingRecHitBuilder.h"
0012 #include "RecoLocalTracker/ClusterParameterEstimator/interface/StripClusterParameterEstimator.h"
0013 #include "Geometry/CommonDetUnit/interface/GluedGeomDet.h"
0014 #include "Geometry/CommonDetUnit/interface/GeomDetType.h"
0015 
0016 class Traj2TrackHits {
0017 private:
0018   const StripClusterParameterEstimator *theCPE = nullptr;
0019   bool keepOrder = false;   // FIXME move to enum
0020   bool removeNoDet = true;  // true == as in conversion from TTRH to TRH
0021 public:
0022   using TrajParams = std::vector<LocalTrajectoryParameters>;
0023   using Chi2sFive = std::vector<unsigned char>;
0024 
0025   static unsigned char toChi2x5(float chi2) {
0026     float tc = std::round(5.f * chi2);
0027     return std::min(tc, 255.f);
0028   }
0029 
0030   // default for final reco::Track
0031   Traj2TrackHits() {}
0032 
0033   Traj2TrackHits(const TransientTrackingRecHitBuilder *builder, bool ikeepOrder, bool noNoDet = true)
0034       : theCPE(static_cast<TkTransientTrackingRecHitBuilder const *>(builder)->stripClusterParameterEstimator()),
0035         keepOrder(ikeepOrder),
0036         removeNoDet(noNoDet) {}
0037 
0038   void operator()(Trajectory const &traj, TrackingRecHitCollection &hits, bool splitting) const {
0039     // ---  NOTA BENE: the convention is to sort hits and measurements "along the momentum".
0040     bool along = traj.direction() == alongMomentum;
0041     auto const &meas = traj.measurements();
0042     hits.reserve(splitting ? 2 * meas.size() : meas.size());
0043     if (!splitting) {
0044       if (keepOrder | along)
0045         copy(meas.begin(), meas.end(), hits);
0046       else
0047         copy(meas.rbegin(), meas.rend(), hits);
0048       return;
0049     }
0050     if (keepOrder | along)
0051       split(meas.begin(), meas.end(), hits, along);
0052     else
0053       split(meas.rbegin(), meas.rend(), hits, along);
0054     hits.shrink_to_fit();
0055   }
0056 
0057   void operator()(Trajectory const &traj,
0058                   TrackingRecHitCollection &hits,
0059                   TrajParams &trajParams,
0060                   Chi2sFive &chi2s) const {
0061     // ---  NOTA BENE: the convention is to sort hits and measurements "along the momentum".
0062     bool along = traj.direction() == alongMomentum;
0063     auto const &meas = traj.measurements();
0064     trajParams.reserve(meas.size());
0065     chi2s.reserve(meas.size());
0066     if (keepOrder | along)
0067       copy(meas.begin(), meas.end(), hits, trajParams, chi2s);
0068     else
0069       copy(meas.rbegin(), meas.rend(), hits, trajParams, chi2s);
0070   }
0071 
0072 private:
0073   template <typename HI>
0074   void copy(HI itm, HI e, TrackingRecHitCollection &hits, TrajParams &trajParams, Chi2sFive &chi2s) const {
0075     for (; itm != e; ++itm)
0076       if ((!removeNoDet) | ((*itm).recHitR().det() != nullptr)) {
0077         hits.push_back((*itm).recHitR().cloneHit());
0078         trajParams.push_back((*itm).updatedState().localParameters());
0079         chi2s.push_back(toChi2x5((*itm).estimate()));
0080       }
0081   }
0082 
0083   template <typename HI>
0084   void copy(HI itm, HI e, TrackingRecHitCollection &hits) const {
0085     for (; itm != e; ++itm)
0086       if ((!removeNoDet) | ((*itm).recHitR().det() != nullptr))
0087         hits.push_back((*itm).recHitR().cloneHit());
0088   }
0089 
0090   template <typename HI>
0091   void split(HI itm, HI e, TrackingRecHitCollection &hits, bool along) const {
0092     for (; itm != e; ++itm) {
0093       auto const &hit = *(*itm).recHit()->hit();
0094       if ((removeNoDet) & ((*itm).recHitR().det() == nullptr))
0095         continue;
0096       if (trackerHitRTTI::isUndef(hit) || trackerHitRTTI::isNotFromCluster(hit) || (hit.dimension() != 2)) {
0097         hits.push_back(hit.clone());
0098         continue;
0099       }
0100       auto const &thit = static_cast<BaseTrackerRecHit const &>(hit);
0101       auto const &clus = thit.firstClusterRef();
0102       if (clus.isPixel())
0103         hits.push_back(hit.clone());
0104       else if (clus.isPhase2())
0105         hits.push_back(hit.clone());
0106       else if (thit.isMatched()) {
0107         auto zdir = itm->updatedState().localDirection().z();
0108         if (keepOrder & (!along))
0109           zdir = -zdir;
0110         split(*itm, static_cast<SiStripMatchedRecHit2D const &>(thit), hits, zdir);
0111       } else if (thit.isProjected()) {
0112         auto detU = static_cast<ProjectedSiStripRecHit2D const &>(thit).originalDet();
0113         hits.push_back(build(*detU, clus));
0114       } else
0115         hits.push_back(clone(thit));
0116     }
0117   }
0118 
0119   TrackingRecHit *clone(BaseTrackerRecHit const &hit2D) const {
0120     auto const &detU = *hit2D.detUnit();
0121     //Use 2D SiStripRecHit in endcap
0122     bool endcap = detU.type().isEndcap();
0123     if (endcap)
0124       return hit2D.clone();
0125     return new SiStripRecHit1D(hit2D.localPosition(),
0126                                LocalError(hit2D.localPositionError().xx(), 0.f, std::numeric_limits<float>::max()),
0127                                *hit2D.det(),
0128                                hit2D.firstClusterRef());
0129   }
0130 
0131   BaseTrackerRecHit *build(GeomDetUnit const &idet, OmniClusterRef const &clus) const {
0132     //Use 2D SiStripRecHit in endcap
0133     bool endcap = idet.type().isEndcap();
0134     auto &&lv = theCPE->localParameters(clus.stripCluster(), idet);
0135     if (endcap)
0136       return new SiStripRecHit2D(lv.first, lv.second, idet, clus);
0137     return new SiStripRecHit1D(
0138         lv.first, LocalError(lv.second.xx(), 0.f, std::numeric_limits<float>::max()), idet, clus);
0139   }
0140 
0141   void split(TrajectoryMeasurement const &itm,
0142              SiStripMatchedRecHit2D const &mhit,
0143              TrackingRecHitCollection &hits,
0144              float zdir) const {
0145     const GluedGeomDet *gdet = static_cast<const GluedGeomDet *>(mhit.det());
0146 
0147     auto hitM = build(*gdet->monoDet(), mhit.monoClusterRef());
0148     auto hitS = build(*gdet->stereoDet(), mhit.stereoClusterRef());
0149 
0150     // we should find a faster way
0151     LocalPoint firstLocalPos = itm.updatedState().surface().toLocal(gdet->monoDet()->position());
0152     LocalPoint secondLocalPos = itm.updatedState().surface().toLocal(gdet->stereoDet()->position());
0153     LocalVector Delta = secondLocalPos - firstLocalPos;
0154     float scalar = Delta.z() * zdir;
0155     // hit along the direction
0156     if (scalar < 0) {
0157       hits.push_back(hitS);
0158       hits.push_back(hitM);
0159     } else {
0160       hits.push_back(hitM);
0161       hits.push_back(hitS);
0162     }
0163   }
0164 };
0165 
0166 #endif