00001
00002 #include "RecoEgamma/EgammaElectronAlgos/interface/GsfElectronAlgo.h"
00003 #include "RecoEgamma/EgammaElectronAlgos/interface/EgAmbiguityTools.h"
00004 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronClassification.h"
00005 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronMomentumCorrector.h"
00006 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronEnergyCorrector.h"
00007 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronUtilities.h"
00008 #include "RecoEgamma/EgammaTools/interface/ConversionFinder.h"
00009
00010 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterFunctionFactory.h"
00011 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h"
00012
00013 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
00014 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
00015 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00016 #include "DataFormats/TrackCandidate/interface/TrackCandidate.h"
00017 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
00018 #include "DataFormats/Math/interface/LorentzVector.h"
00019 #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
00020 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00021 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00022 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00023 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00024 #include "DataFormats/EcalRecHit/interface/EcalRecHit.h"
00025 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00026 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00027 #include "DataFormats/Provenance/interface/Provenance.h"
00028
00029 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00030 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00031 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00032 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00033 #include "Geometry/Records/interface/CaloTopologyRecord.h"
00034
00035 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00036 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00037 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00038 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00039 #include "TrackingTools/GsfTools/interface/MultiTrajectoryStateTransform.h"
00040 #include "TrackingTools/GsfTools/interface/MultiTrajectoryStateMode.h"
00041 #include "TrackingTools/TransientTrackingRecHit/interface/RecHitComparatorByPosition.h"
00042
00043 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00044 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00045
00046 #include "CondFormats/DataRecord/interface/EcalChannelStatusRcd.h"
00047
00048 #include "Geometry/CommonDetUnit/interface/TrackingGeometry.h"
00049 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00050
00051
00052 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00053
00054
00055 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00056
00057 #include <TMath.h>
00058 #include <Math/VectorUtil.h>
00059 #include <Math/Point3D.h>
00060 #include <sstream>
00061 #include <algorithm>
00062
00063
00064 using namespace edm ;
00065 using namespace std ;
00066 using namespace reco ;
00067
00068
00069
00070
00071
00072
00073
00074 struct GsfElectronAlgo::GeneralData
00075 {
00076
00077 GeneralData
00078 ( const InputTagsConfiguration &,
00079 const StrategyConfiguration &,
00080 const CutsConfiguration & cutsCfg,
00081 const CutsConfiguration & cutsCfgPflow,
00082 const ElectronHcalHelper::Configuration & hcalCfg,
00083 const ElectronHcalHelper::Configuration & hcalCfgPflow,
00084 const IsolationConfiguration &,
00085 const SpikeConfiguration &,
00086 EcalClusterFunctionBaseClass * superClusterErrorFunction ) ;
00087 ~GeneralData() ;
00088
00089
00090 const InputTagsConfiguration inputCfg ;
00091 const StrategyConfiguration strategyCfg ;
00092 const CutsConfiguration cutsCfg ;
00093 const CutsConfiguration cutsCfgPflow ;
00094 const IsolationConfiguration isoCfg ;
00095 const SpikeConfiguration spikeCfg ;
00096
00097
00098 ElectronHcalHelper * hcalHelper, * hcalHelperPflow ;
00099 EcalClusterFunctionBaseClass * superClusterErrorFunction ;
00100 } ;
00101
00102 GsfElectronAlgo::GeneralData::GeneralData
00103 ( const InputTagsConfiguration & inputConfig,
00104 const StrategyConfiguration & strategyConfig,
00105 const CutsConfiguration & cutsConfig,
00106 const CutsConfiguration & cutsConfigPflow,
00107 const ElectronHcalHelper::Configuration & hcalConfig,
00108 const ElectronHcalHelper::Configuration & hcalConfigPflow,
00109 const IsolationConfiguration & isoConfig,
00110 const SpikeConfiguration & spikeConfig,
00111 EcalClusterFunctionBaseClass * superClusterErrorFunc
00112 )
00113 : inputCfg(inputConfig),
00114 strategyCfg(strategyConfig),
00115 cutsCfg(cutsConfig),
00116 cutsCfgPflow(cutsConfigPflow),
00117 isoCfg(isoConfig),
00118 spikeCfg(spikeConfig),
00119 hcalHelper(new ElectronHcalHelper(hcalConfig)),
00120 hcalHelperPflow(new ElectronHcalHelper(hcalConfigPflow)),
00121 superClusterErrorFunction(superClusterErrorFunc)
00122 {}
00123
00124 GsfElectronAlgo::GeneralData::~GeneralData()
00125 {
00126 delete hcalHelper ;
00127 delete hcalHelperPflow ;
00128 }
00129
00130
00131
00132
00133
00134 struct GsfElectronAlgo::EventSetupData
00135 {
00136 EventSetupData() ;
00137 ~EventSetupData() ;
00138
00139 unsigned long long cacheIDGeom ;
00140 unsigned long long cacheIDTopo ;
00141 unsigned long long cacheIDTDGeom ;
00142 unsigned long long cacheIDMagField ;
00143 unsigned long long cacheChStatus ;
00144 unsigned long long cacheSevLevel ;
00145
00146 edm::ESHandle<MagneticField> magField ;
00147 edm::ESHandle<CaloGeometry> caloGeom ;
00148 edm::ESHandle<CaloTopology> caloTopo ;
00149 edm::ESHandle<TrackerGeometry> trackerHandle ;
00150 edm::ESHandle<EcalChannelStatus> chStatus ;
00151
00152
00153 const MultiTrajectoryStateTransform * mtsTransform ;
00154 GsfConstraintAtVertex * constraintAtVtx ;
00155 const MultiTrajectoryStateMode * mtsMode ;
00156 } ;
00157
00158 GsfElectronAlgo::EventSetupData::EventSetupData()
00159 : cacheIDGeom(0), cacheIDTopo(0), cacheIDTDGeom(0), cacheIDMagField(0),cacheChStatus(0),
00160 mtsTransform(0), constraintAtVtx(0), mtsMode(new MultiTrajectoryStateMode)
00161 {}
00162
00163 GsfElectronAlgo::EventSetupData::~EventSetupData()
00164 {
00165 delete mtsMode ;
00166 delete constraintAtVtx ;
00167 delete mtsTransform ;
00168 }
00169
00170
00171
00172
00173
00174
00175 struct GsfElectronAlgo::EventData
00176 {
00177
00178 edm::Event * event ;
00179 const reco::BeamSpot * beamspot ;
00180 GsfElectronPtrCollection * electrons ;
00181
00182 EventData() ;
00183 ~EventData() ;
00184
00185
00186 void retreiveOriginalTrackCollections
00187 ( const reco::TrackRef &, const reco::GsfTrackRef & ) ;
00188
00189
00190 edm::Handle<reco::GsfElectronCollection> previousElectrons ;
00191 edm::Handle<reco::GsfElectronCoreCollection> coreElectrons ;
00192 edm::Handle<EcalRecHitCollection> reducedEBRecHits ;
00193 edm::Handle<EcalRecHitCollection> reducedEERecHits ;
00194 edm::Handle<reco::TrackCollection> currentCtfTracks ;
00195 edm::Handle<CaloTowerCollection> towers ;
00196 edm::Handle<edm::ValueMap<float> > pfMva ;
00197 edm::Handle<reco::ElectronSeedCollection> seeds ;
00198 bool originalCtfTrackCollectionRetreived ;
00199 bool originalGsfTrackCollectionRetreived ;
00200 edm::Handle<reco::TrackCollection> originalCtfTracks ;
00201 edm::Handle<reco::GsfTrackCollection> originalGsfTracks ;
00202
00203
00204 ElectronTkIsolation * tkIsolation03, * tkIsolation04 ;
00205 EgammaTowerIsolation * hadDepth1Isolation03, * hadDepth1Isolation04 ;
00206 EgammaTowerIsolation * hadDepth2Isolation03, * hadDepth2Isolation04 ;
00207 EcalRecHitMetaCollection * ecalBarrelHitsMeta ;
00208 EcalRecHitMetaCollection * ecalEndcapHitsMeta ;
00209 EgammaRecHitIsolation * ecalBarrelIsol03, * ecalBarrelIsol04 ;
00210 EgammaRecHitIsolation * ecalEndcapIsol03, * ecalEndcapIsol04 ;
00211 } ;
00212
00213 GsfElectronAlgo::EventData::EventData()
00214 : event(0), beamspot(0),
00215 originalCtfTrackCollectionRetreived(false),
00216 originalGsfTrackCollectionRetreived(false),
00217 tkIsolation03(0), tkIsolation04(0),
00218 hadDepth1Isolation03(0), hadDepth1Isolation04(0),
00219 hadDepth2Isolation03(0), hadDepth2Isolation04(0),
00220 ecalBarrelHitsMeta(0), ecalEndcapHitsMeta(0),
00221 ecalBarrelIsol03(0), ecalBarrelIsol04(0),
00222 ecalEndcapIsol03(0), ecalEndcapIsol04(0)
00223 {
00224 electrons = new GsfElectronPtrCollection ;
00225 }
00226
00227 GsfElectronAlgo::EventData::~EventData()
00228 {
00229 delete tkIsolation03 ;
00230 delete tkIsolation04 ;
00231 delete hadDepth1Isolation03 ;
00232 delete hadDepth1Isolation04 ;
00233 delete hadDepth2Isolation03 ;
00234 delete hadDepth2Isolation04 ;
00235 delete ecalBarrelHitsMeta ;
00236 delete ecalEndcapHitsMeta ;
00237 delete ecalBarrelIsol03 ;
00238 delete ecalBarrelIsol04 ;
00239 delete ecalEndcapIsol03 ;
00240 delete ecalEndcapIsol04 ;
00241
00242 GsfElectronPtrCollection::const_iterator it ;
00243 for ( it = electrons->begin() ; it != electrons->end() ; it++ )
00244 { delete (*it) ; }
00245 delete electrons ;
00246 }
00247
00248 void GsfElectronAlgo::EventData::retreiveOriginalTrackCollections
00249 ( const reco::TrackRef & ctfTrack, const reco::GsfTrackRef & gsfTrack )
00250 {
00251 if ((!originalCtfTrackCollectionRetreived)&&(ctfTrack.isNonnull()))
00252 {
00253 event->get(ctfTrack.id(),originalCtfTracks) ;
00254 originalCtfTrackCollectionRetreived = true ;
00255 }
00256 if ((!originalGsfTrackCollectionRetreived)&&(gsfTrack.isNonnull()))
00257 {
00258 event->get(gsfTrack.id(),originalGsfTracks) ;
00259 originalGsfTrackCollectionRetreived = true ;
00260 }
00261 }
00262
00263
00264
00265
00266
00267
00268 struct GsfElectronAlgo::ElectronData
00269 {
00270
00271 const reco::GsfElectronCoreRef coreRef ;
00272 const reco::GsfTrackRef gsfTrackRef ;
00273 const reco::SuperClusterRef superClusterRef ;
00274 reco::TrackRef ctfTrackRef ;
00275 float shFracInnerHits ;
00276 const reco::BeamSpot beamSpot ;
00277
00278
00279 ElectronData
00280 ( const reco::GsfElectronCoreRef & core,
00281 const reco::BeamSpot & bs ) ;
00282 ~ElectronData() ;
00283
00284
00285 void checkCtfTrack( edm::Handle<reco::TrackCollection> currentCtfTracks ) ;
00286 void computeCharge( int & charge, reco::GsfElectron::ChargeInfo & info ) ;
00287 CaloClusterPtr getEleBasicCluster( const MultiTrajectoryStateTransform * ) ;
00288 bool calculateTSOS( const MultiTrajectoryStateTransform *, GsfConstraintAtVertex * ) ;
00289 void calculateMode( const MultiTrajectoryStateMode * mtsMode ) ;
00290 Candidate::LorentzVector computeMomemtum() ;
00291
00292
00293 TrajectoryStateOnSurface innTSOS ;
00294 TrajectoryStateOnSurface outTSOS ;
00295 TrajectoryStateOnSurface vtxTSOS ;
00296 TrajectoryStateOnSurface sclTSOS ;
00297 TrajectoryStateOnSurface seedTSOS ;
00298 TrajectoryStateOnSurface eleTSOS ;
00299 TrajectoryStateOnSurface constrainedVtxTSOS ;
00300
00301
00302 GlobalVector innMom, seedMom, eleMom, sclMom, vtxMom, outMom ;
00303 GlobalPoint innPos, seedPos, elePos, sclPos, vtxPos, outPos ;
00304 GlobalVector vtxMomWithConstraint ;
00305 } ;
00306
00307 GsfElectronAlgo::ElectronData::ElectronData
00308 ( const reco::GsfElectronCoreRef & core,
00309 const reco::BeamSpot & bs )
00310 : coreRef(core),
00311 gsfTrackRef(coreRef->gsfTrack()),
00312 superClusterRef(coreRef->superCluster()),
00313 ctfTrackRef(coreRef->ctfTrack()), shFracInnerHits(coreRef->ctfGsfOverlap()),
00314 beamSpot(bs)
00315 {}
00316
00317 GsfElectronAlgo::ElectronData::~ElectronData()
00318 {}
00319
00320 void GsfElectronAlgo::ElectronData::checkCtfTrack( edm::Handle<reco::TrackCollection> currentCtfTracks )
00321 {
00322 if (!ctfTrackRef.isNull()) return ;
00323
00324
00325
00326 shFracInnerHits = 0 ;
00327 const TrackCollection * ctfTrackCollection = currentCtfTracks.product() ;
00328
00329
00330 const HitPattern & gsfHitPattern = gsfTrackRef->hitPattern() ;
00331
00332 unsigned int counter ;
00333 TrackCollection::const_iterator ctfTkIter ;
00334 for ( ctfTkIter = ctfTrackCollection->begin() , counter = 0 ;
00335 ctfTkIter != ctfTrackCollection->end() ; ctfTkIter++, counter++ )
00336 {
00337
00338 double dEta = gsfTrackRef->eta() - ctfTkIter->eta() ;
00339 double dPhi = gsfTrackRef->phi() - ctfTkIter->phi() ;
00340 double pi = acos(-1.);
00341 if(std::abs(dPhi) > pi) dPhi = 2*pi - std::abs(dPhi) ;
00342
00343
00344 if (sqrt(dEta*dEta + dPhi*dPhi) > 0.3) continue ;
00345
00346 unsigned int shared = 0 ;
00347 int gsfHitCounter = 0 ;
00348 int numGsfInnerHits = 0 ;
00349 int numCtfInnerHits = 0 ;
00350
00351
00352 const HitPattern & ctfHitPattern = ctfTkIter->hitPattern() ;
00353
00354 trackingRecHit_iterator elHitsIt ;
00355 for ( elHitsIt = gsfTrackRef->recHitsBegin() ;
00356 elHitsIt != gsfTrackRef->recHitsEnd() ;
00357 elHitsIt++, gsfHitCounter++ )
00358 {
00359 if (!((**elHitsIt).isValid()))
00360 { continue ; }
00361
00362
00363 uint32_t gsfHit = gsfHitPattern.getHitPattern(gsfHitCounter) ;
00364 if (!(gsfHitPattern.pixelHitFilter(gsfHit) ||
00365 gsfHitPattern.stripTIBHitFilter(gsfHit) ||
00366 gsfHitPattern.stripTIDHitFilter(gsfHit) ) )
00367 { continue ; }
00368
00369 numGsfInnerHits++ ;
00370
00371 int ctfHitsCounter = 0 ;
00372 numCtfInnerHits = 0 ;
00373 trackingRecHit_iterator ctfHitsIt ;
00374 for ( ctfHitsIt = ctfTkIter->recHitsBegin() ;
00375 ctfHitsIt != ctfTkIter->recHitsEnd() ;
00376 ctfHitsIt++, ctfHitsCounter++ )
00377 {
00378 if(!((**ctfHitsIt).isValid()))
00379 { continue ; }
00380
00381 uint32_t ctfHit = ctfHitPattern.getHitPattern(ctfHitsCounter);
00382 if( !(ctfHitPattern.pixelHitFilter(ctfHit) ||
00383 ctfHitPattern.stripTIBHitFilter(ctfHit) ||
00384 ctfHitPattern.stripTIDHitFilter(ctfHit) ) )
00385 { continue ; }
00386
00387 numCtfInnerHits++ ;
00388
00389 if( (**elHitsIt).sharesInput(&(**ctfHitsIt),TrackingRecHit::all) )
00390 {
00391 shared++ ;
00392 break ;
00393 }
00394
00395 }
00396
00397 }
00398
00399 if ((numGsfInnerHits==0)||(numCtfInnerHits==0))
00400 { continue ; }
00401
00402 if ( static_cast<float>(shared)/min(numGsfInnerHits,numCtfInnerHits) > shFracInnerHits )
00403 {
00404 shFracInnerHits = static_cast<float>(shared)/min(numGsfInnerHits, numCtfInnerHits);
00405 ctfTrackRef = TrackRef(currentCtfTracks,counter);
00406 }
00407 }
00408 }
00409
00410 void GsfElectronAlgo::ElectronData::computeCharge
00411 ( int & charge, GsfElectron::ChargeInfo & info )
00412 {
00413
00414 GlobalPoint orig, scpos ;
00415 ele_convert(beamSpot.position(),orig) ;
00416 ele_convert(superClusterRef->position(),scpos) ;
00417 GlobalVector scvect(scpos-orig) ;
00418 GlobalPoint inntkpos = innTSOS.globalPosition() ;
00419 GlobalVector inntkvect = GlobalVector(inntkpos-orig) ;
00420 float dPhiInnEle=normalized_phi(scvect.phi()-inntkvect.phi()) ;
00421 if(dPhiInnEle>0) info.scPixCharge = -1 ;
00422 else info.scPixCharge = 1 ;
00423
00424
00425 int chargeGsf = gsfTrackRef->charge() ;
00426 info.isGsfScPixConsistent = ((chargeGsf*info.scPixCharge)>0) ;
00427 info.isGsfCtfConsistent = (ctfTrackRef.isNonnull()&&((chargeGsf*ctfTrackRef->charge())>0)) ;
00428 info.isGsfCtfScPixConsistent = (info.isGsfScPixConsistent&&info.isGsfCtfConsistent) ;
00429
00430
00431 if (info.isGsfScPixConsistent||ctfTrackRef.isNull())
00432 { charge = info.scPixCharge ; }
00433 else
00434 { charge = ctfTrackRef->charge() ; }
00435 }
00436
00437 CaloClusterPtr GsfElectronAlgo::ElectronData::getEleBasicCluster
00438 ( const MultiTrajectoryStateTransform * mtsTransform )
00439 {
00440 CaloClusterPtr eleRef ;
00441 TrajectoryStateOnSurface tempTSOS ;
00442 TrajectoryStateOnSurface outTSOS = mtsTransform->outerStateOnSurface(*gsfTrackRef) ;
00443 float dphimin = 1.e30 ;
00444 for (CaloCluster_iterator bc=superClusterRef->clustersBegin(); bc!=superClusterRef->clustersEnd(); bc++)
00445 {
00446 GlobalPoint posclu((*bc)->position().x(),(*bc)->position().y(),(*bc)->position().z()) ;
00447 tempTSOS = mtsTransform->extrapolatedState(outTSOS,posclu) ;
00448 if (!tempTSOS.isValid()) tempTSOS=outTSOS ;
00449 GlobalPoint extrap = tempTSOS.globalPosition() ;
00450 float dphi = EleRelPointPair(posclu,extrap,beamSpot.position()).dPhi() ;
00451 if (std::abs(dphi)<dphimin)
00452 {
00453 dphimin = std::abs(dphi) ;
00454 eleRef = (*bc);
00455 eleTSOS = tempTSOS ;
00456 }
00457 }
00458 return eleRef ;
00459 }
00460
00461 bool GsfElectronAlgo::ElectronData::calculateTSOS
00462 ( const MultiTrajectoryStateTransform * mtsTransform, GsfConstraintAtVertex * constraintAtVtx )
00463 {
00464
00465 innTSOS = mtsTransform->innerStateOnSurface(*gsfTrackRef);
00466 if (!innTSOS.isValid()) return false;
00467
00468
00469
00470 GlobalPoint bsPos ;
00471 ele_convert(beamSpot.position(),bsPos) ;
00472 vtxTSOS = mtsTransform->extrapolatedState(innTSOS,bsPos) ;
00473 if (!vtxTSOS.isValid()) vtxTSOS=innTSOS;
00474
00475
00476 outTSOS = mtsTransform->outerStateOnSurface(*gsfTrackRef);
00477 if (!outTSOS.isValid()) return false;
00478
00479
00480 seedTSOS = mtsTransform->extrapolatedState(outTSOS,
00481 GlobalPoint(superClusterRef->seed()->position().x(),
00482 superClusterRef->seed()->position().y(),
00483 superClusterRef->seed()->position().z()));
00484 if (!seedTSOS.isValid()) seedTSOS=outTSOS;
00485
00486
00487 sclTSOS = mtsTransform->extrapolatedState(innTSOS,GlobalPoint(superClusterRef->x(),superClusterRef->y(),superClusterRef->z()));
00488 if (!sclTSOS.isValid()) sclTSOS=outTSOS;
00489
00490
00491 constrainedVtxTSOS = constraintAtVtx->constrainAtBeamSpot(*gsfTrackRef,beamSpot);
00492
00493 return true ;
00494 }
00495
00496 void GsfElectronAlgo::ElectronData::calculateMode( const MultiTrajectoryStateMode * mtsMode )
00497 {
00498 mtsMode->momentumFromModeCartesian(innTSOS,innMom) ;
00499 mtsMode->positionFromModeCartesian(innTSOS,innPos) ;
00500 mtsMode->momentumFromModeCartesian(seedTSOS,seedMom) ;
00501 mtsMode->positionFromModeCartesian(seedTSOS,seedPos) ;
00502 mtsMode->momentumFromModeCartesian(eleTSOS,eleMom) ;
00503 mtsMode->positionFromModeCartesian(eleTSOS,elePos) ;
00504 mtsMode->momentumFromModeCartesian(sclTSOS,sclMom) ;
00505 mtsMode->positionFromModeCartesian(sclTSOS,sclPos) ;
00506 mtsMode->momentumFromModeCartesian(vtxTSOS,vtxMom) ;
00507 mtsMode->positionFromModeCartesian(vtxTSOS,vtxPos) ;
00508 mtsMode->momentumFromModeCartesian(outTSOS,outMom);
00509 mtsMode->positionFromModeCartesian(outTSOS,outPos) ;
00510 mtsMode->momentumFromModeCartesian(constrainedVtxTSOS,vtxMomWithConstraint);
00511 }
00512
00513 Candidate::LorentzVector GsfElectronAlgo::ElectronData::computeMomemtum()
00514 {
00515 double scale = superClusterRef->energy()/vtxMom.mag() ;
00516 return Candidate::LorentzVector
00517 ( vtxMom.x()*scale,vtxMom.y()*scale,vtxMom.z()*scale,
00518 superClusterRef->energy() ) ;
00519 }
00520
00521
00522
00523
00524
00525
00526 GsfElectronAlgo::GsfElectronAlgo
00527 ( const InputTagsConfiguration & inputCfg,
00528 const StrategyConfiguration & strategyCfg,
00529 const CutsConfiguration & cutsCfg,
00530 const CutsConfiguration & cutsCfgPflow,
00531 const ElectronHcalHelper::Configuration & hcalCfg,
00532 const ElectronHcalHelper::Configuration & hcalCfgPflow,
00533 const IsolationConfiguration & isoCfg,
00534 const SpikeConfiguration & spikeCfg,
00535 EcalClusterFunctionBaseClass * superClusterErrorFunction
00536 )
00537 : generalData_(new GeneralData(inputCfg,strategyCfg,cutsCfg,cutsCfgPflow,hcalCfg,hcalCfgPflow,isoCfg,spikeCfg,superClusterErrorFunction)),
00538 eventSetupData_(new EventSetupData),
00539 eventData_(0), electronData_(0)
00540 {}
00541
00542 GsfElectronAlgo::~GsfElectronAlgo()
00543 {
00544 delete generalData_ ;
00545 delete eventSetupData_ ;
00546 delete eventData_ ;
00547 delete electronData_ ;
00548 }
00549
00550 void GsfElectronAlgo::checkSetup( const edm::EventSetup & es )
00551 {
00552
00553 bool updateField(false);
00554 if (eventSetupData_->cacheIDMagField!=es.get<IdealMagneticFieldRecord>().cacheIdentifier()){
00555 updateField = true;
00556 eventSetupData_->cacheIDMagField=es.get<IdealMagneticFieldRecord>().cacheIdentifier();
00557 es.get<IdealMagneticFieldRecord>().get(eventSetupData_->magField);
00558 }
00559
00560 bool updateGeometry(false);
00561 if (eventSetupData_->cacheIDTDGeom!=es.get<TrackerDigiGeometryRecord>().cacheIdentifier()){
00562 updateGeometry = true;
00563 eventSetupData_->cacheIDTDGeom=es.get<TrackerDigiGeometryRecord>().cacheIdentifier();
00564 es.get<TrackerDigiGeometryRecord>().get(eventSetupData_->trackerHandle);
00565 }
00566
00567 if ( updateField || updateGeometry ) {
00568 delete eventSetupData_->mtsTransform ;
00569 eventSetupData_->mtsTransform = new MultiTrajectoryStateTransform(eventSetupData_->trackerHandle.product(),eventSetupData_->magField.product());
00570 delete eventSetupData_->constraintAtVtx ;
00571 eventSetupData_->constraintAtVtx = new GsfConstraintAtVertex(es) ;
00572 }
00573
00574 if (eventSetupData_->cacheIDGeom!=es.get<CaloGeometryRecord>().cacheIdentifier()){
00575 eventSetupData_->cacheIDGeom=es.get<CaloGeometryRecord>().cacheIdentifier();
00576 es.get<CaloGeometryRecord>().get(eventSetupData_->caloGeom);
00577 }
00578
00579 if (eventSetupData_->cacheIDTopo!=es.get<CaloTopologyRecord>().cacheIdentifier()){
00580 eventSetupData_->cacheIDTopo=es.get<CaloTopologyRecord>().cacheIdentifier();
00581 es.get<CaloTopologyRecord>().get(eventSetupData_->caloTopo);
00582 }
00583
00584 generalData_->hcalHelper->checkSetup(es) ;
00585 generalData_->hcalHelperPflow->checkSetup(es) ;
00586
00587 if (generalData_->superClusterErrorFunction)
00588 { generalData_->superClusterErrorFunction->init(es) ; }
00589
00590
00591 if(eventSetupData_->cacheChStatus!=es.get<EcalChannelStatusRcd>().cacheIdentifier()){
00592 eventSetupData_->cacheChStatus=es.get<EcalChannelStatusRcd>().cacheIdentifier();
00593 es.get<EcalChannelStatusRcd>().get(eventSetupData_->chStatus);
00594 }
00595
00596
00597
00598
00599
00600 }
00601
00602 void GsfElectronAlgo::copyElectrons( GsfElectronCollection & outEle )
00603 {
00604 GsfElectronPtrCollection::const_iterator it ;
00605 for
00606 ( it = eventData_->electrons->begin() ;
00607 it != eventData_->electrons->end() ;
00608 it++ )
00609 { outEle.push_back(**it) ; }
00610 }
00611
00612 void GsfElectronAlgo::beginEvent( edm::Event & event )
00613 {
00614 if (eventData_!=0)
00615 { throw cms::Exception("GsfElectronAlgo|InternalError")<<"unexpected event data" ; }
00616 eventData_ = new EventData ;
00617
00618
00619 eventData_->event = &event ;
00620 event.getByLabel(generalData_->inputCfg.previousGsfElectrons,eventData_->previousElectrons) ;
00621 event.getByLabel(generalData_->inputCfg.gsfElectronCores,eventData_->coreElectrons) ;
00622 event.getByLabel(generalData_->inputCfg.ctfTracks,eventData_->currentCtfTracks) ;
00623 event.getByLabel(generalData_->inputCfg.reducedBarrelRecHitCollection,eventData_->reducedEBRecHits) ;
00624 event.getByLabel(generalData_->inputCfg.reducedEndcapRecHitCollection,eventData_->reducedEERecHits) ;
00625 event.getByLabel(generalData_->inputCfg.hcalTowersTag,eventData_->towers) ;
00626 event.getByLabel(generalData_->inputCfg.pfMVA,eventData_->pfMva) ;
00627 event.getByLabel(generalData_->inputCfg.seedsTag,eventData_->seeds) ;
00628
00629
00630 edm::Handle<reco::BeamSpot> recoBeamSpotHandle ;
00631 event.getByLabel(generalData_->inputCfg.beamSpotTag,recoBeamSpotHandle) ;
00632 eventData_->beamspot = recoBeamSpotHandle.product() ;
00633
00634
00635 generalData_->hcalHelper->readEvent(event) ;
00636 generalData_->hcalHelperPflow->readEvent(event) ;
00637
00638
00639 float extRadiusSmall=0.3, extRadiusLarge=0.4 ;
00640 float intRadiusBarrel=generalData_->isoCfg.intRadiusBarrelTk, intRadiusEndcap=generalData_->isoCfg.intRadiusEndcapTk, stripBarrel=generalData_->isoCfg.stripBarrelTk, stripEndcap=generalData_->isoCfg.stripEndcapTk ;
00641 float ptMin=generalData_->isoCfg.ptMinTk, maxVtxDist=generalData_->isoCfg.maxVtxDistTk, drb=generalData_->isoCfg.maxDrbTk;
00642 eventData_->tkIsolation03 = new ElectronTkIsolation(extRadiusSmall,intRadiusBarrel,intRadiusEndcap,stripBarrel,stripEndcap,ptMin,maxVtxDist,drb,eventData_->currentCtfTracks.product(),eventData_->beamspot->position()) ;
00643 eventData_->tkIsolation04 = new ElectronTkIsolation(extRadiusLarge,intRadiusBarrel,intRadiusEndcap,stripBarrel,stripEndcap,ptMin,maxVtxDist,drb,eventData_->currentCtfTracks.product(),eventData_->beamspot->position()) ;
00644
00645 float egHcalIsoConeSizeOutSmall=0.3, egHcalIsoConeSizeOutLarge=0.4;
00646 float egHcalIsoConeSizeIn=generalData_->isoCfg.intRadiusHcal,egHcalIsoPtMin=generalData_->isoCfg.etMinHcal;
00647 int egHcalDepth1=1, egHcalDepth2=2;
00648 eventData_->hadDepth1Isolation03 = new EgammaTowerIsolation(egHcalIsoConeSizeOutSmall,egHcalIsoConeSizeIn,egHcalIsoPtMin,egHcalDepth1,eventData_->towers.product()) ;
00649 eventData_->hadDepth2Isolation03 = new EgammaTowerIsolation(egHcalIsoConeSizeOutSmall,egHcalIsoConeSizeIn,egHcalIsoPtMin,egHcalDepth2,eventData_->towers.product()) ;
00650 eventData_->hadDepth1Isolation04 = new EgammaTowerIsolation(egHcalIsoConeSizeOutLarge,egHcalIsoConeSizeIn,egHcalIsoPtMin,egHcalDepth1,eventData_->towers.product()) ;
00651 eventData_->hadDepth2Isolation04 = new EgammaTowerIsolation(egHcalIsoConeSizeOutLarge,egHcalIsoConeSizeIn,egHcalIsoPtMin,egHcalDepth2,eventData_->towers.product()) ;
00652
00653 float egIsoConeSizeOutSmall=0.3, egIsoConeSizeOutLarge=0.4, egIsoJurassicWidth=generalData_->isoCfg.jurassicWidth;
00654 float egIsoPtMinBarrel=generalData_->isoCfg.etMinBarrel,egIsoEMinBarrel=generalData_->isoCfg.eMinBarrel, egIsoConeSizeInBarrel=generalData_->isoCfg.intRadiusEcalBarrel;
00655 float egIsoPtMinEndcap=generalData_->isoCfg.etMinEndcaps,egIsoEMinEndcap=generalData_->isoCfg.eMinEndcaps, egIsoConeSizeInEndcap=generalData_->isoCfg.intRadiusEcalEndcaps;
00656 eventData_->ecalBarrelHitsMeta = new EcalRecHitMetaCollection(*eventData_->reducedEBRecHits) ;
00657 eventData_->ecalEndcapHitsMeta = new EcalRecHitMetaCollection(*eventData_->reducedEERecHits) ;
00658 eventData_->ecalBarrelIsol03 = new EgammaRecHitIsolation(egIsoConeSizeOutSmall,egIsoConeSizeInBarrel,egIsoJurassicWidth,egIsoPtMinBarrel,egIsoEMinBarrel,eventSetupData_->caloGeom,eventData_->ecalBarrelHitsMeta,DetId::Ecal);
00659 eventData_->ecalBarrelIsol04 = new EgammaRecHitIsolation(egIsoConeSizeOutLarge,egIsoConeSizeInBarrel,egIsoJurassicWidth,egIsoPtMinBarrel,egIsoEMinBarrel,eventSetupData_->caloGeom,eventData_->ecalBarrelHitsMeta,DetId::Ecal);
00660 eventData_->ecalEndcapIsol03 = new EgammaRecHitIsolation(egIsoConeSizeOutSmall,egIsoConeSizeInEndcap,egIsoJurassicWidth,egIsoPtMinEndcap,egIsoEMinEndcap,eventSetupData_->caloGeom,eventData_->ecalEndcapHitsMeta,DetId::Ecal);
00661 eventData_->ecalEndcapIsol04 = new EgammaRecHitIsolation(egIsoConeSizeOutLarge,egIsoConeSizeInEndcap,egIsoJurassicWidth,egIsoPtMinEndcap,egIsoEMinEndcap,eventSetupData_->caloGeom,eventData_->ecalEndcapHitsMeta,DetId::Ecal);
00662 eventData_->ecalBarrelIsol03->setUseNumCrystals(generalData_->isoCfg.useNumCrystals);
00663 eventData_->ecalBarrelIsol03->setVetoClustered(generalData_->isoCfg.vetoClustered);
00664 eventData_->ecalBarrelIsol03->doSpikeRemoval(eventData_->reducedEBRecHits.product(),eventSetupData_->chStatus.product(),generalData_->spikeCfg.severityLevelCut,generalData_->spikeCfg.severityRecHitThreshold,generalData_->spikeCfg.spikeId,generalData_->spikeCfg.spikeIdThreshold);
00665
00666 eventData_->ecalBarrelIsol03->doFlagChecks(generalData_->spikeCfg.recHitFlagsToBeExcluded);
00667 eventData_->ecalBarrelIsol04->setUseNumCrystals(generalData_->isoCfg.useNumCrystals);
00668 eventData_->ecalBarrelIsol04->setVetoClustered(generalData_->isoCfg.vetoClustered);
00669 eventData_->ecalBarrelIsol04->doSpikeRemoval(eventData_->reducedEBRecHits.product(),eventSetupData_->chStatus.product(),generalData_->spikeCfg.severityLevelCut,generalData_->spikeCfg.severityRecHitThreshold,generalData_->spikeCfg.spikeId,generalData_->spikeCfg.spikeIdThreshold);
00670
00671 eventData_->ecalBarrelIsol04->doFlagChecks(generalData_->spikeCfg.recHitFlagsToBeExcluded);
00672 eventData_->ecalEndcapIsol03->setUseNumCrystals(generalData_->isoCfg.useNumCrystals);
00673 eventData_->ecalEndcapIsol03->setVetoClustered(generalData_->isoCfg.vetoClustered);
00674 eventData_->ecalEndcapIsol03->doFlagChecks(generalData_->spikeCfg.recHitFlagsToBeExcluded);
00675 eventData_->ecalEndcapIsol04->setUseNumCrystals(generalData_->isoCfg.useNumCrystals);
00676 eventData_->ecalEndcapIsol04->setVetoClustered(generalData_->isoCfg.vetoClustered);
00677 eventData_->ecalEndcapIsol04->doFlagChecks(generalData_->spikeCfg.recHitFlagsToBeExcluded);
00678 }
00679
00680 void GsfElectronAlgo::endEvent()
00681 {
00682 if (eventData_==0)
00683 { throw cms::Exception("GsfElectronAlgo|InternalError")<<"lacking event data" ; }
00684 delete eventData_ ;
00685 eventData_ = 0 ;
00686 }
00687
00688 void GsfElectronAlgo::displayInternalElectrons( const std::string & title ) const
00689 {
00690 LogTrace("GsfElectronAlgo") << "========== " << title << " ==========";
00691 LogTrace("GsfElectronAlgo") << "Event: " << eventData_->event->id();
00692 LogTrace("GsfElectronAlgo") << "Number of electrons: " << eventData_->electrons->size() ;
00693 GsfElectronPtrCollection::const_iterator it ;
00694 for ( it = eventData_->electrons->begin(); it != eventData_->electrons->end(); it++ )
00695 {
00696 LogTrace("GsfElectronAlgo") << "Electron with charge, pt, eta, phi: " << (*it)->charge() << " , "
00697 << (*it)->pt() << " , " << (*it)->eta() << " , " << (*it)->phi();
00698 }
00699 LogTrace("GsfElectronAlgo") << "=================================================";
00700 }
00701
00702 void GsfElectronAlgo::completeElectrons()
00703 {
00704 if (electronData_!=0)
00705 { throw cms::Exception("GsfElectronAlgo|InternalError")<<"unexpected electron data" ; }
00706
00707 const GsfElectronCoreCollection * coreCollection = eventData_->coreElectrons.product() ;
00708 for ( unsigned int i=0 ; i<coreCollection->size() ; ++i )
00709 {
00710
00711 const GsfElectronCoreRef coreRef = edm::Ref<GsfElectronCoreCollection>(eventData_->coreElectrons,i) ;
00712 bool coreFound = false ;
00713 GsfElectronPtrCollection::const_iterator itrEle ;
00714 for
00715 ( itrEle = eventData_->electrons->begin() ;
00716 itrEle != eventData_->electrons->end() ;
00717 itrEle++ )
00718 {
00719 if ((*itrEle)->core()==coreRef)
00720 {
00721 coreFound = true ;
00722 break ;
00723 }
00724 }
00725 if (coreFound) continue ;
00726
00727
00728 if (coreRef->superCluster().isNull()) continue ;
00729
00730
00731 delete electronData_ ;
00732 electronData_ = new ElectronData(coreRef,*eventData_->beamspot) ;
00733
00734
00735 if ( !electronData_->calculateTSOS( eventSetupData_->mtsTransform, eventSetupData_->constraintAtVtx ) ) continue ;
00736
00737 createElectron() ;
00738
00739 }
00740
00741 delete electronData_ ;
00742 electronData_ = 0 ;
00743 }
00744
00745 void GsfElectronAlgo::clonePreviousElectrons()
00746 {
00747 const GsfElectronCollection * oldElectrons = eventData_->previousElectrons.product() ;
00748 const GsfElectronCoreCollection * newCores = eventData_->coreElectrons.product() ;
00749 GsfElectronCollection::const_iterator electron ;
00750 for
00751 ( electron = oldElectrons->begin() ;
00752 electron != oldElectrons->end() ;
00753 ++electron )
00754 {
00755 const GsfTrackRef electronGsfTrackRef = electron->gsfTrack() ;
00756 unsigned int icore ;
00757 for ( icore=0 ; icore<newCores->size() ; ++icore )
00758 {
00759 if (electronGsfTrackRef==(*newCores)[icore].gsfTrack())
00760 {
00761 const GsfElectronCoreRef coreRef = edm::Ref<GsfElectronCoreCollection>(eventData_->coreElectrons,icore) ;
00762 eventData_->electrons->push_back(new GsfElectron(*electron,coreRef)) ;
00763 break ;
00764 }
00765 }
00766 }
00767 }
00768
00769 void GsfElectronAlgo::addPflowInfo()
00770 {
00771 GsfElectronPtrCollection::iterator el ;
00772 for
00773 ( el = eventData_->electrons->begin() ;
00774 el != eventData_->electrons->end() ;
00775 el++ )
00776 {
00777
00778
00779
00780 GsfTrackRef gsfTrackRef = (*el)->gsfTrack() ;
00781 float mva = (*eventData_->pfMva.product())[gsfTrackRef] ;
00782 double noCutMin = -999999999 ;
00783 if (mva<noCutMin) { throw cms::Exception("GsfElectronAlgo|UnexpectedMvaValue")<<"unexpected MVA value: "<<mva ; }
00784 (*el)->setMva(mva) ;
00785
00786 setMvaPreselectionFlag(*el) ;
00787 }
00788 }
00789
00790 bool GsfElectronAlgo::isPreselected( GsfElectron * ele )
00791 { return (ele->passingCutBasedPreselection()||ele->passingMvaPreselection()) ; }
00792
00793 void GsfElectronAlgo::removeNotPreselectedElectrons()
00794 {
00795 GsfElectronPtrCollection::size_type ei = 1, emax = eventData_->electrons->size() ;
00796 GsfElectronPtrCollection::iterator eitr = eventData_->electrons->begin() ;
00797 while (eitr!=eventData_->electrons->end())
00798 {
00799 LogTrace("GsfElectronAlgo")<<"========== removed not preselected "<<ei<<"/"<<emax<<"==========" ;
00800 if (isPreselected(*eitr))
00801 { ++eitr ; ++ei ; }
00802 else
00803 { delete (*eitr) ; eitr = eventData_->electrons->erase(eitr) ; ++ei ; }
00804 }
00805 }
00806
00807 void GsfElectronAlgo::setCutBasedPreselectionFlag( GsfElectron * ele, const reco::BeamSpot & bs )
00808 {
00809
00810 ele->setPassCutBasedPreselection(false) ;
00811
00812
00813 bool eg = ele->core()->ecalDrivenSeed() ;
00814 bool pf = ele->core()->trackerDrivenSeed() && !ele->core()->ecalDrivenSeed() ;
00815 if (eg&&pf) { throw cms::Exception("GsfElectronAlgo|BothEcalAndPureTrackerDriven")<<"An electron cannot be both egamma and purely pflow" ; }
00816 if ((!eg)&&(!pf)) { throw cms::Exception("GsfElectronAlgo|NeitherEcalNorPureTrackerDriven")<<"An electron cannot be neither egamma nor purely pflow" ; }
00817 const CutsConfiguration * cfg = (eg?&generalData_->cutsCfg:&generalData_->cutsCfgPflow) ;
00818
00819
00820 double etaValue = EleRelPoint(ele->superCluster()->position(),bs.position()).eta() ;
00821 double etValue = ele->superCluster()->energy()/cosh(etaValue) ;
00822 LogTrace("GsfElectronAlgo") << "Et : " << etValue ;
00823 if (ele->isEB() && (etValue < cfg->minSCEtBarrel)) return ;
00824 if (ele->isEE() && (etValue < cfg->minSCEtEndcaps)) return ;
00825 LogTrace("GsfElectronAlgo") << "Et criteria are satisfied";
00826
00827
00828 double eopValue = ele->eSuperClusterOverP() ;
00829 LogTrace("GsfElectronAlgo") << "E/p : " << eopValue ;
00830 if (ele->isEB() && (eopValue > cfg->maxEOverPBarrel)) return ;
00831 if (ele->isEE() && (eopValue > cfg->maxEOverPEndcaps)) return ;
00832 if (ele->isEB() && (eopValue < cfg->minEOverPBarrel)) return ;
00833 if (ele->isEE() && (eopValue < cfg->minEOverPEndcaps)) return ;
00834 LogTrace("GsfElectronAlgo") << "E/p criteria are satisfied";
00835
00836
00837 LogTrace("GsfElectronAlgo") << "HoE1 : " << ele->hcalDepth1OverEcal() << ", HoE2 : " << ele->hcalDepth2OverEcal();
00838 double had = ele->hcalOverEcal()*ele->superCluster()->energy() ;
00839 const reco::CaloCluster & seedCluster = *(ele->superCluster()->seed()) ;
00840 int detector = seedCluster.hitsAndFractions()[0].first.subdetId() ;
00841 bool HoEveto = false ;
00842 if (detector==EcalBarrel && (had<cfg->maxHBarrel || (had/ele->superCluster()->energy())<cfg->maxHOverEBarrel)) HoEveto=true;
00843 else if (detector==EcalEndcap && (had<cfg->maxHEndcaps || (had/ele->superCluster()->energy())<cfg->maxHOverEEndcaps)) HoEveto=true;
00844 if ( !HoEveto ) return ;
00845 LogTrace("GsfElectronAlgo") << "H/E criteria are satisfied";
00846
00847
00848 double deta = ele->deltaEtaSuperClusterTrackAtVtx() ;
00849 LogTrace("GsfElectronAlgo") << "delta eta : " << deta ;
00850 if (ele->isEB() && (std::abs(deta) > cfg->maxDeltaEtaBarrel)) return ;
00851 if (ele->isEE() && (std::abs(deta) > cfg->maxDeltaEtaEndcaps)) return ;
00852 LogTrace("GsfElectronAlgo") << "Delta eta criteria are satisfied";
00853
00854
00855 double dphi = ele->deltaPhiSuperClusterTrackAtVtx();
00856 LogTrace("GsfElectronAlgo") << "delta phi : " << dphi;
00857 if (ele->isEB() && (std::abs(dphi) > cfg->maxDeltaPhiBarrel)) return ;
00858 if (ele->isEE() && (std::abs(dphi) > cfg->maxDeltaPhiEndcaps)) return ;
00859 LogTrace("GsfElectronAlgo") << "Delta phi criteria are satisfied";
00860
00861
00862 LogTrace("GsfElectronAlgo") << "sigma ieta ieta : " << ele->sigmaIetaIeta();
00863 if (ele->isEB() && (ele->sigmaIetaIeta() > cfg->maxSigmaIetaIetaBarrel)) return ;
00864 if (ele->isEE() && (ele->sigmaIetaIeta() > cfg->maxSigmaIetaIetaEndcaps)) return ;
00865 LogTrace("GsfElectronAlgo") << "Sigma ieta ieta criteria are satisfied";
00866
00867
00868 if (!ele->isEB() && cfg->isBarrel) return ;
00869 if (!ele->isEE() && cfg->isEndcaps) return ;
00870 if (cfg->isFiducial && (ele->isEBEEGap()||ele->isEBEtaGap()||ele->isEBPhiGap()||ele->isEERingGap()||ele->isEEDeeGap())) return ;
00871 LogTrace("GsfElectronAlgo") << "Fiducial flags criteria are satisfied";
00872
00873
00874 edm::RefToBase<TrajectorySeed> seed = ele->gsfTrack()->extra()->seedRef() ;
00875 ElectronSeedRef elseed = seed.castTo<ElectronSeedRef>() ;
00876 if (eg && !generalData_->cutsCfg.seedFromTEC)
00877 {
00878 if (elseed.isNull())
00879 { throw cms::Exception("GsfElectronAlgo|NotElectronSeed")<<"The GsfTrack seed is not an ElectronSeed ?!" ; }
00880 else
00881 { if (elseed->subDet2()==6) return ; }
00882 }
00883
00884
00885 if (std::abs(ele->gsfTrack()->dxy(bs.position()))>cfg->maxTIP) return ;
00886 LogTrace("GsfElectronAlgo") << "TIP criterion is satisfied" ;
00887
00888 LogTrace("GsfElectronAlgo") << "All cut based criteria are satisfied" ;
00889 ele->setPassCutBasedPreselection(true) ;
00890 }
00891
00892 void GsfElectronAlgo::setMvaPreselectionFlag( GsfElectron * ele )
00893 {
00894 ele->setPassMvaPreselection(false) ;
00895 if (ele->core()->ecalDrivenSeed())
00896 { if (ele->mva()>=generalData_->cutsCfg.minMVA) ele->setPassMvaPreselection(true) ; }
00897 else
00898 { if (ele->mva()>=generalData_->cutsCfgPflow.minMVA) ele->setPassMvaPreselection(true) ; }
00899 if (ele->passingMvaPreselection())
00900 { LogTrace("GsfElectronAlgo") << "Mva criterion is satisfied" ; }
00901 }
00902
00903 void GsfElectronAlgo::createElectron()
00904 {
00905
00906 if (generalData_->strategyCfg.ctfTracksCheck)
00907 { electronData_->checkCtfTrack(eventData_->currentCtfTracks) ; }
00908
00909
00910 int eleCharge ;
00911 GsfElectron::ChargeInfo eleChargeInfo ;
00912 electronData_->computeCharge(eleCharge,eleChargeInfo) ;
00913
00914
00915 CaloClusterPtr elbcRef = electronData_->getEleBasicCluster(eventSetupData_->mtsTransform) ;
00916
00917
00918 const reco::CaloCluster & seedCluster = *(electronData_->superClusterRef->seed()) ;
00919
00920
00921
00922 DetId seedXtalId = seedCluster.hitsAndFractions()[0].first ;
00923
00924 electronData_->calculateMode(eventSetupData_->mtsMode) ;
00925
00926
00927
00928
00929
00930
00931 Candidate::LorentzVector momentum = electronData_->computeMomemtum() ;
00932
00933
00934
00935
00936
00937
00938 reco::GsfElectron::TrackClusterMatching tcMatching ;
00939 tcMatching.electronCluster = elbcRef ;
00940 tcMatching.eSuperClusterOverP = (electronData_->vtxMom.mag()>0)?(electronData_->superClusterRef->energy()/electronData_->vtxMom.mag()):(-1.) ;
00941 tcMatching.eSeedClusterOverP = (electronData_->vtxMom.mag()>0.)?(seedCluster.energy()/electronData_->vtxMom.mag()):(-1) ;
00942 tcMatching.eSeedClusterOverPout = (electronData_->seedMom.mag()>0.)?(seedCluster.energy()/electronData_->seedMom.mag()):(-1.) ;
00943 tcMatching.eEleClusterOverPout = (electronData_->eleMom.mag()>0.)?(elbcRef->energy()/electronData_->eleMom.mag()):(-1.) ;
00944
00945 EleRelPointPair scAtVtx(electronData_->superClusterRef->position(),electronData_->sclPos,eventData_->beamspot->position()) ;
00946 tcMatching.deltaEtaSuperClusterAtVtx = scAtVtx.dEta() ;
00947 tcMatching.deltaPhiSuperClusterAtVtx = scAtVtx.dPhi() ;
00948
00949 EleRelPointPair seedAtCalo(seedCluster.position(),electronData_->seedPos,eventData_->beamspot->position()) ;
00950 tcMatching.deltaEtaSeedClusterAtCalo = seedAtCalo.dEta() ;
00951 tcMatching.deltaPhiSeedClusterAtCalo = seedAtCalo.dPhi() ;
00952
00953 EleRelPointPair ecAtCalo(elbcRef->position(),electronData_->elePos,eventData_->beamspot->position()) ;
00954 tcMatching.deltaEtaEleClusterAtCalo = ecAtCalo.dEta() ;
00955 tcMatching.deltaPhiEleClusterAtCalo = ecAtCalo.dPhi() ;
00956
00957
00958
00959
00960
00961
00962 reco::GsfElectron::TrackExtrapolations tkExtra ;
00963 ele_convert(electronData_->vtxPos,tkExtra.positionAtVtx) ;
00964 ele_convert(electronData_->sclPos,tkExtra.positionAtCalo) ;
00965 ele_convert(electronData_->vtxMom,tkExtra.momentumAtVtx) ;
00966 ele_convert(electronData_->sclMom,tkExtra.momentumAtCalo) ;
00967 ele_convert(electronData_->seedMom,tkExtra.momentumOut) ;
00968 ele_convert(electronData_->eleMom,tkExtra.momentumAtEleClus) ;
00969 ele_convert(electronData_->vtxMomWithConstraint,tkExtra.momentumAtVtxWithConstraint) ;
00970
00971
00972
00973
00974
00975
00976 reco::GsfElectron::ClosestCtfTrack ctfInfo ;
00977 ctfInfo.ctfTrack = electronData_->ctfTrackRef ;
00978 ctfInfo.shFracInnerHits = electronData_->shFracInnerHits ;
00979
00980
00981
00982
00983
00984
00985 reco::GsfElectron::FiducialFlags fiducialFlags ;
00986 int detector = seedXtalId.subdetId() ;
00987 double feta=std::abs(electronData_->superClusterRef->position().eta()) ;
00988 if (detector==EcalBarrel)
00989 {
00990 fiducialFlags.isEB = true ;
00991 EBDetId ebdetid(seedXtalId);
00992 if (EBDetId::isNextToEtaBoundary(ebdetid))
00993 {
00994 if (ebdetid.ietaAbs()==85)
00995 { fiducialFlags.isEBEEGap = true ; }
00996 else
00997 { fiducialFlags.isEBEtaGap = true ; }
00998 }
00999 if (EBDetId::isNextToPhiBoundary(ebdetid))
01000 { fiducialFlags.isEBPhiGap = true ; }
01001 }
01002 else if (detector==EcalEndcap)
01003 {
01004 fiducialFlags.isEE = true ;
01005 EEDetId eedetid(seedXtalId);
01006 if (EEDetId::isNextToRingBoundary(eedetid))
01007 {
01008 if (std::abs(feta)<2.)
01009 { fiducialFlags.isEBEEGap = true ; }
01010 else
01011 { fiducialFlags.isEERingGap = true ; }
01012 }
01013 if (EEDetId::isNextToDBoundary(eedetid))
01014 { fiducialFlags.isEEDeeGap = true ; }
01015 }
01016 else
01017 { throw cms::Exception("GsfElectronAlgo|UnknownXtalRegion")<<"createElectron(): do not know if it is a barrel or endcap seed cluster !!!!" ; }
01018
01019
01020
01021
01022
01023
01024 reco::GsfElectron::ShowerShape showerShape ;
01025 const CaloTopology * topology = eventSetupData_->caloTopo.product() ;
01026 const CaloGeometry * geometry = eventSetupData_->caloGeom.product() ;
01027 const EcalRecHitCollection * reducedRecHits = 0 ;
01028 if (fiducialFlags.isEB)
01029 { reducedRecHits = eventData_->reducedEBRecHits.product() ; }
01030 else
01031 { reducedRecHits = eventData_->reducedEERecHits.product() ; }
01032 std::vector<float> covariances = EcalClusterTools::covariances(seedCluster,reducedRecHits,topology,geometry) ;
01033 std::vector<float> localCovariances = EcalClusterTools::localCovariances(seedCluster,reducedRecHits,topology) ;
01034 showerShape.sigmaEtaEta = sqrt(covariances[0]) ;
01035 showerShape.sigmaIetaIeta = sqrt(localCovariances[0]) ;
01036 showerShape.e1x5 = EcalClusterTools::e1x5(seedCluster,reducedRecHits,topology) ;
01037 showerShape.e2x5Max = EcalClusterTools::e2x5Max(seedCluster,reducedRecHits,topology) ;
01038 showerShape.e5x5 = EcalClusterTools::e5x5(seedCluster,reducedRecHits,topology) ;
01039
01040 reco::SuperClusterRef theClus = electronData_->superClusterRef ;
01041 if (electronData_->coreRef->ecalDrivenSeed())
01042 {
01043 showerShape.hcalDepth1OverEcal = generalData_->hcalHelper->hcalESumDepth1(*theClus)/theClus->energy() ;
01044 showerShape.hcalDepth2OverEcal = generalData_->hcalHelper->hcalESumDepth2(*theClus)/theClus->energy() ;
01045 }
01046 else
01047 {
01048 showerShape.hcalDepth1OverEcal = generalData_->hcalHelperPflow->hcalESumDepth1(*theClus)/theClus->energy() ;
01049 showerShape.hcalDepth2OverEcal = generalData_->hcalHelperPflow->hcalESumDepth2(*theClus)/theClus->energy() ;
01050 }
01051
01052
01053
01054
01055
01056
01057 eventData_->retreiveOriginalTrackCollections(electronData_->ctfTrackRef,electronData_->coreRef->gsfTrack()) ;
01058
01059 ConversionFinder conversionFinder ;
01060 double BInTesla = eventSetupData_->magField->inTesla(GlobalPoint(0.,0.,0.)).z() ;
01061 edm::Handle<reco::TrackCollection> ctfTracks = eventData_->originalCtfTracks ;
01062 if (!ctfTracks.isValid()) { ctfTracks = eventData_->currentCtfTracks ; }
01063
01064
01065
01066
01067
01068
01069
01070 ConversionInfo conversionInfo = conversionFinder.getConversionInfo
01071 (*electronData_->coreRef,ctfTracks,eventData_->originalGsfTracks,BInTesla) ;
01072
01073 reco::GsfElectron::ConversionRejection conversionVars ;
01074 conversionVars.flags = conversionInfo.flag() ;
01075 conversionVars.dist = conversionInfo.dist() ;
01076 conversionVars.dcot = conversionInfo.dcot() ;
01077 conversionVars.radius = conversionInfo.radiusOfConversion() ;
01078 if ((conversionVars.flags==0)or(conversionVars.flags==1))
01079 conversionVars.partner = TrackBaseRef(conversionInfo.conversionPartnerCtfTk()) ;
01080 else if ((conversionVars.flags==2)or(conversionVars.flags==3))
01081 conversionVars.partner = TrackBaseRef(conversionInfo.conversionPartnerGsfTk()) ;
01082
01083
01084
01085
01086
01087
01088 float fbrem = (electronData_->outMom.mag()>0.)?((electronData_->innMom.mag()-electronData_->outMom.mag())/electronData_->innMom.mag()):1.e30 ;
01089
01090
01091
01092
01093
01094
01095 GsfElectron * ele = new
01096 GsfElectron
01097 ( momentum,eleCharge,eleChargeInfo,electronData_->coreRef,
01098 tcMatching, tkExtra, ctfInfo,
01099 fiducialFlags,showerShape,
01100 conversionVars,
01101 fbrem) ;
01102
01103
01104 ElectronClassification theClassifier;
01105 theClassifier.correct(*ele);
01106
01107 if (ele->core()->ecalDrivenSeed()) {
01108 ElectronEnergyCorrector theEnCorrector(generalData_->superClusterErrorFunction);
01109 theEnCorrector.correct(*ele, *eventData_->beamspot, generalData_->strategyCfg.applyEtaCorrection);
01110 ElectronMomentumCorrector theMomCorrector;
01111 theMomCorrector.correct(*ele,electronData_->vtxTSOS);
01112 }
01113
01114
01115
01116 reco::GsfElectron::IsolationVariables dr03, dr04 ;
01117 dr03.tkSumPt = eventData_->tkIsolation03->getPtTracks(ele);
01118 dr03.hcalDepth1TowerSumEt = eventData_->hadDepth1Isolation03->getTowerEtSum(ele);
01119 dr03.hcalDepth2TowerSumEt = eventData_->hadDepth2Isolation03->getTowerEtSum(ele);
01120 dr03.ecalRecHitSumEt = eventData_->ecalBarrelIsol03->getEtSum(ele)+eventData_->ecalEndcapIsol03->getEtSum(ele);
01121 dr04.tkSumPt = eventData_->tkIsolation04->getPtTracks(ele);
01122 dr04.hcalDepth1TowerSumEt = eventData_->hadDepth1Isolation04->getTowerEtSum(ele);
01123 dr04.hcalDepth2TowerSumEt = eventData_->hadDepth2Isolation04->getTowerEtSum(ele);
01124 dr04.ecalRecHitSumEt = eventData_->ecalBarrelIsol04->getEtSum(ele)+eventData_->ecalEndcapIsol04->getEtSum(ele);
01125 ele->setIsolation03(dr03);
01126 ele->setIsolation04(dr04);
01127
01128
01129 setCutBasedPreselectionFlag(ele,*eventData_->beamspot) ;
01130
01131 LogTrace("GsfElectronAlgo")<<"Constructed new electron with energy "<< ele->p4().e() ;
01132
01133 eventData_->electrons->push_back(ele) ;
01134 }
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144 void GsfElectronAlgo::setAmbiguityData( bool ignoreNotPreselected )
01145 {
01146 GsfElectronPtrCollection::iterator e1, e2 ;
01147 if (generalData_->strategyCfg.ambSortingStrategy==0)
01148 { eventData_->electrons->sort(EgAmbiguityTools::isBetter) ; }
01149 else if (generalData_->strategyCfg.ambSortingStrategy==1)
01150 { eventData_->electrons->sort(EgAmbiguityTools::isInnerMost(eventSetupData_->trackerHandle)) ; }
01151 else
01152 { throw cms::Exception("GsfElectronAlgo|UnknownAmbiguitySortingStrategy")<<"value of generalData_->strategyCfg.ambSortingStrategy is : "<<generalData_->strategyCfg.ambSortingStrategy ; }
01153
01154
01155 for
01156 ( e1 = eventData_->electrons->begin() ;
01157 e1 != eventData_->electrons->end() ;
01158 ++e1 )
01159 {
01160 (*e1)->clearAmbiguousGsfTracks() ;
01161 (*e1)->setAmbiguous(false) ;
01162 }
01163
01164
01165 for
01166 ( e1 = eventData_->electrons->begin() ;
01167 e1 != eventData_->electrons->end() ;
01168 ++e1 )
01169 {
01170 if ((*e1)->ambiguous()) continue ;
01171 if ( ignoreNotPreselected && !isPreselected(*e1) ) continue ;
01172
01173 SuperClusterRef scRef1 = (*e1)->superCluster();
01174 CaloClusterPtr eleClu1 = (*e1)->electronCluster();
01175 LogDebug("GsfElectronAlgo")
01176 << "Blessing electron with E/P " << (*e1)->eSuperClusterOverP()
01177 << ", cluster " << scRef1.get()
01178 << " & track " << (*e1)->gsfTrack().get() ;
01179
01180 for
01181 ( e2 = e1, ++e2 ;
01182 e2 != eventData_->electrons->end() ;
01183 ++e2 )
01184 {
01185 if ((*e2)->ambiguous()) continue ;
01186 if ( ignoreNotPreselected && !isPreselected(*e2) ) continue ;
01187
01188 SuperClusterRef scRef2 = (*e2)->superCluster();
01189 CaloClusterPtr eleClu2 = (*e2)->electronCluster();
01190
01191
01192 bool sameCluster = false ;
01193 if (generalData_->strategyCfg.ambClustersOverlapStrategy==0)
01194 { sameCluster = (scRef1==scRef2) ; }
01195 else if (generalData_->strategyCfg.ambClustersOverlapStrategy==1)
01196 {
01197 float eMin = 1. ;
01198 float threshold = eMin*cosh(EleRelPoint(scRef1->position(),eventData_->beamspot->position()).eta()) ;
01199 sameCluster =
01200 ( (EgAmbiguityTools::sharedEnergy(&(*eleClu1),&(*eleClu2),eventData_->reducedEBRecHits,eventData_->reducedEERecHits)>=threshold) ||
01201 (EgAmbiguityTools::sharedEnergy(&(*scRef1->seed()),&(*eleClu2),eventData_->reducedEBRecHits,eventData_->reducedEERecHits)>=threshold) ||
01202 (EgAmbiguityTools::sharedEnergy(&(*eleClu1),&(*scRef2->seed()),eventData_->reducedEBRecHits,eventData_->reducedEERecHits)>=threshold) ||
01203 (EgAmbiguityTools::sharedEnergy(&(*scRef1->seed()),&(*scRef2->seed()),eventData_->reducedEBRecHits,eventData_->reducedEERecHits)>=threshold) ) ;
01204 }
01205 else
01206 { throw cms::Exception("GsfElectronAlgo|UnknownAmbiguityClustersOverlapStrategy")<<"value of generalData_->strategyCfg.ambClustersOverlapStrategy is : "<<generalData_->strategyCfg.ambClustersOverlapStrategy ; }
01207
01208
01209 if (sameCluster)
01210 {
01211 LogDebug("GsfElectronAlgo")
01212 << "Discarding electron with E/P " << (*e2)->eSuperClusterOverP()
01213 << ", cluster " << scRef2.get()
01214 << " and track " << (*e2)->gsfTrack().get() ;
01215 (*e1)->addAmbiguousGsfTrack((*e2)->gsfTrack()) ;
01216 (*e2)->setAmbiguous(true) ;
01217 }
01218 else if ((*e1)->gsfTrack()==(*e2)->gsfTrack())
01219 {
01220 LogDebug("GsfElectronAlgo")
01221 << "Forgetting electron with E/P " << (*e2)->eSuperClusterOverP()
01222 << ", cluster " << scRef2.get()
01223 << " and track " << (*e2)->gsfTrack().get() ;
01224 (*e2)->setAmbiguous(true) ;
01225 }
01226 }
01227 }
01228 }
01229
01230 void GsfElectronAlgo::removeAmbiguousElectrons()
01231 {
01232 GsfElectronPtrCollection::size_type ei = 1, emax = eventData_->electrons->size() ;
01233 GsfElectronPtrCollection::iterator eitr = eventData_->electrons->begin() ;
01234 while (eitr!=eventData_->electrons->end())
01235 {
01236 LogTrace("GsfElectronAlgo")<<"========== remove ambiguous "<<ei<<"/"<<emax<<"==========" ;
01237 if ((*eitr)->ambiguous())
01238 { delete (*eitr) ; eitr = eventData_->electrons->erase(eitr) ; ++ei ; }
01239 else
01240 { ++eitr ; ++ei ; }
01241 }
01242 }
01243