CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/PhysicsTools/PatAlgos/plugins/PATMuonProducer.cc

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