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