CMS 3D CMS Logo

PATMuonProducer.cc
Go to the documentation of this file.
1 //
2 //
3 
5 
9 
13 
15 
19 
22 
24 
27 
31 
36 
37 #include "TMath.h"
38 
40 
45 
50 
53 
54 #include <vector>
55 #include <memory>
56 
57 using namespace pat;
58 using namespace std;
59 
61  if (iConfig.getParameter<bool>("computeMuonMVA")) {
62  edm::FileInPath mvaTrainingFile = iConfig.getParameter<edm::FileInPath>("mvaTrainingFile");
63  edm::FileInPath mvaLowPtTrainingFile = iConfig.getParameter<edm::FileInPath>("lowPtmvaTrainingFile");
64  float mvaDrMax = iConfig.getParameter<double>("mvaDrMax");
65  muonMvaEstimator_ = std::make_unique<MuonMvaEstimator>(mvaTrainingFile, mvaDrMax);
66  muonLowPtMvaEstimator_ = std::make_unique<MuonMvaEstimator>(mvaLowPtTrainingFile, mvaDrMax);
67  }
68 
69  if (iConfig.getParameter<bool>("computeSoftMuonMVA")) {
70  edm::FileInPath softMvaTrainingFile = iConfig.getParameter<edm::FileInPath>("softMvaTrainingFile");
71  softMuonMvaEstimator_ = std::make_unique<SoftMuonMvaEstimator>(softMvaTrainingFile);
72  }
73 }
74 
76  : relMiniIsoPUCorrected_(0),
77  useUserData_(iConfig.exists("userData")),
78  computeMuonMVA_(false),
79  computeSoftMuonMVA_(false),
80  recomputeBasicSelectors_(false),
81  mvaUseJec_(false),
82  isolator_(iConfig.exists("userIsolation") ? iConfig.getParameter<edm::ParameterSet>("userIsolation")
83  : edm::ParameterSet(),
84  consumesCollector(),
85  false) {
86  // input source
87  muonToken_ = consumes<edm::View<reco::Muon>>(iConfig.getParameter<edm::InputTag>("muonSource"));
88  // embedding of tracks
89  embedBestTrack_ = iConfig.getParameter<bool>("embedMuonBestTrack");
90  embedTunePBestTrack_ = iConfig.getParameter<bool>("embedTunePMuonBestTrack");
91  forceEmbedBestTrack_ = iConfig.getParameter<bool>("forceBestTrackEmbedding");
92  embedTrack_ = iConfig.getParameter<bool>("embedTrack");
93  embedCombinedMuon_ = iConfig.getParameter<bool>("embedCombinedMuon");
94  embedStandAloneMuon_ = iConfig.getParameter<bool>("embedStandAloneMuon");
95  // embedding of muon MET correction information
96  embedCaloMETMuonCorrs_ = iConfig.getParameter<bool>("embedCaloMETMuonCorrs");
97  embedTcMETMuonCorrs_ = iConfig.getParameter<bool>("embedTcMETMuonCorrs");
99  mayConsume<edm::ValueMap<reco::MuonMETCorrectionData>>(iConfig.getParameter<edm::InputTag>("caloMETMuonCorrs"));
101  mayConsume<edm::ValueMap<reco::MuonMETCorrectionData>>(iConfig.getParameter<edm::InputTag>("tcMETMuonCorrs"));
102  // pflow specific configurables
103  useParticleFlow_ = iConfig.getParameter<bool>("useParticleFlow");
104  embedPFCandidate_ = iConfig.getParameter<bool>("embedPFCandidate");
105  pfMuonToken_ = mayConsume<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfMuonSource"));
106  embedPfEcalEnergy_ = iConfig.getParameter<bool>("embedPfEcalEnergy");
107  // embedding of tracks from TeV refit
108  embedPickyMuon_ = iConfig.getParameter<bool>("embedPickyMuon");
109  embedTpfmsMuon_ = iConfig.getParameter<bool>("embedTpfmsMuon");
110  embedDytMuon_ = iConfig.getParameter<bool>("embedDytMuon");
111  // embedding of inverse beta variable information
112  addInverseBeta_ = iConfig.getParameter<bool>("addInverseBeta");
113  if (addInverseBeta_) {
115  consumes<edm::ValueMap<reco::MuonTimeExtra>>(iConfig.getParameter<edm::InputTag>("sourceMuonTimeExtra"));
116  }
117  // Monte Carlo matching
118  addGenMatch_ = iConfig.getParameter<bool>("addGenMatch");
119  if (addGenMatch_) {
120  embedGenMatch_ = iConfig.getParameter<bool>("embedGenMatch");
121  if (iConfig.existsAs<edm::InputTag>("genParticleMatch")) {
123  iConfig.getParameter<edm::InputTag>("genParticleMatch")));
124  } else {
126  iConfig.getParameter<std::vector<edm::InputTag>>("genParticleMatch"),
127  [this](edm::InputTag const& tag) { return consumes<edm::Association<reco::GenParticleCollection>>(tag); });
128  }
129  }
130  // efficiencies
131  addEfficiencies_ = iConfig.getParameter<bool>("addEfficiencies");
132  if (addEfficiencies_) {
134  pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"), consumesCollector());
135  }
136  // resolutions
137  addResolutions_ = iConfig.getParameter<bool>("addResolutions");
138  if (addResolutions_) {
140  }
141  // puppi
142  addPuppiIsolation_ = iConfig.getParameter<bool>("addPuppiIsolation");
143  if (addPuppiIsolation_) {
145  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationChargedHadrons"));
147  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationNeutralHadrons"));
149  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationPhotons"));
150  //puppiNoLeptons
152  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationChargedHadrons"));
154  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationNeutralHadrons"));
156  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationPhotons"));
157  }
158  // read isoDeposit labels, for direct embedding
159  readIsolationLabels(iConfig, "isoDeposits", isoDepositLabels_, isoDepositTokens_);
160  // read isolation value labels, for direct embedding
162  // check to see if the user wants to add user data
163  if (useUserData_) {
164  userDataHelper_ = PATUserDataHelper<Muon>(iConfig.getParameter<edm::ParameterSet>("userData"), consumesCollector());
165  }
166  // embed high level selection variables
167  embedHighLevelSelection_ = iConfig.getParameter<bool>("embedHighLevelSelection");
168  if (embedHighLevelSelection_) {
169  beamLineToken_ = consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamLineSrc"));
170  pvToken_ = consumes<std::vector<reco::Vertex>>(iConfig.getParameter<edm::InputTag>("pvSrc"));
171  }
172 
173  //for mini-isolation calculation
174  computeMiniIso_ = iConfig.getParameter<bool>("computeMiniIso");
175 
176  computePuppiCombinedIso_ = iConfig.getParameter<bool>("computePuppiCombinedIso");
177 
178  effectiveAreaVec_ = iConfig.getParameter<std::vector<double>>("effectiveAreaVec");
179 
180  miniIsoParams_ = iConfig.getParameter<std::vector<double>>("miniIsoParams");
181  if (computeMiniIso_ && miniIsoParams_.size() != 9) {
182  throw cms::Exception("ParameterError") << "miniIsoParams must have exactly 9 elements.\n";
183  }
184  if (computeMiniIso_ || computePuppiCombinedIso_)
185  pcToken_ = consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfCandsForMiniIso"));
186 
187  // standard selectors
188  recomputeBasicSelectors_ = iConfig.getParameter<bool>("recomputeBasicSelectors");
189  computeMuonMVA_ = iConfig.getParameter<bool>("computeMuonMVA");
190  if (computeMuonMVA_ and not computeMiniIso_)
191  throw cms::Exception("ConfigurationError") << "MiniIso is needed for Muon MVA calculation.\n";
192 
193  if (computeMuonMVA_) {
194  // pfCombinedInclusiveSecondaryVertexV2BJetTags
195  mvaBTagCollectionTag_ = consumes<reco::JetTagCollection>(iConfig.getParameter<edm::InputTag>("mvaJetTag"));
196  mvaL1Corrector_ = consumes<reco::JetCorrector>(iConfig.getParameter<edm::InputTag>("mvaL1Corrector"));
197  mvaL1L2L3ResCorrector_ = consumes<reco::JetCorrector>(iConfig.getParameter<edm::InputTag>("mvaL1L2L3ResCorrector"));
198  rho_ = consumes<double>(iConfig.getParameter<edm::InputTag>("rho"));
199  mvaUseJec_ = iConfig.getParameter<bool>("mvaUseJec");
200  }
201 
202  computeSoftMuonMVA_ = iConfig.getParameter<bool>("computeSoftMuonMVA");
203 
204  // MC info
205  simInfo_ = consumes<edm::ValueMap<reco::MuonSimInfo>>(iConfig.getParameter<edm::InputTag>("muonSimInfo"));
206 
207  addTriggerMatching_ = iConfig.getParameter<bool>("addTriggerMatching");
208  if (addTriggerMatching_) {
210  consumes<std::vector<pat::TriggerObjectStandAlone>>(iConfig.getParameter<edm::InputTag>("triggerObjects"));
211  triggerResults_ = consumes<edm::TriggerResults>(iConfig.getParameter<edm::InputTag>("triggerResults"));
212  }
213  hltCollectionFilters_ = iConfig.getParameter<std::vector<std::string>>("hltCollectionFilters");
214 
215  // produces vector of muons
216  produces<std::vector<Muon>>();
217 }
218 
220 
221 std::optional<GlobalPoint> PATMuonProducer::getMuonDirection(const reco::MuonChamberMatch& chamberMatch,
223  const DetId& chamberId) {
224  const GeomDet* chamberGeometry = geometry->idToDet(chamberId);
225  if (chamberGeometry) {
226  LocalPoint localPosition(chamberMatch.x, chamberMatch.y, 0);
227  return std::optional<GlobalPoint>(std::in_place, chamberGeometry->toGlobal(localPosition));
228  }
229  return std::optional<GlobalPoint>();
230 }
231 
233  edm::Handle<std::vector<pat::TriggerObjectStandAlone>>& triggerObjects,
234  const edm::TriggerNames& names,
236  // L1 trigger object parameters are defined at MB2/ME2. Use the muon
237  // chamber matching information to get the local direction of the
238  // muon trajectory and convert it to a global direction to match the
239  // trigger objects
240 
241  std::optional<GlobalPoint> muonPosition;
242  // Loop over chambers
243  // initialize muonPosition with any available match, just in case
244  // the second station is missing - it's better folling back to
245  // dR matching at IP
246  for (const auto& chamberMatch : aMuon.matches()) {
247  if (chamberMatch.id.subdetId() == MuonSubdetId::DT) {
248  DTChamberId detId(chamberMatch.id.rawId());
249  if (abs(detId.station()) > 3)
250  continue;
251  muonPosition = getMuonDirection(chamberMatch, geometry, detId);
252  if (abs(detId.station()) == 2)
253  break;
254  }
255  if (chamberMatch.id.subdetId() == MuonSubdetId::CSC) {
256  CSCDetId detId(chamberMatch.id.rawId());
257  if (abs(detId.station()) > 3)
258  continue;
259  muonPosition = getMuonDirection(chamberMatch, geometry, detId);
260  if (abs(detId.station()) == 2)
261  break;
262  }
263  }
264  if (not muonPosition)
265  return;
266  for (const auto& triggerObject : *triggerObjects) {
267  if (triggerObject.hasTriggerObjectType(trigger::TriggerL1Mu)) {
268  if (fabs(triggerObject.eta()) < 0.001) {
269  // L1 is defined in X-Y plain
270  if (deltaPhi(triggerObject.phi(), muonPosition->phi()) > 0.1)
271  continue;
272  } else {
273  // 3D L1
274  if (deltaR(triggerObject.p4(), *muonPosition) > 0.15)
275  continue;
276  }
277  pat::TriggerObjectStandAlone obj(triggerObject);
278  obj.unpackPathNames(names);
279  aMuon.addTriggerObjectMatch(obj);
280  }
281  }
282 }
283 
285  edm::Handle<std::vector<pat::TriggerObjectStandAlone>>& triggerObjects,
286  const edm::TriggerNames& names,
287  const std::vector<std::string>& collection_filter_names) {
288  // WARNING: in a case of close-by muons the dR matching may select both muons.
289  // It's better to select the best match for a given collection.
290  for (const auto& triggerObject : *triggerObjects) {
291  if (triggerObject.hasTriggerObjectType(trigger::TriggerMuon)) {
292  bool keepIt = false;
293  for (const auto& name : collection_filter_names) {
294  if (triggerObject.hasCollection(name)) {
295  keepIt = true;
296  break;
297  }
298  }
299  if (not keepIt)
300  continue;
301  if (deltaR(triggerObject.p4(), muon) > 0.1)
302  continue;
303  pat::TriggerObjectStandAlone obj(triggerObject);
304  obj.unpackPathNames(names);
305  muon.addTriggerObjectMatch(obj);
306  }
307  }
308 }
309 
311  // get the tracking Geometry
313  iSetup.get<GlobalTrackingGeometryRecord>().get(geometry);
314  if (!geometry.isValid())
315  throw cms::Exception("FatalError") << "Unable to find GlobalTrackingGeometryRecord in event!\n";
316 
317  // switch off embedding (in unschedules mode)
318  if (iEvent.isRealData()) {
319  addGenMatch_ = false;
320  embedGenMatch_ = false;
321  }
322 
324  iEvent.getByToken(muonToken_, muons);
325 
328  iEvent.getByToken(pcToken_, pc);
329 
330  // get the ESHandle for the transient track builder,
331  // if needed for high level selection embedding
333 
334  if (isolator_.enabled())
335  isolator_.beginEvent(iEvent, iSetup);
337  efficiencyLoader_.newEvent(iEvent);
339  resolutionLoader_.newEvent(iEvent, iSetup);
340 
342  for (size_t j = 0; j < isoDepositTokens_.size(); ++j) {
343  iEvent.getByToken(isoDepositTokens_[j], deposits[j]);
344  }
345 
347  for (size_t j = 0; j < isolationValueTokens_.size(); ++j) {
349  }
350 
351  //value maps for puppi isolation
352  edm::Handle<edm::ValueMap<float>> PUPPIIsolation_charged_hadrons;
353  edm::Handle<edm::ValueMap<float>> PUPPIIsolation_neutral_hadrons;
354  edm::Handle<edm::ValueMap<float>> PUPPIIsolation_photons;
355  //value maps for puppiNoLeptons isolation
356  edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_charged_hadrons;
357  edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_neutral_hadrons;
358  edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_photons;
359  if (addPuppiIsolation_) {
360  //puppi
361  iEvent.getByToken(PUPPIIsolation_charged_hadrons_, PUPPIIsolation_charged_hadrons);
362  iEvent.getByToken(PUPPIIsolation_neutral_hadrons_, PUPPIIsolation_neutral_hadrons);
363  iEvent.getByToken(PUPPIIsolation_photons_, PUPPIIsolation_photons);
364  //puppiNoLeptons
365  iEvent.getByToken(PUPPINoLeptonsIsolation_charged_hadrons_, PUPPINoLeptonsIsolation_charged_hadrons);
366  iEvent.getByToken(PUPPINoLeptonsIsolation_neutral_hadrons_, PUPPINoLeptonsIsolation_neutral_hadrons);
367  iEvent.getByToken(PUPPINoLeptonsIsolation_photons_, PUPPINoLeptonsIsolation_photons);
368  }
369 
370  // inputs for muon mva
371  edm::Handle<reco::JetTagCollection> mvaBTagCollectionTag;
374  if (computeMuonMVA_) {
375  iEvent.getByToken(mvaBTagCollectionTag_, mvaBTagCollectionTag);
376  iEvent.getByToken(mvaL1Corrector_, mvaL1Corrector);
377  iEvent.getByToken(mvaL1L2L3ResCorrector_, mvaL1L2L3ResCorrector);
378  }
379 
380  // prepare the MC genMatchTokens_
381  GenAssociations genMatches(genMatchTokens_.size());
382  if (addGenMatch_) {
383  for (size_t j = 0, nd = genMatchTokens_.size(); j < nd; ++j) {
384  iEvent.getByToken(genMatchTokens_[j], genMatches[j]);
385  }
386  }
387 
388  // prepare the high level selection: needs beamline
389  // OR primary vertex, depending on user selection
392  bool beamSpotIsValid = false;
393  bool primaryVertexIsValid = false;
395  // get the beamspot
396  edm::Handle<reco::BeamSpot> beamSpotHandle;
397  iEvent.getByToken(beamLineToken_, beamSpotHandle);
398 
399  // get the primary vertex
401  iEvent.getByToken(pvToken_, pvHandle);
402 
403  if (beamSpotHandle.isValid()) {
404  beamSpot = *beamSpotHandle;
405  beamSpotIsValid = true;
406  } else {
407  edm::LogError("DataNotAvailable") << "No beam spot available from EventSetup, not adding high level selection \n";
408  }
409  if (pvHandle.isValid() && !pvHandle->empty()) {
410  primaryVertex = pvHandle->at(0);
411  primaryVertexIsValid = true;
412  } else {
413  edm::LogError("DataNotAvailable")
414  << "No primary vertex available from EventSetup, not adding high level selection \n";
415  }
416  // this is needed by the IPTools methods from the tracking group
417  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", trackBuilder);
418  }
419 
420  // MC info
422  bool simInfoIsAvailalbe = iEvent.getByToken(simInfo_, simInfo);
423 
424  // this will be the new object collection
425  std::vector<Muon>* patMuons = new std::vector<Muon>();
426 
428  if (useParticleFlow_) {
429  // get the PFCandidates of type muons
430  iEvent.getByToken(pfMuonToken_, pfMuons);
431 
432  unsigned index = 0;
433  for (reco::PFCandidateConstIterator i = pfMuons->begin(); i != pfMuons->end(); ++i, ++index) {
434  const reco::PFCandidate& pfmu = *i;
435  //const reco::IsolaPFCandidate& pfmu = *i;
436  const reco::MuonRef& muonRef = pfmu.muonRef();
437  assert(muonRef.isNonnull());
438 
439  MuonBaseRef muonBaseRef(muonRef);
440  Muon aMuon(muonBaseRef);
441 
442  if (useUserData_) {
443  userDataHelper_.add(aMuon, iEvent, iSetup);
444  }
445 
446  // embed high level selection
448  // get the tracks
449  reco::TrackRef innerTrack = muonBaseRef->innerTrack();
450  reco::TrackRef globalTrack = muonBaseRef->globalTrack();
451  reco::TrackRef bestTrack = muonBaseRef->muonBestTrack();
452  reco::TrackRef chosenTrack = innerTrack;
453  // Make sure the collection it points to is there
454  if (bestTrack.isNonnull() && bestTrack.isAvailable())
455  chosenTrack = bestTrack;
456 
457  if (chosenTrack.isNonnull() && chosenTrack.isAvailable()) {
458  unsigned int nhits = chosenTrack->numberOfValidHits(); // ????
459  aMuon.setNumberOfValidHits(nhits);
460 
461  reco::TransientTrack tt = trackBuilder->build(chosenTrack);
462  embedHighLevel(aMuon, chosenTrack, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
463  }
464 
465  if (globalTrack.isNonnull() && globalTrack.isAvailable() && !embedCombinedMuon_) {
466  double norm_chi2 = globalTrack->chi2() / globalTrack->ndof();
467  aMuon.setNormChi2(norm_chi2);
468  }
469  }
470  reco::PFCandidateRef pfRef(pfMuons, index);
471  //reco::PFCandidatePtr ptrToMother(pfMuons,index);
472  reco::CandidateBaseRef pfBaseRef(pfRef);
473 
474  aMuon.setPFCandidateRef(pfRef);
475  if (embedPFCandidate_)
476  aMuon.embedPFCandidate();
477  fillMuon(aMuon, muonBaseRef, pfBaseRef, genMatches, deposits, isolationValues);
478 
479  if (computeMiniIso_)
480  setMuonMiniIso(aMuon, pc.product());
481 
482  if (addPuppiIsolation_) {
483  aMuon.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[muonBaseRef],
484  (*PUPPIIsolation_neutral_hadrons)[muonBaseRef],
485  (*PUPPIIsolation_photons)[muonBaseRef]);
486 
487  aMuon.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[muonBaseRef],
488  (*PUPPINoLeptonsIsolation_neutral_hadrons)[muonBaseRef],
489  (*PUPPINoLeptonsIsolation_photons)[muonBaseRef]);
490  } else {
491  aMuon.setIsolationPUPPI(-999., -999., -999.);
492  aMuon.setIsolationPUPPINoLeptons(-999., -999., -999.);
493  }
494 
495  if (embedPfEcalEnergy_) {
496  aMuon.setPfEcalEnergy(pfmu.ecalEnergy());
497  }
498 
499  patMuons->push_back(aMuon);
500  }
501  } else {
503  iEvent.getByToken(muonToken_, muons);
504 
505  // embedding of muon MET corrections
507  //edm::ValueMap<reco::MuonMETCorrectionData> caloMETmuCorValueMap;
509  iEvent.getByToken(caloMETMuonCorrsToken_, caloMETMuonCorrs);
510  //caloMETmuCorValueMap = *caloMETmuCorValueMap_h;
511  }
513  //edm::ValueMap<reco::MuonMETCorrectionData> tcMETmuCorValueMap;
514  if (embedTcMETMuonCorrs_) {
515  iEvent.getByToken(tcMETMuonCorrsToken_, tcMETMuonCorrs);
516  //tcMETmuCorValueMap = *tcMETmuCorValueMap_h;
517  }
518 
519  if (embedPfEcalEnergy_) {
520  // get the PFCandidates of type muons
521  iEvent.getByToken(pfMuonToken_, pfMuons);
522  }
523 
525  if (addInverseBeta_) {
526  // get MuonTimerExtra value map
527  iEvent.getByToken(muonTimeExtraToken_, muonsTimeExtra);
528  }
529 
530  for (edm::View<reco::Muon>::const_iterator itMuon = muons->begin(); itMuon != muons->end(); ++itMuon) {
531  // construct the Muon from the ref -> save ref to original object
532  unsigned int idx = itMuon - muons->begin();
533  MuonBaseRef muonRef = muons->refAt(idx);
534  reco::CandidateBaseRef muonBaseRef(muonRef);
535 
536  Muon aMuon(muonRef);
537  fillMuon(aMuon, muonRef, muonBaseRef, genMatches, deposits, isolationValues);
538  if (computeMiniIso_)
539  setMuonMiniIso(aMuon, pc.product());
540  if (addPuppiIsolation_) {
541  aMuon.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[muonRef],
542  (*PUPPIIsolation_neutral_hadrons)[muonRef],
543  (*PUPPIIsolation_photons)[muonRef]);
544  aMuon.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[muonRef],
545  (*PUPPINoLeptonsIsolation_neutral_hadrons)[muonRef],
546  (*PUPPINoLeptonsIsolation_photons)[muonRef]);
547  } else {
548  aMuon.setIsolationPUPPI(-999., -999., -999.);
549  aMuon.setIsolationPUPPINoLeptons(-999., -999., -999.);
550  }
551 
552  // Isolation
553  if (isolator_.enabled()) {
554  //reco::CandidatePtr mother = ptrToMother->sourceCandidatePtr(0);
555  isolator_.fill(*muons, idx, isolatorTmpStorage_);
556  typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
557  // better to loop backwards, so the vector is resized less times
558  for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(),
559  ed = isolatorTmpStorage_.rend();
560  it != ed;
561  ++it) {
562  aMuon.setIsolation(it->first, it->second);
563  }
564  }
565 
566  // for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
567  // aMuon.setIsoDeposit(isoDepositLabels_[j].first,
568  // (*deposits[j])[muonRef]);
569  // }
570 
571  // add sel to selected
572  edm::Ptr<reco::Muon> muonsPtr = muons->ptrAt(idx);
573  if (useUserData_) {
574  userDataHelper_.add(aMuon, iEvent, iSetup);
575  }
576 
577  // embed high level selection
579  // get the tracks
580  reco::TrackRef innerTrack = itMuon->innerTrack();
581  reco::TrackRef globalTrack = itMuon->globalTrack();
582  reco::TrackRef bestTrack = itMuon->muonBestTrack();
583  reco::TrackRef chosenTrack = innerTrack;
584  // Make sure the collection it points to is there
585  if (bestTrack.isNonnull() && bestTrack.isAvailable())
586  chosenTrack = bestTrack;
587  if (chosenTrack.isNonnull() && chosenTrack.isAvailable()) {
588  unsigned int nhits = chosenTrack->numberOfValidHits(); // ????
589  aMuon.setNumberOfValidHits(nhits);
590 
591  reco::TransientTrack tt = trackBuilder->build(chosenTrack);
592  embedHighLevel(aMuon, chosenTrack, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
593  }
594 
595  if (globalTrack.isNonnull() && globalTrack.isAvailable()) {
596  double norm_chi2 = globalTrack->chi2() / globalTrack->ndof();
597  aMuon.setNormChi2(norm_chi2);
598  }
599  }
600 
601  // embed MET muon corrections
603  aMuon.embedCaloMETMuonCorrs((*caloMETMuonCorrs)[muonRef]);
605  aMuon.embedTcMETMuonCorrs((*tcMETMuonCorrs)[muonRef]);
606 
607  if (embedPfEcalEnergy_) {
608  aMuon.setPfEcalEnergy(-99.0);
609  for (const reco::PFCandidate& pfmu : *pfMuons) {
610  if (pfmu.muonRef().isNonnull()) {
611  if (pfmu.muonRef().id() != muonRef.id())
612  throw cms::Exception("Configuration")
613  << "Muon reference within PF candidates does not point to the muon collection." << std::endl;
614  if (pfmu.muonRef().key() == muonRef.key()) {
615  aMuon.setPfEcalEnergy(pfmu.ecalEnergy());
616  }
617  }
618  }
619  }
620  if (addInverseBeta_) {
621  aMuon.readTimeExtra((*muonsTimeExtra)[muonRef]);
622  }
623  // MC info
624  aMuon.initSimInfo();
625  if (simInfoIsAvailalbe) {
626  const auto& msi = (*simInfo)[muonBaseRef];
627  aMuon.setSimType(msi.primaryClass);
628  aMuon.setExtSimType(msi.extendedClass);
629  aMuon.setSimFlavour(msi.flavour);
630  aMuon.setSimHeaviestMotherFlavour(msi.heaviestMotherFlavour);
631  aMuon.setSimPdgId(msi.pdgId);
632  aMuon.setSimMotherPdgId(msi.motherPdgId);
633  aMuon.setSimBX(msi.tpBX);
634  aMuon.setSimTpEvent(msi.tpEvent);
635  aMuon.setSimProdRho(msi.vertex.Rho());
636  aMuon.setSimProdZ(msi.vertex.Z());
637  aMuon.setSimPt(msi.p4.pt());
638  aMuon.setSimEta(msi.p4.eta());
639  aMuon.setSimPhi(msi.p4.phi());
640  aMuon.setSimMatchQuality(msi.tpAssoQuality);
641  }
642  patMuons->push_back(aMuon);
643  }
644  }
645 
646  // sort muons in pt
647  std::sort(patMuons->begin(), patMuons->end(), pTComparator_);
648 
649  // Store standard muon selection decisions and jet related
650  // quantaties.
651  // Need a separate loop over muons to have all inputs properly
652  // computed and stored in the object.
654  if (computeMuonMVA_)
655  iEvent.getByToken(rho_, rho);
656  const reco::Vertex* pv(nullptr);
657  if (primaryVertexIsValid)
658  pv = &primaryVertex;
659 
662  bool triggerObjectsAvailable = false;
663  bool triggerResultsAvailable = false;
664  if (addTriggerMatching_) {
665  triggerObjectsAvailable = iEvent.getByToken(triggerObjects_, triggerObjects);
666  triggerResultsAvailable = iEvent.getByToken(triggerResults_, triggerResults);
667  }
668 
669  for (auto& muon : *patMuons) {
670  // trigger info
671  if (addTriggerMatching_ and triggerObjectsAvailable and triggerResultsAvailable) {
672  const edm::TriggerNames& triggerNames(iEvent.triggerNames(*triggerResults));
673  fillL1TriggerInfo(muon, triggerObjects, triggerNames, geometry);
675  }
676 
678  muon.setSelectors(0);
679  bool isRun2016BCDEF = (272728 <= iEvent.run() && iEvent.run() <= 278808);
680  muon.setSelectors(muon::makeSelectorBitset(muon, pv, isRun2016BCDEF));
681  }
682  float miniIsoValue = -1;
683  if (computeMiniIso_) {
684  // MiniIsolation working points
685 
686  miniIsoValue = getRelMiniIsoPUCorrected(muon, *rho, effectiveAreaVec_);
687 
688  muon.setSelector(reco::Muon::MiniIsoLoose, miniIsoValue < 0.40);
689  muon.setSelector(reco::Muon::MiniIsoMedium, miniIsoValue < 0.20);
690  muon.setSelector(reco::Muon::MiniIsoTight, miniIsoValue < 0.10);
691  muon.setSelector(reco::Muon::MiniIsoVeryTight, miniIsoValue < 0.05);
692  }
693 
694  double puppiCombinedIsolationPAT = -1;
696  puppiCombinedIsolationPAT = puppiCombinedIsolation(muon, pc.product());
697  muon.setSelector(reco::Muon::PuppiIsoLoose, puppiCombinedIsolationPAT < 0.27);
698  muon.setSelector(reco::Muon::PuppiIsoMedium, puppiCombinedIsolationPAT < 0.22);
699  muon.setSelector(reco::Muon::PuppiIsoTight, puppiCombinedIsolationPAT < 0.12);
700  }
701 
702  float jetPtRatio = 0.0;
703  float jetPtRel = 0.0;
704  float mva = 0.0;
705  float mva_lowpt = 0.0;
706  if (computeMuonMVA_ && primaryVertexIsValid && computeMiniIso_) {
707  if (mvaUseJec_) {
708  mva = globalCache()->muonMvaEstimator()->computeMva(muon,
709  primaryVertex,
710  *(mvaBTagCollectionTag.product()),
711  jetPtRatio,
712  jetPtRel,
713  miniIsoValue,
714  &*mvaL1Corrector,
715  &*mvaL1L2L3ResCorrector);
716  mva_lowpt = globalCache()->muonLowPtMvaEstimator()->computeMva(muon,
717  primaryVertex,
718  *(mvaBTagCollectionTag.product()),
719  jetPtRatio,
720  jetPtRel,
721  miniIsoValue,
722  &*mvaL1Corrector,
723  &*mvaL1L2L3ResCorrector);
724 
725  } else {
726  mva = globalCache()->muonMvaEstimator()->computeMva(
727  muon, primaryVertex, *(mvaBTagCollectionTag.product()), jetPtRatio, jetPtRel, miniIsoValue);
728  mva_lowpt = globalCache()->muonLowPtMvaEstimator()->computeMva(
729  muon, primaryVertex, *(mvaBTagCollectionTag.product()), jetPtRatio, jetPtRel, miniIsoValue);
730  }
731 
732  muon.setMvaValue(mva);
733  muon.setLowPtMvaValue(mva_lowpt);
734  muon.setJetPtRatio(jetPtRatio);
735  muon.setJetPtRel(jetPtRel);
736 
737  // multi-isolation
738  if (computeMiniIso_) {
739  muon.setSelector(reco::Muon::MultiIsoMedium,
740  miniIsoValue < 0.11 && (muon.jetPtRatio() > 0.74 || muon.jetPtRel() > 6.8));
741  }
742 
743  // MVA working points
744  // https://twiki.cern.ch/twiki/bin/viewauth/CMS/LeptonMVA
745  double dB2D = fabs(muon.dB(pat::Muon::PV2D));
746  double dB3D = fabs(muon.dB(pat::Muon::PV3D));
747  double edB3D = fabs(muon.edB(pat::Muon::PV3D));
748  double sip3D = edB3D > 0 ? dB3D / edB3D : 0.0;
749  double dz = fabs(muon.muonBestTrack()->dz(primaryVertex.position()));
750 
751  // muon preselection
752  if (muon.pt() > 5 and muon.isLooseMuon() and muon.passed(reco::Muon::MiniIsoLoose) and sip3D < 8.0 and
753  dB2D < 0.05 and dz < 0.1) {
754  muon.setSelector(reco::Muon::MvaLoose, muon.mvaValue() > -0.60);
755  muon.setSelector(reco::Muon::MvaMedium, muon.mvaValue() > -0.20);
756  muon.setSelector(reco::Muon::MvaTight, muon.mvaValue() > 0.15);
757  muon.setSelector(reco::Muon::MvaVTight, muon.mvaValue() > 0.45);
758  muon.setSelector(reco::Muon::MvaVVTight, muon.mvaValue() > 0.9);
759  }
760  if (muon.pt() > 5 and muon.isLooseMuon() and sip3D < 4 and dB2D < 0.5 and dz < 1) {
761  muon.setSelector(reco::Muon::LowPtMvaLoose, muon.lowptMvaValue() > -0.60);
762  muon.setSelector(reco::Muon::LowPtMvaMedium, muon.lowptMvaValue() > -0.20);
763  }
764  }
765 
766  //SOFT MVA
767  if (computeSoftMuonMVA_) {
768  float mva = globalCache()->softMuonMvaEstimator()->computeMva(muon);
769  muon.setSoftMvaValue(mva);
770  //preselection in SoftMuonMvaEstimator.cc
771  muon.setSelector(reco::Muon::SoftMvaId, muon.softMvaValue() > 0.58); //WP choose for bmm4
772  }
773  }
774 
775  // put products in Event
776  std::unique_ptr<std::vector<Muon>> ptr(patMuons);
777  iEvent.put(std::move(ptr));
778 
779  if (isolator_.enabled())
781 }
782 
784  const MuonBaseRef& muonRef,
785  const reco::CandidateBaseRef& baseRef,
786  const GenAssociations& genMatches,
787  const IsoDepositMaps& deposits,
788  const IsolationValueMaps& isolationValues) const {
789  // in the particle flow algorithm,
790  // the muon momentum is recomputed.
791  // the new value is stored as the momentum of the
792  // resulting PFCandidate of type Muon, and choosen
793  // as the pat::Muon momentum
794  if (useParticleFlow_)
795  aMuon.setP4(aMuon.pfCandidateRef()->p4());
796  if (embedTrack_)
797  aMuon.embedTrack();
799  aMuon.embedStandAloneMuon();
800  if (embedCombinedMuon_)
801  aMuon.embedCombinedMuon();
802 
803  // embed the TeV refit track refs (only available for globalMuons)
804  if (aMuon.isGlobalMuon()) {
806  aMuon.embedPickyMuon();
808  aMuon.embedTpfmsMuon();
810  aMuon.embedDytMuon();
811  }
812 
813  // embed best tracks (at the end, so unless forceEmbedBestTrack_ is true we can save some space not embedding them twice)
814  if (embedBestTrack_)
818 
819  // store the match to the generated final state muons
820  if (addGenMatch_) {
821  for (size_t i = 0, n = genMatches.size(); i < n; ++i) {
822  reco::GenParticleRef genMuon = (*genMatches[i])[baseRef];
823  aMuon.addGenParticleRef(genMuon);
824  }
825  if (embedGenMatch_)
826  aMuon.embedGenParticle();
827  }
828  if (efficiencyLoader_.enabled()) {
829  efficiencyLoader_.setEfficiencies(aMuon, muonRef);
830  }
831 
832  for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
833  if (useParticleFlow_) {
834  if (deposits[j]->contains(baseRef.id())) {
835  aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[baseRef]);
836  } else if (deposits[j]->contains(muonRef.id())) {
837  aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[muonRef]);
838  } else {
839  reco::CandidatePtr source = aMuon.pfCandidateRef()->sourceCandidatePtr(0);
840  aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[source]);
841  }
842  } else {
843  aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[muonRef]);
844  }
845  }
846 
847  for (size_t j = 0; j < isolationValues.size(); ++j) {
848  if (useParticleFlow_) {
849  if (isolationValues[j]->contains(baseRef.id())) {
850  aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[baseRef]);
851  } else if (isolationValues[j]->contains(muonRef.id())) {
852  aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[muonRef]);
853  } else {
854  reco::CandidatePtr source = aMuon.pfCandidateRef()->sourceCandidatePtr(0);
855  aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[source]);
856  }
857  } else {
858  aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[muonRef]);
859  }
860  }
861 
862  if (resolutionLoader_.enabled()) {
864  }
865 }
866 
869  aMuon.p4(),
870  miniIsoParams_[0],
871  miniIsoParams_[1],
872  miniIsoParams_[2],
873  miniIsoParams_[3],
874  miniIsoParams_[4],
875  miniIsoParams_[5],
876  miniIsoParams_[6],
877  miniIsoParams_[7],
878  miniIsoParams_[8]);
879  aMuon.setMiniPFIsolation(miniiso);
880 }
881 
882 double PATMuonProducer::getRelMiniIsoPUCorrected(const pat::Muon& muon, double rho, const std::vector<double>& area) {
883  double mindr(miniIsoParams_[0]);
884  double maxdr(miniIsoParams_[1]);
885  double kt_scale(miniIsoParams_[2]);
886  double drcut = pat::miniIsoDr(muon.p4(), mindr, maxdr, kt_scale);
887  return pat::muonRelMiniIsoPUCorrected(muon.miniPFIsolation(), muon.p4(), drcut, rho, area);
888 }
889 
891  double dR_threshold = 0.4;
892  double dR2_threshold = dR_threshold * dR_threshold;
893  double mix_fraction = 0.5;
894  enum particleType { CH = 0, NH = 1, PH = 2, OTHER = 100000 };
895  double val_PuppiWithLep = 0.0;
896  double val_PuppiWithoutLep = 0.0;
897 
898  for (const auto& cand : *pc) { //pat::pat::PackedCandidate loop start
899 
900  const particleType pType =
901  isChargedHadron(cand.pdgId()) ? CH : isNeutralHadron(cand.pdgId()) ? NH : isPhoton(cand.pdgId()) ? PH : OTHER;
902  if (pType == OTHER) {
903  if (cand.pdgId() != 1 && cand.pdgId() != 2 && abs(cand.pdgId()) != 11 && abs(cand.pdgId()) != 13) {
904  LogTrace("PATMuonProducer") << "candidate with PDGID = " << cand.pdgId()
905  << " is not CH/NH/PH/e/mu or 1/2 (and this is removed from isolation calculation)"
906  << std::endl;
907  }
908  continue;
909  }
910  double d_eta = std::abs(cand.eta() - muon.eta());
911  if (d_eta > dR_threshold)
912  continue;
913 
914  double d_phi = std::abs(reco::deltaPhi(cand.phi(), muon.phi()));
915  if (d_phi > dR_threshold)
916  continue;
917 
918  double dR2 = reco::deltaR2(cand, muon);
919  if (dR2 > dR2_threshold)
920  continue;
921  if (pType == CH && dR2 < 0.0001 * 0.0001)
922  continue;
923  if (pType == NH && dR2 < 0.01 * 0.01)
924  continue;
925  if (pType == PH && dR2 < 0.01 * 0.01)
926  continue;
927  val_PuppiWithLep += cand.pt() * cand.puppiWeight();
928  val_PuppiWithoutLep += cand.pt() * cand.puppiWeightNoLep();
929 
930  } //pat::pat::PackedCandidate loop end
931 
932  double reliso_Puppi_withLep = val_PuppiWithLep / muon.pt();
933  double reliso_Puppi_withoutlep = val_PuppiWithoutLep / muon.pt();
934  double reliso_Puppi_combined = mix_fraction * reliso_Puppi_withLep + (1.0 - mix_fraction) * reliso_Puppi_withoutlep;
935  return reliso_Puppi_combined;
936 }
937 
938 bool PATMuonProducer::isNeutralHadron(long pdgid) { return std::abs(pdgid) == 130; }
939 
940 bool PATMuonProducer::isChargedHadron(long pdgid) { return std::abs(pdgid) == 211; }
941 
942 bool PATMuonProducer::isPhoton(long pdgid) { return pdgid == 22; }
943 
944 // ParameterSet description for module
947  iDesc.setComment("PAT muon producer module");
948 
949  // input source
950  iDesc.add<edm::InputTag>("muonSource", edm::InputTag("no default"))->setComment("input collection");
951 
952  // embedding
953  iDesc.add<bool>("embedMuonBestTrack", true)->setComment("embed muon best track (global pflow)");
954  iDesc.add<bool>("embedTunePMuonBestTrack", true)->setComment("embed muon best track (muon only)");
955  iDesc.add<bool>("forceBestTrackEmbedding", true)
956  ->setComment(
957  "force embedding separately the best tracks even if they're already embedded e.g. as tracker or global "
958  "tracks");
959  iDesc.add<bool>("embedTrack", true)->setComment("embed external track");
960  iDesc.add<bool>("embedStandAloneMuon", true)->setComment("embed external stand-alone muon");
961  iDesc.add<bool>("embedCombinedMuon", false)->setComment("embed external combined muon");
962  iDesc.add<bool>("embedPickyMuon", false)->setComment("embed external picky track");
963  iDesc.add<bool>("embedTpfmsMuon", false)->setComment("embed external tpfms track");
964  iDesc.add<bool>("embedDytMuon", false)->setComment("embed external dyt track ");
965 
966  // embedding of MET muon corrections
967  iDesc.add<bool>("embedCaloMETMuonCorrs", true)->setComment("whether to add MET muon correction for caloMET or not");
968  iDesc.add<edm::InputTag>("caloMETMuonCorrs", edm::InputTag("muonMETValueMapProducer", "muCorrData"))
969  ->setComment("source of MET muon corrections for caloMET");
970  iDesc.add<bool>("embedTcMETMuonCorrs", true)->setComment("whether to add MET muon correction for tcMET or not");
971  iDesc.add<edm::InputTag>("tcMETMuonCorrs", edm::InputTag("muonTCMETValueMapProducer", "muCorrData"))
972  ->setComment("source of MET muon corrections for tcMET");
973 
974  // pf specific parameters
975  iDesc.add<edm::InputTag>("pfMuonSource", edm::InputTag("pfMuons"))->setComment("particle flow input collection");
976  iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
977  iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
978  iDesc.add<bool>("embedPfEcalEnergy", true)->setComment("add ecal energy as reconstructed by PF");
979 
980  // inverse beta computation
981  iDesc.add<bool>("addInverseBeta", true)->setComment("add combined inverse beta");
982  iDesc.add<edm::InputTag>("sourceInverseBeta", edm::InputTag("muons", "combined"))
983  ->setComment("source of inverse beta values");
984 
985  // MC matching configurables
986  iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
987  iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
988  std::vector<edm::InputTag> emptySourceVector;
989  iDesc
990  .addNode(edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
991  edm::ParameterDescription<std::vector<edm::InputTag>>("genParticleMatch", emptySourceVector, true))
992  ->setComment("input with MC match information");
993 
994  // mini-iso
995  iDesc.add<bool>("computeMiniIso", false)->setComment("whether or not to compute and store electron mini-isolation");
996  iDesc.add<bool>("computePuppiCombinedIso", false)
997  ->setComment("whether or not to compute and store puppi combined isolation");
998 
999  iDesc.add<edm::InputTag>("pfCandsForMiniIso", edm::InputTag("packedPFCandidates"))
1000  ->setComment("collection to use to compute mini-iso");
1001  iDesc.add<std::vector<double>>("miniIsoParams", std::vector<double>())
1002  ->setComment("mini-iso parameters to use for muons");
1003 
1004  iDesc.add<bool>("addTriggerMatching", false)->setComment("add L1 and HLT matching to offline muon");
1005 
1007 
1008  // IsoDeposit configurables
1009  edm::ParameterSetDescription isoDepositsPSet;
1010  isoDepositsPSet.addOptional<edm::InputTag>("tracker");
1011  isoDepositsPSet.addOptional<edm::InputTag>("ecal");
1012  isoDepositsPSet.addOptional<edm::InputTag>("hcal");
1013  isoDepositsPSet.addOptional<edm::InputTag>("particle");
1014  isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1015  isoDepositsPSet.addOptional<edm::InputTag>("pfChargedAll");
1016  isoDepositsPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1017  isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1018  isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
1019  isoDepositsPSet.addOptional<std::vector<edm::InputTag>>("user");
1020  iDesc.addOptional("isoDeposits", isoDepositsPSet);
1021 
1022  // isolation values configurables
1023  edm::ParameterSetDescription isolationValuesPSet;
1024  isolationValuesPSet.addOptional<edm::InputTag>("tracker");
1025  isolationValuesPSet.addOptional<edm::InputTag>("ecal");
1026  isolationValuesPSet.addOptional<edm::InputTag>("hcal");
1027  isolationValuesPSet.addOptional<edm::InputTag>("particle");
1028  isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1029  isolationValuesPSet.addOptional<edm::InputTag>("pfChargedAll");
1030  isolationValuesPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1031  isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1032  isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
1033  iDesc.addOptional("isolationValues", isolationValuesPSet);
1034 
1035  iDesc.ifValue(edm::ParameterDescription<bool>("addPuppiIsolation", false, true),
1037  "puppiIsolationChargedHadrons",
1038  edm::InputTag("muonPUPPIIsolation", "h+-DR030-ThresholdVeto000-ConeVeto000"),
1039  true) and
1041  "puppiIsolationNeutralHadrons",
1042  edm::InputTag("muonPUPPIIsolation", "h0-DR030-ThresholdVeto000-ConeVeto001"),
1043  true) and
1045  "puppiIsolationPhotons",
1046  edm::InputTag("muonPUPPIIsolation", "gamma-DR030-ThresholdVeto000-ConeVeto001"),
1047  true) and
1049  "puppiNoLeptonsIsolationChargedHadrons",
1050  edm::InputTag("muonPUPPINoLeptonsIsolation", "h+-DR030-ThresholdVeto000-ConeVeto000"),
1051  true) and
1053  "puppiNoLeptonsIsolationNeutralHadrons",
1054  edm::InputTag("muonPUPPINoLeptonsIsolation", "h0-DR030-ThresholdVeto000-ConeVeto001"),
1055  true) and
1057  "puppiNoLeptonsIsolationPhotons",
1058  edm::InputTag("muonPUPPINoLeptonsIsolation", "gamma-DR030-ThresholdVeto000-ConeVeto001"),
1059  true)) or
1060  false >> edm::EmptyGroupDescription());
1061 
1062  // Efficiency configurables
1063  edm::ParameterSetDescription efficienciesPSet;
1064  efficienciesPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
1065  iDesc.add("efficiencies", efficienciesPSet);
1066  iDesc.add<bool>("addEfficiencies", false);
1067 
1068  // Check to see if the user wants to add user data
1069  edm::ParameterSetDescription userDataPSet;
1071  iDesc.addOptional("userData", userDataPSet);
1072 
1073  edm::ParameterSetDescription isolationPSet;
1074  isolationPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
1075  iDesc.add("userIsolation", isolationPSet);
1076 
1077  iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
1078  edm::ParameterSetDescription highLevelPSet;
1079  highLevelPSet.setAllowAnything();
1080  iDesc.addNode(edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true))
1081  ->setComment("input with high level selection");
1083  ->setComment("input with high level selection");
1084 
1085  //descriptions.add("PATMuonProducer", iDesc);
1086 }
1087 
1088 // embed various impact parameters with errors
1089 // embed high level selection
1094  bool primaryVertexIsValid,
1096  bool beamspotIsValid) {
1097  // Correct to PV
1098 
1099  // PV2D
1100  std::pair<bool, Measurement1D> result =
1101  IPTools::signedTransverseImpactParameter(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex);
1102  double d0_corr = result.second.value();
1103  double d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
1104  aMuon.setDB(d0_corr, d0_err, pat::Muon::PV2D);
1105 
1106  // PV3D
1107  result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex);
1108  d0_corr = result.second.value();
1109  d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
1110  aMuon.setDB(d0_corr, d0_err, pat::Muon::PV3D);
1111 
1112  // Correct to beam spot
1113  // make a fake vertex out of beam spot
1114  reco::Vertex vBeamspot(beamspot.position(), beamspot.rotatedCovariance3D());
1115 
1116  // BS2D
1117  result = IPTools::signedTransverseImpactParameter(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot);
1118  d0_corr = result.second.value();
1119  d0_err = beamspotIsValid ? result.second.error() : -1.0;
1120  aMuon.setDB(d0_corr, d0_err, pat::Muon::BS2D);
1121 
1122  // BS3D
1123  result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot);
1124  d0_corr = result.second.value();
1125  d0_err = beamspotIsValid ? result.second.error() : -1.0;
1126  aMuon.setDB(d0_corr, d0_err, pat::Muon::BS3D);
1127 
1128  // PVDZ
1129  aMuon.setDB(
1130  track->dz(primaryVertex.position()), std::hypot(track->dzError(), primaryVertex.zError()), pat::Muon::PVDZ);
1131 }
1132 
1134 
bool embedTpfmsMuon_
embed track from tpfms muon fit into the muon
edm::EDGetTokenT< edm::ValueMap< float > > PUPPIIsolation_charged_hadrons_
bool enabled() const
&#39;true&#39; if this there is at least one efficiency configured
bool useUserData_
add user data to the muon (this will be data members of th muon even w/o embedding) ...
void readIsolationLabels(const edm::ParameterSet &iConfig, const char *psetName, IsolationLabels &labels, std::vector< edm::EDGetTokenT< edm::ValueMap< T >>> &tokens)
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
edm::EDGetTokenT< edm::ValueMap< float > > PUPPIIsolation_photons_
T getParameter(std::string const &) const
double ecalEnergy() const
return corrected Ecal energy
Definition: PFCandidate.h:220
void setComment(std::string const &value)
Assists in assimilating all pat::UserData into pat objects.
ParameterDescriptionNode * ifValue(ParameterDescription< T > const &switchParameter, std::unique_ptr< ParameterDescriptionCases< T >> cases)
void newEvent(const edm::Event &event)
To be called for each new event, reads in the ValueMaps for efficiencies.
bool addPuppiIsolation_
add puppi isolation
void embedDytMuon()
embed reference to the above dyt Track
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
void embedTpfmsMuon()
embed reference to the above tpfms Track
edm::EDGetTokenT< edm::ValueMap< reco::MuonMETCorrectionData > > tcMETMuonCorrsToken_
source of tcMET muon corrections
double eta() const final
momentum pseudorapidity
void setIsolation(IsolationKeys key, float value)
Definition: Lepton.h:115
bool embedTcMETMuonCorrs_
embed muon MET correction info for tcMET into the muon
class definition
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:160
void embedTcMETMuonCorrs(const reco::MuonMETCorrectionData &t)
edm::EDGetTokenT< std::vector< reco::Vertex > > pvToken_
input source of the primary vertex
bool contains(EventRange const &lh, EventID const &rh)
Definition: EventRange.cc:37
static const int OTHER
edm::EDGetTokenT< edm::ValueMap< reco::MuonTimeExtra > > muonTimeExtraToken_
input tag for reading inverse beta
edm::EDGetTokenT< edm::ValueMap< float > > PUPPINoLeptonsIsolation_photons_
void embedCombinedMuon()
set reference to Track reconstructed in both tracked and muon detector (reimplemented from reco::Muon...
edm::EDGetTokenT< double > rho_
edm::EDGetTokenT< edm::View< reco::Muon > > muonToken_
input source
void embedTunePMuonBestTrack(bool force=false)
bool addEfficiencies_
add efficiencies to the muon (this will be data members of th muon even w/o embedding) ...
edm::EDGetTokenT< edm::ValueMap< reco::MuonMETCorrectionData > > caloMETMuonCorrsToken_
source of caloMET muon corrections
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
enum start value shifted to 81 so as to avoid clashes with PDG codes
void setAllowAnything()
allow any parameter label/value pairs
double zError() const
error on z
Definition: Vertex.h:127
void setSimFlavour(int f)
Definition: Muon.h:323
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
bool embedCaloMETMuonCorrs_
embed muon MET correction info for caloMET into the muon
bool isChargedHadron(long pdgid)
std::pair< bool, Measurement1D > signedTransverseImpactParameter(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:57
~PATMuonProducer() override
default destructur
edm::EDGetTokenT< edm::ValueMap< reco::MuonSimInfo > > simInfo_
MC info.
void embedMuonBestTrack(bool force=false)
std::vector< pat::PackedCandidate > PackedCandidateCollection
void setIsolationPUPPINoLeptons(float chargedhadrons, float neutralhadrons, float photons)
sets PUPPINoLeptons isolations
Definition: Muon.h:205
void setMuonMiniIso(pat::Muon &aMuon, const pat::PackedCandidateCollection *pc)
reco::TransientTrack build(const reco::Track *p) const
PATMuonProducer(const edm::ParameterSet &iConfig, PATMuonHeavyObjectCache const *)
default constructir
bool addTriggerMatching_
Trigger.
void setSimBX(int bx)
Definition: Muon.h:327
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
bool embedBestTrack_
embed the track from best muon measurement (global pflow)
CH
LTS and SET for low trigger suppression.
edm::EDGetTokenT< reco::JetCorrector > mvaL1Corrector_
std::pair< bool, Measurement1D > signedImpactParameter3D(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:81
double pt() const final
transverse momentum
bool addResolutions_
add resolutions to the muon (this will be data members of th muon even w/o embedding) ...
void unpackPathNames(const edm::TriggerNames &names)
unpack trigger names into indices
edm::EDGetTokenT< edm::ValueMap< float > > PUPPINoLeptonsIsolation_charged_hadrons_
std::vector< double > miniIsoParams_
void setSimPhi(float phi)
Definition: Muon.h:333
PFCandidateCollection::const_iterator PFCandidateConstIterator
iterator
void setResolutions(pat::PATObject< T > &obj) const
Sets the efficiencies for this object, using the reference to the original objects.
void setSimProdRho(float rho)
Definition: Muon.h:329
void setSimHeaviestMotherFlavour(int id)
Definition: Muon.h:324
void setPFCandidateRef(const reco::PFCandidateRef &ref)
add a reference to the source IsolatedPFCandidate
Definition: Muon.h:139
bool isRealData() const
Definition: EventBase.h:62
const Point & position() const
position
Definition: Vertex.h:113
void embedHighLevel(pat::Muon &aMuon, reco::TrackRef track, reco::TransientTrack &tt, reco::Vertex &primaryVertex, bool primaryVertexIsValid, reco::BeamSpot &beamspot, bool beamspotIsValid)
std::vector< double > effectiveAreaVec_
ProductID id() const
Definition: RefToBase.h:214
const std::string names[nVars_]
bool isAvailable() const
Definition: Ref.h:537
edm::EDGetTokenT< edm::ValueMap< float > > PUPPINoLeptonsIsolation_neutral_hadrons_
void setSimType(reco::MuonSimType type)
Definition: Muon.h:321
void embedStandAloneMuon()
set reference to Track reconstructed in the muon detector only (reimplemented from reco::Muon) ...
edm::EDGetTokenT< reco::JetTagCollection > mvaBTagCollectionTag_
edm::EDGetTokenT< reco::PFCandidateCollection > pfMuonToken_
input source pfCandidates that will be to be transformed into pat::Muons, when using PF2PAT ...
void setIsolationPUPPI(float chargedhadrons, float neutralhadrons, float photons)
sets PUPPI isolations
Definition: Muon.h:199
pat::helper::MultiIsolator isolator_
helper class to add userdefined isolation values to the muon
std::vector< edm::EDGetTokenT< edm::ValueMap< IsoDeposit > > > isoDepositTokens_
bool enabled() const
&#39;true&#39; if this there is at least one efficiency configured
void setIsoDeposit(IsolationKeys key, const IsoDeposit &dep)
Sets the IsoDeposit associated with some key; if it is already existent, it is overwritten.
Definition: Lepton.h:191
Definition: HeavyIon.h:7
void embedTrack()
set reference to Track reconstructed in the tracker only (reimplemented from reco::Muon) ...
static void fillDescription(edm::ParameterSetDescription &iDesc)
const PFIsolation & miniPFIsolation() const
Definition: Lepton.h:216
edm::EDGetTokenT< reco::BeamSpot > beamLineToken_
input source of the primary vertex/beamspot
bool addInverseBeta_
add combined inverse beta measurement into the muon
bool useParticleFlow_
switch to use particle flow (PF2PAT) or not
pat::PATUserDataHelper< pat::Muon > userDataHelper_
helper class to add userData to the muon
bool enabled() const
True if it has a non null configuration.
Definition: MultiIsolator.h:55
std::vector< edm::Handle< edm::ValueMap< IsoDeposit > > > IsoDepositMaps
bool embedStandAloneMuon_
embed track from muon system into the muon
void setComment(std::string const &value)
double muonRelMiniIsoPUCorrected(const PFIsolation &iso, const math::XYZTLorentzVector &p4, double dr, double rho, const std::vector< double > &area)
edm::EDGetTokenT< edm::TriggerResults > triggerResults_
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void beginEvent(const edm::Event &event, const edm::EventSetup &eventSetup)
GreaterByPt< Muon > pTComparator_
bool embedTrack_
embed the track from inner tracker into the muon
void setDB(double dB, double edB, IPTYPE type=PV2D)
Definition: Muon.h:245
bool addGenMatch_
add generator match information
PATMuonHeavyObjectCache(const edm::ParameterSet &)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
description of config file parameters
Definition: Muon.py:1
void fillL1TriggerInfo(pat::Muon &muon, edm::Handle< std::vector< pat::TriggerObjectStandAlone >> &triggerObjects, const edm::TriggerNames &names, const edm::ESHandle< GlobalTrackingGeometry > &geometry)
bool isGlobalMuon() const override
Definition: Muon.h:298
bool embedPfEcalEnergy_
add ecal PF energy
void embedGenParticle()
Definition: PATObject.h:773
void newEvent(const edm::Event &event, const edm::EventSetup &setup)
To be called for each new event, reads in the EventSetup object.
void embedPFCandidate()
embed the IsolatedPFCandidate pointed to by pfCandidateRef_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
everything that needs to be done during the event loop
reco::PFCandidateRef pfCandidateRef() const
RunNumber_t run() const
Definition: Event.h:107
def pv(vc)
Definition: MetAnalyzer.py:7
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::EDGetTokenT< pat::PackedCandidateCollection > pcToken_
const LorentzVector & p4() const final
four-momentum Lorentz vector
static std::string const triggerResults
Definition: EdmProvDump.cc:45
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isValid() const
Definition: HandleBase.h:70
double puppiCombinedIsolation(const pat::Muon &muon, const pat::PackedCandidateCollection *pc)
#define LogTrace(id)
void readTimeExtra(const reco::MuonTimeExtra &t)
std::vector< std::string > hltCollectionFilters_
reco::MuonRef muonRef() const
Definition: PFCandidate.cc:421
void fillHltTriggerInfo(pat::Muon &muon, edm::Handle< std::vector< pat::TriggerObjectStandAlone >> &triggerObjects, const edm::TriggerNames &names, const std::vector< std::string > &collection_names)
reco::Muon::Selector makeSelectorBitset(reco::Muon const &muon, reco::Vertex const *vertex=0, bool run2016_hip_mitigation=false)
Definition: DetId.h:17
std::vector< std::pair< pat::IsolationKeys, float > > IsolationValuePairs
Definition: MultiIsolator.h:17
bool isAValidMuonTrack(const MuonTrackType &type) const
void initSimInfo(void)
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
void addGenParticleRef(const reco::GenParticleRef &ref)
Definition: PATObject.h:756
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
void setPfEcalEnergy(float pfEcalEnergy)
Definition: Muon.h:275
bool embedTunePBestTrack_
embed the track from best muon measurement (muon only)
T const * product() const
Definition: Handle.h:69
static void fillDescription(edm::ParameterSetDescription &iDesc)
Method for documentation and validation of PSet.
double getRelMiniIsoPUCorrected(const pat::Muon &muon, double rho, const std::vector< double > &area)
void setSimMotherPdgId(int id)
Definition: Muon.h:326
void setEfficiencies(pat::PATObject< T > &obj, const R &originalRef) const
Sets the efficiencies for this object, using the reference to the original objects.
void addTriggerObjectMatch(const TriggerObjectStandAlone &trigObj)
add a trigger match
Definition: PATObject.h:243
void setExtSimType(reco::ExtendedMuonSimType type)
Definition: Muon.h:322
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:145
void setMiniPFIsolation(PFIsolation const &iso)
Definition: Lepton.h:217
std::vector< edm::Handle< edm::Association< reco::GenParticleCollection > > > GenAssociations
edm::EDGetTokenT< reco::JetCorrector > mvaL1L2L3ResCorrector_
void fillMuon(Muon &aMuon, const MuonBaseRef &muonRef, const reco::CandidateBaseRef &baseRef, const GenAssociations &genMatches, const IsoDepositMaps &deposits, const IsolationValueMaps &isolationValues) const
common muon filling, for both the standard and PF2PAT case
ESHandle< TrackerGeometry > geometry
void setSimProdZ(float z)
Definition: Muon.h:330
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
std::vector< edm::Handle< edm::ValueMap< double > > > IsolationValueMaps
pat::helper::EfficiencyLoader efficiencyLoader_
helper class to add efficiencies to the muon
HLT enums.
bool embedPickyMuon_
embed track from picky muon fit into the muon
void setNormChi2(double normChi2)
Definition: Muon.h:260
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:86
bool embedDytMuon_
embed track from DYT muon fit into the muon
void embedCaloMETMuonCorrs(const reco::MuonMETCorrectionData &t)
PFIsolation getMiniPFIsolation(const pat::PackedCandidateCollection *pfcands, const math::XYZTLorentzVector &p4, float mindr=0.05, float maxdr=0.2, float kt_scale=10.0, float ptthresh=0.5, float deadcone_ch=0.0001, float deadcone_pu=0.01, float deadcone_ph=0.01, float deadcone_nh=0.01, float dZ_cut=0.0)
void setSimPdgId(int id)
Definition: Muon.h:325
T get() const
Definition: EventSetup.h:73
void setSimPt(float pt)
Definition: Muon.h:331
const GeomDet * idToDet(DetId) const override
float miniIsoDr(const math::XYZTLorentzVector &p4, float mindr, float maxdr, float kt_scale)
bool isPhoton(long pdgid)
pat::helper::MultiIsolator::IsolationValuePairs isolatorTmpStorage_
isolation value pair for temporary storage before being folded into the muon
edm::EDGetTokenT< std::vector< pat::TriggerObjectStandAlone > > triggerObjects_
bool embedGenMatch_
embed the gen match information into the muon
const Point & position() const
position
Definition: BeamSpot.h:59
IsolationLabels isoDepositLabels_
input source for isoDeposits
std::vector< edm::EDGetTokenT< edm::Association< reco::GenParticleCollection > > > genMatchTokens_
input tags for generator match information
Covariance3DMatrix rotatedCovariance3D() const
Definition: BeamSpot.cc:73
static constexpr int DT
Definition: MuonSubdetId.h:11
IsolationLabels isolationValueLabels_
input source isolation value maps
bool isValid() const
Definition: ESHandle.h:44
void embedPickyMuon()
embed reference to the above picky Track
static constexpr int CSC
Definition: MuonSubdetId.h:12
primaryVertex
hltOfflineBeamSpot for HLTMON
bool forceEmbedBestTrack_
force separate embed of the best track even if already embedded
bool embedPFCandidate_
embed pfCandidates into the muon
double phi() const final
momentum azimuthal angle
std::vector< edm::EDGetTokenT< edm::ValueMap< double > > > isolationValueTokens_
void setNumberOfValidHits(unsigned int numberOfValidHits)
Definition: Muon.h:253
bool computeMuonMVA_
standard muon selectors
void setSimEta(float eta)
Definition: Muon.h:332
bool embedCombinedMuon_
embed track of the combined fit into the muon
Analysis-level muon class.
Definition: Muon.h:51
pat::helper::KinResolutionsLoader resolutionLoader_
helper class to add resolutions to the muon
static std::string const source
Definition: EdmProvDump.cc:47
void setP4(const LorentzVector &p4) final
set 4-momentum
edm::TriggerNames const & triggerNames(edm::TriggerResults const &triggerResults) const override
Definition: Event.cc:265
edm::EDGetTokenT< edm::ValueMap< float > > PUPPIIsolation_neutral_hadrons_
def move(src, dest)
Definition: eostools.py:511
std::optional< GlobalPoint > getMuonDirection(const reco::MuonChamberMatch &chamberMatch, const edm::ESHandle< GlobalTrackingGeometry > &geometry, const DetId &chamberId)
bool isNeutralHadron(long pdgid)
Global3DVector GlobalVector
Definition: GlobalVector.h:10
Analysis-level trigger object class (stand-alone)
void setSimMatchQuality(float quality)
Definition: Muon.h:334
void fill(const edm::View< T > &coll, int idx, IsolationValuePairs &isolations) const
Definition: MultiIsolator.h:84
void setSimTpEvent(int tpEvent)
Definition: Muon.h:328
bool embedHighLevelSelection_
embed high level selection variables