File indexing completed on 2024-04-06 12:23:51
0001
0002
0003
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 }
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
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
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);