CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/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/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         //const TrackingRecHit* firstHit  = 0;
00110         //const TrackingRecHit* secondHit = 0;
00111         //choose the prop dir and hit order accordingly to where the seed is made
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                 //firstHit  = outerHit;
00122                 //secondHit = middleHit;
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                 //firstHit  = innerHit;
00132                 //secondHit = middleHit;
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         /*GlobalTrajectoryParameters originalPar = originalStartingState.parameters();
00139         GlobalTrajectoryParameters newPar = GlobalTrajectoryParameters(originalPar.position(), 
00140                                                                        momentumSign*originalPar.momentum(),
00141                                                                        originalPar.charge(),
00142                                                                        &originalPar.magneticField());
00143         */
00144         
00145         /*FastCircle helix(*thirdPoint, *secondPoint, *firstPoint);
00146         GlobalTrajectoryParameters newPar = GlobalTrajectoryParameters(*secondPoint,
00147                                                                        momentumSign*originalPar.momentum(),
00148                                                                        originalPar.charge(),
00149                                                                        &originalPar.magneticField());*/
00150         //FreeTrajectoryState* startingState = new FreeTrajectoryState(newPar, initialError(trHits[0]));//trHits[1]));
00151         if (!qualityFilter(momentumSign*originalStartingState.momentum())) return 0;
00152         //TrajectorySeed* seed = buildSeed(startingState, trHits, dir);
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         //const TrackingRecHit* firstHit  = 0;
00180         //const TrackingRecHit* secondHit = 0;
00181         std::vector<const TrackingRecHit*> trHits;
00182         //choose the prop dir and hit order accordingly to where the seed is made
00183         if (seedDir == outsideIn){
00184                 LogDebug("SeedFromGenericPairOrTriplet")
00185                         << "Seed from outsideIn alongMomentum OR insideOut oppositeToMomentum";
00186                 firstPoint = &outer;
00187                 secondPoint = &inner;
00188                 //firstHit  = outerHit;
00189                 //secondHit = innerHit;
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                 //firstHit  = innerHit;
00199                 //secondHit = outerHit;
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         /*GlobalTrajectoryParameters gtp(*firstPoint, 
00206                                        momentum,
00207                                        charge,
00208                                        &(*theMagfield));*/
00209         //FreeTrajectoryState* startingState = new FreeTrajectoryState(gtp,initialError(trHits[0]));//trHits[1]));
00210         //if (!qualityFilter(startingState, hits)) return 0;
00211         //TrajectorySeed* seed = buildSeed(startingState, firstHit, dir);
00212         //TrajectorySeed* seed = buildSeed(startingState, trHits, dir);
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                                                         //const TrackingRecHit* firsthit,
00221                                                         std::vector<const TrackingRecHit*>& trHits,
00222                                                         const PropagationDirection& dir) const {
00223         const Propagator* propagator = thePropagatorAlong;
00224         if (dir == oppositeToMomentum) propagator = thePropagatorOpposite;
00225 
00226         //debug
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         //build an initial trajectory state with big errors, 
00238         //then update it with the first hit
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         //TrajectoryStateOnSurface seedTSOS(*startingState, *plane);
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         //build the transientTrackingRecHit for the starting hit, then call the method clone to rematch if needed
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 CurvilinearTrajectoryError SeedFromGenericPairOrTriplet::initialError(const TrackingRecHit* rechit) {
00285         TransientTrackingRecHit::RecHitPointer transHit =  theBuilder->build(rechit);
00286         //AlgebraicSymMatrix C(5,1);
00287         AlgebraicSymMatrix55 C = AlgebraicMatrixID();
00288         //C*=0.1;
00289         if (theSetMomentum){
00290                 C(0,0)=1/theP;
00291                 C(3,3)=transHit->globalPositionError().cxx();
00292                 C(4,4)=transHit->globalPositionError().czz();
00293                 
00294                 //C[0][0]=1/theP;
00295                 //C[3][3]=transHit->globalPositionError().cxx();
00296                 //C[4][4]=transHit->globalPositionError().czz();
00297         } else {
00298                 float zErr = transHit->globalPositionError().czz();
00299                 float transverseErr = transHit->globalPositionError().cxx(); // assume equal cxx cyy
00300                 C(3,3) = transverseErr;
00301                 C(4,4) = zErr;
00302                 //C[3][3] = transverseErr;
00303                 //C[4][4] = zErr;
00304         }
00305 
00306         return CurvilinearTrajectoryError(C);
00307 }
00308 */
00309 bool SeedFromGenericPairOrTriplet::qualityFilter(const SeedingHitSet& hits) const{
00310         //if we are setting the momentum with the PSet we look for aligned hits
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 }