CMS 3D CMS Logo

Phase1L1TJetProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: L1CaloTrigger
4 // Class: Phase1L1TJetProducer
5 //
25 //
26 // Original Simone Bologna
27 // Created: Mon Jul 02 2018
28 //
29 
45 
46 #include "TH2F.h"
47 
48 #include <cmath>
49 
50 #include <algorithm>
51 constexpr int x_scroll_min = -4;
52 constexpr int x_scroll_max = 4;
53 constexpr int y_scroll_min = 0;
54 constexpr int y_scroll_max = 3;
55 
57 public:
58  explicit Phase1L1TJetProducer(const edm::ParameterSet&);
59  ~Phase1L1TJetProducer() override;
60 
61  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
62 
63 private:
64  void produce(edm::Event&, const edm::EventSetup&) override;
65 
67  std::vector<std::tuple<int, int>> findSeeds(float seedThreshold) const;
68 
69  std::vector<reco::CaloJet> _buildJetsFromSeedsWithPUSubtraction(const std::vector<std::tuple<int, int>>& seeds,
70  bool killZeroPt) const;
71  std::vector<reco::CaloJet> _buildJetsFromSeeds(const std::vector<std::tuple<int, int>>& seeds) const;
72 
73  void subtract9x9Pileup(reco::CaloJet& jet) const;
74 
76  float getTowerEnergy(int iEta, int iPhi) const;
77 
78  reco::CaloJet buildJetFromSeed(const std::tuple<int, int>& seed) const;
79 
80  // <3 handy method to fill the calogrid with whatever type
81  template <class Container>
82  void fillCaloGrid(TH2F& caloGrid, const Container& triggerPrimitives);
83 
85  // histogram containing our clustered inputs
86  std::unique_ptr<TH2F> caloGrid_;
87 
88  std::vector<double> etaBinning_;
89  size_t nBinsEta_;
90  unsigned int nBinsPhi_;
91  double phiLow_;
92  double phiUp_;
93  unsigned int jetIEtaSize_;
94  unsigned int jetIPhiSize_;
98 
100 };
101 
103  : // getting configuration settings
104  inputCollectionTag_{
105  consumes<edm::View<reco::Candidate>>(iConfig.getParameter<edm::InputTag>("inputCollectionTag"))},
106  etaBinning_(iConfig.getParameter<std::vector<double>>("etaBinning")),
107  nBinsEta_(etaBinning_.size() - 1),
108  nBinsPhi_(iConfig.getParameter<unsigned int>("nBinsPhi")),
109  phiLow_(iConfig.getParameter<double>("phiLow")),
110  phiUp_(iConfig.getParameter<double>("phiUp")),
111  jetIEtaSize_(iConfig.getParameter<unsigned int>("jetIEtaSize")),
112  jetIPhiSize_(iConfig.getParameter<unsigned int>("jetIPhiSize")),
113  seedPtThreshold_(iConfig.getParameter<double>("seedPtThreshold")),
114  puSubtraction_(iConfig.getParameter<bool>("puSubtraction")),
115  vetoZeroPt_(iConfig.getParameter<bool>("vetoZeroPt")),
116  outputCollectionName_(iConfig.getParameter<std::string>("outputCollectionName")) {
117  caloGrid_ =
118  std::make_unique<TH2F>("caloGrid", "Calorimeter grid", nBinsEta_, etaBinning_.data(), nBinsPhi_, phiLow_, phiUp_);
119  caloGrid_->GetXaxis()->SetTitle("#eta");
120  caloGrid_->GetYaxis()->SetTitle("#phi");
121  produces<std::vector<reco::CaloJet>>(outputCollectionName_).setBranchAlias(outputCollectionName_);
122 }
123 
125 
126 float Phase1L1TJetProducer::getTowerEnergy(int iEta, int iPhi) const {
127  // 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
128 
129  int nBinsEta = caloGrid_->GetNbinsX();
130  int nBinsPhi = caloGrid_->GetNbinsY();
131  while (iPhi < 1) {
132  iPhi += nBinsPhi;
133  }
134  while (iPhi > nBinsPhi) {
135  iPhi -= nBinsPhi;
136  }
137  if (iEta < 1) {
138  return 0;
139  }
140  if (iEta > nBinsEta) {
141  return 0;
142  }
143  return caloGrid_->GetBinContent(iEta, iPhi);
144 }
145 
147  edm::Handle<edm::View<reco::Candidate>> inputCollectionHandle;
148  iEvent.getByToken(inputCollectionTag_, inputCollectionHandle);
149  // dumping the data
150  caloGrid_->Reset();
151  fillCaloGrid<>(*(caloGrid_), *inputCollectionHandle);
152 
153  const auto& seedsVector = findSeeds(seedPtThreshold_); // seedPtThreshold = 6
154  auto l1jetVector = puSubtraction_ ? _buildJetsFromSeedsWithPUSubtraction(seedsVector, vetoZeroPt_)
155  : _buildJetsFromSeeds(seedsVector);
156 
157  // sort by pt
158  std::sort(l1jetVector.begin(), l1jetVector.end(), [](const reco::CaloJet& jet1, const reco::CaloJet& jet2) {
159  return jet1.pt() > jet2.pt();
160  });
161 
162  auto l1jetVectorPtr = std::make_unique<std::vector<reco::CaloJet>>(l1jetVector);
163  iEvent.put(std::move(l1jetVectorPtr), outputCollectionName_);
164 
165  return;
166 }
167 
169  // these variables host the total pt in each sideband and the total pileup contribution
170  float topBandPt = 0;
171  float leftBandPt = 0;
172  float rightBandPt = 0;
173  float bottomBandPt = 0;
174  float pileUpEnergy;
175 
176  // hold the jet's x-y (and z, as I have to use it, even if 2D) location in the histo
177  int xCenter, yCenter, zCenter;
178  // Retrieving histo-coords for seed
179  caloGrid_->GetBinXYZ(caloGrid_->FindFixBin(jet.eta(), jet.phi()), xCenter, yCenter, zCenter);
180 
181  // Computing pileup
182  for (int x = x_scroll_min; x <= x_scroll_max; x++) {
183  for (int y = y_scroll_min; y < y_scroll_max; y++) {
184  // top band, I go up 5 squares to reach the bottom of the top band
185  // +x scrolls from left to right, +y scrolls up
186  topBandPt += getTowerEnergy(xCenter + x, yCenter + (5 + y));
187  // left band, I go left 5 squares (-5) to reach the bottom of the top band
188  // +x scrolls from bottom to top, +y scrolls left
189  leftBandPt += getTowerEnergy(xCenter - (5 + y), yCenter + x);
190  // right band, I go right 5 squares (+5) to reach the bottom of the top band
191  // +x scrolls from bottom to top, +y scrolls right
192  rightBandPt += getTowerEnergy(xCenter + (5 + y), yCenter + x);
193  // right band, I go right 5 squares (+5) to reach the bottom of the top band
194  // +x scrolls from bottom to top, +y scrolls right
195  bottomBandPt += getTowerEnergy(xCenter + x, yCenter - (5 + y));
196  }
197  }
198  // adding bands and removing the maximum band (equivalent to adding the three minimum bands)
199  pileUpEnergy = topBandPt + leftBandPt + rightBandPt + bottomBandPt -
200  std::max(topBandPt, std::max(leftBandPt, std::max(rightBandPt, bottomBandPt)));
201 
202  //preparing the new 4-momentum vector
204  // removing pu contribution
205  float ptAfterPUSubtraction = jet.pt() - pileUpEnergy;
206  ptVector.SetPt((ptAfterPUSubtraction > 0) ? ptAfterPUSubtraction : 0);
207  ptVector.SetEta(jet.eta());
208  ptVector.SetPhi(jet.phi());
209  //updating the jet
210  jet.setP4(ptVector);
211  jet.setPileup(pileUpEnergy);
212  return;
213 }
214 
215 std::vector<std::tuple<int, int>> Phase1L1TJetProducer::findSeeds(float seedThreshold) const {
216  int nBinsX = caloGrid_->GetNbinsX();
217  int nBinsY = caloGrid_->GetNbinsY();
218 
219  std::vector<std::tuple<int, int>> seeds;
220 
221  int etaHalfSize = (int)jetIEtaSize_ / 2;
222  int phiHalfSize = (int)jetIPhiSize_ / 2;
223 
224  // for each point of the grid check if it is a local maximum
225  // to do so I take a point, and look if is greater than the points around it (in the 9x9 neighborhood)
226  // 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)
227  // to prevent mutual exclusion, I check greater for points below and left to the one I am considering (including the bottom-right point)
228 
229  for (int iPhi = 1; iPhi <= nBinsY; iPhi++) {
230  for (int iEta = 1; iEta <= nBinsX; iEta++) {
231  float centralPt = caloGrid_->GetBinContent(iEta, iPhi);
232  if (centralPt < seedThreshold)
233  continue;
234  bool isLocalMaximum = true;
235 
236  // Scanning through the grid centered on the seed
237  for (int etaIndex = -etaHalfSize; etaIndex <= etaHalfSize; etaIndex++) {
238  for (int phiIndex = -phiHalfSize; phiIndex <= phiHalfSize; phiIndex++) {
239  if ((etaIndex == 0) && (phiIndex == 0))
240  continue;
241  if (phiIndex > 0) {
242  if (phiIndex > -etaIndex) {
243  isLocalMaximum = ((isLocalMaximum) && (centralPt > getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
244  } else {
245  isLocalMaximum = ((isLocalMaximum) && (centralPt >= getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
246  }
247  } else {
248  if (phiIndex >= -etaIndex) {
249  isLocalMaximum = ((isLocalMaximum) && (centralPt > getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
250  } else {
251  isLocalMaximum = ((isLocalMaximum) && (centralPt >= getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
252  }
253  }
254  }
255  }
256  if (isLocalMaximum) {
257  seeds.emplace_back(iEta, iPhi);
258  }
259  }
260  }
261 
262  return seeds;
263 }
264 
265 reco::CaloJet Phase1L1TJetProducer::buildJetFromSeed(const std::tuple<int, int>& seed) const {
266  int iEta = std::get<0>(seed);
267  int iPhi = std::get<1>(seed);
268 
269  int etaHalfSize = (int)jetIEtaSize_ / 2;
270  int phiHalfSize = (int)jetIPhiSize_ / 2;
271 
272  float ptSum = 0;
273  // Scanning through the grid centered on the seed
274  for (int etaIndex = -etaHalfSize; etaIndex <= etaHalfSize; etaIndex++) {
275  for (int phiIndex = -phiHalfSize; phiIndex <= phiHalfSize; phiIndex++) {
276  ptSum += getTowerEnergy(iEta + etaIndex, iPhi + phiIndex);
277  }
278  }
279 
280  // Creating a jet with eta phi centered on the seed and momentum equal to the sum of the pt of the components
282  ptVector.SetPt(ptSum);
283  ptVector.SetEta(caloGrid_->GetXaxis()->GetBinCenter(iEta));
284  ptVector.SetPhi(caloGrid_->GetYaxis()->GetBinCenter(iPhi));
286  jet.setP4(ptVector);
287  return jet;
288 }
289 
291  const std::vector<std::tuple<int, int>>& seeds, bool killZeroPt) const {
292  // For each seed take a grid centered on the seed of the size specified by the user
293  // 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.
294  std::vector<reco::CaloJet> jets;
295  for (const auto& seed : seeds) {
298  //killing jets with 0 pt
299  if ((vetoZeroPt_) && (jet.pt() <= 0))
300  continue;
301  jets.push_back(jet);
302  }
303  return jets;
304 }
305 
306 std::vector<reco::CaloJet> Phase1L1TJetProducer::_buildJetsFromSeeds(
307  const std::vector<std::tuple<int, int>>& seeds) const {
308  // For each seed take a grid centered on the seed of the size specified by the user
309  // 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.
310  std::vector<reco::CaloJet> jets;
311  for (const auto& seed : seeds) {
313  jets.push_back(jet);
314  }
315  return jets;
316 }
317 
318 template <class Container>
319 void Phase1L1TJetProducer::fillCaloGrid(TH2F& caloGrid, const Container& triggerPrimitives) {
320  //Filling the calo grid with the primitives
321  for (const auto& primitiveIterator : triggerPrimitives) {
322  caloGrid.Fill(static_cast<float>(primitiveIterator.eta()),
323  static_cast<float>(primitiveIterator.phi()),
324  static_cast<float>(primitiveIterator.pt()));
325  }
326 }
327 
330  desc.add<edm::InputTag>("inputCollectionTag", edm::InputTag("l1pfCandidates", "Puppi"));
331  desc.add<std::vector<double>>("etaBinning");
332  desc.add<unsigned int>("nBinsPhi", 72);
333  desc.add<double>("phiLow", -M_PI);
334  desc.add<double>("phiUp", M_PI);
335  desc.add<unsigned int>("jetIEtaSize", 7);
336  desc.add<unsigned int>("jetIPhiSize", 7);
337  desc.add<double>("seedPtThreshold", 5);
338  desc.add<bool>("puSubtraction", false);
339  desc.add<string>("outputCollectionName", "UncalibratedPhase1L1TJetFromPfCandidates");
340  desc.add<bool>("vetoZeroPt", true);
341  descriptions.add("Phase1L1TJetProducer", desc);
342 }
343 
PFCandidate.h
Phase1L1TJetProducer::vetoZeroPt_
bool vetoZeroPt_
Definition: Phase1L1TJetProducer.cc:97
reco::CaloJet
Jets made from CaloTowers.
Definition: CaloJet.h:27
DDAxes::y
CaloJet.h
Phase1L1TJetProducer
Definition: Phase1L1TJetProducer.cc:56
edm::ParameterSetDescription::add
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Definition: ParameterSetDescription.h:95
EDProducer.h
Phase1L1TJetProducer::buildJetFromSeed
reco::CaloJet buildJetFromSeed(const std::tuple< int, int > &seed) const
Definition: Phase1L1TJetProducer.cc:265
ESHandle.h
Phase1L1TJetProducer::Phase1L1TJetProducer
Phase1L1TJetProducer(const edm::ParameterSet &)
Definition: Phase1L1TJetProducer.cc:102
y_scroll_max
constexpr int y_scroll_max
Definition: Phase1L1TJetProducer.cc:54
edm::EDGetTokenT
Definition: EDGetToken.h:33
reco::Candidate::PolarLorentzVector
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Candidate.h:38
edm::ParameterSetDescription
Definition: ParameterSetDescription.h:52
x_scroll_min
constexpr int x_scroll_min
Definition: Phase1L1TJetProducer.cc:51
y_scroll_min
constexpr int y_scroll_min
Definition: Phase1L1TJetProducer.cc:53
Phase1L1TJetProducer::seedPtThreshold_
double seedPtThreshold_
Definition: Phase1L1TJetProducer.cc:95
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
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:215
Phase1L1TJetProducer::phiUp_
double phiUp_
Definition: Phase1L1TJetProducer.cc:92
reco::JetExtendedAssociation::Container
edm::AssociationVector< reco::JetRefBaseProd, Values > Container
Definition: JetExtendedAssociation.h:29
Phase1L1TJetProducer::fillCaloGrid
void fillCaloGrid(TH2F &caloGrid, const Container &triggerPrimitives)
Definition: Phase1L1TJetProducer.cc:319
Phase1L1TJetProducer::puSubtraction_
bool puSubtraction_
Definition: Phase1L1TJetProducer.cc:96
MakerMacros.h
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
Phase1L1TJetProducer::nBinsPhi_
unsigned int nBinsPhi_
Definition: Phase1L1TJetProducer.cc:90
Service.h
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:126
hgcalTowerMapProducer_cfi.nBinsEta
nBinsEta
Definition: hgcalTowerMapProducer_cfi.py:9
Phase1L1TJetProducer::jetIEtaSize_
unsigned int jetIEtaSize_
Definition: Phase1L1TJetProducer.cc:93
edm::ConfigurationDescriptions
Definition: ConfigurationDescriptions.h:28
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
TFileService.h
Phase1L1TJetProducer::jetIPhiSize_
unsigned int jetIPhiSize_
Definition: Phase1L1TJetProducer.cc:94
InitialStep_cff.seeds
seeds
Definition: InitialStep_cff.py:232
HLT_2018_cff.InputTag
InputTag
Definition: HLT_2018_cff.py:79016
Phase1L1TJetProducer::_buildJetsFromSeedsWithPUSubtraction
std::vector< reco::CaloJet > _buildJetsFromSeedsWithPUSubtraction(const std::vector< std::tuple< int, int >> &seeds, bool killZeroPt) const
Definition: Phase1L1TJetProducer.cc:290
edm::ParameterSet
Definition: ParameterSet.h:36
Phase1L1TJetProducer::~Phase1L1TJetProducer
~Phase1L1TJetProducer() override
Definition: Phase1L1TJetProducer.cc:124
Event.h
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
Phase1L1TJetProducer::caloGrid_
std::unique_ptr< TH2F > caloGrid_
Definition: Phase1L1TJetProducer.cc:86
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:146
M_PI
#define M_PI
Definition: BXVectorInputProducer.cc:50
Phase1L1TJetProducer::_buildJetsFromSeeds
std::vector< reco::CaloJet > _buildJetsFromSeeds(const std::vector< std::tuple< int, int >> &seeds) const
Definition: Phase1L1TJetProducer.cc:306
edm::EventSetup
Definition: EventSetup.h:57
L1Candidate.h
PFCluster.h
Phase1L1TJetProducer::etaBinning_
std::vector< double > etaBinning_
Definition: Phase1L1TJetProducer.cc:88
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
eostools.move
def move(src, dest)
Definition: eostools.py:511
Frameworkfwd.h
Phase1L1TJetProducer::fillDescriptions
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: Phase1L1TJetProducer.cc:328
metsig::jet
Definition: SignAlgoResolutions.h:47
Phase1L1TJetProducer_cfi.nBinsPhi
nBinsPhi
Definition: Phase1L1TJetProducer_cfi.py:20
L1TowerCalibrationProducer_cfi.iEta
iEta
Definition: L1TowerCalibrationProducer_cfi.py:60
Phase1L1TJetProducer::phiLow_
double phiLow_
Definition: Phase1L1TJetProducer.cc:91
Candidate.h
View.h
ParameterSet.h
Phase1L1TJetProducer::subtract9x9Pileup
void subtract9x9Pileup(reco::CaloJet &jet) const
Definition: Phase1L1TJetProducer.cc:168
x_scroll_max
constexpr int x_scroll_max
Definition: Phase1L1TJetProducer.cc:52
edm::Event
Definition: Event.h:73
Phase1L1TJetProducer::inputCollectionTag_
edm::EDGetTokenT< edm::View< reco::Candidate > > inputCollectionTag_
Definition: Phase1L1TJetProducer.cc:84
edm::InputTag
Definition: InputTag.h:15
UEAnalysisJets_cfi.seedThreshold
seedThreshold
Definition: UEAnalysisJets_cfi.py:8
SurveyInfoScenario_cff.seed
seed
Definition: SurveyInfoScenario_cff.py:295
Phase1L1TJetProducer::outputCollectionName_
std::string outputCollectionName_
Definition: Phase1L1TJetProducer.cc:99
Phase1L1TJetProducer::nBinsEta_
size_t nBinsEta_
Definition: Phase1L1TJetProducer.cc:89