CMS 3D CMS Logo

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

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