CMS 3D CMS Logo

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

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