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