CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoTracker/TrackProducer/src/TrackMerger.cc

Go to the documentation of this file.
00001 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00002 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00003 
00004 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00005 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00006 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00007 
00008 #include "RecoTracker/TrackProducer/interface/TrackMerger.h"
00009 
00010 #include <boost/foreach.hpp>
00011 #define foreach BOOST_FOREACH
00012 
00013 #define TRACK_SORT 1 // just use all hits from inner track, then append from outer outside it
00014 #define DET_SORT   0 // sort hits using global position of detector 
00015 #define HIT_SORT   0 // sort hits using global position of hit
00016 
00017 
00018 TrackMerger::TrackMerger(const edm::ParameterSet &iConfig) :
00019     useInnermostState_(iConfig.getParameter<bool>("useInnermostState")),
00020     debug_(iConfig.getUntrackedParameter<bool>("debug",false)),
00021     theBuilderName(iConfig.getParameter<std::string>("ttrhBuilderName"))
00022 {
00023 }
00024 
00025 TrackMerger::~TrackMerger()
00026 {
00027 }
00028 
00029 void TrackMerger::init(const edm::EventSetup &iSetup) 
00030 {
00031     iSetup.get<TrackerDigiGeometryRecord>().get(theGeometry);
00032     iSetup.get<IdealMagneticFieldRecord>().get(theMagField);
00033     iSetup.get<TransientRecHitRecord>().get(theBuilderName,theBuilder);
00034     iSetup.get<IdealGeometryRecord>().get(theTrkTopo);
00035 }
00036 
00037 TrackCandidate TrackMerger::merge(const reco::Track &inner, const reco::Track &outer) const 
00038 {
00039     std::vector<const TrackingRecHit *> hits;
00040     hits.reserve(inner.recHitsSize() + outer.recHitsSize());
00041     if (debug_) std::cout << "Inner track hits: " << std::endl;
00042     for (trackingRecHit_iterator it = inner.recHitsBegin(), ed = inner.recHitsEnd(); it != ed; ++it) {
00043         hits.push_back(&**it);
00044         if (debug_) {
00045             DetId id(hits.back()->geographicalId());
00046             std::cout << "   subdet " << id.subdetId() << "  layer " << theTrkTopo->layer(id) << " valid " << hits.back()->isValid() << "   detid: " << id() << std::endl;
00047         }
00048     }
00049     if (debug_) std::cout << "Outer track hits: " << std::endl;
00050 
00051 #if TRACK_SORT
00052     DetId lastId(hits.back()->geographicalId());
00053     int lastSubdet = lastId.subdetId(); 
00054     unsigned int lastLayer = theTrkTopo->layer(lastId);
00055     for (trackingRecHit_iterator it = outer.recHitsBegin(), ed = outer.recHitsEnd(); it != ed; ++it) {
00056         const TrackingRecHit *hit = &**it;
00057         DetId id(hit->geographicalId());
00058         int thisSubdet = id.subdetId();
00059         if (thisSubdet > lastSubdet || (thisSubdet == lastSubdet && theTrkTopo->layer(id) > lastLayer)) {
00060             hits.push_back(hit);
00061             if (debug_) std::cout << "  adding   subdet " << id.subdetId() << "  layer " << theTrkTopo->layer(id) << " valid " << hit->isValid() << "   detid: " << id() << std::endl;
00062         } else {
00063             if (debug_) std::cout << "  skipping subdet " << thisSubdet << "  layer " << theTrkTopo->layer(id) << " valid " << hit->isValid() << "   detid: " << id() << std::endl;
00064         }
00065     }
00066 #else
00067     size_t nHitsFirstTrack = hits.size();
00068     for (trackingRecHit_iterator it = outer.recHitsBegin(), ed = outer.recHitsEnd(); it != ed; ++it) {
00069         const TrackingRecHit *hit = &**it;
00070         DetId id(hit->geographicalId());
00071         int  lay = theTrkTopo->layer(id);
00072         bool shared = false;
00073         bool valid  = hit->isValid();
00074         if (debug_) std::cout << "   subdet " << id.subdetId() << "  layer " << theTrkTopo->layer(id) << " valid " << valid << "   detid: " << id() << std::endl;
00075         size_t iHit = 0;
00076         foreach(const TrackingRecHit *& hit2, hits) {
00077             ++iHit; if (iHit >  nHitsFirstTrack) break;
00078             DetId id2 = hit2->geographicalId();
00079             if (id.subdetId() != id2.subdetId()) continue;
00080             if (theTrkTopo->layer(id2) != lay) continue;
00081             if (hit->sharesInput(hit2, TrackingRecHit::all)) { 
00082                 if (debug_) std::cout << "        discared as duplicate of other hit" << id() << std::endl;
00083                 shared = true; break; 
00084             }
00085             if (hit2->isValid() && !valid) { 
00086                 if (debug_) std::cout << "        replacing old invalid hit on detid " << id2() << std::endl;
00087                 hit2 = hit; shared = true; break; 
00088             }
00089             if (debug_) std::cout << "        discared as additional hit on layer that already contains hit with detid " << id() << std::endl;
00090             shared = true; break;
00091         }
00092         if (shared) continue;
00093         hits.push_back(hit);
00094     }
00095 #endif
00096     
00097     math::XYZVector p = (inner.innerMomentum() + outer.outerMomentum());
00098     GlobalVector v(p.x(), p.y(), p.z());
00099     if (!useInnermostState_) v *= -1;
00100 
00101     TrackCandidate::RecHitContainer ownHits;
00102     unsigned int nhits = hits.size();
00103     ownHits.reserve(nhits);
00104 
00105 #if TRACK_SORT
00106     if (!useInnermostState_) std::reverse(hits.begin(), hits.end());
00107     foreach(const TrackingRecHit * hit, hits) {
00108         ownHits.push_back(*hit);
00109     }
00110 #elif DET_SORT
00111     // OLD METHOD, sometimes fails
00112     std::sort(hits.begin(), hits.end(), MomentumSort(v, &*theGeometry));
00113 
00114     foreach(const TrackingRecHit * hit, hits) {
00115         ownHits.push_back(*hit);
00116     }
00117 #else
00118     // NEW sort, more accurate
00119     std::vector<TransientTrackingRecHit::RecHitPointer> ttrh(nhits);
00120     for (unsigned int i = 0; i < nhits; ++i) ttrh[i] = theBuilder->build(hits[i]);
00121     std::sort(ttrh.begin(), ttrh.end(), GlobalMomentumSort(v));
00122 
00123     foreach(const TransientTrackingRecHit::RecHitPointer & hit, ttrh) {
00124         ownHits.push_back(*hit->hit());
00125     }
00126 #endif
00127 
00128     PTrajectoryStateOnDet state;
00129     PropagationDirection pdir;
00130     if (useInnermostState_) {
00131         pdir = alongMomentum;
00132         if ((inner.outerPosition()-inner.innerPosition()).Dot(inner.momentum()) >= 0) {
00133             // use inner state
00134             TrajectoryStateOnSurface originalTsosIn(trajectoryStateTransform::innerStateOnSurface(inner, *theGeometry, &*theMagField));
00135             state = trajectoryStateTransform::persistentState( originalTsosIn, DetId(inner.innerDetId()) );
00136         } else { 
00137             // use outer state
00138             TrajectoryStateOnSurface originalTsosOut(trajectoryStateTransform::outerStateOnSurface(inner, *theGeometry, &*theMagField));
00139             state = trajectoryStateTransform::persistentState( originalTsosOut, DetId(inner.outerDetId()) );
00140         }
00141     } else {
00142         pdir = oppositeToMomentum;
00143         if ((outer.outerPosition()-inner.innerPosition()).Dot(inner.momentum()) >= 0) {
00144             // use outer state
00145             TrajectoryStateOnSurface originalTsosOut(trajectoryStateTransform::outerStateOnSurface(outer, *theGeometry, &*theMagField));
00146             state = trajectoryStateTransform::persistentState( originalTsosOut, DetId(outer.outerDetId()) );
00147         } else { 
00148             // use inner state
00149             TrajectoryStateOnSurface originalTsosIn(trajectoryStateTransform::innerStateOnSurface(outer, *theGeometry, &*theMagField));
00150             state = trajectoryStateTransform::persistentState( originalTsosIn, DetId(outer.innerDetId()) );
00151         }
00152 
00153     }
00154      TrajectorySeed seed(state, TrackCandidate::RecHitContainer(), pdir);
00155     return TrackCandidate(ownHits, seed, state, (useInnermostState_ ? inner : outer).seedRef());
00156 }
00157 
00158 
00159 bool TrackMerger::MomentumSort::operator()(const TrackingRecHit *hit1, const TrackingRecHit *hit2) const 
00160 {
00161     const GeomDet *det1 = geom_->idToDet(hit1->geographicalId());
00162     const GeomDet *det2 = geom_->idToDet(hit2->geographicalId());
00163     GlobalPoint p1 = det1->toGlobal(LocalPoint(0,0,0));
00164     GlobalPoint p2 = det2->toGlobal(LocalPoint(0,0,0));
00165     return (p2 - p1).dot(dir_) > 0;
00166 }
00167 
00168 bool TrackMerger::GlobalMomentumSort::operator()(const TransientTrackingRecHit::RecHitPointer &hit1, const TransientTrackingRecHit::RecHitPointer &hit2) const 
00169 {
00170     GlobalPoint p1 = hit1->isValid() ? hit1->globalPosition() : hit1->det()->position();
00171     GlobalPoint p2 = hit2->isValid() ? hit2->globalPosition() : hit2->det()->position();
00172     return (p2 - p1).dot(dir_) > 0;
00173 }