CMS 3D CMS Logo

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