CMS 3D CMS Logo

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

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