CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoTracker/SpecialSeedGenerators/src/SeedFromGenericPairOrTriplet.cc

Go to the documentation of this file.
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         //const TrackingRecHit* firstHit  = 0;
00107         //const TrackingRecHit* secondHit = 0;
00108         //choose the prop dir and hit order accordingly to where the seed is made
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                 //firstHit  = outerHit;
00119                 //secondHit = middleHit;
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                 //firstHit  = innerHit;
00129                 //secondHit = middleHit;
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         /*GlobalTrajectoryParameters originalPar = originalStartingState.parameters();
00136         GlobalTrajectoryParameters newPar = GlobalTrajectoryParameters(originalPar.position(), 
00137                                                                        momentumSign*originalPar.momentum(),
00138                                                                        originalPar.charge(),
00139                                                                        &originalPar.magneticField());
00140         */
00141         
00142         /*FastCircle helix(*thirdPoint, *secondPoint, *firstPoint);
00143         GlobalTrajectoryParameters newPar = GlobalTrajectoryParameters(*secondPoint,
00144                                                                        momentumSign*originalPar.momentum(),
00145                                                                        originalPar.charge(),
00146                                                                        &originalPar.magneticField());*/
00147         //FreeTrajectoryState* startingState = new FreeTrajectoryState(newPar, initialError(trHits[0]));//trHits[1]));
00148         if (!qualityFilter(momentumSign*originalStartingState.momentum())) return 0;
00149         //TrajectorySeed* seed = buildSeed(startingState, trHits, dir);
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         //const TrackingRecHit* firstHit  = 0;
00177         //const TrackingRecHit* secondHit = 0;
00178         std::vector<const TrackingRecHit*> trHits;
00179         //choose the prop dir and hit order accordingly to where the seed is made
00180         if (seedDir == outsideIn){
00181                 LogDebug("SeedFromGenericPairOrTriplet")
00182                         << "Seed from outsideIn alongMomentum OR insideOut oppositeToMomentum";
00183                 firstPoint = &outer;
00184                 secondPoint = &inner;
00185                 //firstHit  = outerHit;
00186                 //secondHit = innerHit;
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                 //firstHit  = innerHit;
00196                 //secondHit = outerHit;
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         /*GlobalTrajectoryParameters gtp(*firstPoint, 
00203                                        momentum,
00204                                        charge,
00205                                        &(*theMagfield));*/
00206         //FreeTrajectoryState* startingState = new FreeTrajectoryState(gtp,initialError(trHits[0]));//trHits[1]));
00207         //if (!qualityFilter(startingState, hits)) return 0;
00208         //TrajectorySeed* seed = buildSeed(startingState, firstHit, dir);
00209         //TrajectorySeed* seed = buildSeed(startingState, trHits, dir);
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                                                         //const TrackingRecHit* firsthit,
00218                                                         std::vector<const TrackingRecHit*>& trHits,
00219                                                         const PropagationDirection& dir) const {
00220         const Propagator* propagator = thePropagatorAlong;
00221         if (dir == oppositeToMomentum) propagator = thePropagatorOpposite;
00222 
00223         //debug
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         //build an initial trajectory state with big errors, 
00235         //then update it with the first hit
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         //TrajectoryStateOnSurface seedTSOS(*startingState, *plane);
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         //build the transientTrackingRecHit for the starting hit, then call the method clone to rematch if needed
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 CurvilinearTrajectoryError SeedFromGenericPairOrTriplet::initialError(const TrackingRecHit* rechit) {
00282         TransientTrackingRecHit::RecHitPointer transHit =  theBuilder->build(rechit);
00283         //AlgebraicSymMatrix C(5,1);
00284         AlgebraicSymMatrix55 C = AlgebraicMatrixID();
00285         //C*=0.1;
00286         if (theSetMomentum){
00287                 C(0,0)=1/theP;
00288                 C(3,3)=transHit->globalPositionError().cxx();
00289                 C(4,4)=transHit->globalPositionError().czz();
00290                 
00291                 //C[0][0]=1/theP;
00292                 //C[3][3]=transHit->globalPositionError().cxx();
00293                 //C[4][4]=transHit->globalPositionError().czz();
00294         } else {
00295                 float zErr = transHit->globalPositionError().czz();
00296                 float transverseErr = transHit->globalPositionError().cxx(); // assume equal cxx cyy
00297                 C(3,3) = transverseErr;
00298                 C(4,4) = zErr;
00299                 //C[3][3] = transverseErr;
00300                 //C[4][4] = zErr;
00301         }
00302 
00303         return CurvilinearTrajectoryError(C);
00304 }
00305 */
00306 bool SeedFromGenericPairOrTriplet::qualityFilter(const SeedingHitSet& hits) const{
00307         //if we are setting the momentum with the PSet we look for aligned hits
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 }