CMS 3D CMS Logo

L1TkMuonProducer.cc
Go to the documentation of this file.
1 // input: L1TkTracks and RegionalMuonCand (standalone with component details)
2 // match the two and produce a collection of TkMuon
3 // eventually, this should be made modular and allow to swap out different algorithms
4 
5 // user include files
25 
26 // system include files
27 #include <memory>
28 #include <string>
29 
30 static constexpr float mu_mass = 0.105658369;
31 static constexpr int barrel_MTF_region = 1;
32 static constexpr int overlap_MTF_region = 2;
33 static constexpr int endcap_MTF_region = 3;
34 static constexpr float eta_scale = 0.010875;
35 static constexpr float phi_scale = 2 * M_PI / 576.;
36 static constexpr float dr2_cutoff = 0.3;
37 static constexpr float matching_factor_eta = 3.;
38 static constexpr float matching_factor_phi = 4.;
39 static constexpr float min_mu_propagator_p = 3.5;
40 static constexpr float min_mu_propagator_barrel_pT = 3.5;
41 static constexpr float max_mu_propagator_eta = 2.5;
42 
43 using namespace l1t;
44 
46 public:
48  typedef std::vector<L1TTTrackType> L1TTTrackCollectionType;
49 
50  struct PropState { //something simple, imagine it's hardware emulation
51  PropState() : pt(-99), eta(-99), phi(-99), sigmaPt(-99), sigmaEta(-99), sigmaPhi(-99), valid(false) {}
52  float pt;
53  float eta;
54  float phi;
55  float sigmaPt;
56  float sigmaEta;
57  float sigmaPhi;
58  bool valid;
59  };
60 
61  enum AlgoType { kTP = 1, kDynamicWindows = 2, kMantra = 3 };
62 
63  explicit L1TkMuonProducer(const edm::ParameterSet&);
64  ~L1TkMuonProducer() override;
65 
66  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
67 
68 private:
69  void produce(edm::Event&, const edm::EventSetup&) override;
70  PropState propagateToGMT(const L1TTTrackType& l1tk) const;
71  double sigmaEtaTP(const RegionalMuonCand& mu) const;
72  double sigmaPhiTP(const RegionalMuonCand& mu) const;
73 
74  // the TP algorithm
75  void runOnMTFCollection_v1(const edm::Handle<RegionalMuonCandBxCollection>&,
78  const int detector) const;
79 
80  // algo for endcap regions using dynamic windows for making the match
81  void runOnMTFCollection_v2(const edm::Handle<EMTFTrackCollection>&,
83  TkMuonCollection& tkMuons) const;
84 
85  // given the matching indexes, build the output collection of track muons
86  void build_tkMuons_from_idxs(TkMuonCollection& tkMuons,
87  const std::vector<int>& matches,
90  int detector) const;
91 
92  void build_tkMuons_from_idxs(TkMuonCollection& tkMuons,
93  const std::vector<int>& matches,
95  const edm::Handle<EMTFTrackCollection>& emtfTksH,
96  int detector) const;
97 
98  // dump and convert tracks to the format needed for the MAnTra correlator
99  std::vector<L1TkMuMantraDF::track_df> product_to_trkvec(const L1TTTrackCollectionType& l1tks) const; // tracks
100  // regional muon finder
101  std::vector<L1TkMuMantraDF::muon_df> product_to_muvec(const RegionalMuonCandBxCollection& l1mtfs) const;
102  // endcap muon finder - eventually to be moved to regional candidate
103  std::vector<L1TkMuMantraDF::muon_df> product_to_muvec(const EMTFTrackCollection& l1mus) const;
104 
105  float etaMin_;
106  float etaMax_;
107  float etaBO_; //eta value for barrel-overlap fontier
108  float etaOE_; //eta value for overlap-endcap fontier
110  float zMax_; // |z_track| < zMax_ in cm
111  float chi2Max_;
112  float pTMinTra_;
113  float dRMax_;
114  int nStubsmin_; // minimum number of stubs
119 
123 
124  std::unique_ptr<L1TkMuCorrDynamicWindows> dwcorr_;
125 
126  std::unique_ptr<L1TkMuMantra> mantracorr_barr_;
127  std::unique_ptr<L1TkMuMantra> mantracorr_ovrl_;
128  std::unique_ptr<L1TkMuMantra> mantracorr_endc_;
130 
134  // the track collection, directly from the EMTF and not formatted by GT
137 };
138 
140  : etaMin_((float)iConfig.getParameter<double>("ETAMIN")),
141  etaMax_((float)iConfig.getParameter<double>("ETAMAX")),
142  etaBO_(iConfig.exists("ETABARRELOVERLAP") ? (float)iConfig.getParameter<double>("ETABARRELOVERLAP") : 0.83),
143  etaOE_(iConfig.exists("ETAOVERLAPENDCAP") ? (float)iConfig.getParameter<double>("ETAOVERLAPENDCAP") : 1.24),
144  useRegionEtaMatching_(iConfig.exists("useRegionEtaMatching") ? iConfig.getParameter<bool>("useRegionEtaMatching")
145  : true),
146  zMax_((float)iConfig.getParameter<double>("ZMAX")),
147  chi2Max_((float)iConfig.getParameter<double>("CHI2MAX")),
148  pTMinTra_((float)iConfig.getParameter<double>("PTMINTRA")),
149  dRMax_((float)iConfig.getParameter<double>("DRmax")),
150  nStubsmin_(iConfig.getParameter<int>("nStubsmin")),
151 
152  // --- mantra corr params
153  mantra_n_trk_par_(iConfig.getParameter<int>("mantra_n_trk_par")),
154  bmtfToken_(consumes<RegionalMuonCandBxCollection>(iConfig.getParameter<edm::InputTag>("L1BMTFInputTag"))),
155  omtfToken_(consumes<RegionalMuonCandBxCollection>(iConfig.getParameter<edm::InputTag>("L1OMTFInputTag"))),
156  emtfToken_(consumes<RegionalMuonCandBxCollection>(iConfig.getParameter<edm::InputTag>("L1EMTFInputTag"))),
157  emtfTCToken_(consumes<EMTFTrackCollection>(iConfig.getParameter<edm::InputTag>("L1EMTFTrackCollectionInputTag"))),
158  trackToken_(consumes<std::vector<TTTrack<Ref_Phase2TrackerDigi_> > >(
159  iConfig.getParameter<edm::InputTag>("L1TrackInputTag"))) {
160  // --------------------- configuration of the muon algorithm type
161 
162  std::string bmtfMatchAlgoVersionString = iConfig.getParameter<std::string>("bmtfMatchAlgoVersion");
163  std::transform(bmtfMatchAlgoVersionString.begin(),
164  bmtfMatchAlgoVersionString.end(),
165  bmtfMatchAlgoVersionString.begin(),
166  ::tolower); // make lowercase
167 
168  std::string omtfMatchAlgoVersionString = iConfig.getParameter<std::string>("omtfMatchAlgoVersion");
169  std::transform(omtfMatchAlgoVersionString.begin(),
170  omtfMatchAlgoVersionString.end(),
171  omtfMatchAlgoVersionString.begin(),
172  ::tolower); // make lowercase
173 
174  std::string emtfMatchAlgoVersionString = iConfig.getParameter<std::string>("emtfMatchAlgoVersion");
175  std::transform(emtfMatchAlgoVersionString.begin(),
176  emtfMatchAlgoVersionString.end(),
177  emtfMatchAlgoVersionString.begin(),
178  ::tolower); // make lowercase
179 
180  if (bmtfMatchAlgoVersionString == "tp")
182  else if (bmtfMatchAlgoVersionString == "mantra")
184  else
185  throw cms::Exception("TkMuAlgoConfig")
186  << "the ID " << bmtfMatchAlgoVersionString << " of the BMTF algo matcher passed is invalid\n";
187 
188  if (omtfMatchAlgoVersionString == "tp")
190  else if (omtfMatchAlgoVersionString == "mantra")
192  else
193  throw cms::Exception("TkMuAlgoConfig")
194  << "the ID " << omtfMatchAlgoVersionString << " of the OMTF algo matcher passed is invalid\n";
195 
196  if (emtfMatchAlgoVersionString == "tp")
198  else if (emtfMatchAlgoVersionString == "dynamicwindows")
200  else if (emtfMatchAlgoVersionString == "mantra")
202  else
203  throw cms::Exception("TkMuAlgoConfig")
204  << "the ID " << emtfMatchAlgoVersionString << " of the EMTF algo matcher passed is invalid\n";
205 
206  correctGMTPropForTkZ_ = iConfig.getParameter<bool>("correctGMTPropForTkZ");
207 
208  use5ParameterFit_ = iConfig.getParameter<bool>("use5ParameterFit");
209  useTPMatchWindows_ = iConfig.getParameter<bool>("useTPMatchWindows");
210  applyQuality_ = iConfig.exists("applyQualityCuts") ? iConfig.getParameter<bool>("applyQualityCuts") : false;
211 
212  produces<TkMuonCollection>();
213 
214  // initializations
216  // FIXME: to merge eventually into an unique file with bith phi and theta boundaries
217  std::string fIn_bounds_name = iConfig.getParameter<edm::FileInPath>("emtfcorr_boundaries").fullPath();
218  std::string fIn_theta_name = iConfig.getParameter<edm::FileInPath>("emtfcorr_theta_windows").fullPath();
219  std::string fIn_phi_name = iConfig.getParameter<edm::FileInPath>("emtfcorr_phi_windows").fullPath();
220  const auto& bounds = L1TkMuCorrDynamicWindows::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l");
221  TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str());
222  TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str());
223  dwcorr_ = std::make_unique<L1TkMuCorrDynamicWindows>(bounds, fIn_theta, fIn_phi);
224 
225  // files can be closed since the correlator code clones the TF1s
226  fIn_theta->Close();
227  fIn_phi->Close();
228 
229  // FIXME: more initialisation using the parameters passed from the cfg
230  dwcorr_->set_safety_factor(iConfig.getParameter<double>("final_window_factor"));
231  dwcorr_->set_sf_initialrelax(iConfig.getParameter<double>("initial_window_factor"));
232 
233  dwcorr_->set_relaxation_pattern(iConfig.getParameter<double>("pt_start_relax"),
234  iConfig.getParameter<double>("pt_end_relax"));
235 
236  dwcorr_->set_do_relax_factor(iConfig.getParameter<bool>("do_relax_factors"));
237 
238  dwcorr_->set_n_trk_par(iConfig.getParameter<int>("n_trk_par"));
239  dwcorr_->set_min_trk_p(iConfig.getParameter<double>("min_trk_p"));
240  dwcorr_->set_max_trk_aeta(iConfig.getParameter<double>("max_trk_aeta"));
241  dwcorr_->set_max_trk_chi2(iConfig.getParameter<double>("max_trk_chi2"));
242  dwcorr_->set_min_trk_nstubs(iConfig.getParameter<int>("min_trk_nstubs"));
243  dwcorr_->set_do_trk_qual_presel(true);
244  }
245 
247  std::string fIn_bounds_name = iConfig.getParameter<edm::FileInPath>("mantra_bmtfcorr_boundaries").fullPath();
248  std::string fIn_theta_name = iConfig.getParameter<edm::FileInPath>("mantra_bmtfcorr_theta_windows").fullPath();
249  std::string fIn_phi_name = iConfig.getParameter<edm::FileInPath>("mantra_bmtfcorr_phi_windows").fullPath();
250 
251  const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l");
252 
253  TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str());
254  TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str());
255 
256  mantracorr_barr_ = std::make_unique<L1TkMuMantra>(bounds, fIn_theta, fIn_phi, "mantra_barrel");
257 
258  fIn_theta->Close();
259  fIn_phi->Close();
260 
261  // settings : NB : now hardcoded, could be read from cfg
262  mantracorr_barr_->set_safety_factor(0.5, 0.5);
263  mantracorr_barr_->setArbitrationType("MaxPt");
264  }
265 
267  std::string fIn_bounds_name = iConfig.getParameter<edm::FileInPath>("mantra_omtfcorr_boundaries").fullPath();
268  std::string fIn_theta_name = iConfig.getParameter<edm::FileInPath>("mantra_omtfcorr_theta_windows").fullPath();
269  std::string fIn_phi_name = iConfig.getParameter<edm::FileInPath>("mantra_omtfcorr_phi_windows").fullPath();
270 
271  const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l");
272 
273  TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str());
274  TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str());
275 
276  mantracorr_ovrl_ = std::make_unique<L1TkMuMantra>(bounds, fIn_theta, fIn_phi, "mantra_overlap");
277 
278  fIn_theta->Close();
279  fIn_phi->Close();
280 
281  // settings : NB : now hardcoded, could be read from cfg
282  mantracorr_ovrl_->set_safety_factor(0.5, 0.5);
283  mantracorr_ovrl_->setArbitrationType("MaxPt");
284  }
285 
287  std::string fIn_bounds_name = iConfig.getParameter<edm::FileInPath>("mantra_emtfcorr_boundaries").fullPath();
288  std::string fIn_theta_name = iConfig.getParameter<edm::FileInPath>("mantra_emtfcorr_theta_windows").fullPath();
289  std::string fIn_phi_name = iConfig.getParameter<edm::FileInPath>("mantra_emtfcorr_phi_windows").fullPath();
290 
291  const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l");
292 
293  TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str());
294  TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str());
295 
296  mantracorr_endc_ = std::make_unique<L1TkMuMantra>(bounds, fIn_theta, fIn_phi, "mantra_endcap");
297 
298  fIn_theta->Close();
299  fIn_phi->Close();
300 
301  // settings : NB : now hardcoded, could be read from cfg
302  mantracorr_endc_->set_safety_factor(0.5, 0.5);
303  mantracorr_endc_->setArbitrationType("MaxPt");
304  }
305 }
306 
308 
309 // ------------ method called to produce the data ------------
311  // the L1Mu objects
316 
317  iEvent.getByToken(bmtfToken_, l1bmtfH);
318  iEvent.getByToken(omtfToken_, l1omtfH);
319  iEvent.getByToken(emtfToken_, l1emtfH);
320  iEvent.getByToken(emtfTCToken_, l1emtfTCH);
321 
322  // the L1Tracks
324  iEvent.getByToken(trackToken_, l1tksH);
325 
326  TkMuonCollection oc_bmtf_tkmuon;
327  TkMuonCollection oc_omtf_tkmuon;
328  TkMuonCollection oc_emtf_tkmuon;
329 
330  std::vector<L1TkMuMantraDF::track_df> mantradf_tracks; // if needed, just encode once for all trk finders
332  mantradf_tracks = product_to_trkvec(*l1tksH.product());
333  }
334 
335  // process each of the MTF collections separately! -- we don't want to filter the muons
336 
337  // ----------------------------------------------------- barrel
338  if (bmtfMatchAlgoVersion_ == kTP)
339  runOnMTFCollection_v1(l1bmtfH, l1tksH, oc_bmtf_tkmuon, barrel_MTF_region);
340  else if (bmtfMatchAlgoVersion_ == kMantra) {
341  const auto& muons = product_to_muvec(*l1bmtfH.product());
342  const auto& match_idx = mantracorr_barr_->find_match(mantradf_tracks, muons);
343  build_tkMuons_from_idxs(oc_bmtf_tkmuon, match_idx, l1tksH, l1bmtfH, barrel_MTF_region);
344  } else {
345  throw cms::Exception("TkMuAlgoConfig") << " barrel : trying to run an invalid algorithm version "
346  << bmtfMatchAlgoVersion_ << " (this should never happen)\n";
347  return;
348  }
349 
350  // ----------------------------------------------------- overlap
351  if (omtfMatchAlgoVersion_ == kTP)
352  runOnMTFCollection_v1(l1omtfH, l1tksH, oc_omtf_tkmuon, overlap_MTF_region);
353  else if (omtfMatchAlgoVersion_ == kMantra) {
354  const auto& muons = product_to_muvec(*l1omtfH.product());
355  const auto& match_idx = mantracorr_ovrl_->find_match(mantradf_tracks, muons);
356  build_tkMuons_from_idxs(oc_omtf_tkmuon, match_idx, l1tksH, l1omtfH, overlap_MTF_region);
357  } else {
358  throw cms::Exception("TkMuAlgoConfig") << " overlap : trying to run an invalid algorithm version "
359  << omtfMatchAlgoVersion_ << " (this should never happen)\n";
360  return;
361  }
362 
363  // ----------------------------------------------------- endcap
364  if (emtfMatchAlgoVersion_ == kTP)
365  runOnMTFCollection_v1(l1emtfH, l1tksH, oc_emtf_tkmuon, endcap_MTF_region);
367  runOnMTFCollection_v2(l1emtfTCH, l1tksH, oc_emtf_tkmuon);
368  else if (emtfMatchAlgoVersion_ == kMantra) {
369  const auto& muons = product_to_muvec(*l1emtfTCH.product());
370  const auto& match_idx = mantracorr_endc_->find_match(mantradf_tracks, muons);
371  //for the TkMu that were built from a EMTFCollection - pass the emtf track as ref
372  build_tkMuons_from_idxs(oc_emtf_tkmuon, match_idx, l1tksH, l1emtfTCH, endcap_MTF_region);
373  } else {
374  throw cms::Exception("TkMuAlgoConfig") << "endcap : trying to run an invalid algorithm version "
375  << emtfMatchAlgoVersion_ << " (this should never happen)\n";
376  return;
377  }
378 
379  // now combine all trk muons into a single output collection!
380  auto oc_tkmuon = std::make_unique<TkMuonCollection>();
381  for (const auto& p : {oc_bmtf_tkmuon, oc_omtf_tkmuon, oc_emtf_tkmuon}) {
382  oc_tkmuon->insert(oc_tkmuon->end(), p.begin(), p.end());
383  }
384 
385  // put the new track+muon objects in the event!
386  iEvent.put(std::move(oc_tkmuon));
387 };
388 
392  const int detector) const {
393  const L1TTTrackCollectionType& l1tks = (*l1tksH.product());
394  const RegionalMuonCandBxCollection& l1mtfs = (*muonH.product());
395 
396  int imu = 0;
397  for (auto l1mu = l1mtfs.begin(0); l1mu != l1mtfs.end(0); ++l1mu) { // considering BX = only
398 
399  edm::Ref<RegionalMuonCandBxCollection> l1muRef(muonH, imu);
400  imu++;
401 
402  float l1mu_eta = l1mu->hwEta() * eta_scale;
403  // get the global phi
404  float l1mu_phi =
405  MicroGMTConfiguration::calcGlobalPhi(l1mu->hwPhi(), l1mu->trackFinderType(), l1mu->processor()) * phi_scale;
406 
407  float l1mu_feta = std::abs(l1mu_eta);
408  if (l1mu_feta < etaMin_)
409  continue;
410  if (l1mu_feta > etaMax_)
411  continue;
412 
413  float drmin = 999;
414 
415  PropState matchProp;
416  int match_idx = -1;
417  int il1tk = -1;
418 
419  int nTracksMatch = 0;
420 
421  for (const auto& l1tk : l1tks) {
422  il1tk++;
423 
424  float l1tk_pt = l1tk.momentum().perp();
425  if (l1tk_pt < pTMinTra_)
426  continue;
427 
428  float l1tk_z = l1tk.POCA().z();
429  if (std::abs(l1tk_z) > zMax_)
430  continue;
431 
432  float l1tk_chi2 = l1tk.chi2();
433  if (l1tk_chi2 > chi2Max_)
434  continue;
435 
436  int l1tk_nstubs = l1tk.getStubRefs().size();
437  if (l1tk_nstubs < nStubsmin_)
438  continue;
439 
440  float l1tk_eta = l1tk.momentum().eta();
441  float l1tk_phi = l1tk.momentum().phi();
442 
443  float dr2 = reco::deltaR2(l1mu_eta, l1mu_phi, l1tk_eta, l1tk_phi);
444  if (dr2 > dr2_cutoff)
445  continue;
446 
447  nTracksMatch++;
448 
449  const PropState& pstate = propagateToGMT(l1tk);
450  if (!pstate.valid)
451  continue;
452 
453  float dr2prop = reco::deltaR2(l1mu_eta, l1mu_phi, pstate.eta, pstate.phi);
454  // FIXME: check if this matching procedure can be improved with
455  // a pT dependent dR window
456  if (dr2prop < drmin) {
457  drmin = dr2prop;
458  match_idx = il1tk;
459  matchProp = pstate;
460  }
461  } // over l1tks
462 
463  LogDebug("L1TkMuonProducer") << "matching index is " << match_idx;
464  if (match_idx >= 0) {
465  const L1TTTrackType& matchTk = l1tks[match_idx];
466 
467  float sigmaEta = sigmaEtaTP(*l1mu);
468  float sigmaPhi = sigmaPhiTP(*l1mu);
469 
470  float etaCut = matching_factor_eta * sqrt(sigmaEta * sigmaEta + matchProp.sigmaEta * matchProp.sigmaEta);
471  float phiCut = matching_factor_phi * sqrt(sigmaPhi * sigmaPhi + matchProp.sigmaPhi * matchProp.sigmaPhi);
472 
473  float dEta = std::abs(matchProp.eta - l1mu_eta);
474  float dPhi = std::abs(deltaPhi(matchProp.phi, l1mu_phi));
475 
476  bool matchCondition = useTPMatchWindows_ ? dEta < etaCut && dPhi < phiCut : drmin < dRMax_;
477 
478  if (matchCondition) {
479  edm::Ptr<L1TTTrackType> l1tkPtr(l1tksH, match_idx);
480 
481  const auto& p3 = matchTk.momentum();
482  float p4e = sqrt(mu_mass * mu_mass + p3.mag2());
483 
484  math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e);
485 
486  const auto& tkv3 = matchTk.POCA();
487  math::XYZPoint v3(tkv3.x(), tkv3.y(), tkv3.z()); // why is this defined?
488 
489  float trkisol = -999;
490 
491  TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol);
492 
493  if (useRegionEtaMatching_) {
494  if (detector == barrel_MTF_region) {
495  if (std::abs(l1tkmu.eta()) > etaBO_)
496  continue;
497  } else if (detector == overlap_MTF_region) {
498  if (std::abs(l1tkmu.eta()) < etaBO_)
499  continue;
500  if (std::abs(l1tkmu.eta()) > etaOE_)
501  continue;
502  } else if (detector == endcap_MTF_region) {
503  if (std::abs(l1tkmu.eta()) < etaOE_)
504  continue;
505  }
506  }
507  l1tkmu.setTrackCurvature(matchTk.rInv());
508  l1tkmu.setTrkzVtx((float)tkv3.z());
509  l1tkmu.setdR(drmin);
510  l1tkmu.setNTracksMatched(nTracksMatch);
511  l1tkmu.setMuonDetector(detector);
512  l1tkmu.setQuality(l1muRef->hwQual());
513  tkMuons.push_back(l1tkmu);
514  }
515  }
516  } //over l1mus
517 }
518 
521  TkMuonCollection& tkMuons) const {
522  const EMTFTrackCollection& l1mus = (*muonH.product());
523  const L1TTTrackCollectionType& l1trks = (*l1tksH.product());
524  const auto& corr_mu_idxs = dwcorr_->find_match(l1mus, l1trks);
525  // it's a vector with as many entries as the L1TT vector.
526  // >= 0 : the idx in the EMTF vector of matched mu
527  // < 0: no match
528 
529  // sanity check
530  if (corr_mu_idxs.size() != l1trks.size())
531  throw cms::Exception("TkMuAlgoOutput")
532  << "the size of tkmu indices does not match the size of input trk collection\n";
533 
534  for (uint il1ttrack = 0; il1ttrack < corr_mu_idxs.size(); ++il1ttrack) {
535  int emtf_idx = corr_mu_idxs[il1ttrack];
536  if (emtf_idx < 0)
537  continue;
538 
539  const L1TTTrackType& matchTk = l1trks[il1ttrack];
540  const auto& p3 = matchTk.momentum();
541  const auto& tkv3 = matchTk.POCA();
542  float p4e = sqrt(mu_mass * mu_mass + p3.mag2());
543  math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e);
544 
546  edm::Ptr<L1TTTrackType> l1tkPtr(l1tksH, il1ttrack);
547  float trkisol = -999; // now doing as in the TP algo
548  TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol);
549 
550  // avoid leaking of candidates to overlap region...
551  if (useRegionEtaMatching_ && std::abs(l1tkmu.eta()) < etaOE_)
552  continue;
553 
554  l1tkmu.setTrackCurvature(matchTk.rInv());
555  l1tkmu.setTrkzVtx((float)tkv3.z());
557  tkMuons.push_back(l1tkmu);
558  }
559 
560  return;
561 }
562 
563 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
565  //The following says we do not know what parameters are allowed so do no validation
566  // Please change this to state exactly what you do use, even if it is no parameters
568  desc.setUnknown();
569  descriptions.addDefault(desc);
570 }
571 
573  auto p3 = tk.momentum();
574  float tk_pt = p3.perp();
575  float tk_p = p3.mag();
576  float tk_eta = p3.eta();
577  float tk_aeta = std::abs(tk_eta);
578  float tk_phi = p3.phi();
579  float tk_q = tk.rInv() > 0 ? 1. : -1.;
580  float tk_z = tk.POCA().z();
582  tk_z = 0;
583 
585  if (tk_p < min_mu_propagator_p)
586  return dest;
587  if (tk_aeta < 1.1 && tk_pt < min_mu_propagator_barrel_pT)
588  return dest;
589  if (tk_aeta > max_mu_propagator_eta)
590  return dest;
591 
592  //0th order:
593  dest.valid = true;
594 
595  float dzCorrPhi = 1.;
596  float deta = 0;
597  float etaProp = tk_aeta;
598 
599  if (tk_aeta < 1.1) {
600  etaProp = 1.1;
601  deta = tk_z / 550. / cosh(tk_aeta);
602  } else {
603  float delta = tk_z / 850.; //roughly scales as distance to 2nd station
604  if (tk_eta > 0)
605  delta *= -1;
606  dzCorrPhi = 1. + delta;
607 
608  float zOzs = tk_z / 850.;
609  if (tk_eta > 0)
610  deta = zOzs / (1. - zOzs);
611  else
612  deta = zOzs / (1. + zOzs);
613  deta = deta * tanh(tk_eta);
614  }
615  float resPhi = tk_phi - 1.464 * tk_q * cosh(1.7) / cosh(etaProp) / tk_pt * dzCorrPhi - M_PI / 144.;
616  resPhi = reco::reduceRange(resPhi);
617 
618  dest.eta = tk_eta + deta;
619  dest.phi = resPhi;
620  dest.pt = tk_pt; //not corrected for eloss
621 
622  dest.sigmaEta = 0.100 / tk_pt; //multiple scattering term
623  dest.sigmaPhi = 0.106 / tk_pt; //need a better estimate for these
624  return dest;
625 }
626 
628  float l1mu_eta = l1mu.hwEta() * eta_scale;
629  if (std::abs(l1mu_eta) <= 1.55)
630  return 0.0288;
631  else if (std::abs(l1mu_eta) > 1.55 && std::abs(l1mu_eta) <= 1.65)
632  return 0.025;
633  else if (std::abs(l1mu_eta) > 1.65 && std::abs(l1mu_eta) <= 2.4)
634  return 0.0144;
635  return 0.0288;
636 }
637 
638 double L1TkMuonProducer::sigmaPhiTP(const RegionalMuonCand& mu) const { return 0.0126; }
639 
640 // ------------------------------------------------------------------------------------------------------------
641 
642 std::vector<L1TkMuMantraDF::track_df> L1TkMuonProducer::product_to_trkvec(const L1TTTrackCollectionType& l1tks) const {
643  std::vector<L1TkMuMantraDF::track_df> result(l1tks.size());
644  for (uint itrk = 0; itrk < l1tks.size(); ++itrk) {
645  auto& trk = l1tks[itrk];
646 
647  result[itrk].pt = trk.momentum().perp();
648  result[itrk].eta = trk.momentum().eta();
649  result[itrk].theta = L1TkMuMantra::to_mpio2_pio2(L1TkMuMantra::eta_to_theta(trk.momentum().eta()));
650  result[itrk].phi = trk.momentum().phi();
651  result[itrk].nstubs = trk.getStubRefs().size();
652  result[itrk].chi2 = trk.chi2();
653  result[itrk].charge = (trk.rInv() > 0 ? 1 : -1);
654  }
655 
656  return result;
657 }
658 
659 std::vector<L1TkMuMantraDF::muon_df> L1TkMuonProducer::product_to_muvec(
660  const RegionalMuonCandBxCollection& l1mtfs) const {
661  std::vector<L1TkMuMantraDF::muon_df> result;
662  for (auto l1mu = l1mtfs.begin(0); l1mu != l1mtfs.end(0); ++l1mu) // considering BX = 0 only
663  {
664  L1TkMuMantraDF::muon_df this_mu;
665  this_mu.pt = l1mu->hwPt() * 0.5;
666  this_mu.eta = l1mu->hwEta() * eta_scale;
668  this_mu.phi =
669  MicroGMTConfiguration::calcGlobalPhi(l1mu->hwPhi(), l1mu->trackFinderType(), l1mu->processor()) * phi_scale;
670  this_mu.charge = (l1mu->hwSign() == 0 ? 1 : -1); // charge sign bit (charge = (-1)^(sign))
671  result.push_back(this_mu);
672  }
673  return result;
674 }
675 
676 std::vector<L1TkMuMantraDF::muon_df> L1TkMuonProducer::product_to_muvec(const EMTFTrackCollection& l1mus) const {
677  std::vector<L1TkMuMantraDF::muon_df> result(l1mus.size());
678  for (uint imu = 0; imu < l1mus.size(); ++imu) {
679  auto& mu = l1mus[imu];
680 
681  // dropping the emtf tracks with certain quality...
682  int emtfQual = (mu.Mode() == 11 || mu.Mode() == 13 || mu.Mode() == 14 || mu.Mode() == 15);
683  if (applyQuality_ && !emtfQual)
684  continue;
685 
686  result[imu].pt = mu.Pt();
687  result[imu].eta = mu.Eta();
689  result[imu].phi = angle_units::operators::convertDegToRad(mu.Phi_glob());
690  result[imu].charge = mu.Charge();
691  }
692  return result;
693 }
694 
696  const std::vector<int>& matches,
699  int detector) const {
700  for (uint imatch = 0; imatch < matches.size(); ++imatch) {
701  int match_trk_idx = matches[imatch];
702  if (match_trk_idx < 0)
703  continue; // this muon was not matched to any candidate
704 
705  // take properties of the track
706  const L1TTTrackType& matchTk = (*l1tksH.product())[match_trk_idx];
707  const auto& p3 = matchTk.momentum();
708  const auto& tkv3 = matchTk.POCA();
709  float p4e = sqrt(mu_mass * mu_mass + p3.mag2());
710  math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e);
711 
712  edm::Ptr<L1TTTrackType> l1tkPtr(l1tksH, match_trk_idx);
713  auto l1muRef = muonH.isValid() ? edm::Ref<RegionalMuonCandBxCollection>(muonH, imatch)
715 
716  float trkisol = -999;
717  TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol);
718  l1tkmu.setTrackCurvature(matchTk.rInv());
719  l1tkmu.setTrkzVtx((float)tkv3.z());
720  l1tkmu.setMuonDetector(detector);
721  l1tkmu.setQuality(l1muRef->hwQual());
722 
723  // apply region cleaning (probably this is not the best way, but since this is going to
724  // be a patch and temporary, it is OK)
725  if (useRegionEtaMatching_) {
726  if (detector == barrel_MTF_region) {
727  if (std::abs(l1tkmu.eta()) > etaBO_)
728  continue;
729  } else if (detector == overlap_MTF_region) {
730  if (std::abs(l1tkmu.eta()) < etaBO_)
731  continue;
732  if (std::abs(l1tkmu.eta()) > etaOE_)
733  continue;
734  } else if (detector == endcap_MTF_region) {
735  if (std::abs(l1tkmu.eta()) < etaOE_)
736  continue;
737  }
738  }
739  tkMuons.push_back(l1tkmu);
740  }
741  return;
742 }
743 
745  const std::vector<int>& matches,
747  const edm::Handle<EMTFTrackCollection>& emtfTksH,
748  int detector) const {
749  for (uint imatch = 0; imatch < matches.size(); ++imatch) {
750  int match_trk_idx = matches[imatch];
751  if (match_trk_idx < 0)
752  continue; // this muon was not matched to any candidate
753 
754  // take properties of the track
755  const L1TTTrackType& matchTk = (*l1tksH.product())[match_trk_idx];
756  const auto& p3 = matchTk.momentum();
757  const auto& tkv3 = matchTk.POCA();
758  float p4e = sqrt(mu_mass * mu_mass + p3.mag2());
759  math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e);
760 
761  edm::Ptr<L1TTTrackType> l1tkPtr(l1tksH, match_trk_idx);
762 
763  auto l1emtfTrk =
764  emtfTksH.isValid() ? edm::Ref<EMTFTrackCollection>(emtfTksH, imatch) : edm::Ref<EMTFTrackCollection>();
765 
766  float trkisol = -999;
767  TkMuon l1tkmu(l1tkp4, l1emtfTrk, l1tkPtr, trkisol);
768  l1tkmu.setTrackCurvature(matchTk.rInv());
769  l1tkmu.setTrkzVtx((float)tkv3.z());
770  l1tkmu.setMuonDetector(detector);
771  l1tkmu.setQuality(l1emtfTrk->Mode());
772 
773  if (useRegionEtaMatching_ && std::abs(l1tkmu.eta()) < etaOE_)
774  continue;
775 
776  tkMuons.push_back(l1tkmu);
777  }
778  return;
779 }
780 
781 //define this as a plug-in
static constexpr float matching_factor_eta
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
static constexpr float min_mu_propagator_barrel_pT
void build_tkMuons_from_idxs(TkMuonCollection &tkMuons, const std::vector< int > &matches, const edm::Handle< L1TTTrackCollectionType > &l1tksH, const edm::Handle< RegionalMuonCandBxCollection > &muonH, int detector) const
static double eta_to_theta(double x)
Definition: L1TkMuMantra.h:85
constexpr double convertDegToRad(NumType degrees)
Definition: angle_units.h:27
static double to_mpio2_pio2(double x)
Definition: L1TkMuMantra.h:90
void runOnMTFCollection_v2(const edm::Handle< EMTFTrackCollection > &, const edm::Handle< L1TTTrackCollectionType > &, TkMuonCollection &tkMuons) const
constexpr T reduceRange(T x)
Definition: deltaPhi.h:18
void setQuality(unsigned int q)
Definition: TkMuon.h:57
T z() const
Definition: PV3DBase.h:61
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::unique_ptr< L1TkMuMantra > mantracorr_barr_
double sigmaPhiTP(const RegionalMuonCand &mu) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
T const * product() const
Definition: Handle.h:70
std::unique_ptr< L1TkMuMantra > mantracorr_endc_
void produce(edm::Event &, const edm::EventSetup &) override
void setdR(float dR)
Definition: TkMuon.h:60
static constexpr int endcap_MTF_region
delete x;
Definition: CaloConfig.h:22
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
GlobalVector momentum() const
Track momentum.
Definition: TTTrack.h:295
AlgoType emtfMatchAlgoVersion_
static constexpr float min_mu_propagator_p
const int hwEta() const
Get compressed eta (returned int * 0.010875 = eta)
const_iterator begin(int bx) const
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
void runOnMTFCollection_v1(const edm::Handle< RegionalMuonCandBxCollection > &, const edm::Handle< L1TTTrackCollectionType > &, TkMuonCollection &tkMuons, const int detector) const
static constexpr int barrel_MTF_region
int iEvent
Definition: GenABIO.cc:224
static std::vector< double > prepare_corr_bounds(std::string fname, std::string hname)
void addDefault(ParameterSetDescription const &psetDescription)
T sqrt(T t)
Definition: SSEVec.h:19
const edm::EDGetTokenT< RegionalMuonCandBxCollection > omtfToken_
void setTrkzVtx(float TrkzVtx)
Definition: TkMuon.h:55
void setNTracksMatched(int nTracksMatch)
Definition: TkMuon.h:61
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double rInv() const
Track curvature.
Definition: TTTrack.h:300
const edm::EDGetTokenT< RegionalMuonCandBxCollection > bmtfToken_
std::vector< TkMuon > TkMuonCollection
Definition: TkMuonFwd.h:16
#define M_PI
const edm::EDGetTokenT< RegionalMuonCandBxCollection > emtfToken_
std::vector< L1TTTrackType > L1TTTrackCollectionType
const edm::EDGetTokenT< EMTFTrackCollection > emtfTCToken_
std::unique_ptr< L1TkMuCorrDynamicWindows > dwcorr_
void setTrackCurvature(double trackCurvature)
Definition: TkMuon.h:62
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
static constexpr float phi_scale
std::vector< L1TkMuMantraDF::muon_df > product_to_muvec(const RegionalMuonCandBxCollection &l1mtfs) const
TTTrack< Ref_Phase2TrackerDigi_ > L1TTTrackType
std::unique_ptr< L1TkMuMantra > mantracorr_ovrl_
static constexpr float eta_scale
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
Class to store the L1 Track Trigger tracks.
Definition: TTTrack.h:29
static constexpr float dr2_cutoff
static std::vector< double > prepare_corr_bounds(const string &fname, const string &hname)
bool isValid() const
Definition: HandleBase.h:70
const edm::EDGetTokenT< std::vector< TTTrack< Ref_Phase2TrackerDigi_ > > > trackToken_
AlgoType omtfMatchAlgoVersion_
const_iterator end(int bx) const
HLT enums.
std::vector< EMTFTrack > EMTFTrackCollection
Definition: EMTFTrack.h:251
PropState propagateToGMT(const L1TTTrackType &l1tk) const
L1TkMuonProducer(const edm::ParameterSet &)
void setMuonDetector(unsigned int detector)
Definition: TkMuon.h:63
static constexpr float matching_factor_phi
std::vector< L1TkMuMantraDF::track_df > product_to_trkvec(const L1TTTrackCollectionType &l1tks) const
double sigmaEtaTP(const RegionalMuonCand &mu) const
static constexpr float mu_mass
static constexpr int overlap_MTF_region
AlgoType bmtfMatchAlgoVersion_
GlobalPoint POCA() const
POCA.
Definition: TTTrack.h:335
def move(src, dest)
Definition: eostools.py:511
static constexpr float max_mu_propagator_eta
#define LogDebug(id)
double eta() const final
momentum pseudorapidity
unsigned transform(const HcalDetId &id, unsigned transformCode)
~L1TkMuonProducer() override