Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:23:51

0001 /**
0002   \class    pat::PATMuonSlimmer PATMuonSlimmer.h "PhysicsTools/PatAlgos/interface/PATMuonSlimmer.h"
0003   \brief    Slimmer of PAT Muons 
0004 */
0005 
0006 #include "FWCore/Framework/interface/Frameworkfwd.h"
0007 #include "FWCore/Framework/interface/stream/EDProducer.h"
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 
0011 #include "DataFormats/Common/interface/View.h"
0012 #include "DataFormats/Common/interface/Association.h"
0013 #include "DataFormats/Common/interface/RefToPtr.h"
0014 
0015 #include "DataFormats/PatCandidates/interface/Muon.h"
0016 #include "PhysicsTools/PatAlgos/interface/ObjectModifier.h"
0017 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0018 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0019 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0020 #include "CommonTools/UtilAlgos/interface/StringCutObjectSelector.h"
0021 #include "DataFormats/Math/interface/libminifloat.h"
0022 
0023 namespace pat {
0024 
0025   class PATMuonSlimmer : public edm::stream::EDProducer<> {
0026   public:
0027     explicit PATMuonSlimmer(const edm::ParameterSet &iConfig);
0028     ~PATMuonSlimmer() override {}
0029 
0030     void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override;
0031 
0032   private:
0033     const edm::EDGetTokenT<pat::MuonCollection> src_;
0034     std::vector<edm::EDGetTokenT<reco::PFCandidateCollection>> pf_;
0035     std::vector<edm::EDGetTokenT<edm::Association<pat::PackedCandidateCollection>>> pf2pc_;
0036     edm::EDGetTokenT<edm::Association<pat::PackedCandidateCollection>> track2LostTrack_;
0037     const bool linkToPackedPF_, linkToLostTrack_;
0038     const StringCutObjectSelector<pat::Muon> saveTeVMuons_, dropDirectionalIso_, dropPfP4_, slimCaloVars_,
0039         slimKinkVars_, slimCaloMETCorr_, slimMatches_, segmentsMuonSelection_;
0040     const bool saveSegments_, modifyMuon_;
0041     std::unique_ptr<pat::ObjectModifier<pat::Muon>> muonModifier_;
0042     std::vector<edm::EDGetTokenT<edm::Association<reco::TrackExtraCollection>>> trackExtraAssocs_;
0043   };
0044 
0045 }  // namespace pat
0046 
0047 pat::PATMuonSlimmer::PATMuonSlimmer(const edm::ParameterSet &iConfig)
0048     : src_(consumes<pat::MuonCollection>(iConfig.getParameter<edm::InputTag>("src"))),
0049       linkToPackedPF_(iConfig.getParameter<bool>("linkToPackedPFCandidates")),
0050       linkToLostTrack_(iConfig.getParameter<bool>("linkToLostTrack")),
0051       saveTeVMuons_(iConfig.getParameter<std::string>("saveTeVMuons")),
0052       dropDirectionalIso_(iConfig.getParameter<std::string>("dropDirectionalIso")),
0053       dropPfP4_(iConfig.getParameter<std::string>("dropPfP4")),
0054       slimCaloVars_(iConfig.getParameter<std::string>("slimCaloVars")),
0055       slimKinkVars_(iConfig.getParameter<std::string>("slimKinkVars")),
0056       slimCaloMETCorr_(iConfig.getParameter<std::string>("slimCaloMETCorr")),
0057       slimMatches_(iConfig.getParameter<std::string>("slimMatches")),
0058       segmentsMuonSelection_(iConfig.getParameter<std::string>("segmentsMuonSelection")),
0059       saveSegments_(iConfig.getParameter<bool>("saveSegments")),
0060       modifyMuon_(iConfig.getParameter<bool>("modifyMuons")) {
0061   if (linkToPackedPF_) {
0062     const std::vector<edm::InputTag> &pf = iConfig.getParameter<std::vector<edm::InputTag>>("pfCandidates");
0063     const std::vector<edm::InputTag> &pf2pc = iConfig.getParameter<std::vector<edm::InputTag>>("packedPFCandidates");
0064     if (pf.size() != pf2pc.size())
0065       throw cms::Exception("Configuration") << "Mismatching pfCandidates and packedPFCandidates\n";
0066     for (const edm::InputTag &tag : pf)
0067       pf_.push_back(consumes<reco::PFCandidateCollection>(tag));
0068     for (const edm::InputTag &tag : pf2pc)
0069       pf2pc_.push_back(consumes<edm::Association<pat::PackedCandidateCollection>>(tag));
0070   }
0071   if (linkToLostTrack_) {
0072     track2LostTrack_ =
0073         consumes<edm::Association<pat::PackedCandidateCollection>>(iConfig.getParameter<edm::InputTag>("lostTracks"));
0074   }
0075 
0076   if (modifyMuon_) {
0077     const edm::ParameterSet &mod_config = iConfig.getParameter<edm::ParameterSet>("modifierConfig");
0078     muonModifier_ = std::make_unique<pat::ObjectModifier<pat::Muon>>(mod_config, consumesCollector());
0079   }
0080   produces<std::vector<pat::Muon>>();
0081   if (saveSegments_) {
0082     produces<DTRecSegment4DCollection>();
0083     produces<CSCSegmentCollection>();
0084   }
0085 
0086   //associations for rekeying of TrackExtra refs in embedded tracks
0087   std::vector<edm::InputTag> trackExtraAssocTags = iConfig.getParameter<std::vector<edm::InputTag>>("trackExtraAssocs");
0088   for (edm::InputTag const &tag : trackExtraAssocTags) {
0089     trackExtraAssocs_.push_back(consumes<edm::Association<reco::TrackExtraCollection>>(tag));
0090   }
0091 }
0092 
0093 void pat::PATMuonSlimmer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0094   using namespace edm;
0095   using namespace std;
0096 
0097   if (modifyMuon_)
0098     muonModifier_->setEventContent(iSetup);
0099 
0100   Handle<pat::MuonCollection> src;
0101   iEvent.getByToken(src_, src);
0102 
0103   auto out = std::make_unique<std::vector<pat::Muon>>();
0104   out->reserve(src->size());
0105 
0106   auto outDTSegments = std::make_unique<DTRecSegment4DCollection>();
0107   std::set<DTRecSegment4DRef> dtSegmentsRefs;
0108   auto outCSCSegments = std::make_unique<CSCSegmentCollection>();
0109   std::set<CSCSegmentRef> cscSegmentsRefs;
0110 
0111   if (modifyMuon_) {
0112     muonModifier_->setEvent(iEvent);
0113   }
0114 
0115   std::map<reco::CandidatePtr, pat::PackedCandidateRef> mu2pc;
0116   if (linkToPackedPF_) {
0117     Handle<reco::PFCandidateCollection> pf;
0118     Handle<edm::Association<pat::PackedCandidateCollection>> pf2pc;
0119     for (unsigned int ipfh = 0, npfh = pf_.size(); ipfh < npfh; ++ipfh) {
0120       iEvent.getByToken(pf_[ipfh], pf);
0121       iEvent.getByToken(pf2pc_[ipfh], pf2pc);
0122       const auto &pfcoll = (*pf);
0123       const auto &pfmap = (*pf2pc);
0124       for (unsigned int i = 0, n = pf->size(); i < n; ++i) {
0125         const reco::PFCandidate &p = pfcoll[i];
0126         if (p.muonRef().isNonnull())
0127           mu2pc[refToPtr(p.muonRef())] = pfmap[reco::PFCandidateRef(pf, i)];
0128       }
0129     }
0130   }
0131   if (linkToLostTrack_) {
0132     const auto &trk2LT = iEvent.get(track2LostTrack_);
0133     for (const auto &mu : *src) {
0134       const auto &track = dynamic_cast<const reco::Muon *>(mu.originalObject())->innerTrack();
0135       if (track.isNonnull() && trk2LT.contains(track.id())) {
0136         const auto &lostTrack = trk2LT[track];
0137         if (lostTrack.isNonnull())
0138           mu2pc[mu.refToOrig_] = lostTrack;
0139       }
0140     }
0141   }
0142 
0143   std::vector<edm::Handle<edm::Association<reco::TrackExtraCollection>>> trackExtraAssocs(trackExtraAssocs_.size());
0144   for (unsigned int i = 0; i < trackExtraAssocs_.size(); ++i) {
0145     iEvent.getByToken(trackExtraAssocs_[i], trackExtraAssocs[i]);
0146   }
0147 
0148   for (vector<pat::Muon>::const_iterator it = src->begin(), ed = src->end(); it != ed; ++it) {
0149     out->push_back(*it);
0150     pat::Muon &mu = out->back();
0151 
0152     if (modifyMuon_) {
0153       muonModifier_->modify(mu);
0154     }
0155 
0156     if (saveTeVMuons_(mu)) {
0157       mu.embedPickyMuon();
0158       mu.embedTpfmsMuon();
0159       mu.embedDytMuon();
0160     }
0161     if (linkToPackedPF_ || linkToLostTrack_) {
0162       mu.refToOrig_ = refToPtr(mu2pc[mu.refToOrig_]);
0163     }
0164     if (dropDirectionalIso_(mu)) {
0165       reco::MuonPFIsolation zero;
0166       mu.setPFIsolation("pfIsoMeanDRProfileR03", zero);
0167       mu.setPFIsolation("pfIsoSumDRProfileR03", zero);
0168       mu.setPFIsolation("pfIsoMeanDRProfileR04", zero);
0169       mu.setPFIsolation("pfIsoSumDRProfileR04", zero);
0170     }
0171     if (mu.isPFMuon() && dropPfP4_(mu))
0172       mu.setPFP4(reco::Particle::LorentzVector());
0173     if (slimCaloVars_(mu) && mu.isEnergyValid()) {
0174       reco::MuonEnergy ene = mu.calEnergy();
0175       if (ene.tower)
0176         ene.tower = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.tower);
0177       if (ene.towerS9)
0178         ene.towerS9 = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.towerS9);
0179       if (ene.had)
0180         ene.had = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.had);
0181       if (ene.hadS9)
0182         ene.hadS9 = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.hadS9);
0183       if (ene.hadMax)
0184         ene.hadMax = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.hadMax);
0185       if (ene.em)
0186         ene.em = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.em);
0187       if (ene.emS25)
0188         ene.emS25 = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.emS25);
0189       if (ene.emMax)
0190         ene.emMax = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.emMax);
0191       if (ene.hcal_time)
0192         ene.hcal_time = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.hcal_time);
0193       if (ene.hcal_timeError)
0194         ene.hcal_timeError = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.hcal_timeError);
0195       if (ene.ecal_time)
0196         ene.ecal_time = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.ecal_time);
0197       if (ene.ecal_timeError)
0198         ene.ecal_timeError = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.ecal_timeError);
0199       ene.ecal_position = math::XYZPointF(MiniFloatConverter::reduceMantissaToNbitsRounding<14>(ene.ecal_position.X()),
0200                                           MiniFloatConverter::reduceMantissaToNbitsRounding<14>(ene.ecal_position.Y()),
0201                                           MiniFloatConverter::reduceMantissaToNbitsRounding<14>(ene.ecal_position.Z()));
0202       ene.hcal_position = math::XYZPointF(MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.hcal_position.X()),
0203                                           MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.hcal_position.Y()),
0204                                           MiniFloatConverter::reduceMantissaToNbitsRounding<12>(ene.hcal_position.Z()));
0205       mu.setCalEnergy(ene);
0206     }
0207     if (slimKinkVars_(mu) && mu.isQualityValid()) {
0208       reco::MuonQuality qual = mu.combinedQuality();
0209       qual.tkKink_position =
0210           math::XYZPointF(MiniFloatConverter::reduceMantissaToNbitsRounding<12>(qual.tkKink_position.X()),
0211                           MiniFloatConverter::reduceMantissaToNbitsRounding<12>(qual.tkKink_position.Y()),
0212                           MiniFloatConverter::reduceMantissaToNbitsRounding<12>(qual.tkKink_position.Z()));
0213       mu.setCombinedQuality(qual);
0214     }
0215     if (slimCaloMETCorr_(mu) && mu.caloMETMuonCorrs().type() != reco::MuonMETCorrectionData::NotUsed) {
0216       reco::MuonMETCorrectionData corrs = mu.caloMETMuonCorrs();
0217       corrs = reco::MuonMETCorrectionData(corrs.type(),
0218                                           MiniFloatConverter::reduceMantissaToNbitsRounding<10>(corrs.corrX()),
0219                                           MiniFloatConverter::reduceMantissaToNbitsRounding<10>(corrs.corrY()));
0220       mu.embedCaloMETMuonCorrs(corrs);
0221     }
0222     if (slimMatches_(mu) && mu.isMatchesValid()) {
0223       for (reco::MuonChamberMatch &cmatch : mu.matches()) {
0224         cmatch.edgeX = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(cmatch.edgeX);
0225         cmatch.edgeY = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(cmatch.edgeY);
0226         cmatch.xErr = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(cmatch.xErr);
0227         cmatch.yErr = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(cmatch.yErr);
0228         cmatch.dXdZErr = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(cmatch.dXdZErr);
0229         cmatch.dYdZErr = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(cmatch.dYdZErr);
0230         for (reco::MuonSegmentMatch &smatch : cmatch.segmentMatches) {
0231           smatch.xErr = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(smatch.xErr);
0232           smatch.yErr = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(smatch.yErr);
0233           smatch.dXdZErr = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(smatch.dXdZErr);
0234           smatch.dYdZErr = MiniFloatConverter::reduceMantissaToNbitsRounding<12>(smatch.dYdZErr);
0235           if (saveSegments_ && segmentsMuonSelection_(mu)) {
0236             if (smatch.dtSegmentRef.isNonnull())
0237               dtSegmentsRefs.insert(smatch.dtSegmentRef);
0238             if (smatch.cscSegmentRef.isNonnull())
0239               cscSegmentsRefs.insert(smatch.cscSegmentRef);
0240           }
0241         }
0242       }
0243     }
0244     // rekey TrackExtra references in embedded tracks
0245     mu.rekeyEmbeddedTracks(trackExtraAssocs);
0246   }
0247 
0248   if (saveSegments_) {
0249     std::map<DTRecSegment4DRef, size_t> dtMap;
0250     std::vector<DTRecSegment4D> outDTSegmentsTmp;
0251     std::map<CSCSegmentRef, size_t> cscMap;
0252     std::vector<CSCSegment> outCSCSegmentsTmp;
0253     for (auto &seg : dtSegmentsRefs) {
0254       dtMap[seg] = outDTSegments->size();
0255       outDTSegmentsTmp.push_back(*seg);
0256     }
0257     for (auto &seg : cscSegmentsRefs) {
0258       cscMap[seg] = outCSCSegments->size();
0259       outCSCSegmentsTmp.push_back(*seg);
0260     }
0261     outDTSegments->put(DTChamberId(), outDTSegmentsTmp.begin(), outDTSegmentsTmp.end());
0262     outCSCSegments->put(CSCDetId(), outCSCSegmentsTmp.begin(), outCSCSegmentsTmp.end());
0263     auto dtHandle = iEvent.put(std::move(outDTSegments));
0264     auto cscHandle = iEvent.put(std::move(outCSCSegments));
0265     for (auto &mu : *out) {
0266       if (mu.isMatchesValid()) {
0267         for (reco::MuonChamberMatch &cmatch : mu.matches()) {
0268           for (reco::MuonSegmentMatch &smatch : cmatch.segmentMatches) {
0269             if (dtMap.find(smatch.dtSegmentRef) != dtMap.end())
0270               smatch.dtSegmentRef = DTRecSegment4DRef(dtHandle, dtMap[smatch.dtSegmentRef]);
0271             if (cscMap.find(smatch.cscSegmentRef) != cscMap.end())
0272               smatch.cscSegmentRef = CSCSegmentRef(cscHandle, cscMap[smatch.cscSegmentRef]);
0273           }
0274         }
0275       }
0276     }
0277   }
0278 
0279   iEvent.put(std::move(out));
0280 }
0281 
0282 #include "FWCore/Framework/interface/MakerMacros.h"
0283 using namespace pat;
0284 DEFINE_FWK_MODULE(PATMuonSlimmer);