Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:28:08

0001 #include "TrackMerger.h"
0002 
0003 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
0004 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
0005 
0006 #define TRACK_SORT 1  // just use all hits from inner track, then append from outer outside it
0007 #define DET_SORT 0    // sort hits using global position of detector
0008 #define HIT_SORT 0    // sort hits using global position of hit
0009 
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 
0012 // #define VI_DEBUG
0013 
0014 #ifdef VI_DEBUG
0015 #define DPRINT(x) std::cout << x << ": "
0016 #define PRINT std::cout
0017 #else
0018 #define DPRINT(x) LogTrace(x)
0019 #define PRINT LogTrace("")
0020 #endif
0021 
0022 TrackMerger::TrackMerger(const edm::ParameterSet &iConfig, edm::ConsumesCollector cc)
0023     : useInnermostState_(iConfig.getParameter<bool>("useInnermostState")),
0024       debug_(false),
0025       theBuilderName(iConfig.getParameter<std::string>("ttrhBuilderName")),
0026       geometryToken_(cc.esConsumes<TrackerGeometry, TrackerDigiGeometryRecord>()),
0027       magFieldToken_(cc.esConsumes<MagneticField, IdealMagneticFieldRecord>()),
0028       builderToken_(
0029           cc.esConsumes<TransientTrackingRecHitBuilder, TransientRecHitRecord>(edm::ESInputTag("", theBuilderName))),
0030       trackerTopoToken_(cc.esConsumes<TrackerTopology, TrackerTopologyRcd>()) {}
0031 
0032 TrackMerger::~TrackMerger() {}
0033 
0034 void TrackMerger::init(const edm::EventSetup &iSetup) {
0035   theGeometry = iSetup.getHandle(geometryToken_);
0036   theMagField = iSetup.getHandle(magFieldToken_);
0037   theBuilder = iSetup.getHandle(builderToken_);
0038   theTrkTopo = iSetup.getHandle(trackerTopoToken_);
0039 }
0040 
0041 TrackCandidate TrackMerger::merge(const reco::Track &inner,
0042                                   const reco::Track &outer,
0043                                   DuplicateTrackType duplicateType) const {
0044   DPRINT("TrackMerger") << std::abs(inner.eta()) << " merging " << inner.algo() << '/' << outer.algo() << ' '
0045                         << inner.eta() << '/' << outer.eta() << std::endl;
0046 
0047   std::vector<const TrackingRecHit *> hits;
0048   hits.reserve(inner.recHitsSize() + outer.recHitsSize());
0049   DPRINT("TrackMerger") << "Inner track hits: " << std::endl;
0050   for (auto it = inner.recHitsBegin(), ed = inner.recHitsEnd(); it != ed; ++it) {
0051     hits.push_back(&**it);
0052     if (debug_) {
0053       DetId id(hits.back()->geographicalId());
0054       PRINT << "   subdet " << id.subdetId() << "  layer " << theTrkTopo->layer(id) << " valid "
0055             << hits.back()->isValid() << "   detid: " << id() << std::endl;
0056     }
0057   }
0058   DPRINT("TrackMerger") << "Outer track hits: " << std::endl;
0059 
0060   if (duplicateType == DuplicateTrackType::Disjoint) {
0061 #if TRACK_SORT
0062     DetId lastId(hits.back()->geographicalId());
0063     int lastSubdet = lastId.subdetId();
0064     unsigned int lastLayer = theTrkTopo->layer(lastId);
0065     for (auto it = outer.recHitsBegin(), ed = outer.recHitsEnd(); it != ed; ++it) {
0066       const TrackingRecHit *hit = &**it;
0067       DetId id(hit->geographicalId());
0068       int thisSubdet = id.subdetId();
0069       if (thisSubdet > lastSubdet || (thisSubdet == lastSubdet && theTrkTopo->layer(id) > lastLayer)) {
0070         hits.push_back(hit);
0071         PRINT << "  adding   subdet " << id.subdetId() << "  layer " << theTrkTopo->layer(id) << " valid "
0072               << hit->isValid() << "   detid: " << id() << std::endl;
0073       } else {
0074         PRINT << "  skipping subdet " << thisSubdet << "  layer " << theTrkTopo->layer(id) << " valid "
0075               << hit->isValid() << "   detid: " << id() << std::endl;
0076       }
0077     }
0078 #else
0079     addSecondTrackHits(hits, outer);
0080 #endif
0081   } else if (duplicateType == DuplicateTrackType::Overlapping) {
0082     addSecondTrackHits(hits, outer);
0083   }
0084 
0085   math::XYZVector p = (inner.innerMomentum() + outer.outerMomentum());
0086   GlobalVector v(p.x(), p.y(), p.z());
0087   if (!useInnermostState_)
0088     v *= -1;
0089 
0090   TrackCandidate::RecHitContainer ownHits;
0091   unsigned int nhits = hits.size();
0092   ownHits.reserve(nhits);
0093 
0094   if (duplicateType == DuplicateTrackType::Disjoint) {
0095 #if TRACK_SORT
0096     if (!useInnermostState_)
0097       std::reverse(hits.begin(), hits.end());
0098     for (auto hit : hits)
0099       ownHits.push_back(*hit);
0100 #elif DET_SORT
0101     // OLD METHOD, sometimes fails
0102     std::sort(hits.begin(), hits.end(), MomentumSort(v, &*theGeometry));
0103     for (auto hit : hits)
0104       ownHits.push_back(*hit);
0105 #else
0106     sortByHitPosition(v, hits, ownHits);
0107 #endif
0108   } else if (duplicateType == DuplicateTrackType::Overlapping) {
0109     sortByHitPosition(v, hits, ownHits);
0110   }
0111 
0112   PTrajectoryStateOnDet state;
0113   PropagationDirection pdir;
0114   if (useInnermostState_) {
0115     pdir = alongMomentum;
0116     if ((inner.outerPosition() - inner.innerPosition()).Dot(inner.momentum()) >= 0) {
0117       // use inner state
0118       TrajectoryStateOnSurface originalTsosIn(
0119           trajectoryStateTransform::innerStateOnSurface(inner, *theGeometry, &*theMagField));
0120       state = trajectoryStateTransform::persistentState(originalTsosIn, DetId(inner.innerDetId()));
0121     } else {
0122       // use outer state
0123       TrajectoryStateOnSurface originalTsosOut(
0124           trajectoryStateTransform::outerStateOnSurface(inner, *theGeometry, &*theMagField));
0125       state = trajectoryStateTransform::persistentState(originalTsosOut, DetId(inner.outerDetId()));
0126     }
0127   } else {
0128     pdir = oppositeToMomentum;
0129     if ((outer.outerPosition() - inner.innerPosition()).Dot(inner.momentum()) >= 0) {
0130       // use outer state
0131       TrajectoryStateOnSurface originalTsosOut(
0132           trajectoryStateTransform::outerStateOnSurface(outer, *theGeometry, &*theMagField));
0133       state = trajectoryStateTransform::persistentState(originalTsosOut, DetId(outer.outerDetId()));
0134     } else {
0135       // use inner state
0136       TrajectoryStateOnSurface originalTsosIn(
0137           trajectoryStateTransform::innerStateOnSurface(outer, *theGeometry, &*theMagField));
0138       state = trajectoryStateTransform::persistentState(originalTsosIn, DetId(outer.innerDetId()));
0139     }
0140   }
0141   TrajectorySeed seed(state, TrackCandidate::RecHitContainer(), pdir);
0142   TrackCandidate ret(ownHits, seed, state, (useInnermostState_ ? inner : outer).seedRef());
0143   ret.setStopReason((uint8_t)(useInnermostState_ ? inner : outer).stopReason());
0144   return ret;
0145 }
0146 
0147 void TrackMerger::addSecondTrackHits(std::vector<const TrackingRecHit *> &hits, const reco::Track &outer) const {
0148   size_t nHitsFirstTrack = hits.size();
0149   for (auto it = outer.recHitsBegin(), ed = outer.recHitsEnd(); it != ed; ++it) {
0150     const TrackingRecHit *hit = &**it;
0151     DetId id(hit->geographicalId());
0152     const auto lay = theTrkTopo->layer(id);
0153     bool shared = false;
0154     bool valid = hit->isValid();
0155     PRINT << "   subdet " << id.subdetId() << "  layer " << theTrkTopo->layer(id) << " valid " << valid
0156           << "   detid: " << id() << std::endl;
0157     size_t iHit = 0;
0158     for (auto hit2 : hits) {
0159       ++iHit;
0160       if (iHit > nHitsFirstTrack)
0161         break;
0162       DetId id2 = hit2->geographicalId();
0163       if (id.subdetId() != id2.subdetId())
0164         continue;
0165       if (theTrkTopo->layer(id2) != lay)
0166         continue;
0167       if (hit->sharesInput(hit2, TrackingRecHit::all)) {
0168         PRINT << "        discared as duplicate of other hit" << id() << std::endl;
0169         shared = true;
0170         break;
0171       }
0172       if (hit2->isValid() && !valid) {
0173         PRINT << "        replacing old invalid hit on detid " << id2() << std::endl;
0174         hit = hit2;
0175         shared = true;
0176         break;
0177       }
0178       PRINT << "        discared as additional hit on layer that already contains hit with detid " << id() << std::endl;
0179       shared = true;
0180       break;
0181     }
0182     if (shared)
0183       continue;
0184     hits.push_back(hit);
0185   }
0186 }
0187 
0188 void TrackMerger::sortByHitPosition(const GlobalVector &v,
0189                                     const std::vector<const TrackingRecHit *> &hits,
0190                                     TrackCandidate::RecHitContainer &ownHits) const {
0191   // NEW sort, more accurate
0192   unsigned int nhits = hits.size();
0193   std::vector<TransientTrackingRecHit::RecHitPointer> ttrh(nhits);
0194   for (unsigned int i = 0; i < nhits; ++i)
0195     ttrh[i] = theBuilder->build(hits[i]);
0196   std::sort(ttrh.begin(), ttrh.end(), GlobalMomentumSort(v));
0197   for (const auto &hit : ttrh)
0198     ownHits.push_back(*hit);
0199 }
0200 
0201 bool TrackMerger::MomentumSort::operator()(const TrackingRecHit *hit1, const TrackingRecHit *hit2) const {
0202   const GeomDet *det1 = geom_->idToDet(hit1->geographicalId());
0203   const GeomDet *det2 = geom_->idToDet(hit2->geographicalId());
0204   GlobalPoint p1 = det1->toGlobal(LocalPoint(0, 0, 0));
0205   GlobalPoint p2 = det2->toGlobal(LocalPoint(0, 0, 0));
0206   return (p2 - p1).dot(dir_) > 0;
0207 }
0208 
0209 bool TrackMerger::GlobalMomentumSort::operator()(const TransientTrackingRecHit::RecHitPointer &hit1,
0210                                                  const TransientTrackingRecHit::RecHitPointer &hit2) const {
0211   GlobalPoint p1 = hit1->isValid() ? hit1->globalPosition() : hit1->det()->position();
0212   GlobalPoint p2 = hit2->isValid() ? hit2->globalPosition() : hit2->det()->position();
0213   return (p2 - p1).dot(dir_) > 0;
0214 }