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
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
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
00134 TrajectoryStateOnSurface originalTsosIn(trajectoryStateTransform::innerStateOnSurface(inner, *theGeometry, &*theMagField));
00135 state = trajectoryStateTransform::persistentState( originalTsosIn, DetId(inner.innerDetId()) );
00136 } else {
00137
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
00145 TrajectoryStateOnSurface originalTsosOut(trajectoryStateTransform::outerStateOnSurface(outer, *theGeometry, &*theMagField));
00146 state = trajectoryStateTransform::persistentState( originalTsosOut, DetId(outer.outerDetId()) );
00147 } else {
00148
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 }