CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/FastSimulation/EgammaElectronAlgos/src/FastElectronSeedGenerator.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    EgammaElectronAlgos
00004 // Class:      FastElectronSeedGenerator.
00005 //
00013 //
00014 // Original Author:  Patrick Janot
00015 //
00016 //
00017 #include "FastSimulation/EgammaElectronAlgos/interface/FastElectronSeedGenerator.h"
00018 
00019 #include "FWCore/Framework/interface/EventSetup.h"
00020 #include "FWCore/Framework/interface/Event.h"
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 #include "DataFormats/Common/interface/Handle.h"
00023 #include "FWCore/Framework/interface/ESHandle.h"
00024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00025 
00026 #include "FastSimulation/EgammaElectronAlgos/interface/FastPixelHitMatcher.h"
00027 #include "FastSimulation/EgammaElectronAlgos/interface/FastElectronSeedGenerator.h"
00028 
00029 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00030 #include "RecoTracker/TkSeedGenerator/interface/FastHelix.h"
00031 
00032 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00033 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00034 
00035 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00036 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00037 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00038 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00039 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
00040 
00041 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00042 #include "FastSimulation/TrackerSetup/interface/TrackerInteractionGeometryRecord.h"
00043 #include "FastSimulation/ParticlePropagator/interface/MagneticFieldMapRecord.h"
00044 #include "FastSimulation/Tracking/interface/TrackerRecHit.h"
00045 
00046 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00047 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00048 
00049 #include <vector>
00050 
00051 //#define FAMOS_DEBUG
00052 
00053 FastElectronSeedGenerator::FastElectronSeedGenerator(
00054   const edm::ParameterSet &pset,
00055   double pTMin,
00056   const edm::InputTag& beamSpot)
00057   :
00058   dynamicphiroad_(pset.getParameter<bool>("dynamicPhiRoad")),
00059   lowPtThreshold_(pset.getParameter<double>("LowPtThreshold")),
00060   highPtThreshold_(pset.getParameter<double>("HighPtThreshold")),
00061   sizeWindowENeg_(pset.getParameter<double>("SizeWindowENeg")),
00062   phimin2_(pset.getParameter<double>("PhiMin2")),
00063   phimax2_(pset.getParameter<double>("PhiMax2")),
00064   deltaPhi1Low_(pset.getParameter<double>("DeltaPhi1Low")),
00065   deltaPhi1High_(pset.getParameter<double>("DeltaPhi1High")),
00066   deltaPhi2_(pset.getParameter<double>("DeltaPhi2")),
00067   pTMin2(pTMin*pTMin),
00068   myGSPixelMatcher(0),
00069   fromTrackerSeeds_(pset.getParameter<bool>("fromTrackerSeeds")),
00070   theUpdator(0), thePropagator(0),
00071   //   theMeasurementTracker(0),
00072   //   theNavigationSchool(0)
00073   theSetup(0), theBeamSpot(beamSpot), pts_(0)
00074 {
00075 
00076 #ifdef FAMOS_DEBUG
00077   std::cout << "FromTrackerSeeds  = " << fromTrackerSeeds_ << std::endl;
00078 #endif
00079 
00080   // Instantiate the pixel hit matcher
00081   searchInTIDTEC = pset.getParameter<bool>("searchInTIDTEC");
00082   myGSPixelMatcher = new FastPixelHitMatcher(pset.getParameter<double>("ePhiMin1"),
00083                                            pset.getParameter<double>("ePhiMax1"),
00084                                            pset.getParameter<double>("pPhiMin1"),
00085                                            pset.getParameter<double>("pPhiMax1"),
00086                                            pset.getParameter<double>("PhiMin2"),
00087                                            pset.getParameter<double>("PhiMax2"),
00088                                            pset.getParameter<double>("z2MinB"),
00089                                            pset.getParameter<double>("z2MaxB"),
00090                                            pset.getParameter<double>("r2MinF"),
00091                                            pset.getParameter<double>("r2MaxF"),
00092                                            pset.getParameter<double>("rMinI"),
00093                                            pset.getParameter<double>("rMaxI"),
00094                                            pset.getParameter<bool>("searchInTIDTEC"));
00095 
00096 }
00097 
00098 FastElectronSeedGenerator::~FastElectronSeedGenerator() {
00099 
00100   //  delete theNavigationSchool;
00101   delete myGSPixelMatcher;
00102   //  delete myMatchPos;
00103   delete thePropagator;
00104   delete theUpdator;
00105 
00106 }
00107 
00108 
00109 void FastElectronSeedGenerator::setupES(const edm::EventSetup& setup) {
00110 
00111   theSetup= &setup;
00112 
00113   edm::ESHandle<MagneticField> pMF;
00114   setup.get<IdealMagneticFieldRecord>().get(pMF);
00115   theMagField = &(*pMF);
00116 
00117   edm::ESHandle<TrackerGeometry>        geometry;
00118   setup.get<TrackerDigiGeometryRecord>().get(geometry);
00119   theTrackerGeometry = &(*geometry);
00120 
00121   edm::ESHandle<GeometricSearchTracker> recoGeom;
00122   setup.get<TrackerRecoGeometryRecord>().get( recoGeom );
00123   theGeomSearchTracker = &(*recoGeom);
00124 
00125   edm::ESHandle<TrackerInteractionGeometry> interGeom;
00126   setup.get<TrackerInteractionGeometryRecord>().get( interGeom );
00127   theTrackerInteractionGeometry = &(*interGeom);
00128 
00129   edm::ESHandle<MagneticFieldMap> fieldMap;
00130   setup.get<MagneticFieldMapRecord>().get(fieldMap);
00131   theMagneticFieldMap = &(*fieldMap);
00132 
00133   thePropagator = new PropagatorWithMaterial(alongMomentum,.000511,&(*theMagField));
00134 
00135   myGSPixelMatcher->setES(theMagneticFieldMap,
00136                           theTrackerGeometry,
00137                           theGeomSearchTracker,
00138                           theTrackerInteractionGeometry);
00139 
00140 }
00141 
00142 void  FastElectronSeedGenerator::run(edm::Event& e,
00143                                       const reco::SuperClusterRefVector &sclRefs,
00144                                       const SiTrackerGSMatchedRecHit2DCollection* theGSRecHits,
00145                                       const edm::SimTrackContainer* theSimTracks,
00146                                       TrajectorySeedCollection *seeds,
00147                                       reco::ElectronSeedCollection & out){
00148 
00149   // Take the seed collection.
00150   theInitialSeedColl=seeds;
00151 
00152   // Get the beam spot
00153   edm::Handle<reco::BeamSpot> recoBeamSpotHandle;
00154   e.getByLabel(theBeamSpot,recoBeamSpotHandle);
00155 
00156   // Get its position
00157   BSPosition_ = recoBeamSpotHandle->position();
00158   double sigmaZ=recoBeamSpotHandle->sigmaZ();
00159   double sigmaZ0Error=recoBeamSpotHandle->sigmaZ0Error();
00160   double sq=sqrt(sigmaZ*sigmaZ+sigmaZ0Error*sigmaZ0Error);
00161   double zmin1 = BSPosition_.z()-3*sq;
00162   double zmax1 = BSPosition_.z()+3*sq;
00163 #ifdef FAMOS_DEBUG
00164   std::cout << "Z Range for pixel matcher : " << zmin1 << " " << BSPosition_.z() << " " << zmax1 << std::endl;
00165 #endif
00166   myGSPixelMatcher->set1stLayerZRange(zmin1,zmax1);
00167 
00168   // A map of vector of pixel seeds, for each clusters
00169   std::map<unsigned,std::vector<reco::ElectronSeed> > myPixelSeeds;
00170 
00171   // No seeding attempted if no hits !
00172   if(theGSRecHits->size() == 0) return;
00173 
00174   if ( !fromTrackerSeeds_ ) {
00175 
00176     // The vector of simTrack Id's carrying GSRecHits
00177     const std::vector<unsigned> theSimTrackIds = theGSRecHits->ids();
00178 
00179     // Loop over the simTrack carrying GSRecHits
00180     for ( unsigned tkId=0;  tkId != theSimTrackIds.size(); ++tkId ) {
00181 
00182       unsigned simTrackId = theSimTrackIds[tkId];
00183       const SimTrack& theSimTrack = (*theSimTracks)[simTrackId];
00184 
00185       // Request a minimum pT for the sim track
00186       if ( theSimTrack.momentum().perp2() < pTMin2 ) continue;
00187 
00188       // Request a minimum number of RecHits (total and in the pixel detector)
00189       unsigned numberOfRecHits = 0;
00190 
00191       // The vector of rechits for seeding
00192 
00193       // 1) Cluster-pixel match seeding:
00194       //    Save a collection of Pixel +TEC +TID hits for seeding electrons
00195       std::vector<unsigned> layerHit(6,static_cast<unsigned>(0));
00196       // const SiTrackerGSMatchedRecHit2D *hit;
00197       TrackerRecHit currentHit;
00198       std::vector<TrackerRecHit> theHits;
00199       TrajectorySeed theTrackerSeed;
00200 
00201       SiTrackerGSMatchedRecHit2DCollection::range theRecHitRange = theGSRecHits->get(simTrackId);
00202       SiTrackerGSMatchedRecHit2DCollection::const_iterator theRecHitRangeIteratorBegin = theRecHitRange.first;
00203       SiTrackerGSMatchedRecHit2DCollection::const_iterator theRecHitRangeIteratorEnd   = theRecHitRange.second;
00204       SiTrackerGSMatchedRecHit2DCollection::const_iterator iterRecHit;
00205       SiTrackerGSMatchedRecHit2DCollection::const_iterator iterRecHit2;
00206 
00207       for ( iterRecHit = theRecHitRangeIteratorBegin;
00208             iterRecHit != theRecHitRangeIteratorEnd;
00209             ++iterRecHit) {
00210         ++numberOfRecHits;
00211 
00212         currentHit = TrackerRecHit(&(*iterRecHit),theTrackerGeometry);
00213         if ( ( currentHit.subDetId() <= 2 ) ||  // Pixel Hits
00214              // Add TID/TEC (optional)
00215              ( searchInTIDTEC &&
00216                ( ( currentHit.subDetId() == 3 &&
00217                    currentHit.ringNumber() < 3 &&
00218                    currentHit.layerNumber() < 3 ) || // TID first two rings, first two layers
00219                  ( currentHit.subDetId() == 6 &&
00220                    currentHit.ringNumber() < 3 &&
00221                    currentHit.layerNumber() < 3 ) ) ) ) // TEC first two rings, first two layers
00222           theHits.push_back(currentHit);
00223       }
00224 
00225       // At least 3 hits
00226       if ( numberOfRecHits < 3 ) continue;
00227 
00228       // At least 2 pixel hits
00229       if ( theHits.size() < 2 ) continue;
00230 
00231       // Loop over clusters
00232 
00233       unsigned csize = sclRefs.size();
00234       for  (unsigned int i=0;i<csize;++i) {
00235 
00236         // Find the pixel seeds (actually only the best one is returned)
00237         LogDebug ("run") << "new cluster, calling addAseedFromThisCluster";
00238         addASeedToThisCluster(sclRefs[i],theHits,theTrackerSeed,myPixelSeeds[i]);
00239 
00240       }
00241 
00242     }
00243   // 2) Check if the seed is in the a-priori seed collection
00244   } else {
00245 
00246     // Loop over the tracker seed
00247 #ifdef FAMOS_DEBUG
00248     std::cout << "We have " << seeds->size() << " tracker seeds!" << std::endl;
00249 #endif
00250     for (unsigned int i=0;i<seeds->size();++i) {
00251 
00252       TrackerRecHit currentHit;
00253       std::vector<TrackerRecHit> theHits;
00254       const TrajectorySeed& theTrackerSeed = (*seeds)[i];
00255       TrajectorySeed::range theSeedRange=theTrackerSeed.recHits();
00256       TrajectorySeed::const_iterator theSeedRangeIteratorBegin = theSeedRange.first;
00257       TrajectorySeed::const_iterator theSeedRangeIteratorEnd   = theSeedRange.second;
00258       TrajectorySeed::const_iterator theSeedItr = theSeedRangeIteratorBegin;
00259 
00260       for ( ; theSeedItr != theSeedRangeIteratorEnd; ++theSeedItr ) {
00261         const SiTrackerGSMatchedRecHit2D * theSeedingRecHit =
00262           (const SiTrackerGSMatchedRecHit2D*) (&(*theSeedItr));
00263         currentHit = TrackerRecHit(theSeedingRecHit,theTrackerGeometry);
00264         theHits.push_back(currentHit);
00265       }
00266 
00267       // Loop over clusters
00268       unsigned csize = sclRefs.size();
00269       for  (unsigned int i=0;i<csize;++i) {
00270 
00271         // Find the pixel seeds (actually only the best one is returned)
00272 #ifdef FAMOS_DEBUG
00273         std::cout << "new cluster, calling addAseedFromThisCluster" << std::endl;
00274 #endif
00275         addASeedToThisCluster(sclRefs[i],theHits,theTrackerSeed,myPixelSeeds[i]);
00276 
00277       }
00278       // End loop over clusters
00279     }
00280     // End loop over seeds
00281   }
00282   // end else
00283 
00284   // Back to the expected collection
00285 
00286   std::map<unsigned,std::vector<reco::ElectronSeed> >::const_iterator px = myPixelSeeds.begin();
00287   std::map<unsigned,std::vector<reco::ElectronSeed> >::const_iterator pxEnd = myPixelSeeds.end();
00288   for ( ; px!=pxEnd; ++px ) {
00289     unsigned nSeeds = (px->second).size();
00290     for ( unsigned ipx = 0; ipx<nSeeds; ++ipx ) {
00291       out.push_back((px->second)[ipx]);
00292       reco::ElectronSeed is = px->second[ipx];
00293     }
00294   }
00295 
00296   LogDebug ("run") << ": For event "<<e.id();
00297   LogDebug ("run") <<"Nr of superclusters: "<<sclRefs.size()
00298                    <<", no. of ElectronSeeds found  = " << out.size();
00299 #ifdef FAMOS_DEBUG
00300   std::cout << ": For event "<<e.id() << std::endl;
00301   std::cout <<"Nr of superclusters: "<<sclRefs.size()
00302             <<", no. of ElectronSeeds found  = " << out.size() << std::endl;
00303 #endif
00304 
00305 }
00306 
00307 void
00308 FastElectronSeedGenerator::addASeedToThisCluster(edm::Ref<reco::SuperClusterCollection> seedCluster,
00309                                                     std::vector<TrackerRecHit>& theHits,
00310                                                     const TrajectorySeed& theTrackerSeed,
00311                                                     std::vector<reco::ElectronSeed>& result)
00312 {
00313 
00314   float clusterEnergy = seedCluster->energy();
00315   GlobalPoint clusterPos(seedCluster->position().x(),
00316                          seedCluster->position().y(),
00317                          seedCluster->position().z());
00318   const GlobalPoint vertexPos(BSPosition_.x(),BSPosition_.y(),BSPosition_.z());
00319 
00320 #ifdef FAMOS_DEBUG
00321   std::cout << "[FastElectronSeedGenerator::seedsFromThisCluster] "
00322             << "new supercluster with energy: " << clusterEnergy << std::endl;
00323   std::cout << "[FastElectronSeedGenerator::seedsFromThisCluster] "
00324             << "and position: " << clusterPos << std::endl;
00325   std::cout << "Vertex position : " << vertexPos << std::endl;
00326 #endif
00327 
00328   //Here change the deltaPhi window of the first pixel layer in function of the seed pT
00329   if (dynamicphiroad_) {
00330     float clusterEnergyT = clusterEnergy*sin(seedCluster->position().theta()) ;
00331 
00332     float deltaPhi1 = 0.875/clusterEnergyT + 0.055;
00333     if (clusterEnergyT < lowPtThreshold_) deltaPhi1= deltaPhi1Low_;
00334     if (clusterEnergyT > highPtThreshold_) deltaPhi1= deltaPhi1High_;
00335 
00336     float ephimin1 = -deltaPhi1*sizeWindowENeg_ ;
00337     float ephimax1 =  deltaPhi1*(1.-sizeWindowENeg_);
00338     float pphimin1 = -deltaPhi1*(1.-sizeWindowENeg_);
00339     float pphimax1 =  deltaPhi1*sizeWindowENeg_;
00340 
00341     float phimin2  = -deltaPhi2_/2.;
00342     float phimax2  =  deltaPhi2_/2.;
00343 
00344     myGSPixelMatcher->set1stLayer(ephimin1,ephimax1,pphimin1,pphimax1);
00345     myGSPixelMatcher->set2ndLayer(phimin2,phimax2);
00346 
00347   }
00348 
00349 
00350 
00351   PropagationDirection dir = alongMomentum;
00352 
00353   // Find the best pixel pair compatible with the cluster
00354   std::vector<std::pair<ConstRecHitPointer,ConstRecHitPointer> > compatPixelHits =
00355     myGSPixelMatcher->compatibleHits(clusterPos, vertexPos, clusterEnergy, theHits);
00356 
00357   // The corresponding origin vertex
00358   double vertexZ = myGSPixelMatcher->getVertex();
00359   GlobalPoint theVertex(BSPosition_.x(),BSPosition_.y(),vertexZ);
00360 
00361   // Create the Electron pixel seed.
00362   if (!compatPixelHits.empty() ) {
00363 #ifdef FAMOS_DEBUG
00364     std::cout << "[FastElectronSeedGenerator::seedsFromThisCluster] "
00365               << " electron compatible hits found " << std::endl;
00366 #endif
00367     // Pixel-matching case: create the seed from scratch
00368     if (!fromTrackerSeeds_) {
00369 
00370       std::vector<std::pair<ConstRecHitPointer,ConstRecHitPointer> >::iterator v;
00371       for (v = compatPixelHits.begin(); v != compatPixelHits.end(); ++v ) {
00372 
00373                 bool valid = prepareElTrackSeed(v->first,v->second, theVertex);
00374                 if (valid) {
00375                   reco::ElectronSeed s(*pts_,recHits_,dir) ;
00376                   s.setCaloCluster(reco::ElectronSeed::CaloClusterRef(seedCluster)) ;
00377                   result.push_back(s);
00378                   delete pts_;
00379                   pts_=0;
00380             }
00381 
00382       }
00383 
00384     // Here we take instead the seed from a-priori seed collection
00385     } else {
00386 
00387       reco::ElectronSeed s(theTrackerSeed);
00388           s.setCaloCluster(reco::ElectronSeed::CaloClusterRef(seedCluster)) ;
00389           result.push_back(s);
00390     }
00391 
00392   }
00393 
00394 #ifdef FAMOS_DEBUG
00395     else
00396       std::cout << "[FastElectronSeedGenerator::seedsFromThisCluster] "
00397                 << " No electron compatible hits found " << std::endl;
00398 #endif
00399 
00400 
00401   // And return !
00402   return ;
00403 
00404 }
00405 
00406 bool FastElectronSeedGenerator::prepareElTrackSeed(ConstRecHitPointer innerhit,
00407                                                       ConstRecHitPointer outerhit,
00408                                                       const GlobalPoint& vertexPos)
00409 {
00410 
00411   // debug prints
00412   LogDebug("") <<"[FastElectronSeedGenerator::prepareElTrackSeed] "
00413                << "inner PixelHit   x,y,z "<<innerhit->globalPosition();
00414   LogDebug("") <<"[FastElectronSeedGenerator::prepareElTrackSeed] "
00415                << "outer PixelHit   x,y,z "<<outerhit->globalPosition();
00416 
00417   pts_=0;
00418   // make a spiral from the two hits and the vertex position
00419   FastHelix helix(outerhit->globalPosition(),innerhit->globalPosition(),vertexPos,*theSetup);
00420   if ( !helix.isValid()) return false;
00421 
00422   FreeTrajectoryState fts = helix.stateAtVertex();
00423 
00424   // Give infinite errors to start the fit (no pattern recognition here).
00425   AlgebraicSymMatrix55 errorMatrix= AlgebraicMatrixID();
00426   fts.setCurvilinearError(errorMatrix*100.);
00427 
00428    TrajectoryStateOnSurface propagatedState = thePropagator->propagate(fts,innerhit->det()->surface()) ;
00429   if (!propagatedState.isValid()) return false;
00430 
00431   // The persitent trajectory state
00432   pts_ =  transformer_.persistentState(propagatedState, innerhit->geographicalId().rawId());
00433 
00434   // The corresponding rechits
00435   recHits_.clear();
00436   recHits_.push_back(innerhit->hit()->clone());
00437   recHits_.push_back(outerhit->hit()->clone());
00438 
00439 
00440   return true;
00441 
00442 }
00443