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