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