CMS 3D CMS Logo

Phase1L1TJetProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: L1CaloTrigger
4 // Class: Phase1L1TJetProducer
5 //
31 //
32 // Original Simone Bologna
33 // Created: Mon Jul 02 2018
34 // Modified 2020 Emyr Clement
35 //
36 
52 
53 #include "TH2F.h"
54 
55 #include <cmath>
56 
57 #include <algorithm>
58 constexpr int x_scroll_min = -4;
59 constexpr int x_scroll_max = 4;
60 constexpr int y_scroll_min = 0;
61 constexpr int y_scroll_max = 3;
62 
64 public:
65  explicit Phase1L1TJetProducer(const edm::ParameterSet&);
66  ~Phase1L1TJetProducer() override;
67 
68  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
69 
70 private:
71  void produce(edm::Event&, const edm::EventSetup&) override;
72 
74  std::vector<std::tuple<int, int>> findSeeds(float seedThreshold) const;
75 
76  // Calculates the pt sum of the bins around the seeds
77  // And applies some PU mitigation
78  // Warning - not used for some time, so user beware
79  std::vector<reco::CaloJet> buildJetsFromSeedsWithPUSubtraction(const std::vector<std::tuple<int, int>>& seeds,
80  bool killZeroPt) const;
81 
82  // Calculates the pt sum of the bins around the seeds
83  std::vector<reco::CaloJet> buildJetsFromSeeds(const std::vector<std::tuple<int, int>>& seeds) const;
84 
85  // Used by buildJetsFromSeedsWithPUSubtraction
86  // Implementation of pileup mitigation
87  // Warning - not used for some time, so user beware
88  void subtract9x9Pileup(reco::CaloJet& jet) const;
89 
91  float getTowerEnergy(int iEta, int iPhi) const;
92 
93  // Implementation of pt sum of bins around one seed
94  reco::CaloJet buildJetFromSeed(const std::tuple<int, int>& seed) const;
95 
96  // <3 handy method to fill the calogrid with whatever type
97  template <class Container>
98  void fillCaloGrid(TH2F& caloGrid, const Container& triggerPrimitives, const unsigned int regionIndex);
99 
100  // Digitise the eta and phi coordinates of input candidates
101  // This converts the quantities to integers to reduce precision
102  // And takes account of bin edge effects i.e. makes sure the
103  // candidate ends up in the correct (i.e. same behaviour as the firmware) bin of caloGrid_
104  std::pair<float, float> getCandidateDigiEtaPhi(const float eta,
105  const float phi,
106  const unsigned int regionIndex) const;
107 
108  // Sorts the input candidates into the PF regions they arrive in
109  // Truncates the inputs. Takes the first N candidates as they are provided, without any sorting (this may be needed in the future and/or provided in this way from emulation of layer 1)
110  template <class Handle>
111  std::vector<std::vector<reco::CandidatePtr>> prepareInputsIntoRegions(const Handle triggerPrimitives);
112 
113  // Converts phi and eta (PF) region indices to a single index
114  unsigned int getRegionIndex(const unsigned int phiRegion, const unsigned int etaRegion) const;
115  // From the single index, calculated by getRegionIndex, provides the lower eta and phi boundaries of the input (PF) region index
116  std::pair<double, double> regionEtaPhiLowEdges(const unsigned int regionIndex) const;
117  // From the single index, calculated by getRegionIndex, provides the upper eta and phi boundaries of the input (PF) region index
118  std::pair<double, double> regionEtaPhiUpEdges(const unsigned int regionIndex) const;
119 
120  // computes MET
121  // Takes grid used by jet finder and projects to 1D histogram of phi, bin contents are total pt in that phi bin
122  // the phi bin index is used to retrieve the sin-cos value from the LUT emulator
123  // the pt of the input is multiplied by that sin cos value to obtain px and py that is added to the total event px & py
124  // after all the inputs have been processed we compute the total pt of the event, and set that as MET
125  l1t::EtSum computeMET(const double etaCut, l1t::EtSum::EtSumType sumType) const;
126 
127  // Determine if this tower should be trimmed or not
128  // Used only when trimmedGrid_ option is set to true
129  // Trim means removing 3 towers in each corner of the square grid
130  // giving a cross shaped grid, which is a bit more circular in shape than a square
131  bool trimTower(const int etaIndex, const int phiIndex) const;
132 
134  // histogram containing our clustered inputs
135  std::unique_ptr<TH2F> caloGrid_;
136 
137  std::vector<double> etaBinning_;
138  size_t nBinsEta_;
139  unsigned int nBinsPhi_;
140  double phiLow_;
141  double phiUp_;
142  unsigned int jetIEtaSize_;
143  unsigned int jetIPhiSize_;
146  double ptlsb_;
147  double philsb_;
148  double etalsb_;
151  // Eta and phi edges of input PF regions
152  std::vector<double> etaRegionEdges_;
153  std::vector<double> phiRegionEdges_;
154  // Maximum number of candidates per input PF region
155  unsigned int maxInputsPerRegion_;
156  // LUT for sin and cos phi, to match that used in firmware
157  std::vector<double> sinPhi_;
158  std::vector<double> cosPhi_;
159  // input eta cut for met calculation
161  // input eta cut for metHF calculation
164 };
165 
167  : // getting configuration settings
168  inputCollectionTag_{
169  consumes<edm::View<reco::Candidate>>(iConfig.getParameter<edm::InputTag>("inputCollectionTag"))},
170  etaBinning_(iConfig.getParameter<std::vector<double>>("etaBinning")),
171  nBinsEta_(etaBinning_.size() - 1),
172  nBinsPhi_(iConfig.getParameter<unsigned int>("nBinsPhi")),
173  phiLow_(iConfig.getParameter<double>("phiLow")),
174  phiUp_(iConfig.getParameter<double>("phiUp")),
175  jetIEtaSize_(iConfig.getParameter<unsigned int>("jetIEtaSize")),
176  jetIPhiSize_(iConfig.getParameter<unsigned int>("jetIPhiSize")),
177  trimmedGrid_(iConfig.getParameter<bool>("trimmedGrid")),
178  seedPtThreshold_(iConfig.getParameter<double>("seedPtThreshold")),
179  ptlsb_(iConfig.getParameter<double>("ptlsb")),
180  philsb_(iConfig.getParameter<double>("philsb")),
181  etalsb_(iConfig.getParameter<double>("etalsb")),
182  puSubtraction_(iConfig.getParameter<bool>("puSubtraction")),
183  vetoZeroPt_(iConfig.getParameter<bool>("vetoZeroPt")),
184  etaRegionEdges_(iConfig.getParameter<std::vector<double>>("etaRegions")),
185  phiRegionEdges_(iConfig.getParameter<std::vector<double>>("phiRegions")),
186  maxInputsPerRegion_(iConfig.getParameter<unsigned int>("maxInputsPerRegion")),
187  sinPhi_(iConfig.getParameter<std::vector<double>>("sinPhi")),
188  cosPhi_(iConfig.getParameter<std::vector<double>>("cosPhi")),
189  metAbsEtaCut_(iConfig.getParameter<double>("metAbsEtaCut")),
190  metHFAbsEtaCut_(iConfig.getParameter<double>("metHFAbsEtaCut")),
191  outputCollectionName_(iConfig.getParameter<std::string>("outputCollectionName")) {
192  caloGrid_ =
193  std::make_unique<TH2F>("caloGrid", "Calorimeter grid", nBinsEta_, etaBinning_.data(), nBinsPhi_, phiLow_, phiUp_);
194  caloGrid_->GetXaxis()->SetTitle("#eta");
195  caloGrid_->GetYaxis()->SetTitle("#phi");
196  produces<std::vector<reco::CaloJet>>(outputCollectionName_).setBranchAlias(outputCollectionName_);
197  produces<std::vector<l1t::EtSum>>(outputCollectionName_ + "MET").setBranchAlias(outputCollectionName_ + "MET");
198 }
199 
201 
202 float Phase1L1TJetProducer::getTowerEnergy(int iEta, int iPhi) const {
203  // We return the pt of a certain bin in the calo grid, taking account of the phi periodicity when overflowing (e.g. phi > phiSize), and returning 0 for the eta out of bounds
204 
205  int nBinsEta = caloGrid_->GetNbinsX();
206  int nBinsPhi = caloGrid_->GetNbinsY();
207  while (iPhi < 1) {
208  iPhi += nBinsPhi;
209  }
210  while (iPhi > nBinsPhi) {
211  iPhi -= nBinsPhi;
212  }
213  if (iEta < 1) {
214  return 0;
215  }
216  if (iEta > nBinsEta) {
217  return 0;
218  }
219  return caloGrid_->GetBinContent(iEta, iPhi);
220 }
221 
223  edm::Handle<edm::View<reco::Candidate>> inputCollectionHandle;
224  iEvent.getByToken(inputCollectionTag_, inputCollectionHandle);
225 
226  // sort inputs into PF regions
227  std::vector<std::vector<reco::CandidatePtr>> inputsInRegions = prepareInputsIntoRegions<>(inputCollectionHandle);
228 
229  // histogramming the data
230  caloGrid_->Reset();
231  for (unsigned int iInputRegion = 0; iInputRegion < inputsInRegions.size(); ++iInputRegion) {
232  fillCaloGrid<>(*(caloGrid_), inputsInRegions[iInputRegion], iInputRegion);
233  }
234 
235  // find the seeds
236  const auto& seedsVector = findSeeds(seedPtThreshold_); // seedPtThreshold = 5
237  // build jets from the seeds
238  auto l1jetVector =
240 
241  // sort by pt
242  std::sort(l1jetVector.begin(), l1jetVector.end(), [](const reco::CaloJet& jet1, const reco::CaloJet& jet2) {
243  return jet1.pt() > jet2.pt();
244  });
245 
246  auto l1jetVectorPtr = std::make_unique<std::vector<reco::CaloJet>>(l1jetVector);
247  iEvent.put(std::move(l1jetVectorPtr), outputCollectionName_);
248 
249  // calculate METs
252  std::unique_ptr<std::vector<l1t::EtSum>> lSumVectorPtr(new std::vector<l1t::EtSum>(0));
253  lSumVectorPtr->push_back(lMET);
254  lSumVectorPtr->push_back(lMETHF);
255  iEvent.put(std::move(lSumVectorPtr), this->outputCollectionName_ + "MET");
256 
257  return;
258 }
259 
261  // these variables host the total pt in each sideband and the total pileup contribution
262  float topBandPt = 0;
263  float leftBandPt = 0;
264  float rightBandPt = 0;
265  float bottomBandPt = 0;
266  float pileUpEnergy;
267 
268  // hold the jet's x-y (and z, as I have to use it, even if 2D) location in the histo
269  int xCenter, yCenter, zCenter;
270  // Retrieving histo-coords for seed
271  caloGrid_->GetBinXYZ(caloGrid_->FindFixBin(jet.eta(), jet.phi()), xCenter, yCenter, zCenter);
272 
273  // Computing pileup
274  for (int x = x_scroll_min; x <= x_scroll_max; x++) {
275  for (int y = y_scroll_min; y < y_scroll_max; y++) {
276  // top band, I go up 5 squares to reach the bottom of the top band
277  // +x scrolls from left to right, +y scrolls up
278  topBandPt += getTowerEnergy(xCenter + x, yCenter + (5 + y));
279  // left band, I go left 5 squares (-5) to reach the bottom of the top band
280  // +x scrolls from bottom to top, +y scrolls left
281  leftBandPt += getTowerEnergy(xCenter - (5 + y), yCenter + x);
282  // right band, I go right 5 squares (+5) to reach the bottom of the top band
283  // +x scrolls from bottom to top, +y scrolls right
284  rightBandPt += getTowerEnergy(xCenter + (5 + y), yCenter + x);
285  // right band, I go right 5 squares (+5) to reach the bottom of the top band
286  // +x scrolls from bottom to top, +y scrolls right
287  bottomBandPt += getTowerEnergy(xCenter + x, yCenter - (5 + y));
288  }
289  }
290  // adding bands and removing the maximum band (equivalent to adding the three minimum bands)
291  pileUpEnergy = topBandPt + leftBandPt + rightBandPt + bottomBandPt -
292  std::max(topBandPt, std::max(leftBandPt, std::max(rightBandPt, bottomBandPt)));
293 
294  //preparing the new 4-momentum vector
296  // removing pu contribution
297  float ptAfterPUSubtraction = jet.pt() - pileUpEnergy;
298  ptVector.SetPt((ptAfterPUSubtraction > 0) ? ptAfterPUSubtraction : 0);
299  ptVector.SetEta(jet.eta());
300  ptVector.SetPhi(jet.phi());
301  //updating the jet
302  jet.setP4(ptVector);
303  jet.setPileup(pileUpEnergy);
304  return;
305 }
306 
307 std::vector<std::tuple<int, int>> Phase1L1TJetProducer::findSeeds(float seedThreshold) const {
308  int nBinsX = caloGrid_->GetNbinsX();
309  int nBinsY = caloGrid_->GetNbinsY();
310 
311  std::vector<std::tuple<int, int>> seeds;
312 
313  int etaHalfSize = (int)jetIEtaSize_ / 2;
314  int phiHalfSize = (int)jetIPhiSize_ / 2;
315 
316  // for each point of the grid check if it is a local maximum
317  // to do so I take a point, and look if is greater than the points around it (in the 9x9 neighborhood)
318  // to prevent mutual exclusion, I check greater or equal for points above and right to the one I am considering (including the top-left point)
319  // to prevent mutual exclusion, I check greater for points below and left to the one I am considering (including the bottom-right point)
320 
321  for (int iPhi = 1; iPhi <= nBinsY; iPhi++) {
322  for (int iEta = 1; iEta <= nBinsX; iEta++) {
323  float centralPt = caloGrid_->GetBinContent(iEta, iPhi);
324  if (centralPt < seedThreshold)
325  continue;
326  bool isLocalMaximum = true;
327 
328  // Scanning through the grid centered on the seed
329  for (int etaIndex = -etaHalfSize; etaIndex <= etaHalfSize; etaIndex++) {
330  for (int phiIndex = -phiHalfSize; phiIndex <= phiHalfSize; phiIndex++) {
331  if (trimmedGrid_) {
332  if (trimTower(etaIndex, phiIndex))
333  continue;
334  }
335 
336  if ((etaIndex == 0) && (phiIndex == 0))
337  continue;
338  if (phiIndex > 0) {
339  if (phiIndex > -etaIndex) {
340  isLocalMaximum = ((isLocalMaximum) && (centralPt > getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
341  } else {
342  isLocalMaximum = ((isLocalMaximum) && (centralPt >= getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
343  }
344  } else {
345  if (phiIndex >= -etaIndex) {
346  isLocalMaximum = ((isLocalMaximum) && (centralPt > getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
347  } else {
348  isLocalMaximum = ((isLocalMaximum) && (centralPt >= getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
349  }
350  }
351  }
352  }
353  if (isLocalMaximum) {
354  seeds.emplace_back(iEta, iPhi);
355  }
356  }
357  }
358 
359  return seeds;
360 }
361 
362 reco::CaloJet Phase1L1TJetProducer::buildJetFromSeed(const std::tuple<int, int>& seed) const {
363  int iEta = std::get<0>(seed);
364  int iPhi = std::get<1>(seed);
365 
366  int etaHalfSize = (int)jetIEtaSize_ / 2;
367  int phiHalfSize = (int)jetIPhiSize_ / 2;
368 
369  float ptSum = 0;
370  // Scanning through the grid centered on the seed
371  for (int etaIndex = -etaHalfSize; etaIndex <= etaHalfSize; etaIndex++) {
372  for (int phiIndex = -phiHalfSize; phiIndex <= phiHalfSize; phiIndex++) {
373  if (trimmedGrid_) {
374  if (trimTower(etaIndex, phiIndex))
375  continue;
376  }
377  ptSum += getTowerEnergy(iEta + etaIndex, iPhi + phiIndex);
378  }
379  }
380 
381  // Creating a jet with eta phi centered on the seed and momentum equal to the sum of the pt of the components
383  ptVector.SetPt(ptSum);
384  ptVector.SetEta(caloGrid_->GetXaxis()->GetBinCenter(iEta));
385  ptVector.SetPhi(caloGrid_->GetYaxis()->GetBinCenter(iPhi));
387  jet.setP4(ptVector);
388  return jet;
389 }
390 
392  const std::vector<std::tuple<int, int>>& seeds, bool killZeroPt) const {
393  // For each seed take a grid centered on the seed of the size specified by the user
394  // Sum the pf in the grid, that will be the pt of the l1t jet. Eta and phi of the jet is taken from the seed.
395  std::vector<reco::CaloJet> jets;
396  for (const auto& seed : seeds) {
399  //killing jets with 0 pt
400  if ((vetoZeroPt_) && (jet.pt() <= 0))
401  continue;
402  jets.push_back(jet);
403  }
404  return jets;
405 }
406 
407 std::vector<reco::CaloJet> Phase1L1TJetProducer::buildJetsFromSeeds(
408  const std::vector<std::tuple<int, int>>& seeds) const {
409  // For each seed take a grid centered on the seed of the size specified by the user
410  // Sum the pf in the grid, that will be the pt of the l1t jet. Eta and phi of the jet is taken from the seed.
411  std::vector<reco::CaloJet> jets;
412  for (const auto& seed : seeds) {
414  jets.push_back(jet);
415  }
416  return jets;
417 }
418 
419 template <class Container>
421  const Container& triggerPrimitives,
422  const unsigned int regionIndex) {
423  //Filling the calo grid with the primitives
424  for (const auto& primitiveIterator : triggerPrimitives) {
425  // Get digitised (floating point with reduced precision) eta and phi
426  std::pair<float, float> digi_EtaPhi =
427  getCandidateDigiEtaPhi(primitiveIterator->eta(), primitiveIterator->phi(), regionIndex);
428 
429  caloGrid.Fill(static_cast<float>(digi_EtaPhi.first),
430  static_cast<float>(digi_EtaPhi.second),
431  static_cast<float>(primitiveIterator->pt()));
432  }
433 }
434 
435 std::pair<float, float> Phase1L1TJetProducer::getCandidateDigiEtaPhi(const float eta,
436  const float phi,
437  const unsigned int regionIndex) const {
438  std::pair<double, double> regionLowEdges = regionEtaPhiLowEdges(regionIndex);
439 
440  int digitisedEta = floor((eta - regionLowEdges.second) / etalsb_);
441  int digitisedPhi = floor((phi - regionLowEdges.first) / philsb_);
442 
443  // If eta or phi is on a bin edge
444  // Put in bin above, to match behaviour of HLS
445  // Unless it's on the last bin of this pf region
446  // Then it is placed in the last bin, not the overflow
447  TAxis* etaAxis = caloGrid_->GetXaxis();
448  std::pair<double, double> regionUpEdges = regionEtaPhiUpEdges(regionIndex);
449  int digiEtaEdgeLastBinUp = floor((regionUpEdges.second - regionLowEdges.second) / etalsb_);
450  // If the digi eta is outside the last bin of this pf region
451  // Set the digitised quantity so it would be in the last bin
452  // These cases could be avoided by sorting input candidates based on digitised eta/phi
453  if (digitisedEta >= digiEtaEdgeLastBinUp) {
454  digitisedEta = digiEtaEdgeLastBinUp - 1;
455  } else {
456  for (int i = 0; i < etaAxis->GetNbins(); ++i) {
457  if (etaAxis->GetBinUpEdge(i) < regionLowEdges.second)
458  continue;
459  int digiEdgeBinUp = floor((etaAxis->GetBinUpEdge(i) - regionLowEdges.second) / etalsb_);
460  if (digiEdgeBinUp == digitisedEta) {
461  digitisedEta += 1;
462  }
463  }
464  }
465 
466  // Similar for phi
467  TAxis* phiAxis = caloGrid_->GetYaxis();
468  int digiPhiEdgeLastBinUp = floor((regionUpEdges.first - regionLowEdges.first) / philsb_);
469  if (digitisedPhi >= digiPhiEdgeLastBinUp) {
470  digitisedPhi = digiPhiEdgeLastBinUp - 1;
471  } else {
472  for (int i = 0; i < phiAxis->GetNbins(); ++i) {
473  if (phiAxis->GetBinUpEdge(i) < regionLowEdges.first)
474  continue;
475  int digiEdgeBinUp = floor((phiAxis->GetBinUpEdge(i) - regionLowEdges.first) / philsb_);
476  if (digiEdgeBinUp == digitisedPhi) {
477  digitisedPhi += 1;
478  }
479  }
480  }
481 
482  // Convert digitised eta and phi back to floating point quantities with reduced precision
483  float floatDigitisedEta = (digitisedEta + 0.5) * etalsb_ + regionLowEdges.second;
484  float floatDigitisedPhi = (digitisedPhi + 0.5) * philsb_ + regionLowEdges.first;
485 
486  return std::pair<float, float>{floatDigitisedEta, floatDigitisedPhi};
487 }
488 
491  desc.add<edm::InputTag>("inputCollectionTag", edm::InputTag("l1pfCandidates", "Puppi"));
492  desc.add<std::vector<double>>("etaBinning");
493  desc.add<unsigned int>("nBinsPhi", 72);
494  desc.add<double>("phiLow", -M_PI);
495  desc.add<double>("phiUp", M_PI);
496  desc.add<unsigned int>("jetIEtaSize", 7);
497  desc.add<unsigned int>("jetIPhiSize", 7);
498  desc.add<bool>("trimmedGrid", false);
499  desc.add<double>("seedPtThreshold", 5);
500  desc.add<double>("ptlsb", 0.25), desc.add<double>("philsb", 0.0043633231), desc.add<double>("etalsb", 0.0043633231),
501  desc.add<bool>("puSubtraction", false);
502  desc.add<string>("outputCollectionName", "UncalibratedPhase1L1TJetFromPfCandidates");
503  desc.add<bool>("vetoZeroPt", true);
504  desc.add<std::vector<double>>("etaRegions");
505  desc.add<std::vector<double>>("phiRegions");
506  desc.add<unsigned int>("maxInputsPerRegion", 18);
507  desc.add<std::vector<double>>("sinPhi");
508  desc.add<std::vector<double>>("cosPhi");
509  desc.add<double>("metAbsEtaCut", 3);
510  desc.add<double>("metHFAbsEtaCut", 5);
511  descriptions.add("Phase1L1TJetProducer", desc);
512 }
513 
514 template <class Handle>
515 std::vector<std::vector<edm::Ptr<reco::Candidate>>> Phase1L1TJetProducer::prepareInputsIntoRegions(
516  const Handle triggerPrimitives) {
517  std::vector<std::vector<reco::CandidatePtr>> inputsInRegions{etaRegionEdges_.size() * (phiRegionEdges_.size() - 1)};
518 
519  for (unsigned int i = 0; i < triggerPrimitives->size(); ++i) {
520  reco::CandidatePtr tp(triggerPrimitives, i);
521 
522  if (tp->phi() < phiRegionEdges_.front() || tp->phi() >= phiRegionEdges_.back() ||
523  tp->eta() < etaRegionEdges_.front() || tp->eta() >= etaRegionEdges_.back())
524  continue;
525 
526  // Which phi region does this tp belong to
527  auto it_phi = phiRegionEdges_.begin();
528  it_phi = std::upper_bound(phiRegionEdges_.begin(), phiRegionEdges_.end(), tp->phi()) - 1;
529 
530  // Which eta region does this tp belong to
531  auto it_eta = etaRegionEdges_.begin();
532  it_eta = std::upper_bound(etaRegionEdges_.begin(), etaRegionEdges_.end(), tp->eta()) - 1;
533 
534  if (it_phi != phiRegionEdges_.end() && it_eta != etaRegionEdges_.end()) {
535  auto phiRegion = it_phi - phiRegionEdges_.begin();
536  auto etaRegion = it_eta - etaRegionEdges_.begin();
537  inputsInRegions[getRegionIndex(phiRegion, etaRegion)].emplace_back(tp);
538  }
539  }
540 
541  // Truncate number of inputs in each pf region
542  for (auto& inputs : inputsInRegions) {
543  if (inputs.size() > maxInputsPerRegion_) {
544  inputs.resize(maxInputsPerRegion_);
545  }
546  }
547 
548  return inputsInRegions;
549 }
550 
551 unsigned int Phase1L1TJetProducer::getRegionIndex(const unsigned int phiRegion, const unsigned int etaRegion) const {
552  return etaRegion * (phiRegionEdges_.size() - 1) + phiRegion;
553 }
554 
555 std::pair<double, double> Phase1L1TJetProducer::regionEtaPhiLowEdges(const unsigned int regionIndex) const {
556  unsigned int phiRegion = regionIndex % (phiRegionEdges_.size() - 1);
557  unsigned int etaRegion = (regionIndex - phiRegion) / (phiRegionEdges_.size() - 1);
558  return std::pair<double, double>{phiRegionEdges_.at(phiRegion), etaRegionEdges_.at(etaRegion)};
559 }
560 
561 std::pair<double, double> Phase1L1TJetProducer::regionEtaPhiUpEdges(const unsigned int regionIndex) const {
562  unsigned int phiRegion = regionIndex % (phiRegionEdges_.size() - 1);
563  unsigned int etaRegion = (regionIndex - phiRegion) / (phiRegionEdges_.size() - 1);
564  if (phiRegion == phiRegionEdges_.size() - 1) {
565  return std::pair<double, double>{phiRegionEdges_.at(phiRegion), etaRegionEdges_.at(etaRegion + 1)};
566  } else if (etaRegion == etaRegionEdges_.size() - 1) {
567  return std::pair<double, double>{phiRegionEdges_.at(phiRegion + 1), etaRegionEdges_.at(etaRegion)};
568  }
569 
570  return std::pair<double, double>{phiRegionEdges_.at(phiRegion + 1), etaRegionEdges_.at(etaRegion + 1)};
571 }
572 
574  const auto lowEtaBin = caloGrid_->GetXaxis()->FindBin(-1.0 * etaCut);
575  const auto highEtaBin = caloGrid_->GetXaxis()->FindBin(etaCut) - 1;
576  const auto phiProjection = caloGrid_->ProjectionY("temp", lowEtaBin, highEtaBin);
577 
578  // Use digitised quantities when summing to improve agreement with firmware
579  int totalDigiPx{0};
580  int totalDigiPy{0};
581 
582  for (int i = 1; i < phiProjection->GetNbinsX() + 1; ++i) {
583  double pt = phiProjection->GetBinContent(i);
584  totalDigiPx += trunc(floor(pt / ptlsb_) * cosPhi_[i - 1]);
585  totalDigiPy += trunc(floor(pt / ptlsb_) * sinPhi_[i - 1]);
586  }
587 
588  double lMET = floor(sqrt(totalDigiPx * totalDigiPx + totalDigiPy * totalDigiPy)) * ptlsb_;
589 
590  math::PtEtaPhiMLorentzVector lMETVector(lMET, 0, acos(totalDigiPx / (lMET / ptlsb_)), 0);
591  l1t::EtSum lMETSum(lMETVector, sumType, 0, 0, 0, 0);
592  return lMETSum;
593 }
594 
595 bool Phase1L1TJetProducer::trimTower(const int etaIndex, const int phiIndex) const {
596  int etaHalfSize = jetIEtaSize_ / 2;
597  int phiHalfSize = jetIPhiSize_ / 2;
598 
599  if (etaIndex == -etaHalfSize || etaIndex == etaHalfSize) {
600  if (phiIndex <= -phiHalfSize + 1 || phiIndex >= phiHalfSize - 1) {
601  return true;
602  }
603  } else if (etaIndex == -etaHalfSize + 1 || etaIndex == etaHalfSize - 1) {
604  if (phiIndex == -phiHalfSize || phiIndex == phiHalfSize) {
605  return true;
606  }
607  }
608 
609  return false;
610 }
pfDeepBoostedJetPreprocessParams_cfi.upper_bound
upper_bound
Definition: pfDeepBoostedJetPreprocessParams_cfi.py:16
PFCandidate.h
Phase1L1TJetProducer::vetoZeroPt_
bool vetoZeroPt_
Definition: Phase1L1TJetProducer.cc:150
reco::CaloJet
Jets made from CaloTowers.
Definition: CaloJet.h:27
DDAxes::y
CaloJet.h
Phase1L1TJetProducer::metHFAbsEtaCut_
double metHFAbsEtaCut_
Definition: Phase1L1TJetProducer.cc:162
mps_fire.i
i
Definition: mps_fire.py:428
Phase1L1TJetProducer
Definition: Phase1L1TJetProducer.cc:63
EDProducer.h
Phase1L1TJetProducer::buildJetFromSeed
reco::CaloJet buildJetFromSeed(const std::tuple< int, int > &seed) const
Definition: Phase1L1TJetProducer.cc:362
Phase1L1TJetProducer::sinPhi_
std::vector< double > sinPhi_
Definition: Phase1L1TJetProducer.cc:157
ESHandle.h
Phase1L1TJetProducer::Phase1L1TJetProducer
Phase1L1TJetProducer(const edm::ParameterSet &)
Definition: Phase1L1TJetProducer.cc:166
Phase1L1TJetProducer::trimmedGrid_
bool trimmedGrid_
Definition: Phase1L1TJetProducer.cc:144
DiDispStaMuonMonitor_cfi.pt
pt
Definition: DiDispStaMuonMonitor_cfi.py:39
Handle
y_scroll_max
constexpr int y_scroll_max
Definition: Phase1L1TJetProducer.cc:61
edm::EDGetTokenT
Definition: EDGetToken.h:33
reco::Candidate::PolarLorentzVector
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Candidate.h:38
Phase1L1TJetProducer::cosPhi_
std::vector< double > cosPhi_
Definition: Phase1L1TJetProducer.cc:158
HLT_FULL_cff.InputTag
InputTag
Definition: HLT_FULL_cff.py:89301
edm::ParameterSetDescription
Definition: ParameterSetDescription.h:52
x_scroll_min
constexpr int x_scroll_min
Definition: Phase1L1TJetProducer.cc:58
y_scroll_min
constexpr int y_scroll_min
Definition: Phase1L1TJetProducer.cc:60
Phase1L1TJetProducer::seedPtThreshold_
double seedPtThreshold_
Definition: Phase1L1TJetProducer.cc:145
edm::one::EDProducer
Definition: EDProducer.h:30
singleTopDQM_cfi.jets
jets
Definition: singleTopDQM_cfi.py:42
DDAxes::x
reco::LeafCandidate::pt
double pt() const final
transverse momentum
Definition: LeafCandidate.h:146
Phase1L1TJetProducer::trimTower
bool trimTower(const int etaIndex, const int phiIndex) const
Definition: Phase1L1TJetProducer.cc:595
Phase1L1TJetProducer::getCandidateDigiEtaPhi
std::pair< float, float > getCandidateDigiEtaPhi(const float eta, const float phi, const unsigned int regionIndex) const
Definition: Phase1L1TJetProducer.cc:435
edm::Handle
Definition: AssociativeIterator.h:50
Phase1L1TJetProducer::findSeeds
std::vector< std::tuple< int, int > > findSeeds(float seedThreshold) const
Finds the seeds in the caloGrid, seeds are saved in a vector that contain the index in the TH2F of ea...
Definition: Phase1L1TJetProducer.cc:307
Phase1L1TJetProducer::phiUp_
double phiUp_
Definition: Phase1L1TJetProducer.cc:141
reco::JetExtendedAssociation::Container
edm::AssociationVector< reco::JetRefBaseProd, Values > Container
Definition: JetExtendedAssociation.h:29
Phase1L1TJetProducer::maxInputsPerRegion_
unsigned int maxInputsPerRegion_
Definition: Phase1L1TJetProducer.cc:155
Phase1L1TJetProducer::etaRegionEdges_
std::vector< double > etaRegionEdges_
Definition: Phase1L1TJetProducer.cc:152
Phase1L1TJetProducer::puSubtraction_
bool puSubtraction_
Definition: Phase1L1TJetProducer.cc:149
fileCollector.seed
seed
Definition: fileCollector.py:127
Phase1L1TJetProducer::prepareInputsIntoRegions
std::vector< std::vector< reco::CandidatePtr > > prepareInputsIntoRegions(const Handle triggerPrimitives)
MakerMacros.h
Phase1L1TJetProducer::getRegionIndex
unsigned int getRegionIndex(const unsigned int phiRegion, const unsigned int etaRegion) const
Definition: Phase1L1TJetProducer.cc:551
Phase1L1TJetProducer::metAbsEtaCut_
double metAbsEtaCut_
Definition: Phase1L1TJetProducer.cc:160
DEFINE_FWK_MODULE
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::ConfigurationDescriptions::add
void add(std::string const &label, ParameterSetDescription const &psetDescription)
Definition: ConfigurationDescriptions.cc:57
L1Analysis::kMissingEtHF
Definition: L1AnalysisL1UpgradeDataFormat.h:25
Phase1L1TJetProducer::nBinsPhi_
unsigned int nBinsPhi_
Definition: Phase1L1TJetProducer.cc:139
Service.h
PVValHelper::eta
Definition: PVValidationHelpers.h:70
Phase1L1TJetProducer::getTowerEnergy
float getTowerEnergy(int iEta, int iPhi) const
Get the energy of a certain tower while correctly handling phi periodicity in case of overflow.
Definition: Phase1L1TJetProducer.cc:202
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
hgcalTowerMapProducer_cfi.nBinsEta
nBinsEta
Definition: hgcalTowerMapProducer_cfi.py:10
Phase1L1TJetProducer::fillCaloGrid
void fillCaloGrid(TH2F &caloGrid, const Container &triggerPrimitives, const unsigned int regionIndex)
Definition: Phase1L1TJetProducer.cc:420
Phase1L1TJetProducer::jetIEtaSize_
unsigned int jetIEtaSize_
Definition: Phase1L1TJetProducer.cc:142
cmsswSequenceInfo.tp
tp
Definition: cmsswSequenceInfo.py:17
edm::ConfigurationDescriptions
Definition: ConfigurationDescriptions.h:28
Phase1L1TJetProducer::buildJetsFromSeedsWithPUSubtraction
std::vector< reco::CaloJet > buildJetsFromSeedsWithPUSubtraction(const std::vector< std::tuple< int, int >> &seeds, bool killZeroPt) const
Definition: Phase1L1TJetProducer.cc:391
Phase1L1TJetProducer::jetIPhiSize_
unsigned int jetIPhiSize_
Definition: Phase1L1TJetProducer.cc:143
dyt_utils::etaRegion
etaRegion
Definition: DynamicTruncation.h:44
Phase1L1TJetProducer::philsb_
double philsb_
Definition: Phase1L1TJetProducer.cc:147
edm::ParameterSet
Definition: ParameterSet.h:47
Phase1L1TJetProducer::etalsb_
double etalsb_
Definition: Phase1L1TJetProducer.cc:148
Phase1L1TJetProducer::~Phase1L1TJetProducer
~Phase1L1TJetProducer() override
Definition: Phase1L1TJetProducer.cc:200
Event.h
fftjetproducer_cfi.etaCut
etaCut
Definition: fftjetproducer_cfi.py:168
PVValHelper::phi
Definition: PVValidationHelpers.h:69
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
jetUpdater_cfi.sort
sort
Definition: jetUpdater_cfi.py:29
Phase1L1TJetProducer::caloGrid_
std::unique_ptr< TH2F > caloGrid_
Definition: Phase1L1TJetProducer.cc:135
l1t::EtSum
Definition: EtSum.h:20
LorentzVector.h
createfilelist.int
int
Definition: createfilelist.py:10
iEvent
int iEvent
Definition: GenABIO.cc:224
Phase1L1TJetProducer::produce
void produce(edm::Event &, const edm::EventSetup &) override
Definition: Phase1L1TJetProducer.cc:222
M_PI
#define M_PI
Definition: BXVectorInputProducer.cc:49
PixelMapPlotter.inputs
inputs
Definition: PixelMapPlotter.py:490
trackerHitRTTI::vector
Definition: trackerHitRTTI.h:21
edm::EventSetup
Definition: EventSetup.h:58
L1Candidate.h
L1Analysis::kMissingEt
Definition: L1AnalysisL1UpgradeDataFormat.h:19
AlCaHLTBitMon_QueryRunRegistry.string
string string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
edm::Ptr< Candidate >
PFCluster.h
Phase1L1TJetProducer::etaBinning_
std::vector< double > etaBinning_
Definition: Phase1L1TJetProducer.cc:137
DDAxes::phi
submitPVResolutionJobs.desc
string desc
Definition: submitPVResolutionJobs.py:251
eostools.move
def move(src, dest)
Definition: eostools.py:511
DetachedQuadStep_cff.seeds
seeds
Definition: DetachedQuadStep_cff.py:195
Frameworkfwd.h
Phase1L1TJetProducer::fillDescriptions
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: Phase1L1TJetProducer.cc:489
metsig::jet
Definition: SignAlgoResolutions.h:47
Phase1L1TJetProducer::regionEtaPhiUpEdges
std::pair< double, double > regionEtaPhiUpEdges(const unsigned int regionIndex) const
Definition: Phase1L1TJetProducer.cc:561
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
Phase1L1TJetProducer_cfi.nBinsPhi
nBinsPhi
Definition: Phase1L1TJetProducer_cfi.py:23
Phase1L1TJetProducer::phiRegionEdges_
std::vector< double > phiRegionEdges_
Definition: Phase1L1TJetProducer.cc:153
l1t::EtSum::EtSumType
EtSumType
Definition: EtSum.h:22
L1TowerCalibrationProducer_cfi.iEta
iEta
Definition: L1TowerCalibrationProducer_cfi.py:60
Phase1L1TJetProducer::phiLow_
double phiLow_
Definition: Phase1L1TJetProducer.cc:140
math::PtEtaPhiMLorentzVector
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
Candidate.h
Phase1L1TJetProducer::computeMET
l1t::EtSum computeMET(const double etaCut, l1t::EtSum::EtSumType sumType) const
Definition: Phase1L1TJetProducer.cc:573
View.h
ParameterSet.h
EtSum.h
Phase1L1TJetProducer::subtract9x9Pileup
void subtract9x9Pileup(reco::CaloJet &jet) const
Definition: Phase1L1TJetProducer.cc:260
x_scroll_max
constexpr int x_scroll_max
Definition: Phase1L1TJetProducer.cc:59
Phase1L1TJetProducer::ptlsb_
double ptlsb_
Definition: Phase1L1TJetProducer.cc:146
edm::Event
Definition: Event.h:73
pileupReCalc_HLTpaths.trunc
trunc
Definition: pileupReCalc_HLTpaths.py:143
Phase1L1TJetProducer::inputCollectionTag_
edm::EDGetTokenT< edm::View< reco::Candidate > > inputCollectionTag_
Definition: Phase1L1TJetProducer.cc:133
Phase1L1TJetProducer::regionEtaPhiLowEdges
std::pair< double, double > regionEtaPhiLowEdges(const unsigned int regionIndex) const
Definition: Phase1L1TJetProducer.cc:555
edm::InputTag
Definition: InputTag.h:15
Phase1L1TJetProducer::buildJetsFromSeeds
std::vector< reco::CaloJet > buildJetsFromSeeds(const std::vector< std::tuple< int, int >> &seeds) const
Definition: Phase1L1TJetProducer.cc:407
Phase1L1TJetProducer::outputCollectionName_
std::string outputCollectionName_
Definition: Phase1L1TJetProducer.cc:163
Phase1L1TJetProducer::nBinsEta_
size_t nBinsEta_
Definition: Phase1L1TJetProducer.cc:138