CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/PhysicsTools/PatAlgos/plugins/PATElectronProducer.cc

Go to the documentation of this file.
00001 //
00002 // $Id: PATElectronProducer.cc,v 1.46.2.2 2011/04/12 21:41:44 rwolf Exp $
00003 //
00004 
00005 #include "PhysicsTools/PatAlgos/plugins/PATElectronProducer.h"
00006 
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "FWCore/ParameterSet/interface/FileInPath.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 
00036 #include <vector>
00037 #include <memory>
00038 
00039 
00040 using namespace pat;
00041 using namespace std;
00042 
00043 
00044 PATElectronProducer::PATElectronProducer(const edm::ParameterSet & iConfig) :
00045   isolator_(iConfig.exists("userIsolation") ? iConfig.getParameter<edm::ParameterSet>("userIsolation") : edm::ParameterSet(), false) ,
00046   useUserData_(iConfig.exists("userData"))
00047 {
00048 
00049   // general configurables
00050   electronSrc_      = iConfig.getParameter<edm::InputTag>( "electronSource" );
00051   embedGsfElectronCore_    = iConfig.getParameter<bool>         ( "embedGsfElectronCore" );
00052   embedGsfTrack_    = iConfig.getParameter<bool>         ( "embedGsfTrack" );
00053   embedSuperCluster_= iConfig.getParameter<bool>         ( "embedSuperCluster" );
00054   embedTrack_       = iConfig.getParameter<bool>         ( "embedTrack" );
00055 
00056   // pflow specific
00057   pfElecSrc_           = iConfig.getParameter<edm::InputTag>( "pfElectronSource" );
00058   useParticleFlow_        = iConfig.getParameter<bool>( "useParticleFlow" );
00059   embedPFCandidate_   = iConfig.getParameter<bool>( "embedPFCandidate" );
00060 
00061 
00062   // MC matching configurables
00063   addGenMatch_      = iConfig.getParameter<bool>          ( "addGenMatch" );
00064   if (addGenMatch_) {
00065     embedGenMatch_ = iConfig.getParameter<bool>         ( "embedGenMatch" );
00066     if (iConfig.existsAs<edm::InputTag>("genParticleMatch")) {
00067       genMatchSrc_.push_back(iConfig.getParameter<edm::InputTag>( "genParticleMatch" ));
00068     } else {
00069       genMatchSrc_ = iConfig.getParameter<std::vector<edm::InputTag> >( "genParticleMatch" );
00070     }
00071   }
00072 
00073   // resolution configurables
00074   addResolutions_   = iConfig.getParameter<bool>         ( "addResolutions" );
00075   if (addResolutions_) {
00076     resolutionLoader_ = pat::helper::KinResolutionsLoader(iConfig.getParameter<edm::ParameterSet>("resolutions"));
00077   }
00078 
00079 
00080   // electron ID configurables
00081   addElecID_        = iConfig.getParameter<bool>         ( "addElectronID" );
00082   if (addElecID_) {
00083     // it might be a single electron ID
00084     if (iConfig.existsAs<edm::InputTag>("electronIDSource")) {
00085       elecIDSrcs_.push_back(NameTag("", iConfig.getParameter<edm::InputTag>("electronIDSource")));
00086     }
00087     // or there might be many of them
00088     if (iConfig.existsAs<edm::ParameterSet>("electronIDSources")) {
00089       // please don't configure me twice
00090       if (!elecIDSrcs_.empty()) throw cms::Exception("Configuration") <<
00091                                   "PATElectronProducer: you can't specify both 'electronIDSource' and 'electronIDSources'\n";
00092       // read the different electron ID names
00093       edm::ParameterSet idps = iConfig.getParameter<edm::ParameterSet>("electronIDSources");
00094       std::vector<std::string> names = idps.getParameterNamesForType<edm::InputTag>();
00095       for (std::vector<std::string>::const_iterator it = names.begin(), ed = names.end(); it != ed; ++it) {
00096         elecIDSrcs_.push_back(NameTag(*it, idps.getParameter<edm::InputTag>(*it)));
00097       }
00098     }
00099     // but in any case at least once
00100     if (elecIDSrcs_.empty()) throw cms::Exception("Configuration") <<
00101                                "PATElectronProducer: id addElectronID is true, you must specify either:\n" <<
00102                                "\tInputTag electronIDSource = <someTag>\n" << "or\n" <<
00103                                "\tPSet electronIDSources = { \n" <<
00104                                "\t\tInputTag <someName> = <someTag>   // as many as you want \n " <<
00105                                "\t}\n";
00106   }
00107 
00108   // construct resolution calculator
00109 
00110   //   // IsoDeposit configurables
00111   //   if (iConfig.exists("isoDeposits")) {
00112   //      edm::ParameterSet depconf = iConfig.getParameter<edm::ParameterSet>("isoDeposits");
00113   //      if (depconf.exists("tracker")) isoDepositLabels_.push_back(std::make_pair(TrackerIso, depconf.getParameter<edm::InputTag>("tracker")));
00114   //      if (depconf.exists("ecal"))    isoDepositLabels_.push_back(std::make_pair(ECalIso, depconf.getParameter<edm::InputTag>("ecal")));
00115   //      if (depconf.exists("hcal"))    isoDepositLabels_.push_back(std::make_pair(HCalIso, depconf.getParameter<edm::InputTag>("hcal")));
00116 
00117 
00118   //      if (depconf.exists("user")) {
00119   //         std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag> >("user");
00120   //         std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
00121   //         int key = UserBaseIso;
00122   //         for ( ; it != ed; ++it, ++key) {
00123   //             isoDepositLabels_.push_back(std::make_pair(IsolationKeys(key), *it));
00124   //         }
00125   //      }
00126   //   }
00127 
00128   // read isoDeposit labels, for direct embedding
00129   readIsolationLabels(iConfig, "isoDeposits", isoDepositLabels_);
00130 
00131   // read isolation value labels, for direct embedding
00132   readIsolationLabels(iConfig, "isolationValues", isolationValueLabels_);
00133 
00134   // Efficiency configurables
00135   addEfficiencies_ = iConfig.getParameter<bool>("addEfficiencies");
00136   if (addEfficiencies_) {
00137     efficiencyLoader_ = pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"));
00138   }
00139 
00140   // Check to see if the user wants to add user data
00141   if ( useUserData_ ) {
00142     userDataHelper_ = PATUserDataHelper<Electron>(iConfig.getParameter<edm::ParameterSet>("userData"));
00143   }
00144 
00145   // embed high level selection variables?
00146   embedHighLevelSelection_ = iConfig.getParameter<bool>("embedHighLevelSelection");
00147   if ( embedHighLevelSelection_ ) {
00148     beamLineSrc_ = iConfig.getParameter<edm::InputTag>("beamLineSrc");
00149     usePV_ = iConfig.getParameter<bool>("usePV");
00150     pvSrc_ = iConfig.getParameter<edm::InputTag>("pvSrc");
00151   }
00152 
00153 
00154   // produces vector of muons
00155   produces<std::vector<Electron> >();
00156 
00157 }
00158 
00159 
00160 PATElectronProducer::~PATElectronProducer() {
00161 }
00162 
00163 
00164 void PATElectronProducer::produce(edm::Event & iEvent, const edm::EventSetup & iSetup) {
00165 
00166   // Get the collection of electrons from the event
00167   edm::Handle<edm::View<reco::GsfElectron> > electrons;
00168   iEvent.getByLabel(electronSrc_, electrons);
00169 
00170   if (iEvent.isRealData()){
00171        addGenMatch_ = false;
00172        embedGenMatch_ = false;
00173    }
00174 
00175   // Get the ESHandle for the transient track builder, if needed for
00176   // high level selection embedding
00177   edm::ESHandle<TransientTrackBuilder> trackBuilder;
00178 
00179   if (isolator_.enabled()) isolator_.beginEvent(iEvent,iSetup);
00180 
00181   if (efficiencyLoader_.enabled()) efficiencyLoader_.newEvent(iEvent);
00182   if (resolutionLoader_.enabled()) resolutionLoader_.newEvent(iEvent, iSetup);
00183 
00184   IsoDepositMaps deposits(isoDepositLabels_.size());
00185   for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00186     iEvent.getByLabel(isoDepositLabels_[j].second, deposits[j]);
00187   }
00188 
00189   IsolationValueMaps isolationValues(isolationValueLabels_.size());
00190   for (size_t j = 0; j<isolationValueLabels_.size(); ++j) {
00191     iEvent.getByLabel(isolationValueLabels_[j].second, isolationValues[j]);
00192   }
00193 
00194   // prepare the MC matching
00195   GenAssociations  genMatches(genMatchSrc_.size());
00196   if (addGenMatch_) {
00197     for (size_t j = 0, nd = genMatchSrc_.size(); j < nd; ++j) {
00198       iEvent.getByLabel(genMatchSrc_[j], genMatches[j]);
00199     }
00200   }
00201 
00202   // prepare ID extraction
00203   std::vector<edm::Handle<edm::ValueMap<float> > > idhandles;
00204   std::vector<pat::Electron::IdPair>               ids;
00205   if (addElecID_) {
00206     idhandles.resize(elecIDSrcs_.size());
00207     ids.resize(elecIDSrcs_.size());
00208     for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
00209       iEvent.getByLabel(elecIDSrcs_[i].second, idhandles[i]);
00210       ids[i].first = elecIDSrcs_[i].first;
00211     }
00212   }
00213 
00214 
00215   // prepare the high level selection:
00216   // needs beamline
00217   reco::TrackBase::Point beamPoint(0,0,0);
00218   reco::Vertex primaryVertex;
00219   if ( embedHighLevelSelection_ ) {
00220     // Get the beamspot
00221     reco::BeamSpot beamSpot;
00222     edm::Handle<reco::BeamSpot> beamSpotHandle;
00223     iEvent.getByLabel(beamLineSrc_, beamSpotHandle);
00224 
00225 
00226     // Get the primary vertex
00227     edm::Handle< std::vector<reco::Vertex> > pvHandle;
00228     iEvent.getByLabel( pvSrc_, pvHandle );
00229 
00230     if ( ! usePV_ ) {
00231       if ( beamSpotHandle.isValid() ){
00232         beamSpot = *beamSpotHandle;
00233       } else{
00234         edm::LogError("DataNotAvailable")
00235           << "No beam spot available from EventSetup, not adding high level selection \n";
00236       }
00237 
00238       double x0 = beamSpot.x0();
00239       double y0 = beamSpot.y0();
00240       double z0 = beamSpot.z0();
00241 
00242       beamPoint = reco::TrackBase::Point ( x0, y0, z0 );
00243     } else {
00244       if ( pvHandle.isValid() ) {
00245         primaryVertex = pvHandle->at(0);
00246       } else {
00247         edm::LogError("DataNotAvailable")
00248           << "No primary vertex available from EventSetup, not adding high level selection \n";
00249       }
00250 
00251       // This is needed by the IPTools methods from the tracking group
00252       iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", trackBuilder);
00253     }
00254   }
00255 
00256   std::vector<Electron> * patElectrons = new std::vector<Electron>();
00257 
00258   if( useParticleFlow_ ) {
00259     edm::Handle< reco::PFCandidateCollection >  pfElectrons;
00260     iEvent.getByLabel(pfElecSrc_, pfElectrons);
00261     unsigned index=0;
00262 
00263     for( reco::PFCandidateConstIterator i = pfElectrons->begin();
00264          i != pfElectrons->end(); ++i, ++index) {
00265 
00266       reco::PFCandidateRef pfRef(pfElectrons, index);
00267       reco::PFCandidatePtr ptrToPFElectron(pfElectrons,index);
00268 //       reco::CandidateBaseRef pfBaseRef( pfRef );
00269 
00270       reco::GsfTrackRef PfTk= i->gsfTrackRef();
00271 
00272       bool Matched=false;
00273       bool MatchedToAmbiguousGsfTrack=false;
00274       for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end(); ++itElectron) {
00275         unsigned int idx = itElectron - electrons->begin();
00276         if (Matched || MatchedToAmbiguousGsfTrack) continue;
00277 
00278         reco::GsfTrackRef EgTk= itElectron->gsfTrack();
00279 
00280         if (itElectron->gsfTrack()==i->gsfTrackRef()){
00281           Matched=true;
00282         }
00283         else {
00284           for( reco::GsfTrackRefVector::const_iterator it = itElectron->ambiguousGsfTracksBegin() ;
00285                it!=itElectron->ambiguousGsfTracksEnd(); it++ ){
00286             MatchedToAmbiguousGsfTrack |= (bool)(i->gsfTrackRef()==(*it));
00287           }
00288         }
00289 
00290         if (Matched || MatchedToAmbiguousGsfTrack){
00291 
00292           // ptr needed for finding the matched gen particle
00293           reco::CandidatePtr ptrToGsfElectron(electrons,idx);
00294 
00295           // ref to base needed for the construction of the pat object
00296           const edm::RefToBase<reco::GsfElectron>& elecsRef = electrons->refAt(idx);
00297           Electron anElectron(elecsRef);
00298           anElectron.setPFCandidateRef( pfRef  );
00299 
00300           if( embedPFCandidate_ ) anElectron.embedPFCandidate();
00301 
00302           if ( useUserData_ ) {
00303             userDataHelper_.add( anElectron, iEvent, iSetup );
00304           }
00305 
00306 
00307           // embed high level selection
00308           if ( embedHighLevelSelection_ ) {
00309             // get the global track
00310             reco::GsfTrackRef track = PfTk;
00311 
00312             // Make sure the collection it points to is there
00313             if ( track.isNonnull() && track.isAvailable() ) {
00314 
00315               if ( !usePV_ ) {
00316                 double corr_d0 = track->dxy( beamPoint );
00317                 anElectron.setDB( corr_d0, -1.0 );
00318               } else {
00319                 reco::TransientTrack tt = trackBuilder->build(track);
00320                 std::pair<bool,Measurement1D> result = IPTools::absoluteTransverseImpactParameter(tt, primaryVertex);
00321                 double d0_corr = result.second.value();
00322                 double d0_err = result.second.error();
00323                 anElectron.setDB( d0_corr, d0_err );
00324               }
00325             }
00326           }
00327 
00328           //Electron Id
00329 
00330           if (addElecID_) {
00331             //STANDARD EL ID
00332             for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
00333               ids[i].second = (*idhandles[i])[elecsRef];
00334             }
00335             //SPECIFIC PF ID
00336             ids.push_back(std::make_pair("pf_evspi",pfRef->mva_e_pi()));
00337             ids.push_back(std::make_pair("pf_evsmu",pfRef->mva_e_mu()));
00338             anElectron.setElectronIDs(ids);
00339           }
00340 
00341 //        fillElectron(anElectron,elecsRef,pfBaseRef,
00342 //                     genMatches, deposits, isolationValues);
00343 
00344           //COLIN small warning !
00345           // we are currently choosing to take the 4-momentum of the PFCandidate;
00346           // the momentum of the GsfElectron is saved though
00347           // we must therefore match the GsfElectron.
00348           // because of this, we should not change the source of the electron matcher
00349           // to the collection of PFElectrons in the python configuration
00350           // I don't know what to do with the efficiencyLoader, since I don't know
00351           // what this class is for. 
00352           fillElectron2( anElectron, 
00353                          ptrToPFElectron, 
00354                          ptrToGsfElectron, 
00355                          ptrToGsfElectron, 
00356                          genMatches, deposits, isolationValues );
00357 
00358           //COLIN need to use fillElectron2 in the non-pflow case as well, and to test it.
00359 
00360           patElectrons->push_back(anElectron);
00361         }
00362       }
00363       //if( !Matched && !MatchedToAmbiguousGsfTrack) std::cout << "!!!!A pf electron could not be matched to a gsf!!!!"  << std::endl;
00364     }
00365   }
00366 
00367   else{
00368     for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end(); ++itElectron) {
00369       // construct the Electron from the ref -> save ref to original object
00370       unsigned int idx = itElectron - electrons->begin();
00371       edm::RefToBase<reco::GsfElectron> elecsRef = electrons->refAt(idx);
00372       reco::CandidateBaseRef elecBaseRef(elecsRef);
00373       Electron anElectron(elecsRef);
00374 
00375       // add resolution info
00376 
00377       // Isolation
00378       if (isolator_.enabled()) {
00379         isolator_.fill(*electrons, idx, isolatorTmpStorage_);
00380         typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
00381         // better to loop backwards, so the vector is resized less times
00382         for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(), ed = isolatorTmpStorage_.rend(); it != ed; ++it) {
00383           anElectron.setIsolation(it->first, it->second);
00384         }
00385       }
00386 
00387       for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00388         anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[elecsRef]);
00389       }
00390 
00391       // add electron ID info
00392       if (addElecID_) {
00393         for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
00394           ids[i].second = (*idhandles[i])[elecsRef];
00395         }
00396         anElectron.setElectronIDs(ids);
00397       }
00398 
00399 
00400       if ( useUserData_ ) {
00401         userDataHelper_.add( anElectron, iEvent, iSetup );
00402       }
00403 
00404 
00405       // embed high level selection
00406       if ( embedHighLevelSelection_ ) {
00407         // get the global track
00408         reco::GsfTrackRef track = itElectron->gsfTrack();
00409 
00410         // Make sure the collection it points to is there
00411         if ( track.isNonnull() && track.isAvailable() ) {
00412 
00413           if ( !usePV_ ) {
00414             double corr_d0 = track->dxy( beamPoint );
00415             anElectron.setDB( corr_d0, -1.0 );
00416           } else {
00417             reco::TransientTrack tt = trackBuilder->build(track);
00418             std::pair<bool,Measurement1D> result = IPTools::absoluteTransverseImpactParameter(tt, primaryVertex);
00419             double d0_corr = result.second.value();
00420             double d0_err = result.second.error();
00421             anElectron.setDB( d0_corr, d0_err );
00422           }
00423         }
00424       }
00425 
00426       // add sel to selected
00427       fillElectron( anElectron, elecsRef,elecBaseRef,
00428                     genMatches, deposits, isolationValues);
00429       patElectrons->push_back(anElectron);
00430     }
00431   }
00432 
00433   // sort electrons in pt
00434   std::sort(patElectrons->begin(), patElectrons->end(), pTComparator_);
00435 
00436   // add the electrons to the event output
00437   std::auto_ptr<std::vector<Electron> > ptr(patElectrons);
00438   iEvent.put(ptr);
00439 
00440   // clean up
00441   if (isolator_.enabled()) isolator_.endEvent();
00442 
00443 }
00444 
00445 void PATElectronProducer::fillElectron(Electron& anElectron,
00446                                        const edm::RefToBase<reco::GsfElectron>& elecRef,
00447                                        const reco::CandidateBaseRef& baseRef,
00448                                        const GenAssociations& genMatches,
00449                                        const IsoDepositMaps& deposits,
00450                                        const IsolationValueMaps& isolationValues
00451                                        ) const {
00452 
00453   //COLIN: might want to use the PFCandidate 4-mom. Which one is in use now?
00454   //   if (useParticleFlow_)
00455   //     aMuon.setP4( aMuon.pfCandidateRef()->p4() );
00456 
00457   //COLIN:
00458   //In the embedding case, the reference cannot be used to look into a value map.
00459   //therefore, one has to had the PFCandidateRef to this function, which becomes a bit
00460   //too much specific.
00461 
00462   // in fact, this function needs a baseref or ptr for genmatch
00463   // and a baseref or ptr for isodeposits and isolationvalues.
00464   // baseref is not needed
00465   // the ptrForIsolation and ptrForMatching should be defined upstream.
00466 
00467   // is the concrete elecRef needed for the efficiency loader? what is this loader?
00468   // how can we make it compatible with the particle flow electrons?
00469 
00470   if (embedGsfElectronCore_) anElectron.embedGsfElectronCore();
00471   if (embedGsfTrack_) anElectron.embedGsfTrack();
00472   if (embedSuperCluster_) anElectron.embedSuperCluster();
00473   if (embedTrack_) anElectron.embedTrack();
00474 
00475   // store the match to the generated final state muons
00476   if (addGenMatch_) {
00477     for(size_t i = 0, n = genMatches.size(); i < n; ++i) {
00478       if(useParticleFlow_) {
00479         reco::GenParticleRef genElectron = (*genMatches[i])[anElectron.pfCandidateRef()];
00480         anElectron.addGenParticleRef(genElectron);
00481       }
00482       else {
00483         reco::GenParticleRef genElectron = (*genMatches[i])[elecRef];
00484         anElectron.addGenParticleRef(genElectron);
00485       }
00486     }
00487     if (embedGenMatch_) anElectron.embedGenParticle();
00488   }
00489 
00490   if (efficiencyLoader_.enabled()) {
00491     efficiencyLoader_.setEfficiencies( anElectron, elecRef );
00492   }
00493 
00494   if (resolutionLoader_.enabled()) {
00495     resolutionLoader_.setResolutions(anElectron);
00496   }
00497 
00498   for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00499     if(useParticleFlow_) {
00500 
00501       reco::PFCandidateRef pfcandref =  anElectron.pfCandidateRef();
00502       assert(!pfcandref.isNull());
00503       reco::CandidatePtr source = pfcandref->sourceCandidatePtr(0);
00504       anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00505                           (*deposits[j])[source]);
00506     }
00507     else
00508       anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00509                           (*deposits[j])[elecRef]);
00510   }
00511 
00512   for (size_t j = 0; j<isolationValues.size(); ++j) {
00513     if(useParticleFlow_) {
00514       reco::CandidatePtr source = anElectron.pfCandidateRef()->sourceCandidatePtr(0);
00515       anElectron.setIsolation(isolationValueLabels_[j].first,
00516                          (*isolationValues[j])[source]);
00517     }
00518     else
00519       anElectron.setIsolation(isolationValueLabels_[j].first,
00520                          (*isolationValues[j])[elecRef]);
00521   }
00522 
00523 
00524 
00525 }
00526 
00527 void PATElectronProducer::fillElectron2( Electron& anElectron,
00528                                          const reco::CandidatePtr& candPtrForIsolation,
00529                                          const reco::CandidatePtr& candPtrForGenMatch,
00530                                          const reco::CandidatePtr& candPtrForLoader,
00531                                          const GenAssociations& genMatches,
00532                                          const IsoDepositMaps& deposits,
00533                                          const IsolationValueMaps& isolationValues) const {
00534 
00535   //COLIN/Florian: use the PFCandidate 4-mom.
00536   anElectron.setEcalDrivenMomentum(anElectron.p4()) ;
00537   anElectron.setP4( anElectron.pfCandidateRef()->p4() );
00538   // Safer to take the mva from the PFCandidate in case of ambiguosity
00539   anElectron.setMva( anElectron.pfCandidateRef()->mva_e_pi() ); 
00540 
00541   // is the concrete elecRef needed for the efficiency loader? what is this loader?
00542   // how can we make it compatible with the particle flow electrons?
00543 
00544   if (embedGsfElectronCore_) anElectron.embedGsfElectronCore();
00545   if (embedGsfTrack_) anElectron.embedGsfTrack();
00546   if (embedSuperCluster_) anElectron.embedSuperCluster();
00547   if (embedTrack_) anElectron.embedTrack();
00548 
00549   // store the match to the generated final state muons
00550 
00551   if (addGenMatch_) {
00552     for(size_t i = 0, n = genMatches.size(); i < n; ++i) {
00553       reco::GenParticleRef genElectron = (*genMatches[i])[candPtrForGenMatch];
00554       anElectron.addGenParticleRef(genElectron);
00555     }
00556     if (embedGenMatch_) anElectron.embedGenParticle();
00557   }
00558 
00559   //COLIN what's this? does it have to be GsfElectron specific?
00560   if (efficiencyLoader_.enabled()) {
00561     efficiencyLoader_.setEfficiencies( anElectron, candPtrForLoader );
00562   }
00563 
00564   if (resolutionLoader_.enabled()) {
00565     resolutionLoader_.setResolutions(anElectron);
00566   }
00567 
00568   for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00569     if( isoDepositLabels_[j].first==pat::TrackIso ||
00570         isoDepositLabels_[j].first==pat::EcalIso ||
00571         isoDepositLabels_[j].first==pat::HcalIso ) {
00572 
00573       anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00574                                (*deposits[j])[candPtrForGenMatch]);
00575     }
00576     else if (deposits[j]->contains(candPtrForIsolation.id())) {
00577       anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00578                                (*deposits[j])[candPtrForIsolation]);
00579     }
00580     else {
00581       anElectron.setIsoDeposit(isoDepositLabels_[j].first,
00582                                (*deposits[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
00583     }
00584   }
00585 
00586   for (size_t j = 0; j<isolationValues.size(); ++j) {
00587     if( isolationValueLabels_[j].first==pat::TrackIso ||
00588         isolationValueLabels_[j].first==pat::EcalIso ||
00589         isolationValueLabels_[j].first==pat::HcalIso ) {
00590       anElectron.setIsolation(isolationValueLabels_[j].first,
00591                               (*isolationValues[j])[candPtrForGenMatch]);
00592     }
00593     else if (isolationValues[j]->contains(candPtrForIsolation.id())) {
00594       anElectron.setIsolation(isolationValueLabels_[j].first,
00595                               (*isolationValues[j])[candPtrForIsolation]);
00596     }
00597     else {
00598       anElectron.setIsolation(isolationValueLabels_[j].first,
00599                               (*isolationValues[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
00600     }
00601   }
00602 }
00603 
00604 
00605 // ParameterSet description for module
00606 void PATElectronProducer::fillDescriptions(edm::ConfigurationDescriptions & descriptions)
00607 {
00608   edm::ParameterSetDescription iDesc;
00609   iDesc.setComment("PAT electron producer module");
00610 
00611   // input source
00612   iDesc.add<edm::InputTag>("electronSource", edm::InputTag("no default"))->setComment("input collection");
00613 
00614   // embedding
00615   iDesc.add<bool>("embedGsfElectronCore", true)->setComment("embed external gsf electron core");
00616   iDesc.add<bool>("embedGsfTrack", true)->setComment("embed external gsf track");
00617   iDesc.add<bool>("embedSuperCluster", true)->setComment("embed external super cluster");
00618   iDesc.add<bool>("embedTrack", false)->setComment("embed external track");
00619 
00620   // pf specific parameters
00621   iDesc.add<edm::InputTag>("pfElectronSource", edm::InputTag("pfElectrons"))->setComment("particle flow input collection");
00622   iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
00623   iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
00624 
00625   // MC matching configurables
00626   iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
00627   iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
00628   std::vector<edm::InputTag> emptySourceVector;
00629   iDesc.addNode( edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
00630                  edm::ParameterDescription<std::vector<edm::InputTag> >("genParticleMatch", emptySourceVector, true)
00631                  )->setComment("input with MC match information");
00632 
00633   // electron ID configurables
00634   iDesc.add<bool>("addElectronID",true)->setComment("add electron ID variables");
00635   edm::ParameterSetDescription electronIDSourcesPSet;
00636   electronIDSourcesPSet.setAllowAnything();
00637   iDesc.addNode( edm::ParameterDescription<edm::InputTag>("electronIDSource", edm::InputTag(), true) xor
00638                  edm::ParameterDescription<edm::ParameterSetDescription>("electronIDSources", electronIDSourcesPSet, true)
00639                  )->setComment("input with electron ID variables");
00640 
00641 
00642   // IsoDeposit configurables
00643   edm::ParameterSetDescription isoDepositsPSet;
00644   isoDepositsPSet.addOptional<edm::InputTag>("tracker");
00645   isoDepositsPSet.addOptional<edm::InputTag>("ecal");
00646   isoDepositsPSet.addOptional<edm::InputTag>("hcal");
00647   isoDepositsPSet.addOptional<edm::InputTag>("pfAllParticles");
00648   isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
00649   isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
00650   isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
00651   isoDepositsPSet.addOptional<std::vector<edm::InputTag> >("user");
00652   iDesc.addOptional("isoDeposits", isoDepositsPSet);
00653 
00654   // isolation values configurables
00655   edm::ParameterSetDescription isolationValuesPSet;
00656   isolationValuesPSet.addOptional<edm::InputTag>("tracker");
00657   isolationValuesPSet.addOptional<edm::InputTag>("ecal");
00658   isolationValuesPSet.addOptional<edm::InputTag>("hcal");
00659   isolationValuesPSet.addOptional<edm::InputTag>("pfAllParticles");
00660   isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
00661   isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
00662   isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
00663   isolationValuesPSet.addOptional<std::vector<edm::InputTag> >("user");
00664   iDesc.addOptional("isolationValues", isolationValuesPSet);
00665 
00666   // Efficiency configurables
00667   edm::ParameterSetDescription efficienciesPSet;
00668   efficienciesPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
00669   iDesc.add("efficiencies", efficienciesPSet);
00670   iDesc.add<bool>("addEfficiencies", false);
00671 
00672   // Check to see if the user wants to add user data
00673   edm::ParameterSetDescription userDataPSet;
00674   PATUserDataHelper<Electron>::fillDescription(userDataPSet);
00675   iDesc.addOptional("userData", userDataPSet);
00676 
00677   // electron shapes
00678   iDesc.add<bool>("addElectronShapes", true);
00679   iDesc.add<edm::InputTag>("reducedBarrelRecHitCollection", edm::InputTag("reducedEcalRecHitsEB"));
00680   iDesc.add<edm::InputTag>("reducedEndcapRecHitCollection", edm::InputTag("reducedEcalRecHitsEE"));
00681 
00682   edm::ParameterSetDescription isolationPSet;
00683   isolationPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
00684   iDesc.add("userIsolation", isolationPSet);
00685 
00686   // Resolution configurables
00687   pat::helper::KinResolutionsLoader::fillDescription(iDesc);
00688 
00689   iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
00690   edm::ParameterSetDescription highLevelPSet;
00691   highLevelPSet.setAllowAnything();
00692   iDesc.addNode( edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true)
00693                  )->setComment("input with high level selection");
00694   iDesc.addNode( edm::ParameterDescription<edm::InputTag>("pvSrc", edm::InputTag(), true)
00695                  )->setComment("input with high level selection");
00696   iDesc.addNode( edm::ParameterDescription<bool>("usePV", bool(), true)
00697                  )->setComment("input with high level selection, use primary vertex (true) or beam line (false)");
00698 
00699   descriptions.add("PATElectronProducer", iDesc);
00700 
00701 }
00702 
00703 
00704 
00705 void PATElectronProducer::readIsolationLabels( const edm::ParameterSet & iConfig,
00706                                                const char* psetName,
00707                                                IsolationLabels& labels) {
00708 
00709   labels.clear();
00710 
00711   if (iConfig.exists( psetName )) {
00712     edm::ParameterSet depconf
00713       = iConfig.getParameter<edm::ParameterSet>(psetName);
00714 
00715     if (depconf.exists("tracker")) labels.push_back(std::make_pair(pat::TrackIso, depconf.getParameter<edm::InputTag>("tracker")));
00716     if (depconf.exists("ecal"))    labels.push_back(std::make_pair(pat::EcalIso, depconf.getParameter<edm::InputTag>("ecal")));
00717     if (depconf.exists("hcal"))    labels.push_back(std::make_pair(pat::HcalIso, depconf.getParameter<edm::InputTag>("hcal")));
00718     if (depconf.exists("pfAllParticles"))  {
00719       labels.push_back(std::make_pair(pat::PfAllParticleIso, depconf.getParameter<edm::InputTag>("pfAllParticles")));
00720     }
00721     if (depconf.exists("pfChargedHadrons"))  {
00722       labels.push_back(std::make_pair(pat::PfChargedHadronIso, depconf.getParameter<edm::InputTag>("pfChargedHadrons")));
00723     }
00724     if (depconf.exists("pfNeutralHadrons"))  {
00725       labels.push_back(std::make_pair(pat::PfNeutralHadronIso, depconf.getParameter<edm::InputTag>("pfNeutralHadrons")));
00726     }
00727     if (depconf.exists("pfPhotons")) {
00728       labels.push_back(std::make_pair(pat::PfGammaIso, depconf.getParameter<edm::InputTag>("pfPhotons")));
00729     }
00730     if (depconf.exists("user")) {
00731       std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag> >("user");
00732       std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
00733       int key = UserBaseIso;
00734       for ( ; it != ed; ++it, ++key) {
00735         labels.push_back(std::make_pair(IsolationKeys(key), *it));
00736       }
00737     }
00738   }
00739 
00740 
00741 }
00742 
00743 
00744 #include "FWCore/Framework/interface/MakerMacros.h"
00745 
00746 DEFINE_FWK_MODULE(PATElectronProducer);