00001 #include "RecoTracker/SpecialSeedGenerators/interface/SeedFromGenericPairOrTriplet.h"
00002 #include "RecoTracker/TkSeedGenerator/interface/FastHelix.h"
00003 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00004 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00007 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00008 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h"
00009 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00010
00011 SeedFromGenericPairOrTriplet::SeedFromGenericPairOrTriplet(const MagneticField* mf,
00012 const TrackerGeometry* geom,
00013 const TransientTrackingRecHitBuilder* builder,
00014 const Propagator* propagatorAlong,
00015 const Propagator* propagatorOpposite,
00016 const std::vector<int>& charges,
00017 bool momFromPSet,
00018 double errorRescaling):theMagfield(mf), theTracker(geom), theBuilder(builder), thePropagatorAlong(propagatorAlong), thePropagatorOpposite(propagatorOpposite), theSetMomentum(momFromPSet), theCharges(charges), theErrorRescaling(errorRescaling){}
00019
00020
00021 std::vector<TrajectorySeed*> SeedFromGenericPairOrTriplet::seed(const SeedingHitSet& hits,
00022 const PropagationDirection& dir,
00023 const NavigationDirection& seedDir,
00024 const edm::EventSetup& iSetup){
00025 std::vector<TrajectorySeed*> seeds;
00026 if (hits.size() == 3) {
00027 if(!theSetMomentum){
00028 TrajectorySeed* seed = seedFromTriplet(hits, dir, seedDir, iSetup);
00029 if (seed) seeds.push_back(seed);
00030 } else {
00031 for (std::vector<int>::const_iterator iCh = theCharges.begin(); iCh != theCharges.end(); iCh++){
00032 TrajectorySeed* seed = seedFromTriplet(hits, dir, seedDir, iSetup, *iCh);
00033 if(seed) seeds.push_back(seed);
00034 }
00035 }
00036
00037 } else if (hits.size() == 2){
00038 if(!theSetMomentum){
00039 TrajectorySeed* seed = seedFromPair(hits, dir, seedDir);
00040 if (seed) seeds.push_back(seed);
00041 } else {
00042 for (std::vector<int>::const_iterator iCh = theCharges.begin(); iCh != theCharges.end(); iCh++){
00043 TrajectorySeed* seed = seedFromPair(hits, dir, seedDir, *iCh);
00044 if (seed) seeds.push_back(seed);
00045 }
00046 }
00047 } else {
00048 throw cms::Exception("CombinatorialSeedGeneratorForCosmics") << " Wrong number of hits in Set: "
00049 << hits.size() << ", should be 2 or 3 ";
00050 }
00051 return seeds;
00052 }
00053
00054 TrajectorySeed* SeedFromGenericPairOrTriplet::seedFromTriplet(const SeedingHitSet& hits,
00055 const PropagationDirection& dir,
00056 const NavigationDirection& seedDir,
00057 const edm::EventSetup& iSetup, int charge) const{
00058 if (hits.size() != 3) {
00059 throw cms::Exception("CombinatorialSeedGeneratorForCosmics") <<
00060 "call to SeedFromGenericPairOrTriplet::seedFromTriplet with " << hits.size() << " hits ";
00061 }
00062
00063 const TrackingRecHit* innerHit = hits[0]->hit();
00064 const TrackingRecHit* middleHit = hits[1]->hit();
00065 const TrackingRecHit* outerHit = hits[2]->hit();
00066 GlobalPoint inner = theTracker->idToDet(innerHit->geographicalId() )->surface().toGlobal(innerHit->localPosition() );
00067 GlobalPoint middle = theTracker->idToDet(middleHit->geographicalId())->surface().toGlobal(middleHit->localPosition());
00068 GlobalPoint outer = theTracker->idToDet(outerHit->geographicalId() )->surface().toGlobal(outerHit->localPosition() );
00069 if (theSetMomentum){
00070 LogDebug("SeedFromGenericPairOrTriplet") <<
00071 "Using the following hits: outer(r, phi, theta) " << outerHit->geographicalId().subdetId()<< " (" << outer.perp()
00072 << ", " << outer.phi()
00073 << "," << outer.theta()
00074 << ") " << middleHit->geographicalId().subdetId() << " middle ("
00075 << middle.perp() << ", "
00076 << middle.phi() << ","
00077 << middle.theta() << ") "
00078 <<innerHit->geographicalId().subdetId() <<" inner ("
00079 << inner.perp()
00080 << ", " << inner.phi()
00081 << "," << inner.theta() <<") "
00082 << " (x, y, z) outer ("
00083 << inner.x() << ", "
00084 << inner.y() << ", "
00085 << inner.z() << ") middle ("
00086 << middle.x() << ", "
00087 << middle.y() << ", "
00088 << middle.z() << ")";
00089 SeedingHitSet newSet;
00090 if (seedDir == outsideIn){
00091 newSet.add(hits[1]);
00092 newSet.add(hits[2]);
00093 } else {
00094 newSet.add(hits[0]);
00095 newSet.add(hits[1]);
00096 }
00097 if (!qualityFilter(hits)) return 0;
00098 TrajectorySeed* seed = seedFromPair(newSet, dir, seedDir, charge);
00099 return seed;
00100
00101 }
00102 GlobalPoint* firstPoint = 0;
00103 GlobalPoint* secondPoint = 0;
00104 GlobalPoint* thirdPoint = 0;
00105 int momentumSign = 1;
00106
00107
00108
00109 std::vector<const TrackingRecHit*> trHits;
00110 if (seedDir == outsideIn){
00111 LogDebug("SeedFromGenericPairOrTriplet")
00112 << "Seed from outsideIn alongMomentum OR insideOut oppositeToMomentum";
00113 firstPoint = &outer;
00114 secondPoint = &middle;
00115 thirdPoint = &inner;
00116 trHits.push_back(outerHit);
00117 trHits.push_back(middleHit);
00118
00119
00120 } else {
00121 LogDebug("SeedFromGenericPairOrTriplet")
00122 << "Seed from outsideIn oppositeToMomentum OR insideOut alongMomentum";
00123 firstPoint = &inner;
00124 secondPoint = &middle;
00125 thirdPoint = &outer;
00126 trHits.push_back(innerHit);
00127 trHits.push_back(middleHit);
00128
00129
00130 }
00131 if (dir == oppositeToMomentum) momentumSign = -1;
00132 FastHelix helix(*thirdPoint, *secondPoint, *firstPoint, iSetup);
00133 FreeTrajectoryState originalStartingState = helix.stateAtVertex();
00134 LogDebug("SeedFromGenericPairOrTriplet") << "originalStartingState " << originalStartingState;
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 if (!qualityFilter(momentumSign*originalStartingState.momentum())) return 0;
00149
00150 TrajectorySeed* seed = buildSeed(momentumSign*originalStartingState.momentum(),originalStartingState.charge(), trHits, dir);
00151 return seed;
00152 }
00153
00154 TrajectorySeed* SeedFromGenericPairOrTriplet::seedFromPair(const SeedingHitSet& hits,
00155 const PropagationDirection& dir,
00156 const NavigationDirection& seedDir, int charge) const{
00157 if (hits.size() != 2) {
00158 throw cms::Exception("CombinatorialSeedGeneratorForCosmics") <<
00159 "call to SeedFromGenericPairOrTriplet::seedFromPair with " << hits.size() << " hits ";
00160 }
00161 const TrackingRecHit* innerHit = hits[0]->hit();
00162 const TrackingRecHit* outerHit = hits[1]->hit();
00163 GlobalPoint inner = theTracker->idToDet(innerHit->geographicalId() )->surface().toGlobal(innerHit->localPosition() );
00164 GlobalPoint outer = theTracker->idToDet(outerHit->geographicalId() )->surface().toGlobal(outerHit->localPosition() );
00165 LogDebug("SeedFromGenericPairOrTriplet") <<
00166 "Using the following hits: outer(r, phi, theta) (" << outer.perp()
00167 << ", " << outer.phi()
00168 << "," << outer.theta()
00169 <<") inner ("
00170 << inner.perp()
00171 << ", " << inner.phi()
00172 << "," << inner.theta() <<")";
00173 GlobalPoint* firstPoint = 0;
00174 GlobalPoint* secondPoint = 0;
00175 int momentumSign = 1;
00176
00177
00178 std::vector<const TrackingRecHit*> trHits;
00179
00180 if (seedDir == outsideIn){
00181 LogDebug("SeedFromGenericPairOrTriplet")
00182 << "Seed from outsideIn alongMomentum OR insideOut oppositeToMomentum";
00183 firstPoint = &outer;
00184 secondPoint = &inner;
00185
00186
00187 trHits.push_back(outerHit);
00188 trHits.push_back(innerHit);
00189 } else {
00190 LogDebug("SeedFromGenericPairOrTriplet")
00191 << "Seed from outsideIn oppositeToMomentum OR insideOut alongMomentum";
00192 firstPoint = &inner;
00193 secondPoint = &outer;
00194 momentumSign = -1;
00195
00196
00197 trHits.push_back(innerHit);
00198 trHits.push_back(outerHit);
00199 }
00200 if (dir == oppositeToMomentum) momentumSign = -1;
00201 GlobalVector momentum = momentumSign*theP*(*secondPoint-*firstPoint).unit();
00202
00203
00204
00205
00206
00207
00208
00209
00210 TrajectorySeed* seed = buildSeed(momentum, charge, trHits, dir);
00211 return seed;
00212 }
00213
00214
00215 TrajectorySeed* SeedFromGenericPairOrTriplet::buildSeed(const GlobalVector& momentum,
00216 int charge,
00217
00218 std::vector<const TrackingRecHit*>& trHits,
00219 const PropagationDirection& dir) const {
00220 const Propagator* propagator = thePropagatorAlong;
00221 if (dir == oppositeToMomentum) propagator = thePropagatorOpposite;
00222
00223
00224 GlobalPoint first = theTracker->idToDet(trHits[0]->geographicalId() )->surface().toGlobal(trHits[0]->localPosition() );
00225 GlobalPoint second = theTracker->idToDet(trHits[1]->geographicalId() )->surface().toGlobal(trHits[1]->localPosition() );
00226 LogDebug("SeedFromGenericPairOrTriplet") <<
00227 "Using the following hits: first(r, phi, theta) (" << first.perp()
00228 << ", " << first.phi()
00229 << "," << first.theta()
00230 <<") second ("
00231 << second.perp()
00232 << ", " << second.phi()
00233 << "," << second.theta() <<")";
00234
00235
00236 TransientTrackingRecHit::RecHitPointer transHit = theBuilder->build(trHits[0]);
00237 LocalVector lmom = transHit->surface()->toLocal(momentum);
00238 LocalTrajectoryParameters ltp(charge/momentum.mag(),
00239 lmom.x()/lmom.z(),lmom.y()/lmom.z(),
00240 transHit->localPosition().x(),
00241 transHit->localPosition().y(),
00242 lmom.z()>0.?1.:-1.);
00243
00244 LocalTrajectoryError lte(100.,100.,
00245 (1.+(lmom.x()/lmom.z())*(lmom.x()/lmom.z())),
00246 (1.+(lmom.y()/lmom.z())*(lmom.y()/lmom.z())),
00247 1./momentum.mag());
00248
00249 TrajectoryStateOnSurface initialState(ltp,lte,*transHit->surface(),&(*theMagfield));
00250 KFUpdator updator;
00251 TrajectoryStateOnSurface startingState = updator.update(initialState,*transHit);
00252
00253 TransientTrackingRecHit::RecHitPointer transHit2 = theBuilder->build(trHits[1]);
00254
00255
00256 const TrajectoryStateOnSurface propTSOS = propagator->propagate(startingState,*(transHit2->surface()));
00257 if (!propTSOS.isValid()){
00258 LogDebug("SeedFromGenericPairOrTriplet") << "first propagation failed";
00259 return 0;
00260 }
00261 TrajectoryStateOnSurface seedTSOS = updator.update(propTSOS, *transHit2);
00262 if (!seedTSOS.isValid()){
00263 LogDebug("SeedFromGenericPairOrTriplet") << "first update failed";
00264 return 0;
00265 }
00266 LogDebug("SeedFromGenericPairOrTriplet") << "starting TSOS " << seedTSOS ;
00267 seedTSOS.rescaleError(theErrorRescaling);
00268 PTrajectoryStateOnDet *PTraj=
00269 theTransformer.persistentState(seedTSOS, trHits[1]->geographicalId().rawId());
00270 edm::OwnVector<TrackingRecHit> seed_hits;
00271
00272 std::vector<const TrackingRecHit*>::const_iterator ihits;
00273 for (ihits = trHits.begin(); ihits != trHits.end(); ihits++){
00274 seed_hits.push_back((*ihits)->clone());
00275 }
00276 TrajectorySeed* seed = new TrajectorySeed(*PTraj,seed_hits,dir);
00277 delete PTraj;
00278 return seed;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 bool SeedFromGenericPairOrTriplet::qualityFilter(const SeedingHitSet& hits) const{
00307
00308 if (theSetMomentum){
00309 if (hits.size()==3){
00310 std::vector<GlobalPoint> gPoints;
00311 unsigned int nHits = hits.size();
00312 for (unsigned int iHit = 0; iHit < nHits; ++iHit) gPoints.push_back(hits[iHit]->globalPosition());
00313 unsigned int subid=(*hits[0]).geographicalId().subdetId();
00314 if(subid == StripSubdetector::TEC || subid == StripSubdetector::TID){
00315 LogDebug("SeedFromGenericPairOrTriplet")
00316 << "In the endcaps we cannot decide if hits are aligned with only phi and z";
00317 return true;
00318 }
00319 FastCircle circle(gPoints[0],
00320 gPoints[1],
00321 gPoints[2]);
00322 if (circle.rho() < 500 && circle.rho() != 0) {
00323 LogDebug("SeedFromGenericPairOrTriplet") <<
00324 "Seed qualityFilter rejected because rho = " << circle.rho();
00325 return false;
00326 }
00327
00328 }
00329 }
00330 return true;
00331 }
00332
00333 bool SeedFromGenericPairOrTriplet::qualityFilter(const GlobalVector& momentum) const{
00334 if (!theSetMomentum){
00335 if (momentum.perp() < theP) return false;
00336 }
00337 return true;
00338 }