CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/PhysicsTools/PatAlgos/plugins/PATMuonProducer.cc

Go to the documentation of this file.
00001 //
00002 // $Id: PATMuonProducer.cc,v 1.49.2.2 2012/09/21 15:49:27 vadler Exp $
00003 //
00004 
00005 #include "PhysicsTools/PatAlgos/plugins/PATMuonProducer.h"
00006 
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "FWCore/ParameterSet/interface/FileInPath.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 
00011 #include "DataFormats/MuonReco/interface/Muon.h"
00012 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00013 #include "DataFormats/MuonReco/interface/MuonCocktails.h"
00014 
00015 #include "DataFormats/TrackReco/interface/TrackToTrackMap.h"
00016 
00017 #include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidateFwd.h"
00018 #include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidate.h"
00019 
00020 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
00021 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00022 
00023 #include "DataFormats/Common/interface/Association.h"
00024 
00025 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00026 #include "DataFormats/VertexReco/interface/Vertex.h"
00027 
00028 
00029 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00030 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00031 
00032 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00033 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00034 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00035 #include "TrackingTools/IPTools/interface/IPTools.h"
00036 
00037 
00038 #include "TMath.h"
00039 
00040 #include <vector>
00041 #include <memory>
00042 
00043 
00044 using namespace pat;
00045 using namespace std;
00046 
00047 
00048 PATMuonProducer::PATMuonProducer(const edm::ParameterSet & iConfig) : useUserData_(iConfig.exists("userData")),
00049   isolator_(iConfig.exists("userIsolation") ? iConfig.getParameter<edm::ParameterSet>("userIsolation") : edm::ParameterSet(), false)
00050 {
00051   // input source
00052   muonSrc_ = iConfig.getParameter<edm::InputTag>( "muonSource" );
00053   // embedding of tracks
00054   embedBestTrack_ = iConfig.getParameter<bool>( "embedMuonBestTrack" );
00055   embedImprovedBestTrack_ = iConfig.getParameter<bool>( "embedImprovedMuonBestTrack" );
00056   embedTrack_ = iConfig.getParameter<bool>( "embedTrack" );
00057   embedCombinedMuon_ = iConfig.getParameter<bool>( "embedCombinedMuon"   );
00058   embedStandAloneMuon_ = iConfig.getParameter<bool>( "embedStandAloneMuon" );
00059   // embedding of muon MET correction information
00060   embedCaloMETMuonCorrs_ = iConfig.getParameter<bool>("embedCaloMETMuonCorrs" );
00061   embedTcMETMuonCorrs_ = iConfig.getParameter<bool>("embedTcMETMuonCorrs"   );
00062   caloMETMuonCorrs_ = iConfig.getParameter<edm::InputTag>("caloMETMuonCorrs" );
00063   tcMETMuonCorrs_ = iConfig.getParameter<edm::InputTag>("tcMETMuonCorrs"   );
00064   // pflow specific configurables
00065   useParticleFlow_ = iConfig.getParameter<bool>( "useParticleFlow" );
00066   embedPFCandidate_ = iConfig.getParameter<bool>( "embedPFCandidate" );
00067   pfMuonSrc_ = iConfig.getParameter<edm::InputTag>( "pfMuonSource" );
00068   // embedding of tracks from TeV refit
00069   embedPickyMuon_ = iConfig.getParameter<bool>( "embedPickyMuon" );
00070   embedTpfmsMuon_ = iConfig.getParameter<bool>( "embedTpfmsMuon" );
00071   embedDytMuon_ = iConfig.getParameter<bool>( "embedDytMuon" );
00072   // Monte Carlo matching
00073   addGenMatch_ = iConfig.getParameter<bool>( "addGenMatch" );
00074   if(addGenMatch_){
00075     embedGenMatch_ = iConfig.getParameter<bool>( "embedGenMatch" );
00076     if(iConfig.existsAs<edm::InputTag>("genParticleMatch")){
00077       genMatchSrc_.push_back(iConfig.getParameter<edm::InputTag>( "genParticleMatch" ));
00078     } else {
00079       genMatchSrc_ = iConfig.getParameter<std::vector<edm::InputTag> >( "genParticleMatch" );
00080     }
00081   }
00082   // efficiencies
00083   addEfficiencies_ = iConfig.getParameter<bool>("addEfficiencies");
00084   if(addEfficiencies_){
00085     efficiencyLoader_ = pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"));
00086   }
00087   // resolutions
00088   addResolutions_ = iConfig.getParameter<bool>("addResolutions");
00089   if (addResolutions_) {
00090     resolutionLoader_ = pat::helper::KinResolutionsLoader(iConfig.getParameter<edm::ParameterSet>("resolutions"));
00091   }
00092   // read isoDeposit labels, for direct embedding
00093   readIsolationLabels(iConfig, "isoDeposits", isoDepositLabels_);
00094   // read isolation value labels, for direct embedding
00095   readIsolationLabels(iConfig, "isolationValues", isolationValueLabels_);
00096   // check to see if the user wants to add user data
00097   if( useUserData_ ){
00098     userDataHelper_ = PATUserDataHelper<Muon>(iConfig.getParameter<edm::ParameterSet>("userData"));
00099   }
00100   // embed high level selection variables
00101   usePV_ = true;
00102   embedHighLevelSelection_ = iConfig.getParameter<bool>("embedHighLevelSelection");
00103   if ( embedHighLevelSelection_ ) {
00104     beamLineSrc_ = iConfig.getParameter<edm::InputTag>("beamLineSrc");
00105     usePV_ = iConfig.getParameter<bool>("usePV");
00106     pvSrc_ = iConfig.getParameter<edm::InputTag>("pvSrc");
00107   }
00108   // produces vector of muons
00109   produces<std::vector<Muon> >();
00110 }
00111 
00112 
00113 PATMuonProducer::~PATMuonProducer()
00114 {
00115 }
00116 
00117 void PATMuonProducer::produce(edm::Event & iEvent, const edm::EventSetup & iSetup)
00118 {
00119   // switch off embedding (in unschedules mode)
00120   if (iEvent.isRealData()){
00121     addGenMatch_   = false;
00122     embedGenMatch_ = false;
00123   }
00124 
00125   edm::Handle<edm::View<reco::Muon> > muons;
00126   iEvent.getByLabel(muonSrc_, muons);
00127 
00128   // get the ESHandle for the transient track builder,
00129   // if needed for high level selection embedding
00130   edm::ESHandle<TransientTrackBuilder> trackBuilder;
00131 
00132   if(isolator_.enabled()) isolator_.beginEvent(iEvent,iSetup);
00133   if(efficiencyLoader_.enabled()) efficiencyLoader_.newEvent(iEvent);
00134   if(resolutionLoader_.enabled()) resolutionLoader_.newEvent(iEvent, iSetup);
00135 
00136   IsoDepositMaps deposits(isoDepositLabels_.size());
00137   for (size_t j = 0; j<isoDepositLabels_.size(); ++j) {
00138     iEvent.getByLabel(isoDepositLabels_[j].second, deposits[j]);
00139   }
00140 
00141   IsolationValueMaps isolationValues(isolationValueLabels_.size());
00142   for (size_t j = 0; j<isolationValueLabels_.size(); ++j) {
00143     iEvent.getByLabel(isolationValueLabels_[j].second, isolationValues[j]);
00144   }
00145 
00146   // prepare the MC matching
00147   GenAssociations  genMatches(genMatchSrc_.size());
00148   if (addGenMatch_) {
00149     for (size_t j = 0, nd = genMatchSrc_.size(); j < nd; ++j) {
00150       iEvent.getByLabel(genMatchSrc_[j], genMatches[j]);
00151     }
00152   }
00153 
00154   // prepare the high level selection: needs beamline
00155   // OR primary vertex, depending on user selection
00156   reco::TrackBase::Point beamPoint(0,0,0);
00157   reco::Vertex primaryVertex;
00158   reco::BeamSpot beamSpot;
00159   bool beamSpotIsValid = false;
00160   bool primaryVertexIsValid = false;
00161   if ( embedHighLevelSelection_ ) {
00162     // get the beamspot
00163     edm::Handle<reco::BeamSpot> beamSpotHandle;
00164     iEvent.getByLabel(beamLineSrc_, beamSpotHandle);
00165 
00166     // get the primary vertex
00167     edm::Handle< std::vector<reco::Vertex> > pvHandle;
00168     iEvent.getByLabel( pvSrc_, pvHandle );
00169 
00170     if( beamSpotHandle.isValid() ){
00171       beamSpot = *beamSpotHandle;
00172       beamSpotIsValid = true;
00173     } else{
00174       edm::LogError("DataNotAvailable")
00175         << "No beam spot available from EventSetup, not adding high level selection \n";
00176     }
00177     beamPoint = reco::TrackBase::Point ( beamSpot.x0(), beamSpot.y0(), beamSpot.z0() );
00178     if( pvHandle.isValid() && !pvHandle->empty() ) {
00179       primaryVertex = pvHandle->at(0);
00180       primaryVertexIsValid = true;
00181     } else {
00182       edm::LogError("DataNotAvailable")
00183         << "No primary vertex available from EventSetup, not adding high level selection \n";
00184     }
00185     // this is needed by the IPTools methods from the tracking group
00186     iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", trackBuilder);
00187   }
00188 
00189   // this will be the new object collection
00190   std::vector<Muon> * patMuons = new std::vector<Muon>();
00191 
00192   if( useParticleFlow_ ){
00193     // get the PFCandidates of type muons
00194     edm::Handle< reco::PFCandidateCollection >  pfMuons;
00195     iEvent.getByLabel(pfMuonSrc_, pfMuons);
00196 
00197     unsigned index=0;
00198     for( reco::PFCandidateConstIterator i = pfMuons->begin(); i != pfMuons->end(); ++i, ++index) {
00199       const reco::PFCandidate& pfmu = *i;
00200       //const reco::IsolaPFCandidate& pfmu = *i;
00201       const reco::MuonRef& muonRef = pfmu.muonRef();
00202       assert( muonRef.isNonnull() );
00203 
00204       MuonBaseRef muonBaseRef(muonRef);
00205       Muon aMuon(muonBaseRef);
00206 
00207       if ( useUserData_ ) {
00208         userDataHelper_.add( aMuon, iEvent, iSetup );
00209       }
00210 
00211       // embed high level selection
00212       if ( embedHighLevelSelection_ ) {
00213         // get the tracks
00214         reco::TrackRef innerTrack = muonBaseRef->innerTrack();
00215         reco::TrackRef globalTrack= muonBaseRef->globalTrack();
00216         reco::TrackRef bestTrack  = muon::muonBestTrack(*muonBaseRef, reco::defaultTuneP).first;
00217 
00218         // Make sure the collection it points to is there
00219         if ( bestTrack.isNonnull() && bestTrack.isAvailable() ) {
00220           unsigned int nhits = bestTrack->numberOfValidHits(); // ????
00221           aMuon.setNumberOfValidHits( nhits );
00222 
00223           reco::TransientTrack tt = trackBuilder->build(bestTrack);
00224           embedHighLevel( aMuon,
00225                           bestTrack,
00226                           tt,
00227                           primaryVertex,
00228                           primaryVertexIsValid,
00229                           beamSpot,
00230                           beamSpotIsValid );
00231 
00232           // Correct to PV, or beam spot
00233           if ( !usePV_ ) {
00234             double corr_d0 = -1.0 * bestTrack->dxy( beamPoint );
00235             aMuon.setDB( corr_d0, -1.0 );
00236           } else {
00237             std::pair<bool,Measurement1D> result = IPTools::absoluteTransverseImpactParameter(tt, primaryVertex);
00238             double d0_corr = result.second.value();
00239             double d0_err = result.second.error();
00240             aMuon.setDB( d0_corr, d0_err );
00241           }
00242         }
00243 
00244         if ( globalTrack.isNonnull() && globalTrack.isAvailable() ) {
00245           double norm_chi2 = globalTrack->chi2() / globalTrack->ndof();
00246           aMuon.setNormChi2( norm_chi2 );
00247         }
00248       }
00249       reco::PFCandidateRef pfRef(pfMuons,index);
00250       //reco::PFCandidatePtr ptrToMother(pfMuons,index);
00251       reco::CandidateBaseRef pfBaseRef( pfRef );
00252 
00253       aMuon.setPFCandidateRef( pfRef  );
00254       if( embedPFCandidate_ ) aMuon.embedPFCandidate();
00255       fillMuon( aMuon, muonBaseRef, pfBaseRef, genMatches, deposits, isolationValues );
00256       patMuons->push_back(aMuon);
00257     }
00258   }
00259   else {
00260     edm::Handle<edm::View<reco::Muon> > muons;
00261     iEvent.getByLabel(muonSrc_, muons);
00262 
00263     // embedding of muon MET corrections
00264     edm::Handle<edm::ValueMap<reco::MuonMETCorrectionData> > caloMETMuonCorrs;
00265     //edm::ValueMap<reco::MuonMETCorrectionData> caloMETmuCorValueMap;
00266     if(embedCaloMETMuonCorrs_){
00267       iEvent.getByLabel(caloMETMuonCorrs_, caloMETMuonCorrs);
00268       //caloMETmuCorValueMap  = *caloMETmuCorValueMap_h;
00269     }
00270     edm::Handle<edm::ValueMap<reco::MuonMETCorrectionData> > tcMETMuonCorrs;
00271     //edm::ValueMap<reco::MuonMETCorrectionData> tcMETmuCorValueMap;
00272     if(embedTcMETMuonCorrs_) {
00273       iEvent.getByLabel(tcMETMuonCorrs_, tcMETMuonCorrs);
00274       //tcMETmuCorValueMap  = *tcMETmuCorValueMap_h;
00275     }
00276     for (edm::View<reco::Muon>::const_iterator itMuon = muons->begin(); itMuon != muons->end(); ++itMuon) {
00277       // construct the Muon from the ref -> save ref to original object
00278       unsigned int idx = itMuon - muons->begin();
00279       MuonBaseRef muonRef = muons->refAt(idx);
00280       reco::CandidateBaseRef muonBaseRef( muonRef );
00281 
00282       Muon aMuon(muonRef);
00283       fillMuon( aMuon, muonRef, muonBaseRef, genMatches, deposits, isolationValues);
00284 
00285       // Isolation
00286       if (isolator_.enabled()) {
00287         //reco::CandidatePtr mother =  ptrToMother->sourceCandidatePtr(0);
00288         isolator_.fill(*muons, idx, isolatorTmpStorage_);
00289         typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
00290         // better to loop backwards, so the vector is resized less times
00291         for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(), ed = isolatorTmpStorage_.rend(); it != ed; ++it) {
00292           aMuon.setIsolation(it->first, it->second);
00293         }
00294       }
00295 
00296       //       for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00297       //        aMuon.setIsoDeposit(isoDepositLabels_[j].first,
00298       //                            (*deposits[j])[muonRef]);
00299       //       }
00300 
00301       // add sel to selected
00302       edm::Ptr<reco::Muon> muonsPtr = muons->ptrAt(idx);
00303       if ( useUserData_ ) {
00304         userDataHelper_.add( aMuon, iEvent, iSetup );
00305       }
00306 
00307       // embed high level selection
00308       if ( embedHighLevelSelection_ ) {
00309         // get the tracks
00310         reco::TrackRef innerTrack = itMuon->innerTrack();
00311         reco::TrackRef globalTrack= itMuon->globalTrack();
00312         reco::TrackRef bestTrack  = muon::muonBestTrack(*itMuon, reco::defaultTuneP).first;
00313 
00314         // Make sure the collection it points to is there
00315         if ( bestTrack.isNonnull() && bestTrack.isAvailable() ) {
00316           unsigned int nhits = bestTrack->numberOfValidHits(); // ????
00317           aMuon.setNumberOfValidHits( nhits );
00318 
00319           reco::TransientTrack tt = trackBuilder->build(bestTrack);
00320           embedHighLevel( aMuon,
00321                           bestTrack,
00322                           tt,
00323                           primaryVertex,
00324                           primaryVertexIsValid,
00325                           beamSpot,
00326                           beamSpotIsValid );
00327 
00328           // Correct to PV, or beam spot
00329           if ( !usePV_ ) {
00330             double corr_d0 = -1.0 * bestTrack->dxy( beamPoint );
00331             aMuon.setDB( corr_d0, -1.0 );
00332           } else {
00333             std::pair<bool,Measurement1D> result = IPTools::absoluteTransverseImpactParameter(tt, primaryVertex);
00334             double d0_corr = result.second.value();
00335             double d0_err = result.second.error();
00336             aMuon.setDB( d0_corr, d0_err );
00337           }
00338         }
00339 
00340         if ( globalTrack.isNonnull() && globalTrack.isAvailable() ) {
00341           double norm_chi2 = globalTrack->chi2() / globalTrack->ndof();
00342           aMuon.setNormChi2( norm_chi2 );
00343         }
00344       }
00345 
00346       // embed MET muon corrections
00347       if( embedCaloMETMuonCorrs_ ) aMuon.embedCaloMETMuonCorrs((*caloMETMuonCorrs)[muonRef]);
00348       if( embedTcMETMuonCorrs_ ) aMuon.embedTcMETMuonCorrs((*tcMETMuonCorrs  )[muonRef]);
00349 
00350       patMuons->push_back(aMuon);
00351     }
00352   }
00353 
00354   // sort muons in pt
00355   std::sort(patMuons->begin(), patMuons->end(), pTComparator_);
00356 
00357   // put genEvt object in Event
00358   std::auto_ptr<std::vector<Muon> > ptr(patMuons);
00359   iEvent.put(ptr);
00360 
00361   if (isolator_.enabled()) isolator_.endEvent();
00362 }
00363 
00364 
00365 void PATMuonProducer::fillMuon( Muon& aMuon, const MuonBaseRef& muonRef, const reco::CandidateBaseRef& baseRef, const GenAssociations& genMatches, const IsoDepositMaps& deposits, const IsolationValueMaps& isolationValues ) const
00366 {
00367   // in the particle flow algorithm,
00368   // the muon momentum is recomputed.
00369   // the new value is stored as the momentum of the
00370   // resulting PFCandidate of type Muon, and choosen
00371   // as the pat::Muon momentum
00372   if (useParticleFlow_)
00373     aMuon.setP4( aMuon.pfCandidateRef()->p4() );
00374   if (embedBestTrack_)         aMuon.embedMuonBestTrack();
00375   reco::Muon::MuonTrackTypePair newBestTrack = muon::muonBestTrack(aMuon, reco::defaultTuneP);
00376   aMuon.setBestTrack(newBestTrack.second);
00377   if (embedImprovedBestTrack_) aMuon.embedImprovedMuonBestTrack();
00378   reco::Muon::MuonTrackTypePair newImprovedBestTrack = muon::muonBestTrack(aMuon, reco::improvedTuneP);
00379   aMuon.setImprovedBestTrack(newImprovedBestTrack.second);
00380   if (embedTrack_)          aMuon.embedTrack();
00381   if (embedStandAloneMuon_) aMuon.embedStandAloneMuon();
00382   if (embedCombinedMuon_)   aMuon.embedCombinedMuon();
00383 
00384   // embed the TeV refit track refs (only available for globalMuons)
00385   if (aMuon.isGlobalMuon()) {
00386     if (embedPickyMuon_ && aMuon.isAValidMuonTrack(reco::Muon::Picky))
00387       aMuon.embedPickyMuon();
00388     if (embedTpfmsMuon_ && aMuon.isAValidMuonTrack(reco::Muon::TPFMS))
00389       aMuon.embedTpfmsMuon();
00390     if (embedDytMuon_ && aMuon.isAValidMuonTrack(reco::Muon::DYT))
00391       aMuon.embedDytMuon();
00392   }
00393 
00394   // store the match to the generated final state muons
00395   if (addGenMatch_) {
00396     for(size_t i = 0, n = genMatches.size(); i < n; ++i) {
00397       reco::GenParticleRef genMuon = (*genMatches[i])[baseRef];
00398       aMuon.addGenParticleRef(genMuon);
00399     }
00400     if (embedGenMatch_) aMuon.embedGenParticle();
00401   }
00402   if (efficiencyLoader_.enabled()) {
00403     efficiencyLoader_.setEfficiencies( aMuon, muonRef );
00404   }
00405 
00406   for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
00407     if(useParticleFlow_) {
00408       if (deposits[j]->contains(baseRef.id())) {
00409         aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[baseRef]);
00410       } else if (deposits[j]->contains(muonRef.id())){
00411         aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[muonRef]);
00412       } else {
00413         reco::CandidatePtr source = aMuon.pfCandidateRef()->sourceCandidatePtr(0);
00414         aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[source]);
00415       }
00416     }
00417     else{
00418       aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[muonRef]);
00419     }
00420   }
00421 
00422   for (size_t j = 0; j<isolationValues.size(); ++j) {
00423     if(useParticleFlow_) {
00424       if (isolationValues[j]->contains(baseRef.id())) {
00425         aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[baseRef]);
00426       } else if (isolationValues[j]->contains(muonRef.id())) {
00427         aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[muonRef]);
00428       } else {
00429         reco::CandidatePtr source = aMuon.pfCandidateRef()->sourceCandidatePtr(0);
00430         aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[source]);
00431       }
00432     }
00433     else{
00434       aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[muonRef]);
00435     }
00436   }
00437 
00438   if (resolutionLoader_.enabled()) {
00439     resolutionLoader_.setResolutions(aMuon);
00440   }
00441 }
00442 
00443 // ParameterSet description for module
00444 void PATMuonProducer::fillDescriptions(edm::ConfigurationDescriptions & descriptions)
00445 {
00446   edm::ParameterSetDescription iDesc;
00447   iDesc.setComment("PAT muon producer module");
00448 
00449   // input source
00450   iDesc.add<edm::InputTag>("muonSource", edm::InputTag("no default"))->setComment("input collection");
00451 
00452   // embedding
00453   iDesc.add<bool>("embedMuonBestTrack", true)->setComment("embed muon best track");
00454   iDesc.add<bool>("embedImprovedMuonBestTrack", true)->setComment("embed muon best track, new tuneP (only 53X)");
00455   iDesc.add<bool>("embedTrack", true)->setComment("embed external track");
00456   iDesc.add<bool>("embedStandAloneMuon", true)->setComment("embed external stand-alone muon");
00457   iDesc.add<bool>("embedCombinedMuon", false)->setComment("embed external combined muon");
00458   iDesc.add<bool>("embedPickyMuon", false)->setComment("embed external picky track");
00459   iDesc.add<bool>("embedTpfmsMuon", false)->setComment("embed external tpfms track");
00460   iDesc.add<bool>("embedDytMuon", false)->setComment("embed external dyt track ");
00461 
00462   // embedding of MET muon corrections
00463   iDesc.add<bool>("embedCaloMETMuonCorrs", true)->setComment("whether to add MET muon correction for caloMET or not");
00464   iDesc.add<edm::InputTag>("caloMETMuonCorrs", edm::InputTag("muonMETValueMapProducer"  , "muCorrData"))->setComment("source of MET muon corrections for caloMET");
00465   iDesc.add<bool>("embedTcMETMuonCorrs", true)->setComment("whether to add MET muon correction for tcMET or not");
00466   iDesc.add<edm::InputTag>("tcMETMuonCorrs", edm::InputTag("muonTCMETValueMapProducer"  , "muCorrData"))->setComment("source of MET muon corrections for tcMET");
00467 
00468   // pf specific parameters
00469   iDesc.add<edm::InputTag>("pfMuonSource", edm::InputTag("pfMuons"))->setComment("particle flow input collection");
00470   iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
00471   iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
00472 
00473   // MC matching configurables
00474   iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
00475   iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
00476   std::vector<edm::InputTag> emptySourceVector;
00477   iDesc.addNode( edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
00478                  edm::ParameterDescription<std::vector<edm::InputTag> >("genParticleMatch", emptySourceVector, true)
00479                  )->setComment("input with MC match information");
00480 
00481   pat::helper::KinResolutionsLoader::fillDescription(iDesc);
00482 
00483   // IsoDeposit configurables
00484   edm::ParameterSetDescription isoDepositsPSet;
00485   isoDepositsPSet.addOptional<edm::InputTag>("tracker");
00486   isoDepositsPSet.addOptional<edm::InputTag>("ecal");
00487   isoDepositsPSet.addOptional<edm::InputTag>("hcal");
00488   isoDepositsPSet.addOptional<edm::InputTag>("particle");
00489   isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
00490   isoDepositsPSet.addOptional<edm::InputTag>("pfChargedAll");
00491   isoDepositsPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
00492   isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
00493   isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
00494   isoDepositsPSet.addOptional<std::vector<edm::InputTag> >("user");
00495   iDesc.addOptional("isoDeposits", isoDepositsPSet);
00496 
00497   // isolation values configurables
00498   edm::ParameterSetDescription isolationValuesPSet;
00499   isolationValuesPSet.addOptional<edm::InputTag>("tracker");
00500   isolationValuesPSet.addOptional<edm::InputTag>("ecal");
00501   isolationValuesPSet.addOptional<edm::InputTag>("hcal");
00502   isolationValuesPSet.addOptional<edm::InputTag>("particle");
00503   isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
00504   isolationValuesPSet.addOptional<edm::InputTag>("pfChargedAll");
00505   isolationValuesPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
00506   isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
00507   isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
00508   iDesc.addOptional("isolationValues", isolationValuesPSet);
00509 
00510   // Efficiency configurables
00511   edm::ParameterSetDescription efficienciesPSet;
00512   efficienciesPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
00513   iDesc.add("efficiencies", efficienciesPSet);
00514   iDesc.add<bool>("addEfficiencies", false);
00515 
00516   // Check to see if the user wants to add user data
00517   edm::ParameterSetDescription userDataPSet;
00518   PATUserDataHelper<Muon>::fillDescription(userDataPSet);
00519   iDesc.addOptional("userData", userDataPSet);
00520 
00521   edm::ParameterSetDescription isolationPSet;
00522   isolationPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
00523   iDesc.add("userIsolation", isolationPSet);
00524 
00525   iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
00526   edm::ParameterSetDescription highLevelPSet;
00527   highLevelPSet.setAllowAnything();
00528   iDesc.addNode( edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true)
00529                  )->setComment("input with high level selection");
00530   iDesc.addNode( edm::ParameterDescription<edm::InputTag>("pvSrc", edm::InputTag(), true)
00531                  )->setComment("input with high level selection");
00532   iDesc.addNode( edm::ParameterDescription<bool>("usePV", bool(), true)
00533                  )->setComment("input with high level selection, use primary vertex (true) or beam line (false)");
00534 
00535   //descriptions.add("PATMuonProducer", iDesc);
00536 }
00537 
00538 
00539 void PATMuonProducer::readIsolationLabels( const edm::ParameterSet & iConfig, const char* psetName, IsolationLabels& labels)
00540 {
00541   labels.clear();
00542 
00543   if (iConfig.exists( psetName )) {
00544     edm::ParameterSet depconf = iConfig.getParameter<edm::ParameterSet>(psetName);
00545 
00546     if (depconf.exists("tracker")) labels.push_back(std::make_pair(pat::TrackIso, depconf.getParameter<edm::InputTag>("tracker")));
00547     if (depconf.exists("ecal"))    labels.push_back(std::make_pair(pat::EcalIso, depconf.getParameter<edm::InputTag>("ecal")));
00548     if (depconf.exists("hcal"))    labels.push_back(std::make_pair(pat::HcalIso, depconf.getParameter<edm::InputTag>("hcal")));
00549     if (depconf.exists("pfAllParticles"))  {
00550       labels.push_back(std::make_pair(pat::PfAllParticleIso, depconf.getParameter<edm::InputTag>("pfAllParticles")));
00551     }
00552     if (depconf.exists("pfChargedHadrons"))  {
00553       labels.push_back(std::make_pair(pat::PfChargedHadronIso, depconf.getParameter<edm::InputTag>("pfChargedHadrons")));
00554     }
00555     if (depconf.exists("pfChargedAll"))  {
00556       labels.push_back(std::make_pair(pat::PfChargedAllIso, depconf.getParameter<edm::InputTag>("pfChargedAll")));
00557     }
00558     if (depconf.exists("pfPUChargedHadrons"))  {
00559       labels.push_back(std::make_pair(pat::PfPUChargedHadronIso, depconf.getParameter<edm::InputTag>("pfPUChargedHadrons")));
00560     }
00561     if (depconf.exists("pfNeutralHadrons"))  {
00562       labels.push_back(std::make_pair(pat::PfNeutralHadronIso, depconf.getParameter<edm::InputTag>("pfNeutralHadrons")));
00563     }
00564     if (depconf.exists("pfPhotons")) {
00565       labels.push_back(std::make_pair(pat::PfGammaIso, depconf.getParameter<edm::InputTag>("pfPhotons")));
00566     }
00567     if (depconf.exists("user")) {
00568       std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag> >("user");
00569       std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
00570       int key = UserBaseIso;
00571       for ( ; it != ed; ++it, ++key) {
00572         labels.push_back(std::make_pair(IsolationKeys(key), *it));
00573       }
00574     }
00575   }
00576 }
00577 
00578 
00579 
00580 // embed various impact parameters with errors
00581 // embed high level selection
00582 void PATMuonProducer::embedHighLevel( pat::Muon & aMuon,
00583                                       reco::TrackRef track,
00584                                       reco::TransientTrack & tt,
00585                                       reco::Vertex & primaryVertex,
00586                                       bool primaryVertexIsValid,
00587                                       reco::BeamSpot & beamspot,
00588                                       bool beamspotIsValid
00589                                       )
00590 {
00591   // Correct to PV
00592 
00593   // PV2D
00594   std::pair<bool,Measurement1D> result =
00595     IPTools::signedTransverseImpactParameter(tt,
00596                                              GlobalVector(track->px(),
00597                                                           track->py(),
00598                                                           track->pz()),
00599                                              primaryVertex);
00600   double d0_corr = result.second.value();
00601   double d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
00602   aMuon.setDB( d0_corr, d0_err, pat::Muon::PV2D);
00603 
00604 
00605   // PV3D
00606   result =
00607     IPTools::signedImpactParameter3D(tt,
00608                                      GlobalVector(track->px(),
00609                                                   track->py(),
00610                                                   track->pz()),
00611                                      primaryVertex);
00612   d0_corr = result.second.value();
00613   d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
00614   aMuon.setDB( d0_corr, d0_err, pat::Muon::PV3D);
00615 
00616 
00617   // Correct to beam spot
00618   // make a fake vertex out of beam spot
00619   reco::Vertex vBeamspot(beamspot.position(), beamspot.rotatedCovariance3D());
00620 
00621   // BS2D
00622   result =
00623     IPTools::signedTransverseImpactParameter(tt,
00624                                              GlobalVector(track->px(),
00625                                                           track->py(),
00626                                                           track->pz()),
00627                                              vBeamspot);
00628   d0_corr = result.second.value();
00629   d0_err = beamspotIsValid ? result.second.error() : -1.0;
00630   aMuon.setDB( d0_corr, d0_err, pat::Muon::BS2D);
00631 
00632     // BS3D
00633   result =
00634     IPTools::signedImpactParameter3D(tt,
00635                                      GlobalVector(track->px(),
00636                                                   track->py(),
00637                                                     track->pz()),
00638                                      vBeamspot);
00639   d0_corr = result.second.value();
00640   d0_err = beamspotIsValid ? result.second.error() : -1.0;
00641   aMuon.setDB( d0_corr, d0_err, pat::Muon::BS3D);
00642 }
00643 
00644 #include "FWCore/Framework/interface/MakerMacros.h"
00645 
00646 DEFINE_FWK_MODULE(PATMuonProducer);