Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:22:47

0001 //
0002 //
0003 
0004 /**
0005   \class    pat::L1MuonMatcher L1MuonMatcher.h "MuonAnalysis/MuonAssociators/interface/L1MuonMatcher.h"
0006   \brief    Matcher of reconstructed objects to L1 Muons
0007 
0008   \author   Giovanni Petrucciani
0009   \version  $Id: L1MuonMatcher.cc,v 1.4 2011/03/31 09:59:33 gpetrucc Exp $
0010 */
0011 
0012 #include "FWCore/Framework/interface/stream/EDProducer.h"
0013 #include "FWCore/Framework/interface/Event.h"
0014 #include "FWCore/Utilities/interface/InputTag.h"
0015 
0016 #include "DataFormats/Math/interface/deltaR.h"
0017 #include "DataFormats/Math/interface/deltaPhi.h"
0018 
0019 #include "DataFormats/Common/interface/Association.h"
0020 #include "DataFormats/Common/interface/ValueMap.h"
0021 #include "DataFormats/Common/interface/Ptr.h"
0022 #include "DataFormats/Common/interface/View.h"
0023 
0024 #include "MuonAnalysis/MuonAssociators/interface/L1MuonMatcherAlgo.h"
0025 
0026 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
0027 
0028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0029 
0030 namespace pat {
0031 
0032   class L1MuonMatcher : public edm::stream::EDProducer<> {
0033   public:
0034     explicit L1MuonMatcher(const edm::ParameterSet &iConfig);
0035     ~L1MuonMatcher() override {}
0036 
0037     void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override;
0038 
0039   private:
0040     typedef pat::TriggerObjectStandAlone PATPrimitive;
0041     typedef pat::TriggerObjectStandAloneCollection PATPrimitiveCollection;
0042     typedef pat::TriggerObjectStandAloneMatch PATTriggerAssociation;
0043 
0044     L1MuonMatcherAlgo matcher_;
0045 
0046     /// Tokens for input collections
0047     edm::EDGetTokenT<edm::View<reco::Candidate> > recoToken_;
0048     edm::EDGetTokenT<std::vector<l1extra::L1MuonParticle> > l1Token_;
0049     edm::EDGetTokenT<l1t::MuonBxCollection> l1tToken_;
0050 
0051     /// Labels to set as filter names in the output
0052     std::string labelL1_, labelProp_;
0053 
0054     /// Write out additional info as ValueMaps
0055     bool writeExtraInfo_;
0056 
0057     /// Allow to run both on legacy or stage2 (2016) L1 Muon trigger output
0058     bool useStage2L1_;
0059 
0060     /// Skim stage2 BX vector
0061     int firstBX_;
0062     int lastBX_;
0063 
0064     /// Store extra information in a ValueMap
0065     template <typename Hand, typename T>
0066     void storeExtraInfo(edm::Event &iEvent,
0067                         const Hand &handle,
0068                         const std::vector<T> &values,
0069                         const std::string &label) const;
0070   };
0071 
0072 }  // namespace pat
0073 
0074 pat::L1MuonMatcher::L1MuonMatcher(const edm::ParameterSet &iConfig)
0075     : matcher_(iConfig, consumesCollector()),
0076       recoToken_(consumes<edm::View<reco::Candidate> >(iConfig.getParameter<edm::InputTag>("src"))),
0077       labelL1_(iConfig.getParameter<std::string>("setL1Label")),
0078       labelProp_(iConfig.getParameter<std::string>("setPropLabel")),
0079       writeExtraInfo_(iConfig.getParameter<bool>("writeExtraInfo")),
0080       useStage2L1_(iConfig.getParameter<bool>("useStage2L1")),
0081       firstBX_(iConfig.getParameter<int>("firstBX")),
0082       lastBX_(iConfig.getParameter<int>("lastBX")) {
0083   if (useStage2L1_) {
0084     l1tToken_ = consumes<l1t::MuonBxCollection>(iConfig.getParameter<edm::InputTag>("matched"));
0085   } else {
0086     l1Token_ = consumes<std::vector<l1extra::L1MuonParticle> >(iConfig.getParameter<edm::InputTag>("matched"));
0087   }
0088   produces<PATPrimitiveCollection>("l1muons");         // l1 in PAT format
0089   produces<PATPrimitiveCollection>("propagatedReco");  // reco to muon station 2
0090   produces<PATTriggerAssociation>("propagatedReco");   // asso reco to propagated reco
0091   produces<PATTriggerAssociation>();                   // asso reco to l1
0092   if (writeExtraInfo_) {
0093     produces<edm::ValueMap<float> >("deltaR");
0094     produces<edm::ValueMap<float> >("deltaPhi");
0095     produces<edm::ValueMap<int> >("quality");
0096     produces<edm::ValueMap<int> >("bx");
0097     if (useStage2L1_) {
0098       produces<edm::ValueMap<int> >("iPhi");
0099       produces<edm::ValueMap<int> >("tfIndex");
0100     }
0101     produces<edm::ValueMap<int> >("isolated");
0102     produces<edm::ValueMap<reco::CandidatePtr> >();
0103     produces<edm::ValueMap<reco::CandidatePtr> >("l1ToReco");
0104   }
0105 }
0106 
0107 void pat::L1MuonMatcher::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0108   using namespace edm;
0109   using namespace std;
0110 
0111   matcher_.init(iSetup);
0112 
0113   Handle<View<reco::Candidate> > reco;
0114   Handle<vector<l1extra::L1MuonParticle> > l1s;
0115   Handle<l1t::MuonBxCollection> l1tBX;
0116 
0117   std::vector<l1t::Muon> l1ts;
0118   std::vector<size_t> bxIdxs;
0119 
0120   int minBxIdx = 0;
0121   size_t l1size = 0;
0122 
0123   iEvent.getByToken(recoToken_, reco);
0124 
0125   if (useStage2L1_) {
0126     iEvent.getByToken(l1tToken_, l1tBX);
0127     l1size = l1tBX->size();
0128 
0129     int minBX = max(firstBX_, l1tBX->getFirstBX());
0130     int maxBX = min(lastBX_, l1tBX->getLastBX());
0131 
0132     minBxIdx = l1tBX->begin(minBX) - l1tBX->begin();
0133     std::copy(l1tBX->begin(minBX), l1tBX->end(maxBX), std::back_inserter(l1ts));
0134 
0135     for (int ibx = l1tBX->getFirstBX(); ibx <= l1tBX->getLastBX(); ++ibx) {
0136       bxIdxs.push_back(l1tBX->end(ibx) - l1tBX->begin());
0137     }
0138   } else {
0139     iEvent.getByToken(l1Token_, l1s);
0140     l1size = l1s->size();
0141   }
0142 
0143   unique_ptr<PATPrimitiveCollection> propOut(new PATPrimitiveCollection());
0144   unique_ptr<PATPrimitiveCollection> l1Out(new PATPrimitiveCollection());
0145   std::vector<edm::Ptr<reco::Candidate> > l1rawMatches(reco->size());
0146   vector<int> isSelected(l1size, -1);
0147   std::vector<edm::Ptr<reco::Candidate> > whichRecoMatch(l1size);
0148   vector<int> propMatches(reco->size(), -1);
0149   vector<int> fullMatches(reco->size(), -1);
0150   vector<float> deltaRs(reco->size(), 999), deltaPhis(reco->size(), 999);
0151   vector<int> quality(reco->size(), 0), bx(reco->size(), -999), isolated(reco->size(), -999);
0152   vector<int> iPhi(reco->size(), 0), tfIndex(reco->size(), -999);
0153   for (int i = 0, n = reco->size(); i < n; ++i) {
0154     TrajectoryStateOnSurface propagated;
0155     const reco::Candidate &mu = (*reco)[i];
0156     int match = useStage2L1_ ? matcher_.match(mu, l1ts, deltaRs[i], deltaPhis[i], propagated)
0157                              : matcher_.match(mu, *l1s, deltaRs[i], deltaPhis[i], propagated);
0158     if (propagated.isValid()) {
0159       GlobalPoint pos = propagated.globalPosition();
0160       propMatches[i] = propOut->size();
0161       propOut->push_back(PATPrimitive(math::PtEtaPhiMLorentzVector(mu.pt(), pos.eta(), pos.phi(), mu.mass())));
0162       propOut->back().addFilterLabel(labelProp_);
0163       propOut->back().setCharge(mu.charge());
0164     }
0165     if (match != -1) {
0166       if (useStage2L1_) {
0167         match += minBxIdx;
0168       }
0169 
0170       whichRecoMatch[match] = reco->ptrAt(i);
0171 
0172       int charge = 0;
0173       math::PtEtaPhiMLorentzVector p4;
0174 
0175       if (useStage2L1_) {
0176         const l1t::Muon &l1t = (*l1tBX)[match];
0177         charge = l1t.charge();
0178         p4 = l1t.polarP4();
0179       } else {
0180         const l1extra::L1MuonParticle &l1 = (*l1s)[match];
0181         charge = l1.charge();
0182         p4 = l1.polarP4();
0183       }
0184 
0185       if (isSelected[match] == -1) {  // copy to output if needed
0186         isSelected[match] = l1Out->size();
0187         l1Out->push_back(PATPrimitive(p4));
0188         l1Out->back().addFilterLabel(labelL1_);
0189         l1Out->back().setCharge(charge);
0190       }
0191 
0192       fullMatches[i] = isSelected[match];  // index in the output collection
0193 
0194       if (useStage2L1_) {
0195         const l1t::Muon &l1t = (*l1tBX)[match];
0196         quality[i] = l1t.hwQual();
0197         bx[i] = l1tBX->getFirstBX() + (std::upper_bound(bxIdxs.begin(), bxIdxs.end(), match) - bxIdxs.begin());
0198         isolated[i] = l1t.hwIso();
0199         l1rawMatches[i] = edm::Ptr<reco::Candidate>(l1tBX, size_t(match));
0200         iPhi[i] = l1t.hwPhi();
0201         tfIndex[i] = l1t.tfMuonIndex();
0202       } else {
0203         const L1MuGMTCand &gmt = (*l1s)[match].gmtMuonCand();
0204         quality[i] = gmt.quality();
0205         bx[i] = gmt.bx();
0206         isolated[i] = gmt.isol();
0207         l1rawMatches[i] = edm::Ptr<reco::Candidate>(l1s, size_t(match));
0208       }
0209     }
0210   }
0211 
0212   OrphanHandle<PATPrimitiveCollection> l1Done = iEvent.put(std::move(l1Out), "l1muons");
0213   OrphanHandle<PATPrimitiveCollection> propDone = iEvent.put(std::move(propOut), "propagatedReco");
0214 
0215   unique_ptr<PATTriggerAssociation> propAss(new PATTriggerAssociation(propDone));
0216   PATTriggerAssociation::Filler propFiller(*propAss);
0217   propFiller.insert(reco, propMatches.begin(), propMatches.end());
0218   propFiller.fill();
0219   iEvent.put(std::move(propAss), "propagatedReco");
0220 
0221   unique_ptr<PATTriggerAssociation> fullAss(new PATTriggerAssociation(l1Done));
0222   PATTriggerAssociation::Filler fullFiller(*fullAss);
0223   fullFiller.insert(reco, fullMatches.begin(), fullMatches.end());
0224   fullFiller.fill();
0225   iEvent.put(std::move(fullAss));
0226 
0227   if (writeExtraInfo_) {
0228     storeExtraInfo(iEvent, reco, deltaRs, "deltaR");
0229     storeExtraInfo(iEvent, reco, deltaPhis, "deltaPhi");
0230     storeExtraInfo(iEvent, reco, bx, "bx");
0231     storeExtraInfo(iEvent, reco, isolated, "isolated");
0232     storeExtraInfo(iEvent, reco, quality, "quality");
0233     storeExtraInfo(iEvent, reco, l1rawMatches, "");
0234     if (useStage2L1_) {
0235       storeExtraInfo(iEvent, l1tBX, whichRecoMatch, "l1ToReco");
0236       storeExtraInfo(iEvent, reco, tfIndex, "tfIndex");
0237       storeExtraInfo(iEvent, reco, iPhi, "iPhi");
0238     } else {
0239       storeExtraInfo(iEvent, l1s, whichRecoMatch, "l1ToReco");
0240     }
0241   }
0242 }
0243 
0244 template <typename Hand, typename T>
0245 void pat::L1MuonMatcher::storeExtraInfo(edm::Event &iEvent,
0246                                         const Hand &handle,
0247                                         const std::vector<T> &values,
0248                                         const std::string &label) const {
0249   using namespace edm;
0250   using namespace std;
0251   unique_ptr<ValueMap<T> > valMap(new ValueMap<T>());
0252   typename edm::ValueMap<T>::Filler filler(*valMap);
0253   filler.insert(handle, values.begin(), values.end());
0254   filler.fill();
0255   iEvent.put(std::move(valMap), label);
0256 }
0257 
0258 #include "FWCore/Framework/interface/MakerMacros.h"
0259 using namespace pat;
0260 DEFINE_FWK_MODULE(L1MuonMatcher);