File indexing completed on 2022-06-14 02:53:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0013 #include "DataFormats/Common/interface/Association.h"
0014 #include "DataFormats/Common/interface/TriggerResults.h"
0015 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0016 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
0017 #include "DataFormats/Math/interface/deltaPhi.h"
0018 #include "DataFormats/Math/interface/deltaR.h"
0019 #include "DataFormats/MuonReco/interface/Muon.h"
0020 #include "DataFormats/MuonReco/interface/MuonSimInfo.h"
0021 #include "DataFormats/MuonReco/interface/MuonTimeExtra.h"
0022 #include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidate.h"
0023 #include "DataFormats/PatCandidates/interface/Muon.h"
0024 #include "DataFormats/PatCandidates/interface/PFIsolation.h"
0025 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0026 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
0027 #include "DataFormats/PatCandidates/interface/UserData.h"
0028 #include "DataFormats/VertexReco/interface/Vertex.h"
0029 #include "FWCore/Framework/interface/Event.h"
0030 #include "FWCore/Framework/interface/stream/EDProducer.h"
0031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0032 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0033 #include "FWCore/ParameterSet/interface/EmptyGroupDescription.h"
0034 #include "FWCore/ParameterSet/interface/FileInPath.h"
0035 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0036 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0037 #include "FWCore/Utilities/interface/Exception.h"
0038 #include "FWCore/Utilities/interface/transform.h"
0039 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0040 #include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h"
0041 #include "JetMETCorrections/JetCorrector/interface/JetCorrector.h"
0042 #include "PhysicsTools/PatAlgos/interface/EfficiencyLoader.h"
0043 #include "PhysicsTools/PatAlgos/interface/KinResolutionsLoader.h"
0044 #include "PhysicsTools/PatAlgos/interface/MultiIsolator.h"
0045 #include "PhysicsTools/PatAlgos/interface/MuonMvaEstimator.h"
0046 #include "PhysicsTools/PatAlgos/interface/MuonMvaIDEstimator.h"
0047 #include "PhysicsTools/PatAlgos/interface/PATUserDataHelper.h"
0048 #include "PhysicsTools/PatAlgos/interface/SoftMuonMvaEstimator.h"
0049 #include "PhysicsTools/PatUtils/interface/MiniIsolation.h"
0050 #include "TrackingTools/IPTools/interface/IPTools.h"
0051 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0052 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0053 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0054
0055 namespace pat {
0056
0057 class PATMuonHeavyObjectCache {
0058 public:
0059 PATMuonHeavyObjectCache(const edm::ParameterSet&);
0060
0061 pat::MuonMvaEstimator const& muonMvaEstimator() const { return *muonMvaEstimator_; }
0062 pat::MuonMvaEstimator const& muonLowPtMvaEstimator() const { return *muonLowPtMvaEstimator_; }
0063 pat::MuonMvaIDEstimator const& muonMvaIDEstimator() const { return *muonMvaIDEstimator_; }
0064 pat::SoftMuonMvaEstimator const& softMuonMvaEstimator() const { return *softMuonMvaEstimator_; }
0065
0066 private:
0067 std::unique_ptr<const pat::MuonMvaEstimator> muonLowPtMvaEstimator_;
0068 std::unique_ptr<const pat::MuonMvaEstimator> muonMvaEstimator_;
0069 std::unique_ptr<const pat::MuonMvaIDEstimator> muonMvaIDEstimator_;
0070 std::unique_ptr<const pat::SoftMuonMvaEstimator> softMuonMvaEstimator_;
0071 };
0072
0073
0074 class TrackerIsolationPt;
0075 class CaloIsolationEnergy;
0076
0077
0078 class PATMuonProducer : public edm::stream::EDProducer<edm::GlobalCache<PATMuonHeavyObjectCache>> {
0079 public:
0080
0081 explicit PATMuonProducer(const edm::ParameterSet& iConfig, PATMuonHeavyObjectCache const*);
0082
0083 ~PATMuonProducer() override;
0084
0085 static std::unique_ptr<PATMuonHeavyObjectCache> initializeGlobalCache(const edm::ParameterSet& iConfig) {
0086 return std::make_unique<PATMuonHeavyObjectCache>(iConfig);
0087 }
0088
0089 static void globalEndJob(PATMuonHeavyObjectCache*) {}
0090
0091
0092 void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0093
0094 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0095
0096 private:
0097
0098 typedef edm::RefToBase<reco::Muon> MuonBaseRef;
0099 typedef std::vector<edm::Handle<edm::Association<reco::GenParticleCollection>>> GenAssociations;
0100 typedef std::vector<edm::Handle<edm::ValueMap<IsoDeposit>>> IsoDepositMaps;
0101 typedef std::vector<edm::Handle<edm::ValueMap<double>>> IsolationValueMaps;
0102 typedef std::pair<pat::IsolationKeys, edm::InputTag> IsolationLabel;
0103 typedef std::vector<IsolationLabel> IsolationLabels;
0104
0105
0106 void fillMuon(Muon& aMuon,
0107 const MuonBaseRef& muonRef,
0108 const reco::CandidateBaseRef& baseRef,
0109 const GenAssociations& genMatches,
0110 const IsoDepositMaps& deposits,
0111 const IsolationValueMaps& isolationValues) const;
0112
0113
0114 template <typename T>
0115 void readIsolationLabels(const edm::ParameterSet& iConfig,
0116 const char* psetName,
0117 IsolationLabels& labels,
0118 std::vector<edm::EDGetTokenT<edm::ValueMap<T>>>& tokens);
0119
0120 void setMuonMiniIso(pat::Muon& aMuon, const pat::PackedCandidateCollection* pc);
0121 double getRelMiniIsoPUCorrected(const pat::Muon& muon, double rho, const std::vector<double>& area);
0122
0123 double puppiCombinedIsolation(const pat::Muon& muon, const pat::PackedCandidateCollection* pc);
0124 bool isNeutralHadron(long pdgid);
0125 bool isChargedHadron(long pdgid);
0126 bool isPhoton(long pdgid);
0127
0128
0129
0130 void embedHighLevel(pat::Muon& aMuon,
0131 reco::TrackRef track,
0132 reco::TransientTrack& tt,
0133 reco::Vertex& primaryVertex,
0134 bool primaryVertexIsValid,
0135 reco::BeamSpot& beamspot,
0136 bool beamspotIsValid);
0137 double relMiniIsoPUCorrected(const pat::Muon& aMuon, double rho);
0138 std::optional<GlobalPoint> getMuonDirection(const reco::MuonChamberMatch& chamberMatch,
0139 const edm::ESHandle<GlobalTrackingGeometry>& geometry,
0140 const DetId& chamberId);
0141 void fillL1TriggerInfo(pat::Muon& muon,
0142 edm::Handle<std::vector<pat::TriggerObjectStandAlone>>& triggerObjects,
0143 const edm::TriggerNames& names,
0144 const edm::ESHandle<GlobalTrackingGeometry>& geometry);
0145 void fillHltTriggerInfo(pat::Muon& muon,
0146 edm::Handle<std::vector<pat::TriggerObjectStandAlone>>& triggerObjects,
0147 const edm::TriggerNames& names,
0148 const std::vector<std::string>& collection_names);
0149
0150 private:
0151
0152 edm::EDGetTokenT<edm::View<reco::Muon>> muonToken_;
0153
0154
0155 edm::EDGetTokenT<pat::PackedCandidateCollection> pcToken_;
0156 bool computeMiniIso_;
0157 bool computePuppiCombinedIso_;
0158 std::vector<double> effectiveAreaVec_;
0159 std::vector<double> miniIsoParams_;
0160 double relMiniIsoPUCorrected_;
0161
0162
0163 bool embedBestTrack_;
0164
0165 bool embedTunePBestTrack_;
0166
0167 bool forceEmbedBestTrack_;
0168
0169 bool embedTrack_;
0170
0171 bool embedStandAloneMuon_;
0172
0173 bool embedCombinedMuon_;
0174
0175 bool embedCaloMETMuonCorrs_;
0176
0177 edm::EDGetTokenT<edm::ValueMap<reco::MuonMETCorrectionData>> caloMETMuonCorrsToken_;
0178
0179 bool embedTcMETMuonCorrs_;
0180
0181 edm::EDGetTokenT<edm::ValueMap<reco::MuonMETCorrectionData>> tcMETMuonCorrsToken_;
0182
0183 bool embedPickyMuon_;
0184
0185 bool embedTpfmsMuon_;
0186
0187 bool embedDytMuon_;
0188
0189 bool addInverseBeta_;
0190
0191 edm::EDGetTokenT<edm::ValueMap<reco::MuonTimeExtra>> muonTimeExtraToken_;
0192
0193 bool addGenMatch_;
0194
0195 std::vector<edm::EDGetTokenT<edm::Association<reco::GenParticleCollection>>> genMatchTokens_;
0196
0197 bool embedGenMatch_;
0198
0199 bool addResolutions_;
0200
0201 pat::helper::KinResolutionsLoader resolutionLoader_;
0202
0203 bool useParticleFlow_;
0204
0205 edm::EDGetTokenT<reco::PFCandidateCollection> pfMuonToken_;
0206
0207 bool embedPFCandidate_;
0208
0209 bool embedHighLevelSelection_;
0210
0211 edm::EDGetTokenT<reco::BeamSpot> beamLineToken_;
0212
0213 edm::EDGetTokenT<std::vector<reco::Vertex>> pvToken_;
0214
0215 IsolationLabels isoDepositLabels_;
0216 std::vector<edm::EDGetTokenT<edm::ValueMap<IsoDeposit>>> isoDepositTokens_;
0217
0218 IsolationLabels isolationValueLabels_;
0219 std::vector<edm::EDGetTokenT<edm::ValueMap<double>>> isolationValueTokens_;
0220
0221 bool addEfficiencies_;
0222
0223 bool useUserData_;
0224
0225 bool embedPfEcalEnergy_;
0226
0227 bool addPuppiIsolation_;
0228
0229 edm::EDGetTokenT<edm::ValueMap<float>> PUPPIIsolation_charged_hadrons_;
0230 edm::EDGetTokenT<edm::ValueMap<float>> PUPPIIsolation_neutral_hadrons_;
0231 edm::EDGetTokenT<edm::ValueMap<float>> PUPPIIsolation_photons_;
0232
0233 edm::EDGetTokenT<edm::ValueMap<float>> PUPPINoLeptonsIsolation_charged_hadrons_;
0234 edm::EDGetTokenT<edm::ValueMap<float>> PUPPINoLeptonsIsolation_neutral_hadrons_;
0235 edm::EDGetTokenT<edm::ValueMap<float>> PUPPINoLeptonsIsolation_photons_;
0236
0237 bool computeMuonMVA_;
0238 bool computeMuonIDMVA_;
0239 bool computeSoftMuonMVA_;
0240 bool recomputeBasicSelectors_;
0241 bool mvaUseJec_;
0242 edm::EDGetTokenT<reco::JetTagCollection> mvaBTagCollectionTag_;
0243 edm::EDGetTokenT<reco::JetCorrector> mvaL1Corrector_;
0244 edm::EDGetTokenT<reco::JetCorrector> mvaL1L2L3ResCorrector_;
0245 edm::EDGetTokenT<double> rho_;
0246
0247
0248
0249 pat::helper::MultiIsolator isolator_;
0250
0251 pat::helper::MultiIsolator::IsolationValuePairs isolatorTmpStorage_;
0252
0253 pat::helper::EfficiencyLoader efficiencyLoader_;
0254
0255 pat::PATUserDataHelper<pat::Muon> userDataHelper_;
0256
0257
0258 edm::EDGetTokenT<edm::ValueMap<reco::MuonSimInfo>> simInfo_;
0259
0260
0261 bool addTriggerMatching_;
0262 edm::EDGetTokenT<std::vector<pat::TriggerObjectStandAlone>> triggerObjects_;
0263 edm::EDGetTokenT<edm::TriggerResults> triggerResults_;
0264 std::vector<std::string> hltCollectionFilters_;
0265
0266 const edm::ESGetToken<GlobalTrackingGeometry, GlobalTrackingGeometryRecord> geometryToken_;
0267 const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> transientTrackBuilderToken_;
0268
0269 const edm::EDPutTokenT<std::vector<Muon>> patMuonPutToken_;
0270 };
0271
0272 }
0273
0274 template <typename T>
0275 void pat::PATMuonProducer::readIsolationLabels(const edm::ParameterSet& iConfig,
0276 const char* psetName,
0277 pat::PATMuonProducer::IsolationLabels& labels,
0278 std::vector<edm::EDGetTokenT<edm::ValueMap<T>>>& tokens) {
0279 labels.clear();
0280
0281 if (iConfig.exists(psetName)) {
0282 edm::ParameterSet depconf = iConfig.getParameter<edm::ParameterSet>(psetName);
0283
0284 if (depconf.exists("tracker"))
0285 labels.emplace_back(pat::TrackIso, depconf.getParameter<edm::InputTag>("tracker"));
0286 if (depconf.exists("ecal"))
0287 labels.emplace_back(pat::EcalIso, depconf.getParameter<edm::InputTag>("ecal"));
0288 if (depconf.exists("hcal"))
0289 labels.emplace_back(pat::HcalIso, depconf.getParameter<edm::InputTag>("hcal"));
0290 if (depconf.exists("pfAllParticles")) {
0291 labels.emplace_back(pat::PfAllParticleIso, depconf.getParameter<edm::InputTag>("pfAllParticles"));
0292 }
0293 if (depconf.exists("pfChargedHadrons")) {
0294 labels.emplace_back(pat::PfChargedHadronIso, depconf.getParameter<edm::InputTag>("pfChargedHadrons"));
0295 }
0296 if (depconf.exists("pfChargedAll")) {
0297 labels.emplace_back(pat::PfChargedAllIso, depconf.getParameter<edm::InputTag>("pfChargedAll"));
0298 }
0299 if (depconf.exists("pfPUChargedHadrons")) {
0300 labels.emplace_back(pat::PfPUChargedHadronIso, depconf.getParameter<edm::InputTag>("pfPUChargedHadrons"));
0301 }
0302 if (depconf.exists("pfNeutralHadrons")) {
0303 labels.emplace_back(pat::PfNeutralHadronIso, depconf.getParameter<edm::InputTag>("pfNeutralHadrons"));
0304 }
0305 if (depconf.exists("pfPhotons")) {
0306 labels.emplace_back(pat::PfGammaIso, depconf.getParameter<edm::InputTag>("pfPhotons"));
0307 }
0308 if (depconf.exists("user")) {
0309 std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag>>("user");
0310 std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
0311 int key = pat::IsolationKeys::UserBaseIso;
0312 for (; it != ed; ++it, ++key) {
0313 labels.push_back(std::make_pair(pat::IsolationKeys(key), *it));
0314 }
0315 tokens = edm::vector_transform(
0316 labels, [this](IsolationLabel const& label) { return consumes<edm::ValueMap<T>>(label.second); });
0317 }
0318 }
0319 tokens = edm::vector_transform(labels, [this](pat::PATMuonProducer::IsolationLabel const& label) {
0320 return consumes<edm::ValueMap<T>>(label.second);
0321 });
0322 }
0323
0324 using namespace pat;
0325 using namespace std;
0326
0327 PATMuonHeavyObjectCache::PATMuonHeavyObjectCache(const edm::ParameterSet& iConfig) {
0328 if (iConfig.getParameter<bool>("computeMuonMVA")) {
0329 edm::FileInPath mvaTrainingFile = iConfig.getParameter<edm::FileInPath>("mvaTrainingFile");
0330 edm::FileInPath mvaLowPtTrainingFile = iConfig.getParameter<edm::FileInPath>("lowPtmvaTrainingFile");
0331 float mvaDrMax = iConfig.getParameter<double>("mvaDrMax");
0332 muonMvaEstimator_ = std::make_unique<MuonMvaEstimator>(mvaTrainingFile, mvaDrMax);
0333 muonLowPtMvaEstimator_ = std::make_unique<MuonMvaEstimator>(mvaLowPtTrainingFile, mvaDrMax);
0334 }
0335
0336 if (iConfig.getParameter<bool>("computeMuonIDMVA")) {
0337 edm::FileInPath mvaIDTrainingFile = iConfig.getParameter<edm::FileInPath>("mvaIDTrainingFile");
0338 muonMvaIDEstimator_ = std::make_unique<MuonMvaIDEstimator>(mvaIDTrainingFile);
0339 }
0340
0341 if (iConfig.getParameter<bool>("computeSoftMuonMVA")) {
0342 edm::FileInPath softMvaTrainingFile = iConfig.getParameter<edm::FileInPath>("softMvaTrainingFile");
0343 softMuonMvaEstimator_ = std::make_unique<SoftMuonMvaEstimator>(softMvaTrainingFile);
0344 }
0345 }
0346
0347 PATMuonProducer::PATMuonProducer(const edm::ParameterSet& iConfig, PATMuonHeavyObjectCache const*)
0348 : relMiniIsoPUCorrected_(0),
0349 useUserData_(iConfig.exists("userData")),
0350 computeMuonMVA_(false),
0351 computeMuonIDMVA_(false),
0352 computeSoftMuonMVA_(false),
0353 recomputeBasicSelectors_(false),
0354 mvaUseJec_(false),
0355 isolator_(iConfig.getParameter<edm::ParameterSet>("userIsolation"), consumesCollector(), false),
0356 geometryToken_{esConsumes()},
0357 transientTrackBuilderToken_{esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))},
0358 patMuonPutToken_{produces<std::vector<Muon>>()} {
0359
0360 muonToken_ = consumes<edm::View<reco::Muon>>(iConfig.getParameter<edm::InputTag>("muonSource"));
0361
0362 embedBestTrack_ = iConfig.getParameter<bool>("embedMuonBestTrack");
0363 embedTunePBestTrack_ = iConfig.getParameter<bool>("embedTunePMuonBestTrack");
0364 forceEmbedBestTrack_ = iConfig.getParameter<bool>("forceBestTrackEmbedding");
0365 embedTrack_ = iConfig.getParameter<bool>("embedTrack");
0366 embedCombinedMuon_ = iConfig.getParameter<bool>("embedCombinedMuon");
0367 embedStandAloneMuon_ = iConfig.getParameter<bool>("embedStandAloneMuon");
0368
0369 embedCaloMETMuonCorrs_ = iConfig.getParameter<bool>("embedCaloMETMuonCorrs");
0370 embedTcMETMuonCorrs_ = iConfig.getParameter<bool>("embedTcMETMuonCorrs");
0371 caloMETMuonCorrsToken_ =
0372 mayConsume<edm::ValueMap<reco::MuonMETCorrectionData>>(iConfig.getParameter<edm::InputTag>("caloMETMuonCorrs"));
0373 tcMETMuonCorrsToken_ =
0374 mayConsume<edm::ValueMap<reco::MuonMETCorrectionData>>(iConfig.getParameter<edm::InputTag>("tcMETMuonCorrs"));
0375
0376 useParticleFlow_ = iConfig.getParameter<bool>("useParticleFlow");
0377 embedPFCandidate_ = iConfig.getParameter<bool>("embedPFCandidate");
0378 pfMuonToken_ = mayConsume<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfMuonSource"));
0379 embedPfEcalEnergy_ = iConfig.getParameter<bool>("embedPfEcalEnergy");
0380
0381 embedPickyMuon_ = iConfig.getParameter<bool>("embedPickyMuon");
0382 embedTpfmsMuon_ = iConfig.getParameter<bool>("embedTpfmsMuon");
0383 embedDytMuon_ = iConfig.getParameter<bool>("embedDytMuon");
0384
0385 addInverseBeta_ = iConfig.getParameter<bool>("addInverseBeta");
0386 if (addInverseBeta_) {
0387 muonTimeExtraToken_ =
0388 consumes<edm::ValueMap<reco::MuonTimeExtra>>(iConfig.getParameter<edm::InputTag>("sourceMuonTimeExtra"));
0389 }
0390
0391 addGenMatch_ = iConfig.getParameter<bool>("addGenMatch");
0392 if (addGenMatch_) {
0393 embedGenMatch_ = iConfig.getParameter<bool>("embedGenMatch");
0394 if (iConfig.existsAs<edm::InputTag>("genParticleMatch")) {
0395 genMatchTokens_.push_back(consumes<edm::Association<reco::GenParticleCollection>>(
0396 iConfig.getParameter<edm::InputTag>("genParticleMatch")));
0397 } else {
0398 genMatchTokens_ = edm::vector_transform(
0399 iConfig.getParameter<std::vector<edm::InputTag>>("genParticleMatch"),
0400 [this](edm::InputTag const& tag) { return consumes<edm::Association<reco::GenParticleCollection>>(tag); });
0401 }
0402 }
0403
0404 addEfficiencies_ = iConfig.getParameter<bool>("addEfficiencies");
0405 if (addEfficiencies_) {
0406 efficiencyLoader_ =
0407 pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"), consumesCollector());
0408 }
0409
0410 addResolutions_ = iConfig.getParameter<bool>("addResolutions");
0411 if (addResolutions_) {
0412 resolutionLoader_ =
0413 pat::helper::KinResolutionsLoader(iConfig.getParameter<edm::ParameterSet>("resolutions"), consumesCollector());
0414 }
0415
0416 addPuppiIsolation_ = iConfig.getParameter<bool>("addPuppiIsolation");
0417 if (addPuppiIsolation_) {
0418 PUPPIIsolation_charged_hadrons_ =
0419 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationChargedHadrons"));
0420 PUPPIIsolation_neutral_hadrons_ =
0421 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationNeutralHadrons"));
0422 PUPPIIsolation_photons_ =
0423 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationPhotons"));
0424
0425 PUPPINoLeptonsIsolation_charged_hadrons_ =
0426 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationChargedHadrons"));
0427 PUPPINoLeptonsIsolation_neutral_hadrons_ =
0428 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationNeutralHadrons"));
0429 PUPPINoLeptonsIsolation_photons_ =
0430 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationPhotons"));
0431 }
0432
0433 readIsolationLabels(iConfig, "isoDeposits", isoDepositLabels_, isoDepositTokens_);
0434
0435 readIsolationLabels(iConfig, "isolationValues", isolationValueLabels_, isolationValueTokens_);
0436
0437 if (useUserData_) {
0438 userDataHelper_ = PATUserDataHelper<Muon>(iConfig.getParameter<edm::ParameterSet>("userData"), consumesCollector());
0439 }
0440
0441 embedHighLevelSelection_ = iConfig.getParameter<bool>("embedHighLevelSelection");
0442 if (embedHighLevelSelection_) {
0443 beamLineToken_ = consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamLineSrc"));
0444 pvToken_ = consumes<std::vector<reco::Vertex>>(iConfig.getParameter<edm::InputTag>("pvSrc"));
0445 }
0446
0447
0448 computeMiniIso_ = iConfig.getParameter<bool>("computeMiniIso");
0449
0450 computePuppiCombinedIso_ = iConfig.getParameter<bool>("computePuppiCombinedIso");
0451
0452 effectiveAreaVec_ = iConfig.getParameter<std::vector<double>>("effectiveAreaVec");
0453
0454 miniIsoParams_ = iConfig.getParameter<std::vector<double>>("miniIsoParams");
0455 if (computeMiniIso_ && miniIsoParams_.size() != 9) {
0456 throw cms::Exception("ParameterError") << "miniIsoParams must have exactly 9 elements.\n";
0457 }
0458 if (computeMiniIso_ || computePuppiCombinedIso_)
0459 pcToken_ = consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfCandsForMiniIso"));
0460
0461
0462 recomputeBasicSelectors_ = iConfig.getParameter<bool>("recomputeBasicSelectors");
0463 computeMuonMVA_ = iConfig.getParameter<bool>("computeMuonMVA");
0464 computeMuonIDMVA_ = iConfig.getParameter<bool>("computeMuonIDMVA");
0465 if (computeMuonMVA_ and not computeMiniIso_)
0466 throw cms::Exception("ConfigurationError") << "MiniIso is needed for Muon MVA calculation.\n";
0467
0468 if (computeMuonMVA_) {
0469
0470 mvaBTagCollectionTag_ = consumes<reco::JetTagCollection>(iConfig.getParameter<edm::InputTag>("mvaJetTag"));
0471 mvaL1Corrector_ = consumes<reco::JetCorrector>(iConfig.getParameter<edm::InputTag>("mvaL1Corrector"));
0472 mvaL1L2L3ResCorrector_ = consumes<reco::JetCorrector>(iConfig.getParameter<edm::InputTag>("mvaL1L2L3ResCorrector"));
0473 rho_ = consumes<double>(iConfig.getParameter<edm::InputTag>("rho"));
0474 mvaUseJec_ = iConfig.getParameter<bool>("mvaUseJec");
0475 }
0476
0477 computeSoftMuonMVA_ = iConfig.getParameter<bool>("computeSoftMuonMVA");
0478
0479
0480 simInfo_ = consumes<edm::ValueMap<reco::MuonSimInfo>>(iConfig.getParameter<edm::InputTag>("muonSimInfo"));
0481
0482 addTriggerMatching_ = iConfig.getParameter<bool>("addTriggerMatching");
0483 if (addTriggerMatching_) {
0484 triggerObjects_ =
0485 consumes<std::vector<pat::TriggerObjectStandAlone>>(iConfig.getParameter<edm::InputTag>("triggerObjects"));
0486 triggerResults_ = consumes<edm::TriggerResults>(iConfig.getParameter<edm::InputTag>("triggerResults"));
0487 }
0488 hltCollectionFilters_ = iConfig.getParameter<std::vector<std::string>>("hltCollectionFilters");
0489 }
0490
0491 PATMuonProducer::~PATMuonProducer() {}
0492
0493 std::optional<GlobalPoint> PATMuonProducer::getMuonDirection(const reco::MuonChamberMatch& chamberMatch,
0494 const edm::ESHandle<GlobalTrackingGeometry>& geometry,
0495 const DetId& chamberId) {
0496 const GeomDet* chamberGeometry = geometry->idToDet(chamberId);
0497 if (chamberGeometry) {
0498 LocalPoint localPosition(chamberMatch.x, chamberMatch.y, 0);
0499 return std::optional<GlobalPoint>(std::in_place, chamberGeometry->toGlobal(localPosition));
0500 }
0501 return std::optional<GlobalPoint>();
0502 }
0503
0504 void PATMuonProducer::fillL1TriggerInfo(pat::Muon& aMuon,
0505 edm::Handle<std::vector<pat::TriggerObjectStandAlone>>& triggerObjects,
0506 const edm::TriggerNames& names,
0507 const edm::ESHandle<GlobalTrackingGeometry>& geometry) {
0508
0509
0510
0511
0512
0513 std::optional<GlobalPoint> muonPosition;
0514
0515
0516
0517
0518 for (const auto& chamberMatch : aMuon.matches()) {
0519 if (chamberMatch.id.subdetId() == MuonSubdetId::DT) {
0520 DTChamberId detId(chamberMatch.id.rawId());
0521 if (abs(detId.station()) > 3)
0522 continue;
0523 muonPosition = getMuonDirection(chamberMatch, geometry, detId);
0524 if (abs(detId.station()) == 2)
0525 break;
0526 }
0527 if (chamberMatch.id.subdetId() == MuonSubdetId::CSC) {
0528 CSCDetId detId(chamberMatch.id.rawId());
0529 if (abs(detId.station()) > 3)
0530 continue;
0531 muonPosition = getMuonDirection(chamberMatch, geometry, detId);
0532 if (abs(detId.station()) == 2)
0533 break;
0534 }
0535 }
0536 if (not muonPosition)
0537 return;
0538 for (const auto& triggerObject : *triggerObjects) {
0539 if (triggerObject.hasTriggerObjectType(trigger::TriggerL1Mu)) {
0540 if (std::abs(triggerObject.eta()) < 0.001) {
0541
0542 if (deltaPhi(triggerObject.phi(), muonPosition->phi()) > 0.1)
0543 continue;
0544 } else {
0545
0546 if (deltaR(triggerObject.p4(), *muonPosition) > 0.15)
0547 continue;
0548 }
0549 pat::TriggerObjectStandAlone obj(triggerObject);
0550 obj.unpackPathNames(names);
0551 aMuon.addTriggerObjectMatch(obj);
0552 }
0553 }
0554 }
0555
0556 void PATMuonProducer::fillHltTriggerInfo(pat::Muon& muon,
0557 edm::Handle<std::vector<pat::TriggerObjectStandAlone>>& triggerObjects,
0558 const edm::TriggerNames& names,
0559 const std::vector<std::string>& collection_filter_names) {
0560
0561
0562 for (const auto& triggerObject : *triggerObjects) {
0563 if (triggerObject.hasTriggerObjectType(trigger::TriggerMuon)) {
0564 bool keepIt = false;
0565 for (const auto& name : collection_filter_names) {
0566 if (triggerObject.hasCollection(name)) {
0567 keepIt = true;
0568 break;
0569 }
0570 }
0571 if (not keepIt)
0572 continue;
0573 if (deltaR(triggerObject.p4(), muon) > 0.1)
0574 continue;
0575 pat::TriggerObjectStandAlone obj(triggerObject);
0576 obj.unpackPathNames(names);
0577 muon.addTriggerObjectMatch(obj);
0578 }
0579 }
0580 }
0581
0582 void PATMuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0583
0584 auto geometry = iSetup.getHandle(geometryToken_);
0585 if (!geometry.isValid())
0586 throw cms::Exception("FatalError") << "Unable to find GlobalTrackingGeometryRecord in event!\n";
0587
0588
0589 if (iEvent.isRealData()) {
0590 addGenMatch_ = false;
0591 embedGenMatch_ = false;
0592 }
0593
0594 edm::Handle<edm::View<reco::Muon>> muons;
0595 iEvent.getByToken(muonToken_, muons);
0596
0597 edm::Handle<pat::PackedCandidateCollection> pc;
0598 if (computeMiniIso_ || computePuppiCombinedIso_)
0599 iEvent.getByToken(pcToken_, pc);
0600
0601
0602
0603 TransientTrackBuilder const* trackBuilder = nullptr;
0604
0605 if (isolator_.enabled())
0606 isolator_.beginEvent(iEvent, iSetup);
0607 if (efficiencyLoader_.enabled())
0608 efficiencyLoader_.newEvent(iEvent);
0609 if (resolutionLoader_.enabled())
0610 resolutionLoader_.newEvent(iEvent, iSetup);
0611
0612 IsoDepositMaps deposits(isoDepositTokens_.size());
0613 for (size_t j = 0; j < isoDepositTokens_.size(); ++j) {
0614 iEvent.getByToken(isoDepositTokens_[j], deposits[j]);
0615 }
0616
0617 IsolationValueMaps isolationValues(isolationValueTokens_.size());
0618 for (size_t j = 0; j < isolationValueTokens_.size(); ++j) {
0619 iEvent.getByToken(isolationValueTokens_[j], isolationValues[j]);
0620 }
0621
0622
0623 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_charged_hadrons;
0624 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_neutral_hadrons;
0625 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_photons;
0626
0627 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_charged_hadrons;
0628 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_neutral_hadrons;
0629 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_photons;
0630 if (addPuppiIsolation_) {
0631
0632 iEvent.getByToken(PUPPIIsolation_charged_hadrons_, PUPPIIsolation_charged_hadrons);
0633 iEvent.getByToken(PUPPIIsolation_neutral_hadrons_, PUPPIIsolation_neutral_hadrons);
0634 iEvent.getByToken(PUPPIIsolation_photons_, PUPPIIsolation_photons);
0635
0636 iEvent.getByToken(PUPPINoLeptonsIsolation_charged_hadrons_, PUPPINoLeptonsIsolation_charged_hadrons);
0637 iEvent.getByToken(PUPPINoLeptonsIsolation_neutral_hadrons_, PUPPINoLeptonsIsolation_neutral_hadrons);
0638 iEvent.getByToken(PUPPINoLeptonsIsolation_photons_, PUPPINoLeptonsIsolation_photons);
0639 }
0640
0641
0642 edm::Handle<reco::JetTagCollection> mvaBTagCollectionTag;
0643 edm::Handle<reco::JetCorrector> mvaL1Corrector;
0644 edm::Handle<reco::JetCorrector> mvaL1L2L3ResCorrector;
0645 if (computeMuonMVA_) {
0646 iEvent.getByToken(mvaBTagCollectionTag_, mvaBTagCollectionTag);
0647 iEvent.getByToken(mvaL1Corrector_, mvaL1Corrector);
0648 iEvent.getByToken(mvaL1L2L3ResCorrector_, mvaL1L2L3ResCorrector);
0649 }
0650
0651
0652 GenAssociations genMatches(genMatchTokens_.size());
0653 if (addGenMatch_) {
0654 for (size_t j = 0, nd = genMatchTokens_.size(); j < nd; ++j) {
0655 iEvent.getByToken(genMatchTokens_[j], genMatches[j]);
0656 }
0657 }
0658
0659
0660
0661 reco::Vertex primaryVertex;
0662 reco::BeamSpot beamSpot;
0663 bool beamSpotIsValid = false;
0664 bool primaryVertexIsValid = false;
0665 if (embedHighLevelSelection_) {
0666
0667 edm::Handle<reco::BeamSpot> beamSpotHandle;
0668 iEvent.getByToken(beamLineToken_, beamSpotHandle);
0669
0670
0671 edm::Handle<std::vector<reco::Vertex>> pvHandle;
0672 iEvent.getByToken(pvToken_, pvHandle);
0673
0674 if (beamSpotHandle.isValid()) {
0675 beamSpot = *beamSpotHandle;
0676 beamSpotIsValid = true;
0677 } else {
0678 edm::LogError("DataNotAvailable") << "No beam spot available from EventSetup, not adding high level selection \n";
0679 }
0680 if (pvHandle.isValid() && !pvHandle->empty()) {
0681 primaryVertex = pvHandle->at(0);
0682 primaryVertexIsValid = true;
0683 } else {
0684 edm::LogError("DataNotAvailable")
0685 << "No primary vertex available from EventSetup, not adding high level selection \n";
0686 }
0687
0688 trackBuilder = &iSetup.getData(transientTrackBuilderToken_);
0689 }
0690
0691
0692 edm::Handle<edm::ValueMap<reco::MuonSimInfo>> simInfo;
0693 bool simInfoIsAvailalbe = iEvent.getByToken(simInfo_, simInfo);
0694
0695
0696 std::vector<Muon> patMuons;
0697
0698 edm::Handle<reco::PFCandidateCollection> pfMuons;
0699 if (useParticleFlow_) {
0700
0701 iEvent.getByToken(pfMuonToken_, pfMuons);
0702
0703 unsigned index = 0;
0704 for (reco::PFCandidateConstIterator i = pfMuons->begin(); i != pfMuons->end(); ++i, ++index) {
0705 const reco::PFCandidate& pfmu = *i;
0706
0707 const reco::MuonRef& muonRef = pfmu.muonRef();
0708 assert(muonRef.isNonnull());
0709
0710 MuonBaseRef muonBaseRef(muonRef);
0711 Muon aMuon(muonBaseRef);
0712
0713 if (useUserData_) {
0714 userDataHelper_.add(aMuon, iEvent, iSetup);
0715 }
0716
0717
0718 if (embedHighLevelSelection_) {
0719
0720 reco::TrackRef innerTrack = muonBaseRef->innerTrack();
0721 reco::TrackRef globalTrack = muonBaseRef->globalTrack();
0722 reco::TrackRef bestTrack = muonBaseRef->muonBestTrack();
0723 reco::TrackRef chosenTrack = innerTrack;
0724
0725 if (bestTrack.isNonnull() && bestTrack.isAvailable())
0726 chosenTrack = bestTrack;
0727
0728 if (chosenTrack.isNonnull() && chosenTrack.isAvailable()) {
0729 unsigned int nhits = chosenTrack->numberOfValidHits();
0730 aMuon.setNumberOfValidHits(nhits);
0731
0732 reco::TransientTrack tt = trackBuilder->build(chosenTrack);
0733 embedHighLevel(aMuon, chosenTrack, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
0734 }
0735
0736 if (globalTrack.isNonnull() && globalTrack.isAvailable() && !embedCombinedMuon_) {
0737 double norm_chi2 = globalTrack->chi2() / globalTrack->ndof();
0738 aMuon.setNormChi2(norm_chi2);
0739 }
0740 }
0741 reco::PFCandidateRef pfRef(pfMuons, index);
0742
0743 reco::CandidateBaseRef pfBaseRef(pfRef);
0744
0745 aMuon.setPFCandidateRef(pfRef);
0746 if (embedPFCandidate_)
0747 aMuon.embedPFCandidate();
0748 fillMuon(aMuon, muonBaseRef, pfBaseRef, genMatches, deposits, isolationValues);
0749
0750 if (computeMiniIso_)
0751 setMuonMiniIso(aMuon, pc.product());
0752
0753 if (addPuppiIsolation_) {
0754 aMuon.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[muonBaseRef],
0755 (*PUPPIIsolation_neutral_hadrons)[muonBaseRef],
0756 (*PUPPIIsolation_photons)[muonBaseRef]);
0757
0758 aMuon.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[muonBaseRef],
0759 (*PUPPINoLeptonsIsolation_neutral_hadrons)[muonBaseRef],
0760 (*PUPPINoLeptonsIsolation_photons)[muonBaseRef]);
0761 } else {
0762 aMuon.setIsolationPUPPI(-999., -999., -999.);
0763 aMuon.setIsolationPUPPINoLeptons(-999., -999., -999.);
0764 }
0765
0766 if (embedPfEcalEnergy_) {
0767 aMuon.setPfEcalEnergy(pfmu.ecalEnergy());
0768 }
0769
0770 patMuons.push_back(aMuon);
0771 }
0772 } else {
0773 edm::Handle<edm::View<reco::Muon>> muons;
0774 iEvent.getByToken(muonToken_, muons);
0775
0776
0777 edm::Handle<edm::ValueMap<reco::MuonMETCorrectionData>> caloMETMuonCorrs;
0778
0779 if (embedCaloMETMuonCorrs_) {
0780 iEvent.getByToken(caloMETMuonCorrsToken_, caloMETMuonCorrs);
0781
0782 }
0783 edm::Handle<edm::ValueMap<reco::MuonMETCorrectionData>> tcMETMuonCorrs;
0784
0785 if (embedTcMETMuonCorrs_) {
0786 iEvent.getByToken(tcMETMuonCorrsToken_, tcMETMuonCorrs);
0787
0788 }
0789
0790 if (embedPfEcalEnergy_ || embedPFCandidate_) {
0791
0792 iEvent.getByToken(pfMuonToken_, pfMuons);
0793 }
0794
0795 edm::Handle<edm::ValueMap<reco::MuonTimeExtra>> muonsTimeExtra;
0796 if (addInverseBeta_) {
0797
0798 iEvent.getByToken(muonTimeExtraToken_, muonsTimeExtra);
0799 }
0800
0801 for (edm::View<reco::Muon>::const_iterator itMuon = muons->begin(); itMuon != muons->end(); ++itMuon) {
0802
0803 unsigned int idx = itMuon - muons->begin();
0804 MuonBaseRef muonRef = muons->refAt(idx);
0805 reco::CandidateBaseRef muonBaseRef(muonRef);
0806
0807 Muon aMuon(muonRef);
0808 fillMuon(aMuon, muonRef, muonBaseRef, genMatches, deposits, isolationValues);
0809 if (computeMiniIso_)
0810 setMuonMiniIso(aMuon, pc.product());
0811 if (addPuppiIsolation_) {
0812 aMuon.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[muonRef],
0813 (*PUPPIIsolation_neutral_hadrons)[muonRef],
0814 (*PUPPIIsolation_photons)[muonRef]);
0815 aMuon.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[muonRef],
0816 (*PUPPINoLeptonsIsolation_neutral_hadrons)[muonRef],
0817 (*PUPPINoLeptonsIsolation_photons)[muonRef]);
0818 } else {
0819 aMuon.setIsolationPUPPI(-999., -999., -999.);
0820 aMuon.setIsolationPUPPINoLeptons(-999., -999., -999.);
0821 }
0822
0823
0824 if (isolator_.enabled()) {
0825
0826 isolator_.fill(*muons, idx, isolatorTmpStorage_);
0827 typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
0828
0829 for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(),
0830 ed = isolatorTmpStorage_.rend();
0831 it != ed;
0832 ++it) {
0833 aMuon.setIsolation(it->first, it->second);
0834 }
0835 }
0836
0837
0838
0839
0840
0841
0842
0843 edm::Ptr<reco::Muon> muonsPtr = muons->ptrAt(idx);
0844 if (useUserData_) {
0845 userDataHelper_.add(aMuon, iEvent, iSetup);
0846 }
0847
0848
0849 if (embedHighLevelSelection_) {
0850
0851 reco::TrackRef innerTrack = itMuon->innerTrack();
0852 reco::TrackRef globalTrack = itMuon->globalTrack();
0853 reco::TrackRef bestTrack = itMuon->muonBestTrack();
0854 reco::TrackRef chosenTrack = innerTrack;
0855
0856 if (bestTrack.isNonnull() && bestTrack.isAvailable())
0857 chosenTrack = bestTrack;
0858 if (chosenTrack.isNonnull() && chosenTrack.isAvailable()) {
0859 unsigned int nhits = chosenTrack->numberOfValidHits();
0860 aMuon.setNumberOfValidHits(nhits);
0861
0862 reco::TransientTrack tt = trackBuilder->build(chosenTrack);
0863 embedHighLevel(aMuon, chosenTrack, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
0864 }
0865
0866 if (globalTrack.isNonnull() && globalTrack.isAvailable()) {
0867 double norm_chi2 = globalTrack->chi2() / globalTrack->ndof();
0868 aMuon.setNormChi2(norm_chi2);
0869 }
0870 }
0871
0872
0873 if (embedCaloMETMuonCorrs_)
0874 aMuon.embedCaloMETMuonCorrs((*caloMETMuonCorrs)[muonRef]);
0875 if (embedTcMETMuonCorrs_)
0876 aMuon.embedTcMETMuonCorrs((*tcMETMuonCorrs)[muonRef]);
0877
0878 if (embedPfEcalEnergy_ || embedPFCandidate_) {
0879 if (embedPfEcalEnergy_)
0880 aMuon.setPfEcalEnergy(-99.0);
0881 unsigned index = 0;
0882 for (const reco::PFCandidate& pfmu : *pfMuons) {
0883 if (pfmu.muonRef().isNonnull()) {
0884 if (pfmu.muonRef().id() != muonRef.id())
0885 throw cms::Exception("Configuration")
0886 << "Muon reference within PF candidates does not point to the muon collection." << std::endl;
0887 if (pfmu.muonRef().key() == muonRef.key()) {
0888 reco::PFCandidateRef pfRef(pfMuons, index);
0889 aMuon.setPFCandidateRef(pfRef);
0890 if (embedPfEcalEnergy_)
0891 aMuon.setPfEcalEnergy(pfmu.ecalEnergy());
0892 if (embedPFCandidate_)
0893 aMuon.embedPFCandidate();
0894 break;
0895 }
0896 }
0897 index++;
0898 }
0899 }
0900
0901 if (addInverseBeta_) {
0902 aMuon.readTimeExtra((*muonsTimeExtra)[muonRef]);
0903 }
0904
0905 aMuon.initSimInfo();
0906 if (simInfoIsAvailalbe) {
0907 const auto& msi = (*simInfo)[muonBaseRef];
0908 aMuon.setSimType(msi.primaryClass);
0909 aMuon.setExtSimType(msi.extendedClass);
0910 aMuon.setSimFlavour(msi.flavour);
0911 aMuon.setSimHeaviestMotherFlavour(msi.heaviestMotherFlavour);
0912 aMuon.setSimPdgId(msi.pdgId);
0913 aMuon.setSimMotherPdgId(msi.motherPdgId);
0914 aMuon.setSimBX(msi.tpBX);
0915 aMuon.setSimTpEvent(msi.tpEvent);
0916 aMuon.setSimProdRho(msi.vertex.Rho());
0917 aMuon.setSimProdZ(msi.vertex.Z());
0918 aMuon.setSimPt(msi.p4.pt());
0919 aMuon.setSimEta(msi.p4.eta());
0920 aMuon.setSimPhi(msi.p4.phi());
0921 aMuon.setSimMatchQuality(msi.tpAssoQuality);
0922 }
0923 patMuons.push_back(aMuon);
0924 }
0925 }
0926
0927
0928 std::sort(patMuons.begin(), patMuons.end(), [](auto const& t1, auto const& t2) { return t1.pt() > t2.pt(); });
0929
0930
0931
0932
0933
0934 edm::Handle<double> rho;
0935 if (computeMuonMVA_)
0936 iEvent.getByToken(rho_, rho);
0937 const reco::Vertex* pv(nullptr);
0938 if (primaryVertexIsValid)
0939 pv = &primaryVertex;
0940
0941 edm::Handle<std::vector<pat::TriggerObjectStandAlone>> triggerObjects;
0942 edm::Handle<edm::TriggerResults> triggerResults;
0943 bool triggerObjectsAvailable = false;
0944 bool triggerResultsAvailable = false;
0945 if (addTriggerMatching_) {
0946 triggerObjectsAvailable = iEvent.getByToken(triggerObjects_, triggerObjects);
0947 triggerResultsAvailable = iEvent.getByToken(triggerResults_, triggerResults);
0948 }
0949
0950 for (auto& muon : patMuons) {
0951
0952 if (addTriggerMatching_ and triggerObjectsAvailable and triggerResultsAvailable) {
0953 const edm::TriggerNames& triggerNames(iEvent.triggerNames(*triggerResults));
0954 fillL1TriggerInfo(muon, triggerObjects, triggerNames, geometry);
0955 fillHltTriggerInfo(muon, triggerObjects, triggerNames, hltCollectionFilters_);
0956 }
0957
0958 if (recomputeBasicSelectors_) {
0959 muon.setSelectors(0);
0960 bool isRun2016BCDEF = (272728 <= iEvent.run() && iEvent.run() <= 278808);
0961 muon.setSelectors(muon::makeSelectorBitset(muon, pv, isRun2016BCDEF));
0962 }
0963 float miniIsoValue = -1;
0964 if (computeMiniIso_) {
0965
0966
0967 miniIsoValue = getRelMiniIsoPUCorrected(muon, *rho, effectiveAreaVec_);
0968
0969 muon.setSelector(reco::Muon::MiniIsoLoose, miniIsoValue < 0.40);
0970 muon.setSelector(reco::Muon::MiniIsoMedium, miniIsoValue < 0.20);
0971 muon.setSelector(reco::Muon::MiniIsoTight, miniIsoValue < 0.10);
0972 muon.setSelector(reco::Muon::MiniIsoVeryTight, miniIsoValue < 0.05);
0973 }
0974
0975 double puppiCombinedIsolationPAT = -1;
0976 if (computePuppiCombinedIso_) {
0977 puppiCombinedIsolationPAT = puppiCombinedIsolation(muon, pc.product());
0978 muon.setSelector(reco::Muon::PuppiIsoLoose, puppiCombinedIsolationPAT < 0.27);
0979 muon.setSelector(reco::Muon::PuppiIsoMedium, puppiCombinedIsolationPAT < 0.22);
0980 muon.setSelector(reco::Muon::PuppiIsoTight, puppiCombinedIsolationPAT < 0.12);
0981 }
0982
0983 float jetPtRatio = 0.0;
0984 float jetPtRel = 0.0;
0985 float mva = 0.0;
0986 float mva_lowpt = 0.0;
0987 if (computeMuonMVA_ && primaryVertexIsValid && computeMiniIso_) {
0988 if (mvaUseJec_) {
0989 mva = globalCache()->muonMvaEstimator().computeMva(muon,
0990 primaryVertex,
0991 *(mvaBTagCollectionTag.product()),
0992 jetPtRatio,
0993 jetPtRel,
0994 miniIsoValue,
0995 mvaL1Corrector.product(),
0996 mvaL1L2L3ResCorrector.product());
0997 mva_lowpt = globalCache()->muonLowPtMvaEstimator().computeMva(muon,
0998 primaryVertex,
0999 *(mvaBTagCollectionTag.product()),
1000 jetPtRatio,
1001 jetPtRel,
1002 miniIsoValue,
1003 mvaL1Corrector.product(),
1004 mvaL1L2L3ResCorrector.product());
1005
1006 } else {
1007 mva = globalCache()->muonMvaEstimator().computeMva(
1008 muon, primaryVertex, *mvaBTagCollectionTag, jetPtRatio, jetPtRel, miniIsoValue);
1009 mva_lowpt = globalCache()->muonLowPtMvaEstimator().computeMva(
1010 muon, primaryVertex, *mvaBTagCollectionTag, jetPtRatio, jetPtRel, miniIsoValue);
1011 }
1012
1013 muon.setMvaValue(mva);
1014 muon.setLowPtMvaValue(mva_lowpt);
1015 muon.setJetPtRatio(jetPtRatio);
1016 muon.setJetPtRel(jetPtRel);
1017
1018
1019 if (computeMiniIso_) {
1020 muon.setSelector(reco::Muon::MultiIsoMedium,
1021 miniIsoValue < 0.11 && (muon.jetPtRatio() > 0.74 || muon.jetPtRel() > 6.8));
1022 }
1023
1024
1025
1026 const double dB2D = std::abs(muon.dB(pat::Muon::PV2D));
1027 const double dB3D = std::abs(muon.dB(pat::Muon::PV3D));
1028 const double edB3D = std::abs(muon.edB(pat::Muon::PV3D));
1029 const double sip3D = edB3D > 0 ? dB3D / edB3D : 0.0;
1030 const double dz = std::abs(muon.muonBestTrack()->dz(primaryVertex.position()));
1031
1032
1033 if (muon.pt() > 5 and muon.isLooseMuon() and muon.passed(reco::Muon::MiniIsoLoose) and sip3D < 8.0 and
1034 dB2D < 0.05 and dz < 0.1) {
1035 muon.setSelector(reco::Muon::MvaLoose, muon.mvaValue() > -0.60);
1036 muon.setSelector(reco::Muon::MvaMedium, muon.mvaValue() > -0.20);
1037 muon.setSelector(reco::Muon::MvaTight, muon.mvaValue() > 0.15);
1038 muon.setSelector(reco::Muon::MvaVTight, muon.mvaValue() > 0.45);
1039 muon.setSelector(reco::Muon::MvaVVTight, muon.mvaValue() > 0.9);
1040 }
1041 if (muon.pt() > 5 and muon.isLooseMuon() and sip3D < 4 and dB2D < 0.5 and dz < 1) {
1042 muon.setSelector(reco::Muon::LowPtMvaLoose, muon.lowptMvaValue() > -0.60);
1043 muon.setSelector(reco::Muon::LowPtMvaMedium, muon.lowptMvaValue() > -0.20);
1044 }
1045 }
1046
1047
1048 float mvaID = 0.0;
1049 constexpr int MVAsentinelValue = -99;
1050 constexpr float mvaIDmediumCut = 0.08;
1051 constexpr float mvaIDtightCut = 0.12;
1052 if (computeMuonIDMVA_) {
1053 const double dz = std::abs(muon.muonBestTrack()->dz(primaryVertex.position()));
1054 const double dxy = std::abs(muon.muonBestTrack()->dxy(primaryVertex.position()));
1055 if (muon.isLooseMuon()) {
1056 mvaID = globalCache()->muonMvaIDEstimator().computeMVAID(muon)[1];
1057 } else {
1058 mvaID = MVAsentinelValue;
1059 }
1060 muon.setMvaIDValue(mvaID);
1061 muon.setSelector(reco::Muon::MvaIDwpMedium, muon.mvaIDValue() > mvaIDmediumCut);
1062 muon.setSelector(reco::Muon::MvaIDwpTight, muon.mvaIDValue() > mvaIDtightCut and dz < 0.5 and dxy < 0.2);
1063 }
1064
1065
1066 if (computeSoftMuonMVA_) {
1067 float mva = globalCache()->softMuonMvaEstimator().computeMva(muon);
1068 muon.setSoftMvaValue(mva);
1069
1070 muon.setSelector(reco::Muon::SoftMvaId, muon.softMvaValue() > 0.58);
1071 }
1072 }
1073
1074
1075 iEvent.emplace(patMuonPutToken_, std::move(patMuons));
1076
1077 if (isolator_.enabled())
1078 isolator_.endEvent();
1079 }
1080
1081 void PATMuonProducer::fillMuon(Muon& aMuon,
1082 const MuonBaseRef& muonRef,
1083 const reco::CandidateBaseRef& baseRef,
1084 const GenAssociations& genMatches,
1085 const IsoDepositMaps& deposits,
1086 const IsolationValueMaps& isolationValues) const {
1087
1088
1089
1090
1091
1092 if (useParticleFlow_)
1093 aMuon.setP4(aMuon.pfCandidateRef()->p4());
1094 if (embedTrack_)
1095 aMuon.embedTrack();
1096 if (embedStandAloneMuon_)
1097 aMuon.embedStandAloneMuon();
1098 if (embedCombinedMuon_)
1099 aMuon.embedCombinedMuon();
1100
1101
1102 if (aMuon.isGlobalMuon()) {
1103 if (embedPickyMuon_ && aMuon.isAValidMuonTrack(reco::Muon::Picky))
1104 aMuon.embedPickyMuon();
1105 if (embedTpfmsMuon_ && aMuon.isAValidMuonTrack(reco::Muon::TPFMS))
1106 aMuon.embedTpfmsMuon();
1107 if (embedDytMuon_ && aMuon.isAValidMuonTrack(reco::Muon::DYT))
1108 aMuon.embedDytMuon();
1109 }
1110
1111
1112 if (embedBestTrack_)
1113 aMuon.embedMuonBestTrack(forceEmbedBestTrack_);
1114 if (embedTunePBestTrack_)
1115 aMuon.embedTunePMuonBestTrack(forceEmbedBestTrack_);
1116
1117
1118 if (addGenMatch_) {
1119 for (auto const& genMatch : genMatches) {
1120 reco::GenParticleRef genMuon = (*genMatch)[baseRef];
1121 aMuon.addGenParticleRef(genMuon);
1122 }
1123 if (embedGenMatch_)
1124 aMuon.embedGenParticle();
1125 }
1126 if (efficiencyLoader_.enabled()) {
1127 efficiencyLoader_.setEfficiencies(aMuon, muonRef);
1128 }
1129
1130 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
1131 if (useParticleFlow_) {
1132 if (deposits[j]->contains(baseRef.id())) {
1133 aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[baseRef]);
1134 } else if (deposits[j]->contains(muonRef.id())) {
1135 aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[muonRef]);
1136 } else {
1137 reco::CandidatePtr source = aMuon.pfCandidateRef()->sourceCandidatePtr(0);
1138 aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[source]);
1139 }
1140 } else {
1141 aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[muonRef]);
1142 }
1143 }
1144
1145 for (size_t j = 0; j < isolationValues.size(); ++j) {
1146 if (useParticleFlow_) {
1147 if (isolationValues[j]->contains(baseRef.id())) {
1148 aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[baseRef]);
1149 } else if (isolationValues[j]->contains(muonRef.id())) {
1150 aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[muonRef]);
1151 } else {
1152 reco::CandidatePtr source = aMuon.pfCandidateRef()->sourceCandidatePtr(0);
1153 aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[source]);
1154 }
1155 } else {
1156 aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[muonRef]);
1157 }
1158 }
1159
1160 if (resolutionLoader_.enabled()) {
1161 resolutionLoader_.setResolutions(aMuon);
1162 }
1163 }
1164
1165 void PATMuonProducer::setMuonMiniIso(Muon& aMuon, const PackedCandidateCollection* pc) {
1166 pat::PFIsolation miniiso = pat::getMiniPFIsolation(pc,
1167 aMuon.polarP4(),
1168 miniIsoParams_[0],
1169 miniIsoParams_[1],
1170 miniIsoParams_[2],
1171 miniIsoParams_[3],
1172 miniIsoParams_[4],
1173 miniIsoParams_[5],
1174 miniIsoParams_[6],
1175 miniIsoParams_[7],
1176 miniIsoParams_[8]);
1177 aMuon.setMiniPFIsolation(miniiso);
1178 }
1179
1180 double PATMuonProducer::getRelMiniIsoPUCorrected(const pat::Muon& muon, double rho, const std::vector<double>& area) {
1181 double mindr(miniIsoParams_[0]);
1182 double maxdr(miniIsoParams_[1]);
1183 double kt_scale(miniIsoParams_[2]);
1184 double drcut = pat::miniIsoDr(muon.polarP4(), mindr, maxdr, kt_scale);
1185 return pat::muonRelMiniIsoPUCorrected(muon.miniPFIsolation(), muon.polarP4(), drcut, rho, area);
1186 }
1187
1188 double PATMuonProducer::puppiCombinedIsolation(const pat::Muon& muon, const pat::PackedCandidateCollection* pc) {
1189 constexpr double dR_threshold = 0.4;
1190 constexpr double dR2_threshold = dR_threshold * dR_threshold;
1191 constexpr double mix_fraction = 0.5;
1192 enum particleType { CH = 0, NH = 1, PH = 2, OTHER = 100000 };
1193 double val_PuppiWithLep = 0.0;
1194 double val_PuppiWithoutLep = 0.0;
1195
1196 for (const auto& cand : *pc) {
1197
1198 const particleType pType = isChargedHadron(cand.pdgId()) ? CH
1199 : isNeutralHadron(cand.pdgId()) ? NH
1200 : isPhoton(cand.pdgId()) ? PH
1201 : OTHER;
1202 if (pType == OTHER) {
1203 if (cand.pdgId() != 1 && cand.pdgId() != 2 && abs(cand.pdgId()) != 11 && abs(cand.pdgId()) != 13) {
1204 LogTrace("PATMuonProducer") << "candidate with PDGID = " << cand.pdgId()
1205 << " is not CH/NH/PH/e/mu or 1/2 (and this is removed from isolation calculation)"
1206 << std::endl;
1207 }
1208 continue;
1209 }
1210 double d_eta = std::abs(cand.eta() - muon.eta());
1211 if (d_eta > dR_threshold)
1212 continue;
1213
1214 double d_phi = std::abs(reco::deltaPhi(cand.phi(), muon.phi()));
1215 if (d_phi > dR_threshold)
1216 continue;
1217
1218 double dR2 = reco::deltaR2(cand, muon);
1219 if (dR2 > dR2_threshold)
1220 continue;
1221 if (pType == CH && dR2 < 0.0001 * 0.0001)
1222 continue;
1223 if (pType == NH && dR2 < 0.01 * 0.01)
1224 continue;
1225 if (pType == PH && dR2 < 0.01 * 0.01)
1226 continue;
1227 val_PuppiWithLep += cand.pt() * cand.puppiWeight();
1228 val_PuppiWithoutLep += cand.pt() * cand.puppiWeightNoLep();
1229
1230 }
1231
1232 double reliso_Puppi_withLep = val_PuppiWithLep / muon.pt();
1233 double reliso_Puppi_withoutlep = val_PuppiWithoutLep / muon.pt();
1234 double reliso_Puppi_combined = mix_fraction * reliso_Puppi_withLep + (1.0 - mix_fraction) * reliso_Puppi_withoutlep;
1235 return reliso_Puppi_combined;
1236 }
1237
1238 bool PATMuonProducer::isNeutralHadron(long pdgid) { return std::abs(pdgid) == 130; }
1239
1240 bool PATMuonProducer::isChargedHadron(long pdgid) { return std::abs(pdgid) == 211; }
1241
1242 bool PATMuonProducer::isPhoton(long pdgid) { return pdgid == 22; }
1243
1244
1245 void PATMuonProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
1246 edm::ParameterSetDescription iDesc;
1247 iDesc.setComment("PAT muon producer module");
1248
1249
1250 iDesc.add<edm::InputTag>("muonSource", edm::InputTag("no default"))->setComment("input collection");
1251
1252
1253 iDesc.add<bool>("embedMuonBestTrack", true)->setComment("embed muon best track (global pflow)");
1254 iDesc.add<bool>("embedTunePMuonBestTrack", true)->setComment("embed muon best track (muon only)");
1255 iDesc.add<bool>("forceBestTrackEmbedding", true)
1256 ->setComment(
1257 "force embedding separately the best tracks even if they're already embedded e.g. as tracker or global "
1258 "tracks");
1259 iDesc.add<bool>("embedTrack", true)->setComment("embed external track");
1260 iDesc.add<bool>("embedStandAloneMuon", true)->setComment("embed external stand-alone muon");
1261 iDesc.add<bool>("embedCombinedMuon", false)->setComment("embed external combined muon");
1262 iDesc.add<bool>("embedPickyMuon", false)->setComment("embed external picky track");
1263 iDesc.add<bool>("embedTpfmsMuon", false)->setComment("embed external tpfms track");
1264 iDesc.add<bool>("embedDytMuon", false)->setComment("embed external dyt track ");
1265
1266
1267 iDesc.add<bool>("embedCaloMETMuonCorrs", true)->setComment("whether to add MET muon correction for caloMET or not");
1268 iDesc.add<edm::InputTag>("caloMETMuonCorrs", edm::InputTag("muonMETValueMapProducer", "muCorrData"))
1269 ->setComment("source of MET muon corrections for caloMET");
1270 iDesc.add<bool>("embedTcMETMuonCorrs", true)->setComment("whether to add MET muon correction for tcMET or not");
1271 iDesc.add<edm::InputTag>("tcMETMuonCorrs", edm::InputTag("muonTCMETValueMapProducer", "muCorrData"))
1272 ->setComment("source of MET muon corrections for tcMET");
1273
1274
1275 iDesc.add<edm::InputTag>("pfMuonSource", edm::InputTag("pfMuons"))->setComment("particle flow input collection");
1276 iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
1277 iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
1278 iDesc.add<bool>("embedPfEcalEnergy", true)->setComment("add ecal energy as reconstructed by PF");
1279
1280
1281 iDesc.add<bool>("addInverseBeta", true)->setComment("add combined inverse beta");
1282 iDesc.add<edm::InputTag>("sourceInverseBeta", edm::InputTag("muons", "combined"))
1283 ->setComment("source of inverse beta values");
1284
1285
1286 iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
1287 iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
1288 std::vector<edm::InputTag> emptySourceVector;
1289 iDesc
1290 .addNode(edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
1291 edm::ParameterDescription<std::vector<edm::InputTag>>("genParticleMatch", emptySourceVector, true))
1292 ->setComment("input with MC match information");
1293
1294
1295 iDesc.add<bool>("computeMiniIso", false)->setComment("whether or not to compute and store electron mini-isolation");
1296 iDesc.add<bool>("computePuppiCombinedIso", false)
1297 ->setComment("whether or not to compute and store puppi combined isolation");
1298
1299 iDesc.add<edm::InputTag>("pfCandsForMiniIso", edm::InputTag("packedPFCandidates"))
1300 ->setComment("collection to use to compute mini-iso");
1301 iDesc.add<std::vector<double>>("miniIsoParams", std::vector<double>())
1302 ->setComment("mini-iso parameters to use for muons");
1303
1304 iDesc.add<bool>("addTriggerMatching", false)->setComment("add L1 and HLT matching to offline muon");
1305
1306 pat::helper::KinResolutionsLoader::fillDescription(iDesc);
1307
1308
1309 edm::ParameterSetDescription isoDepositsPSet;
1310 isoDepositsPSet.addOptional<edm::InputTag>("tracker");
1311 isoDepositsPSet.addOptional<edm::InputTag>("ecal");
1312 isoDepositsPSet.addOptional<edm::InputTag>("hcal");
1313 isoDepositsPSet.addOptional<edm::InputTag>("particle");
1314 isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1315 isoDepositsPSet.addOptional<edm::InputTag>("pfChargedAll");
1316 isoDepositsPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1317 isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1318 isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
1319 isoDepositsPSet.addOptional<std::vector<edm::InputTag>>("user");
1320 iDesc.addOptional("isoDeposits", isoDepositsPSet);
1321
1322
1323 edm::ParameterSetDescription isolationValuesPSet;
1324 isolationValuesPSet.addOptional<edm::InputTag>("tracker");
1325 isolationValuesPSet.addOptional<edm::InputTag>("ecal");
1326 isolationValuesPSet.addOptional<edm::InputTag>("hcal");
1327 isolationValuesPSet.addOptional<edm::InputTag>("particle");
1328 isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1329 isolationValuesPSet.addOptional<edm::InputTag>("pfChargedAll");
1330 isolationValuesPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1331 isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1332 isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
1333 iDesc.addOptional("isolationValues", isolationValuesPSet);
1334
1335 iDesc.ifValue(edm::ParameterDescription<bool>("addPuppiIsolation", false, true),
1336 true >> (edm::ParameterDescription<edm::InputTag>(
1337 "puppiIsolationChargedHadrons",
1338 edm::InputTag("muonPUPPIIsolation", "h+-DR030-ThresholdVeto000-ConeVeto000"),
1339 true) and
1340 edm::ParameterDescription<edm::InputTag>(
1341 "puppiIsolationNeutralHadrons",
1342 edm::InputTag("muonPUPPIIsolation", "h0-DR030-ThresholdVeto000-ConeVeto001"),
1343 true) and
1344 edm::ParameterDescription<edm::InputTag>(
1345 "puppiIsolationPhotons",
1346 edm::InputTag("muonPUPPIIsolation", "gamma-DR030-ThresholdVeto000-ConeVeto001"),
1347 true) and
1348 edm::ParameterDescription<edm::InputTag>(
1349 "puppiNoLeptonsIsolationChargedHadrons",
1350 edm::InputTag("muonPUPPINoLeptonsIsolation", "h+-DR030-ThresholdVeto000-ConeVeto000"),
1351 true) and
1352 edm::ParameterDescription<edm::InputTag>(
1353 "puppiNoLeptonsIsolationNeutralHadrons",
1354 edm::InputTag("muonPUPPINoLeptonsIsolation", "h0-DR030-ThresholdVeto000-ConeVeto001"),
1355 true) and
1356 edm::ParameterDescription<edm::InputTag>(
1357 "puppiNoLeptonsIsolationPhotons",
1358 edm::InputTag("muonPUPPINoLeptonsIsolation", "gamma-DR030-ThresholdVeto000-ConeVeto001"),
1359 true)) or
1360 false >> edm::EmptyGroupDescription());
1361
1362
1363 edm::ParameterSetDescription efficienciesPSet;
1364 efficienciesPSet.setAllowAnything();
1365 iDesc.add("efficiencies", efficienciesPSet);
1366 iDesc.add<bool>("addEfficiencies", false);
1367
1368
1369 edm::ParameterSetDescription userDataPSet;
1370 PATUserDataHelper<Muon>::fillDescription(userDataPSet);
1371 iDesc.addOptional("userData", userDataPSet);
1372
1373 edm::ParameterSetDescription isolationPSet;
1374 isolationPSet.setAllowAnything();
1375 iDesc.add("userIsolation", isolationPSet);
1376
1377 iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
1378 edm::ParameterSetDescription highLevelPSet;
1379 highLevelPSet.setAllowAnything();
1380 iDesc.addNode(edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true))
1381 ->setComment("input with high level selection");
1382 iDesc.addNode(edm::ParameterDescription<edm::InputTag>("pvSrc", edm::InputTag(), true))
1383 ->setComment("input with high level selection");
1384
1385
1386 }
1387
1388
1389
1390 void PATMuonProducer::embedHighLevel(pat::Muon& aMuon,
1391 reco::TrackRef track,
1392 reco::TransientTrack& tt,
1393 reco::Vertex& primaryVertex,
1394 bool primaryVertexIsValid,
1395 reco::BeamSpot& beamspot,
1396 bool beamspotIsValid) {
1397
1398
1399
1400 aMuon.setDB(track->dxy(primaryVertex.position()),
1401 track->dxyError(primaryVertex.position(), primaryVertex.covariance()),
1402 pat::Muon::PV2D);
1403
1404
1405 std::pair<bool, Measurement1D> result =
1406 IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex);
1407 double d0_corr = result.second.value();
1408 double d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
1409 aMuon.setDB(d0_corr, d0_err, pat::Muon::PV3D);
1410
1411
1412
1413
1414 aMuon.setDB(track->dxy(beamspot), track->dxyError(beamspot), pat::Muon::BS2D);
1415
1416
1417 reco::Vertex vBeamspot(beamspot.position(), beamspot.rotatedCovariance3D());
1418
1419
1420 result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot);
1421 d0_corr = result.second.value();
1422 d0_err = beamspotIsValid ? result.second.error() : -1.0;
1423 aMuon.setDB(d0_corr, d0_err, pat::Muon::BS3D);
1424
1425
1426 aMuon.setDB(
1427 track->dz(primaryVertex.position()), std::hypot(track->dzError(), primaryVertex.zError()), pat::Muon::PVDZ);
1428 }
1429
1430 #include "FWCore/Framework/interface/MakerMacros.h"
1431
1432 DEFINE_FWK_MODULE(PATMuonProducer);