00001
00002
00003
00004 #include "PhysicsTools/PatAlgos/plugins/PATElectronProducer.h"
00005
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "FWCore/ParameterSet/interface/FileInPath.h"
00008 #include "FWCore/Utilities/interface/isFinite.h"
00009
00010 #include "DataFormats/Common/interface/Association.h"
00011 #include "DataFormats/Common/interface/ValueMap.h"
00012 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
00013 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00014
00015 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
00016 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00017
00018 #include "PhysicsTools/PatUtils/interface/TrackerIsolationPt.h"
00019 #include "PhysicsTools/PatUtils/interface/CaloIsolationEnergy.h"
00020
00021 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00022 #include "DataFormats/VertexReco/interface/Vertex.h"
00023
00024
00025 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00026 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00027
00028 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00029 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00030 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00031 #include "TrackingTools/IPTools/interface/IPTools.h"
00032
00033 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
00034 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00035 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00036 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterLazyTools.h"
00037 #include "RecoEgamma/EgammaTools/interface/ConversionTools.h"
00038 #include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00039 #include "Geometry/CaloTopology/interface/CaloTopology.h"
00040 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00041
00042 #include <vector>
00043 #include <memory>
00044
00045
00046 using namespace pat;
00047 using namespace std;
00048
00049
00050 PATElectronProducer::PATElectronProducer(const edm::ParameterSet & iConfig) :
00051 isolator_(iConfig.exists("userIsolation") ? iConfig.getParameter<edm::ParameterSet>("userIsolation") : edm::ParameterSet(), false) ,
00052 useUserData_(iConfig.exists("userData"))
00053 {
00054
00055 electronSrc_ = iConfig.getParameter<edm::InputTag>( "electronSource" );
00056 embedGsfElectronCore_ = iConfig.getParameter<bool>( "embedGsfElectronCore" );
00057 embedGsfTrack_ = iConfig.getParameter<bool>( "embedGsfTrack" );
00058 embedSuperCluster_ = iConfig.getParameter<bool> ( "embedSuperCluster" );
00059 embedSeedCluster_ = iConfig.getParameter<bool>( "embedSeedCluster" );
00060 embedTrack_ = iConfig.getParameter<bool>( "embedTrack" );
00061 embedRecHits_ = iConfig.getParameter<bool>( "embedRecHits" );
00062
00063 pfElecSrc_ = iConfig.getParameter<edm::InputTag>( "pfElectronSource" );
00064 pfCandidateMap_ = iConfig.getParameter<edm::InputTag>( "pfCandidateMap" );
00065 useParticleFlow_ = iConfig.getParameter<bool>( "useParticleFlow" );
00066 embedPFCandidate_ = iConfig.getParameter<bool>( "embedPFCandidate" );
00067
00068 reducedBarrelRecHitCollection_ = iConfig.getParameter<edm::InputTag>("reducedBarrelRecHitCollection");
00069 reducedEndcapRecHitCollection_ = iConfig.getParameter<edm::InputTag>("reducedEndcapRecHitCollection");
00070
00071 addGenMatch_ = iConfig.getParameter<bool>( "addGenMatch" );
00072 if (addGenMatch_) {
00073 embedGenMatch_ = iConfig.getParameter<bool>( "embedGenMatch" );
00074 if (iConfig.existsAs<edm::InputTag>("genParticleMatch")) {
00075 genMatchSrc_.push_back(iConfig.getParameter<edm::InputTag>( "genParticleMatch" ));
00076 }
00077 else {
00078 genMatchSrc_ = iConfig.getParameter<std::vector<edm::InputTag> >( "genParticleMatch" );
00079 }
00080 }
00081
00082 addResolutions_ = iConfig.getParameter<bool>( "addResolutions" );
00083 if (addResolutions_) {
00084 resolutionLoader_ = pat::helper::KinResolutionsLoader(iConfig.getParameter<edm::ParameterSet>("resolutions"));
00085 }
00086
00087 addElecID_ = iConfig.getParameter<bool>( "addElectronID" );
00088 if (addElecID_) {
00089
00090 if (iConfig.existsAs<edm::InputTag>("electronIDSource")) {
00091 elecIDSrcs_.push_back(NameTag("", iConfig.getParameter<edm::InputTag>("electronIDSource")));
00092 }
00093
00094 if (iConfig.existsAs<edm::ParameterSet>("electronIDSources")) {
00095
00096 if (!elecIDSrcs_.empty()){
00097 throw cms::Exception("Configuration") << "PATElectronProducer: you can't specify both 'electronIDSource' and 'electronIDSources'\n";
00098 }
00099
00100 edm::ParameterSet idps = iConfig.getParameter<edm::ParameterSet>("electronIDSources");
00101 std::vector<std::string> names = idps.getParameterNamesForType<edm::InputTag>();
00102 for (std::vector<std::string>::const_iterator it = names.begin(), ed = names.end(); it != ed; ++it) {
00103 elecIDSrcs_.push_back(NameTag(*it, idps.getParameter<edm::InputTag>(*it)));
00104 }
00105 }
00106
00107 if (elecIDSrcs_.empty()){
00108 throw cms::Exception("Configuration") <<
00109 "PATElectronProducer: id addElectronID is true, you must specify either:\n" <<
00110 "\tInputTag electronIDSource = <someTag>\n" << "or\n" <<
00111 "\tPSet electronIDSources = { \n" <<
00112 "\t\tInputTag <someName> = <someTag> // as many as you want \n " <<
00113 "\t}\n";
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 readIsolationLabels(iConfig, "isoDeposits", isoDepositLabels_);
00138
00139 readIsolationLabels(iConfig, "isolationValues", isolationValueLabels_);
00140
00141 readIsolationLabels(iConfig, "isolationValuesNoPFId", isolationValueLabelsNoPFId_);
00142
00143 addEfficiencies_ = iConfig.getParameter<bool>("addEfficiencies");
00144 if (addEfficiencies_) {
00145 efficiencyLoader_ = pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"));
00146 }
00147
00148 if ( useUserData_ ) {
00149 userDataHelper_ = PATUserDataHelper<Electron>(iConfig.getParameter<edm::ParameterSet>("userData"));
00150 }
00151
00152 embedHighLevelSelection_ = iConfig.getParameter<bool>("embedHighLevelSelection");
00153 beamLineSrc_ = iConfig.getParameter<edm::InputTag>("beamLineSrc");
00154 if ( embedHighLevelSelection_ ) {
00155 usePV_ = iConfig.getParameter<bool>("usePV");
00156 pvSrc_ = iConfig.getParameter<edm::InputTag>("pvSrc");
00157 }
00158
00159 produces<std::vector<Electron> >();
00160 }
00161
00162
00163 PATElectronProducer::~PATElectronProducer()
00164 {
00165 }
00166
00167
00168 void PATElectronProducer::produce(edm::Event & iEvent, const edm::EventSetup & iSetup)
00169 {
00170
00171 if (iEvent.isRealData()){
00172 addGenMatch_ = false;
00173 embedGenMatch_ = false;
00174 }
00175
00176 edm::ESHandle<CaloTopology> theCaloTopology;
00177 iSetup.get<CaloTopologyRecord>().get(theCaloTopology);
00178 ecalTopology_ = & (*theCaloTopology);
00179
00180
00181 edm::Handle<edm::View<reco::GsfElectron> > electrons;
00182 iEvent.getByLabel(electronSrc_, electrons);
00183
00184
00185 edm::InputTag reducedEBRecHitCollection(string("reducedEcalRecHitsEB"));
00186 edm::InputTag reducedEERecHitCollection(string("reducedEcalRecHitsEE"));
00187
00188 EcalClusterLazyTools lazyTools(iEvent, iSetup, reducedBarrelRecHitCollection_, reducedEndcapRecHitCollection_);
00189
00190
00191 edm::Handle<reco::ConversionCollection> hConversions;
00192 iEvent.getByLabel("allConversions", hConversions);
00193
00194
00195
00196 edm::ESHandle<TransientTrackBuilder> trackBuilder;
00197
00198 if (isolator_.enabled()) isolator_.beginEvent(iEvent,iSetup);
00199
00200 if (efficiencyLoader_.enabled()) efficiencyLoader_.newEvent(iEvent);
00201 if (resolutionLoader_.enabled()) resolutionLoader_.newEvent(iEvent, iSetup);
00202
00203 IsoDepositMaps deposits(isoDepositLabels_.size());
00204 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00205 iEvent.getByLabel(isoDepositLabels_[j].second, deposits[j]);
00206 }
00207
00208 IsolationValueMaps isolationValues(isolationValueLabels_.size());
00209 for (size_t j = 0; j<isolationValueLabels_.size(); ++j) {
00210 iEvent.getByLabel(isolationValueLabels_[j].second, isolationValues[j]);
00211 }
00212
00213 IsolationValueMaps isolationValuesNoPFId(isolationValueLabelsNoPFId_.size());
00214 for (size_t j = 0; j<isolationValueLabelsNoPFId_.size(); ++j) {
00215 iEvent.getByLabel(isolationValueLabelsNoPFId_[j].second, isolationValuesNoPFId[j]);
00216 }
00217
00218
00219 GenAssociations genMatches(genMatchSrc_.size());
00220 if (addGenMatch_) {
00221 for (size_t j = 0, nd = genMatchSrc_.size(); j < nd; ++j) {
00222 iEvent.getByLabel(genMatchSrc_[j], genMatches[j]);
00223 }
00224 }
00225
00226
00227 std::vector<edm::Handle<edm::ValueMap<float> > > idhandles;
00228 std::vector<pat::Electron::IdPair> ids;
00229 if (addElecID_) {
00230 idhandles.resize(elecIDSrcs_.size());
00231 ids.resize(elecIDSrcs_.size());
00232 for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
00233 iEvent.getByLabel(elecIDSrcs_[i].second, idhandles[i]);
00234 ids[i].first = elecIDSrcs_[i].first;
00235 }
00236 }
00237
00238
00239
00240
00241 reco::TrackBase::Point beamPoint(0,0,0);
00242 reco::Vertex primaryVertex;
00243 reco::BeamSpot beamSpot;
00244 bool beamSpotIsValid = false;
00245 bool primaryVertexIsValid = false;
00246
00247
00248 edm::Handle<reco::BeamSpot> beamSpotHandle;
00249 iEvent.getByLabel(beamLineSrc_, beamSpotHandle);
00250
00251 if ( embedHighLevelSelection_ ) {
00252
00253 edm::Handle< std::vector<reco::Vertex> > pvHandle;
00254 iEvent.getByLabel( pvSrc_, pvHandle );
00255
00256
00257 iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", trackBuilder);
00258
00259 if ( ! usePV_ ) {
00260
00261 if ( beamSpotHandle.isValid() ){
00262 beamSpot = *beamSpotHandle;
00263 beamSpotIsValid = true;
00264 } else{
00265 edm::LogError("DataNotAvailable")
00266 << "No beam spot available from EventSetup, not adding high level selection \n";
00267 }
00268
00269 double x0 = beamSpot.x0();
00270 double y0 = beamSpot.y0();
00271 double z0 = beamSpot.z0();
00272
00273 beamPoint = reco::TrackBase::Point ( x0, y0, z0 );
00274 } else {
00275 if ( pvHandle.isValid() && !pvHandle->empty() ) {
00276 primaryVertex = pvHandle->at(0);
00277 primaryVertexIsValid = true;
00278 } else {
00279 edm::LogError("DataNotAvailable")
00280 << "No primary vertex available from EventSetup, not adding high level selection \n";
00281 }
00282 }
00283 }
00284
00285 std::vector<Electron> * patElectrons = new std::vector<Electron>();
00286
00287 if( useParticleFlow_ ) {
00288 edm::Handle< reco::PFCandidateCollection > pfElectrons;
00289 iEvent.getByLabel(pfElecSrc_, pfElectrons);
00290 unsigned index=0;
00291
00292 for( reco::PFCandidateConstIterator i = pfElectrons->begin();
00293 i != pfElectrons->end(); ++i, ++index) {
00294
00295 reco::PFCandidateRef pfRef(pfElectrons, index);
00296 reco::PFCandidatePtr ptrToPFElectron(pfElectrons,index);
00297
00298
00299 reco::GsfTrackRef PfTk= i->gsfTrackRef();
00300
00301 bool Matched=false;
00302 bool MatchedToAmbiguousGsfTrack=false;
00303 for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end(); ++itElectron) {
00304 unsigned int idx = itElectron - electrons->begin();
00305 if (Matched || MatchedToAmbiguousGsfTrack) continue;
00306
00307 reco::GsfTrackRef EgTk= itElectron->gsfTrack();
00308
00309 if (itElectron->gsfTrack()==i->gsfTrackRef()){
00310 Matched=true;
00311 }
00312 else {
00313 for( reco::GsfTrackRefVector::const_iterator it = itElectron->ambiguousGsfTracksBegin() ;
00314 it!=itElectron->ambiguousGsfTracksEnd(); it++ ){
00315 MatchedToAmbiguousGsfTrack |= (bool)(i->gsfTrackRef()==(*it));
00316 }
00317 }
00318
00319 if (Matched || MatchedToAmbiguousGsfTrack){
00320
00321
00322 reco::CandidatePtr ptrToGsfElectron(electrons,idx);
00323
00324
00325 const edm::RefToBase<reco::GsfElectron>& elecsRef = electrons->refAt(idx);
00326 Electron anElectron(elecsRef);
00327 anElectron.setPFCandidateRef( pfRef );
00328
00329
00330 anElectron.setIsPF( true );
00331
00332 if( embedPFCandidate_ ) anElectron.embedPFCandidate();
00333
00334 if ( useUserData_ ) {
00335 userDataHelper_.add( anElectron, iEvent, iSetup );
00336 }
00337
00338 double ip3d = -999;
00339
00340
00341 if ( embedHighLevelSelection_ ) {
00342
00343 reco::GsfTrackRef track = PfTk;
00344
00345
00346 if ( track.isNonnull() && track.isAvailable() ) {
00347
00348 reco::TransientTrack tt = trackBuilder->build(track);
00349 embedHighLevel( anElectron,
00350 track,
00351 tt,
00352 primaryVertex,
00353 primaryVertexIsValid,
00354 beamSpot,
00355 beamSpotIsValid );
00356
00357 std::pair<bool,Measurement1D> ip3dpv = IPTools::absoluteImpactParameter3D(tt, primaryVertex);
00358 ip3d = ip3dpv.second.value();
00359
00360 if ( !usePV_ ) {
00361 double corr_d0 = track->dxy( beamPoint );
00362 anElectron.setDB( corr_d0, -1.0 );
00363 } else {
00364 std::pair<bool,Measurement1D> result = IPTools::absoluteTransverseImpactParameter(tt, primaryVertex);
00365 double d0_corr = result.second.value();
00366 double d0_err = result.second.error();
00367 anElectron.setDB( d0_corr, d0_err );
00368 }
00369 }
00370 }
00371
00372
00373
00374 if (addElecID_) {
00375
00376 for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
00377 ids[i].second = (*idhandles[i])[elecsRef];
00378 }
00379
00380 ids.push_back(std::make_pair("pf_evspi",pfRef->mva_e_pi()));
00381 ids.push_back(std::make_pair("pf_evsmu",pfRef->mva_e_mu()));
00382 anElectron.setElectronIDs(ids);
00383 }
00384
00385
00386 double r9 = lazyTools.e3x3( *( itElectron->superCluster()->seed())) / itElectron->superCluster()->rawEnergy() ;
00387 double sigmaIphiIphi;
00388 double sigmaIetaIphi;
00389 std::vector<float> vCov = lazyTools.localCovariances(*( itElectron->superCluster()->seed()));
00390 if( !edm::isNotFinite(vCov[2])) sigmaIphiIphi = sqrt(vCov[2]);
00391 else sigmaIphiIphi = 0;
00392 sigmaIetaIphi = vCov[1];
00393 anElectron.setMvaVariables( r9, sigmaIphiIphi, sigmaIetaIphi, ip3d);
00394
00395
00396 bool barrel = itElectron->isEB();
00397 DetId seed = lazyTools.getMaximum(*(itElectron->superCluster()->seed())).first;
00398 std::vector<DetId> selectedCells = (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal,EcalBarrel)->getWindow(seed,5,5):
00399 ecalTopology_->getSubdetectorTopology(DetId::Ecal,EcalEndcap)->getWindow(seed,5,5);
00400
00401 std::vector< std::pair<DetId, float> >::const_iterator it=itElectron->superCluster()->hitsAndFractions().begin();
00402 std::vector< std::pair<DetId, float> >::const_iterator itend=itElectron->superCluster()->hitsAndFractions().end();
00403 for( ; it!=itend ; ++it) {
00404 DetId id=it->first;
00405
00406 std::vector<DetId>::const_iterator itcheck = find(selectedCells.begin(),selectedCells.end(),id);
00407 if ( itcheck == selectedCells.end()) {
00408 selectedCells.push_back(id);
00409 }
00410 }
00411
00412
00413 edm::Handle< EcalRecHitCollection > rechitsH ;
00414 if(barrel)
00415 iEvent.getByLabel(reducedBarrelRecHitCollection_,rechitsH);
00416 else
00417 iEvent.getByLabel(reducedEndcapRecHitCollection_,rechitsH);
00418
00419 EcalRecHitCollection selectedRecHits;
00420 const EcalRecHitCollection *recHits = rechitsH.product();
00421
00422 unsigned nSelectedCells = selectedCells.size();
00423 for (unsigned icell = 0 ; icell < nSelectedCells ; ++icell) {
00424 EcalRecHitCollection::const_iterator it = recHits->find( selectedCells[icell] );
00425 if ( it != recHits->end() ) {
00426 selectedRecHits.push_back(*it);
00427 }
00428 }
00429 selectedRecHits.sort();
00430 if (embedRecHits_) anElectron.embedRecHits(& selectedRecHits);
00431
00432
00433 bool passconversionveto = false;
00434 if( hConversions.isValid()){
00435
00436 passconversionveto = !ConversionTools::hasMatchedConversion( *itElectron, hConversions, beamSpotHandle->position());
00437 }else{
00438
00439 passconversionveto = itElectron->gsfTrack()->trackerExpectedHitsInner().numberOfLostHits() < 1;
00440 }
00441
00442 anElectron.setPassConversionVeto( passconversionveto );
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 fillElectron2( anElectron,
00457 ptrToPFElectron,
00458 ptrToGsfElectron,
00459 ptrToGsfElectron,
00460 genMatches, deposits, isolationValues );
00461
00462
00463
00464 patElectrons->push_back(anElectron);
00465 }
00466 }
00467
00468 }
00469 }
00470
00471 else{
00472
00473 edm::Handle<edm::ValueMap<reco::PFCandidatePtr> >ValMapH;
00474 bool valMapPresent = iEvent.getByLabel(pfCandidateMap_,ValMapH);
00475
00476 edm::Handle< reco::PFCandidateCollection > pfElectrons;
00477 bool pfCandsPresent = iEvent.getByLabel(pfElecSrc_, pfElectrons);
00478
00479 for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end(); ++itElectron) {
00480
00481
00482 unsigned int idx = itElectron - electrons->begin();
00483 edm::RefToBase<reco::GsfElectron> elecsRef = electrons->refAt(idx);
00484 reco::CandidateBaseRef elecBaseRef(elecsRef);
00485 Electron anElectron(elecsRef);
00486
00487
00488 bool pfId = false;
00489
00490 if ( pfCandsPresent ) {
00491
00492 const reco::GsfTrackRef& trkRef = itElectron->gsfTrack();
00493 int index = 0;
00494 for( reco::PFCandidateConstIterator ie = pfElectrons->begin();
00495 ie != pfElectrons->end(); ++ie, ++index) {
00496 if(ie->particleId()!=reco::PFCandidate::e) continue;
00497 const reco::GsfTrackRef& pfTrkRef= ie->gsfTrackRef();
00498 if( trkRef == pfTrkRef ) {
00499 pfId = true;
00500 reco::PFCandidateRef pfRef(pfElectrons, index);
00501 anElectron.setPFCandidateRef( pfRef );
00502 break;
00503 }
00504 }
00505 }
00506 else if( valMapPresent ) {
00507
00508 const edm::ValueMap<reco::PFCandidatePtr> & myValMap(*ValMapH);
00509
00510 const reco::PFCandidatePtr& pfElePtr(myValMap[elecsRef]);
00511 pfId= pfElePtr.isNonnull();
00512 }
00513
00514 anElectron.setIsPF( pfId );
00515
00516
00517
00518
00519 if (isolator_.enabled()) {
00520 isolator_.fill(*electrons, idx, isolatorTmpStorage_);
00521 typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
00522
00523 for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(), ed = isolatorTmpStorage_.rend(); it != ed; ++it) {
00524 anElectron.setIsolation(it->first, it->second);
00525 }
00526 }
00527
00528 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00529 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[elecsRef]);
00530 }
00531
00532
00533 if (addElecID_) {
00534 for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
00535 ids[i].second = (*idhandles[i])[elecsRef];
00536 }
00537 anElectron.setElectronIDs(ids);
00538 }
00539
00540
00541 if ( useUserData_ ) {
00542 userDataHelper_.add( anElectron, iEvent, iSetup );
00543 }
00544
00545
00546 double ip3d = -999;
00547
00548
00549 if ( embedHighLevelSelection_ ) {
00550
00551 reco::GsfTrackRef track = itElectron->gsfTrack();
00552
00553
00554 if ( track.isNonnull() && track.isAvailable() ) {
00555
00556 reco::TransientTrack tt = trackBuilder->build(track);
00557 embedHighLevel( anElectron,
00558 track,
00559 tt,
00560 primaryVertex,
00561 primaryVertexIsValid,
00562 beamSpot,
00563 beamSpotIsValid );
00564
00565 std::pair<bool,Measurement1D> ip3dpv = IPTools::absoluteImpactParameter3D(tt, primaryVertex);
00566 ip3d = ip3dpv.second.value();
00567
00568 if ( !usePV_ ) {
00569 double corr_d0 = track->dxy( beamPoint );
00570 anElectron.setDB( corr_d0, -1.0 );
00571 } else {
00572 std::pair<bool,Measurement1D> result = IPTools::absoluteTransverseImpactParameter(tt, primaryVertex);
00573 double d0_corr = result.second.value();
00574 double d0_err = result.second.error();
00575 anElectron.setDB( d0_corr, d0_err );
00576 }
00577 }
00578 }
00579
00580
00581 double r9 = lazyTools.e3x3( *( itElectron->superCluster()->seed())) / itElectron->superCluster()->rawEnergy() ;
00582 double sigmaIphiIphi;
00583 double sigmaIetaIphi;
00584 std::vector<float> vCov = lazyTools.localCovariances(*( itElectron->superCluster()->seed()));
00585 if( !edm::isNotFinite(vCov[2])) sigmaIphiIphi = sqrt(vCov[2]);
00586 else sigmaIphiIphi = 0;
00587 sigmaIetaIphi = vCov[1];
00588 anElectron.setMvaVariables( r9, sigmaIphiIphi, sigmaIetaIphi, ip3d);
00589
00590
00591 bool barrel= itElectron->isEB();
00592 DetId seed=lazyTools.getMaximum(*(itElectron->superCluster()->seed())).first;
00593 std::vector<DetId> selectedCells = (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal,EcalBarrel)->getWindow(seed,5,5):
00594 ecalTopology_->getSubdetectorTopology(DetId::Ecal,EcalEndcap)->getWindow(seed,5,5);
00595
00596
00597 std::vector< std::pair<DetId, float> >::const_iterator it=itElectron->superCluster()->hitsAndFractions().begin();
00598 std::vector< std::pair<DetId, float> >::const_iterator itend=itElectron->superCluster()->hitsAndFractions().end();
00599 for( ; it!=itend ; ++it) {
00600 DetId id=it->first;
00601
00602 std::vector<DetId>::const_iterator itcheck = find(selectedCells.begin(),selectedCells.end(),id);
00603 if ( itcheck == selectedCells.end()) {
00604 selectedCells.push_back(id);
00605 }
00606 }
00607
00608
00609 edm::Handle< EcalRecHitCollection > rechitsH ;
00610 if(barrel)
00611 iEvent.getByLabel(reducedBarrelRecHitCollection_,rechitsH);
00612 else
00613 iEvent.getByLabel(reducedEndcapRecHitCollection_,rechitsH);
00614
00615 EcalRecHitCollection selectedRecHits;
00616 const EcalRecHitCollection *recHits = rechitsH.product();
00617
00618 unsigned nSelectedCells = selectedCells.size();
00619 for (unsigned icell = 0 ; icell < nSelectedCells ; ++icell) {
00620 EcalRecHitCollection::const_iterator it = recHits->find( selectedCells[icell] );
00621 if ( it != recHits->end() ) {
00622 selectedRecHits.push_back(*it);
00623 }
00624 }
00625 selectedRecHits.sort();
00626 if (embedRecHits_) anElectron.embedRecHits(& selectedRecHits);
00627
00628
00629 bool passconversionveto = false;
00630 if( hConversions.isValid()){
00631
00632 passconversionveto = !ConversionTools::hasMatchedConversion( *itElectron, hConversions, beamSpotHandle->position());
00633 }else{
00634
00635 passconversionveto = itElectron->gsfTrack()->trackerExpectedHitsInner().numberOfLostHits() < 1;
00636 }
00637 anElectron.setPassConversionVeto( passconversionveto );
00638
00639
00640 fillElectron( anElectron, elecsRef,elecBaseRef,
00641 genMatches, deposits, pfId, isolationValues, isolationValuesNoPFId);
00642 patElectrons->push_back(anElectron);
00643 }
00644 }
00645
00646
00647 std::sort(patElectrons->begin(), patElectrons->end(), pTComparator_);
00648
00649
00650 std::auto_ptr<std::vector<Electron> > ptr(patElectrons);
00651 iEvent.put(ptr);
00652
00653
00654 if (isolator_.enabled()) isolator_.endEvent();
00655
00656 }
00657
00658 void PATElectronProducer::fillElectron(Electron& anElectron,
00659 const edm::RefToBase<reco::GsfElectron>& elecRef,
00660 const reco::CandidateBaseRef& baseRef,
00661 const GenAssociations& genMatches,
00662 const IsoDepositMaps& deposits,
00663 const bool pfId,
00664 const IsolationValueMaps& isolationValues,
00665 const IsolationValueMaps& isolationValuesNoPFId
00666 ) const {
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 if (embedGsfElectronCore_) anElectron.embedGsfElectronCore();
00686 if (embedGsfTrack_) anElectron.embedGsfTrack();
00687 if (embedSuperCluster_) anElectron.embedSuperCluster();
00688 if (embedSeedCluster_) anElectron.embedSeedCluster();
00689 if (embedTrack_) anElectron.embedTrack();
00690
00691
00692 if (addGenMatch_) {
00693 for(size_t i = 0, n = genMatches.size(); i < n; ++i) {
00694 if(useParticleFlow_) {
00695 reco::GenParticleRef genElectron = (*genMatches[i])[anElectron.pfCandidateRef()];
00696 anElectron.addGenParticleRef(genElectron);
00697 }
00698 else {
00699 reco::GenParticleRef genElectron = (*genMatches[i])[elecRef];
00700 anElectron.addGenParticleRef(genElectron);
00701 }
00702 }
00703 if (embedGenMatch_) anElectron.embedGenParticle();
00704 }
00705
00706 if (efficiencyLoader_.enabled()) {
00707 efficiencyLoader_.setEfficiencies( anElectron, elecRef );
00708 }
00709
00710 if (resolutionLoader_.enabled()) {
00711 resolutionLoader_.setResolutions(anElectron);
00712 }
00713
00714 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00715 if(useParticleFlow_) {
00716
00717 reco::PFCandidateRef pfcandref = anElectron.pfCandidateRef();
00718 assert(!pfcandref.isNull());
00719 reco::CandidatePtr source = pfcandref->sourceCandidatePtr(0);
00720 anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00721 (*deposits[j])[source]);
00722 }
00723 else
00724 anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00725 (*deposits[j])[elecRef]);
00726 }
00727
00728 for (size_t j = 0; j<isolationValues.size(); ++j) {
00729 if(useParticleFlow_) {
00730 reco::CandidatePtr source = anElectron.pfCandidateRef()->sourceCandidatePtr(0);
00731 anElectron.setIsolation(isolationValueLabels_[j].first,
00732 (*isolationValues[j])[source]);
00733 }
00734 else
00735 if(pfId){
00736 anElectron.setIsolation(isolationValueLabels_[j].first,(*isolationValues[j])[elecRef]);
00737 }
00738 }
00739
00740
00741 for (size_t j = 0; j<isolationValuesNoPFId.size(); ++j) {
00742 if( !pfId) {
00743 anElectron.setIsolation(isolationValueLabelsNoPFId_[j].first,(*isolationValuesNoPFId[j])[elecRef]);
00744 }
00745 }
00746
00747 }
00748
00749 void PATElectronProducer::fillElectron2( Electron& anElectron,
00750 const reco::CandidatePtr& candPtrForIsolation,
00751 const reco::CandidatePtr& candPtrForGenMatch,
00752 const reco::CandidatePtr& candPtrForLoader,
00753 const GenAssociations& genMatches,
00754 const IsoDepositMaps& deposits,
00755 const IsolationValueMaps& isolationValues) const {
00756
00757
00758 anElectron.setEcalDrivenMomentum(anElectron.p4()) ;
00759 anElectron.setP4( anElectron.pfCandidateRef()->p4() );
00760
00761
00762
00763
00764
00765 if (embedGsfElectronCore_) anElectron.embedGsfElectronCore();
00766 if (embedGsfTrack_) anElectron.embedGsfTrack();
00767 if (embedSuperCluster_) anElectron.embedSuperCluster();
00768 if (embedSeedCluster_) anElectron.embedSeedCluster();
00769 if (embedTrack_) anElectron.embedTrack();
00770
00771
00772
00773 if (addGenMatch_) {
00774 for(size_t i = 0, n = genMatches.size(); i < n; ++i) {
00775 reco::GenParticleRef genElectron = (*genMatches[i])[candPtrForGenMatch];
00776 anElectron.addGenParticleRef(genElectron);
00777 }
00778 if (embedGenMatch_) anElectron.embedGenParticle();
00779 }
00780
00781
00782 if (efficiencyLoader_.enabled()) {
00783 efficiencyLoader_.setEfficiencies( anElectron, candPtrForLoader );
00784 }
00785
00786 if (resolutionLoader_.enabled()) {
00787 resolutionLoader_.setResolutions(anElectron);
00788 }
00789
00790 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00791 if( isoDepositLabels_[j].first==pat::TrackIso ||
00792 isoDepositLabels_[j].first==pat::EcalIso ||
00793 isoDepositLabels_[j].first==pat::HcalIso ||
00794 deposits[j]->contains(candPtrForGenMatch.id())) {
00795 anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00796 (*deposits[j])[candPtrForGenMatch]);
00797 }
00798 else if (deposits[j]->contains(candPtrForIsolation.id())) {
00799 anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00800 (*deposits[j])[candPtrForIsolation]);
00801 }
00802 else {
00803 anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00804 (*deposits[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
00805 }
00806 }
00807
00808 for (size_t j = 0; j<isolationValues.size(); ++j) {
00809 if( isolationValueLabels_[j].first==pat::TrackIso ||
00810 isolationValueLabels_[j].first==pat::EcalIso ||
00811 isolationValueLabels_[j].first==pat::HcalIso ||
00812 isolationValues[j]->contains(candPtrForGenMatch.id())) {
00813 anElectron.setIsolation(isolationValueLabels_[j].first,
00814 (*isolationValues[j])[candPtrForGenMatch]);
00815 }
00816 else if (isolationValues[j]->contains(candPtrForIsolation.id())) {
00817 anElectron.setIsolation(isolationValueLabels_[j].first,
00818 (*isolationValues[j])[candPtrForIsolation]);
00819 }
00820 else {
00821 anElectron.setIsolation(isolationValueLabels_[j].first,
00822 (*isolationValues[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
00823 }
00824 }
00825 }
00826
00827
00828
00829 void PATElectronProducer::fillDescriptions(edm::ConfigurationDescriptions & descriptions)
00830 {
00831 edm::ParameterSetDescription iDesc;
00832 iDesc.setComment("PAT electron producer module");
00833
00834
00835 iDesc.add<edm::InputTag>("pfCandidateMap", edm::InputTag("no default"))->setComment("input collection");
00836 iDesc.add<edm::InputTag>("electronSource", edm::InputTag("no default"))->setComment("input collection");
00837
00838
00839 iDesc.add<bool>("embedGsfElectronCore", true)->setComment("embed external gsf electron core");
00840 iDesc.add<bool>("embedGsfTrack", true)->setComment("embed external gsf track");
00841 iDesc.add<bool>("embedSuperCluster", true)->setComment("embed external super cluster");
00842 iDesc.add<bool>("embedSeedCluster", true)->setComment("embed external seed cluster");
00843 iDesc.add<bool>("embedTrack", false)->setComment("embed external track");
00844 iDesc.add<bool>("embedRecHits", true)->setComment("embed external RecHits");
00845
00846
00847 iDesc.add<edm::InputTag>("pfElectronSource", edm::InputTag("pfElectrons"))->setComment("particle flow input collection");
00848 iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
00849 iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
00850
00851
00852 iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
00853 iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
00854 std::vector<edm::InputTag> emptySourceVector;
00855 iDesc.addNode( edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
00856 edm::ParameterDescription<std::vector<edm::InputTag> >("genParticleMatch", emptySourceVector, true)
00857 )->setComment("input with MC match information");
00858
00859
00860 iDesc.add<bool>("addElectronID",true)->setComment("add electron ID variables");
00861 edm::ParameterSetDescription electronIDSourcesPSet;
00862 electronIDSourcesPSet.setAllowAnything();
00863 iDesc.addNode( edm::ParameterDescription<edm::InputTag>("electronIDSource", edm::InputTag(), true) xor
00864 edm::ParameterDescription<edm::ParameterSetDescription>("electronIDSources", electronIDSourcesPSet, true)
00865 )->setComment("input with electron ID variables");
00866
00867
00868
00869 edm::ParameterSetDescription isoDepositsPSet;
00870 isoDepositsPSet.addOptional<edm::InputTag>("tracker");
00871 isoDepositsPSet.addOptional<edm::InputTag>("ecal");
00872 isoDepositsPSet.addOptional<edm::InputTag>("hcal");
00873 isoDepositsPSet.addOptional<edm::InputTag>("pfAllParticles");
00874 isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
00875 isoDepositsPSet.addOptional<edm::InputTag>("pfChargedAll");
00876 isoDepositsPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
00877 isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
00878 isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
00879 isoDepositsPSet.addOptional<std::vector<edm::InputTag> >("user");
00880 iDesc.addOptional("isoDeposits", isoDepositsPSet);
00881
00882
00883 edm::ParameterSetDescription isolationValuesPSet;
00884 isolationValuesPSet.addOptional<edm::InputTag>("tracker");
00885 isolationValuesPSet.addOptional<edm::InputTag>("ecal");
00886 isolationValuesPSet.addOptional<edm::InputTag>("hcal");
00887 isolationValuesPSet.addOptional<edm::InputTag>("pfAllParticles");
00888 isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
00889 isolationValuesPSet.addOptional<edm::InputTag>("pfChargedAll");
00890 isolationValuesPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
00891 isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
00892 isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
00893 isolationValuesPSet.addOptional<std::vector<edm::InputTag> >("user");
00894 iDesc.addOptional("isolationValues", isolationValuesPSet);
00895
00896
00897 edm::ParameterSetDescription isolationValuesNoPFIdPSet;
00898 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("tracker");
00899 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("ecal");
00900 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("hcal");
00901 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfAllParticles");
00902 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfChargedHadrons");
00903 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfChargedAll");
00904 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
00905 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
00906 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfPhotons");
00907 isolationValuesNoPFIdPSet.addOptional<std::vector<edm::InputTag> >("user");
00908 iDesc.addOptional("isolationValuesNoPFId", isolationValuesNoPFIdPSet);
00909
00910
00911 edm::ParameterSetDescription efficienciesPSet;
00912 efficienciesPSet.setAllowAnything();
00913 iDesc.add("efficiencies", efficienciesPSet);
00914 iDesc.add<bool>("addEfficiencies", false);
00915
00916
00917 edm::ParameterSetDescription userDataPSet;
00918 PATUserDataHelper<Electron>::fillDescription(userDataPSet);
00919 iDesc.addOptional("userData", userDataPSet);
00920
00921
00922 iDesc.add<bool>("addElectronShapes", true);
00923 iDesc.add<edm::InputTag>("reducedBarrelRecHitCollection", edm::InputTag("reducedEcalRecHitsEB"));
00924 iDesc.add<edm::InputTag>("reducedEndcapRecHitCollection", edm::InputTag("reducedEcalRecHitsEE"));
00925
00926 edm::ParameterSetDescription isolationPSet;
00927 isolationPSet.setAllowAnything();
00928 iDesc.add("userIsolation", isolationPSet);
00929
00930
00931 pat::helper::KinResolutionsLoader::fillDescription(iDesc);
00932
00933 iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
00934 edm::ParameterSetDescription highLevelPSet;
00935 highLevelPSet.setAllowAnything();
00936 iDesc.addNode( edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true)
00937 )->setComment("input with high level selection");
00938 iDesc.addNode( edm::ParameterDescription<edm::InputTag>("pvSrc", edm::InputTag(), true)
00939 )->setComment("input with high level selection");
00940 iDesc.addNode( edm::ParameterDescription<bool>("usePV", bool(), true)
00941 )->setComment("input with high level selection, use primary vertex (true) or beam line (false)");
00942
00943 descriptions.add("PATElectronProducer", iDesc);
00944
00945 }
00946
00947
00948
00949 void PATElectronProducer::readIsolationLabels( const edm::ParameterSet & iConfig,
00950 const char* psetName,
00951 IsolationLabels& labels) {
00952
00953 labels.clear();
00954
00955 if (iConfig.exists( psetName )) {
00956 edm::ParameterSet depconf
00957 = iConfig.getParameter<edm::ParameterSet>(psetName);
00958
00959 if (depconf.exists("tracker")) labels.push_back(std::make_pair(pat::TrackIso, depconf.getParameter<edm::InputTag>("tracker")));
00960 if (depconf.exists("ecal")) labels.push_back(std::make_pair(pat::EcalIso, depconf.getParameter<edm::InputTag>("ecal")));
00961 if (depconf.exists("hcal")) labels.push_back(std::make_pair(pat::HcalIso, depconf.getParameter<edm::InputTag>("hcal")));
00962 if (depconf.exists("pfAllParticles")) {
00963 labels.push_back(std::make_pair(pat::PfAllParticleIso, depconf.getParameter<edm::InputTag>("pfAllParticles")));
00964 }
00965 if (depconf.exists("pfChargedHadrons")) {
00966 labels.push_back(std::make_pair(pat::PfChargedHadronIso, depconf.getParameter<edm::InputTag>("pfChargedHadrons")));
00967 }
00968 if (depconf.exists("pfChargedAll")) {
00969 labels.push_back(std::make_pair(pat::PfChargedAllIso, depconf.getParameter<edm::InputTag>("pfChargedAll")));
00970 }
00971 if (depconf.exists("pfPUChargedHadrons")) {
00972 labels.push_back(std::make_pair(pat::PfPUChargedHadronIso, depconf.getParameter<edm::InputTag>("pfPUChargedHadrons")));
00973 }
00974 if (depconf.exists("pfNeutralHadrons")) {
00975 labels.push_back(std::make_pair(pat::PfNeutralHadronIso, depconf.getParameter<edm::InputTag>("pfNeutralHadrons")));
00976 }
00977 if (depconf.exists("pfPhotons")) {
00978 labels.push_back(std::make_pair(pat::PfGammaIso, depconf.getParameter<edm::InputTag>("pfPhotons")));
00979 }
00980 if (depconf.exists("user")) {
00981 std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag> >("user");
00982 std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
00983 int key = UserBaseIso;
00984 for ( ; it != ed; ++it, ++key) {
00985 labels.push_back(std::make_pair(IsolationKeys(key), *it));
00986 }
00987 }
00988 }
00989
00990
00991 }
00992
00993
00994
00995
00996 void PATElectronProducer::embedHighLevel( pat::Electron & anElectron,
00997 reco::GsfTrackRef track,
00998 reco::TransientTrack & tt,
00999 reco::Vertex & primaryVertex,
01000 bool primaryVertexIsValid,
01001 reco::BeamSpot & beamspot,
01002 bool beamspotIsValid
01003 )
01004 {
01005
01006
01007
01008 std::pair<bool,Measurement1D> result =
01009 IPTools::signedTransverseImpactParameter(tt,
01010 GlobalVector(track->px(),
01011 track->py(),
01012 track->pz()),
01013 primaryVertex);
01014 double d0_corr = result.second.value();
01015 double d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
01016 anElectron.setDB( d0_corr, d0_err, pat::Electron::PV2D);
01017
01018
01019
01020 result =
01021 IPTools::signedImpactParameter3D(tt,
01022 GlobalVector(track->px(),
01023 track->py(),
01024 track->pz()),
01025 primaryVertex);
01026 d0_corr = result.second.value();
01027 d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
01028 anElectron.setDB( d0_corr, d0_err, pat::Electron::PV3D);
01029
01030
01031
01032
01033 reco::Vertex vBeamspot(beamspot.position(), beamspot.covariance3D());
01034
01035
01036 result =
01037 IPTools::signedTransverseImpactParameter(tt,
01038 GlobalVector(track->px(),
01039 track->py(),
01040 track->pz()),
01041 vBeamspot);
01042 d0_corr = result.second.value();
01043 d0_err = beamspotIsValid ? result.second.error() : -1.0;
01044 anElectron.setDB( d0_corr, d0_err, pat::Electron::BS2D);
01045
01046
01047 result =
01048 IPTools::signedImpactParameter3D(tt,
01049 GlobalVector(track->px(),
01050 track->py(),
01051 track->pz()),
01052 vBeamspot);
01053 d0_corr = result.second.value();
01054 d0_err = beamspotIsValid ? result.second.error() : -1.0;
01055 anElectron.setDB( d0_corr, d0_err, pat::Electron::BS3D);
01056 }
01057
01058 #include "FWCore/Framework/interface/MakerMacros.h"
01059
01060 DEFINE_FWK_MODULE(PATElectronProducer);