File indexing completed on 2024-04-06 12:20:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include "FWCore/Framework/interface/Frameworkfwd.h"
0038 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0039 #include "FWCore/Framework/interface/one/EDProducer.h"
0040 #include "DataFormats/JetReco/interface/CaloJet.h"
0041 #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h"
0042 #include "DataFormats/L1TParticleFlow/interface/PFCluster.h"
0043 #include "DataFormats/L1Trigger/interface/L1Candidate.h"
0044 #include "DataFormats/Common/interface/View.h"
0045 #include "DataFormats/Candidate/interface/Candidate.h"
0046 #include "FWCore/Framework/interface/MakerMacros.h"
0047 #include "FWCore/Framework/interface/Event.h"
0048 #include "DataFormats/Math/interface/LorentzVector.h"
0049 #include "FWCore/ServiceRegistry/interface/Service.h"
0050 #include "DataFormats/L1Trigger/interface/EtSum.h"
0051
0052 #include "TH2F.h"
0053
0054 #include <cmath>
0055
0056 #include <algorithm>
0057 constexpr int x_scroll_min = -4;
0058 constexpr int x_scroll_max = 4;
0059 constexpr int y_scroll_min = 0;
0060 constexpr int y_scroll_max = 3;
0061
0062 class Phase1L1TJetProducer : public edm::one::EDProducer<> {
0063 public:
0064 explicit Phase1L1TJetProducer(const edm::ParameterSet&);
0065 ~Phase1L1TJetProducer() override;
0066
0067 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0068
0069 private:
0070 void produce(edm::Event&, const edm::EventSetup&) override;
0071
0072
0073 std::vector<std::tuple<int, int>> findSeeds(float seedThreshold) const;
0074
0075
0076
0077
0078 std::vector<reco::CaloJet> buildJetsFromSeedsWithPUSubtraction(const std::vector<std::tuple<int, int>>& seeds,
0079 bool killZeroPt) const;
0080
0081
0082 std::vector<reco::CaloJet> buildJetsFromSeeds(const std::vector<std::tuple<int, int>>& seeds) const;
0083
0084
0085
0086
0087 void subtract9x9Pileup(reco::CaloJet& jet) const;
0088
0089
0090 float getTowerEnergy(int iEta, int iPhi) const;
0091
0092
0093 reco::CaloJet buildJetFromSeed(const std::tuple<int, int>& seed) const;
0094
0095
0096 template <class Container>
0097 void fillCaloGrid(TH2F& caloGrid, const Container& triggerPrimitives, const unsigned int regionIndex);
0098
0099
0100
0101
0102
0103 std::pair<float, float> getCandidateDigiEtaPhi(const float eta,
0104 const float phi,
0105 const unsigned int regionIndex) const;
0106
0107
0108
0109 template <class Handle>
0110 std::vector<std::vector<reco::CandidatePtr>> prepareInputsIntoRegions(const Handle triggerPrimitives);
0111
0112
0113 unsigned int getRegionIndex(const unsigned int phiRegion, const unsigned int etaRegion) const;
0114
0115 std::pair<double, double> regionEtaPhiLowEdges(const unsigned int regionIndex) const;
0116
0117 std::pair<double, double> regionEtaPhiUpEdges(const unsigned int regionIndex) const;
0118
0119
0120
0121
0122
0123
0124 l1t::EtSum computeMET(const double etaCut, l1t::EtSum::EtSumType sumType) const;
0125
0126
0127
0128
0129
0130 bool trimTower(const int etaIndex, const int phiIndex) const;
0131
0132 edm::EDGetTokenT<edm::View<reco::Candidate>> inputCollectionTag_;
0133
0134 std::unique_ptr<TH2F> caloGrid_;
0135
0136 std::vector<double> etaBinning_;
0137 size_t nBinsEta_;
0138 unsigned int nBinsPhi_;
0139 double phiLow_;
0140 double phiUp_;
0141 unsigned int jetIEtaSize_;
0142 unsigned int jetIPhiSize_;
0143 bool trimmedGrid_;
0144 double seedPtThreshold_;
0145 double ptlsb_;
0146 double philsb_;
0147 double etalsb_;
0148 bool puSubtraction_;
0149 bool vetoZeroPt_;
0150
0151 std::vector<double> etaRegionEdges_;
0152 std::vector<double> phiRegionEdges_;
0153
0154 unsigned int maxInputsPerRegion_;
0155
0156 std::vector<double> sinPhi_;
0157 std::vector<double> cosPhi_;
0158
0159 double metAbsEtaCut_;
0160
0161 double metHFAbsEtaCut_;
0162 std::string outputCollectionName_;
0163 };
0164
0165 Phase1L1TJetProducer::Phase1L1TJetProducer(const edm::ParameterSet& iConfig)
0166 :
0167 inputCollectionTag_{
0168 consumes<edm::View<reco::Candidate>>(iConfig.getParameter<edm::InputTag>("inputCollectionTag"))},
0169 etaBinning_(iConfig.getParameter<std::vector<double>>("etaBinning")),
0170 nBinsEta_(etaBinning_.size() - 1),
0171 nBinsPhi_(iConfig.getParameter<unsigned int>("nBinsPhi")),
0172 phiLow_(iConfig.getParameter<double>("phiLow")),
0173 phiUp_(iConfig.getParameter<double>("phiUp")),
0174 jetIEtaSize_(iConfig.getParameter<unsigned int>("jetIEtaSize")),
0175 jetIPhiSize_(iConfig.getParameter<unsigned int>("jetIPhiSize")),
0176 trimmedGrid_(iConfig.getParameter<bool>("trimmedGrid")),
0177 seedPtThreshold_(iConfig.getParameter<double>("seedPtThreshold")),
0178 ptlsb_(iConfig.getParameter<double>("ptlsb")),
0179 philsb_(iConfig.getParameter<double>("philsb")),
0180 etalsb_(iConfig.getParameter<double>("etalsb")),
0181 puSubtraction_(iConfig.getParameter<bool>("puSubtraction")),
0182 vetoZeroPt_(iConfig.getParameter<bool>("vetoZeroPt")),
0183 etaRegionEdges_(iConfig.getParameter<std::vector<double>>("etaRegions")),
0184 phiRegionEdges_(iConfig.getParameter<std::vector<double>>("phiRegions")),
0185 maxInputsPerRegion_(iConfig.getParameter<unsigned int>("maxInputsPerRegion")),
0186 sinPhi_(iConfig.getParameter<std::vector<double>>("sinPhi")),
0187 cosPhi_(iConfig.getParameter<std::vector<double>>("cosPhi")),
0188 metAbsEtaCut_(iConfig.getParameter<double>("metAbsEtaCut")),
0189 metHFAbsEtaCut_(iConfig.getParameter<double>("metHFAbsEtaCut")),
0190 outputCollectionName_(iConfig.getParameter<std::string>("outputCollectionName")) {
0191 caloGrid_ =
0192 std::make_unique<TH2F>("caloGrid", "Calorimeter grid", nBinsEta_, etaBinning_.data(), nBinsPhi_, phiLow_, phiUp_);
0193 caloGrid_->GetXaxis()->SetTitle("#eta");
0194 caloGrid_->GetYaxis()->SetTitle("#phi");
0195 produces<std::vector<reco::CaloJet>>(outputCollectionName_).setBranchAlias(outputCollectionName_);
0196 produces<std::vector<l1t::EtSum>>(outputCollectionName_ + "MET").setBranchAlias(outputCollectionName_ + "MET");
0197 }
0198
0199 Phase1L1TJetProducer::~Phase1L1TJetProducer() {}
0200
0201 float Phase1L1TJetProducer::getTowerEnergy(int iEta, int iPhi) const {
0202
0203
0204 int nBinsEta = caloGrid_->GetNbinsX();
0205 int nBinsPhi = caloGrid_->GetNbinsY();
0206 while (iPhi < 1) {
0207 iPhi += nBinsPhi;
0208 }
0209 while (iPhi > nBinsPhi) {
0210 iPhi -= nBinsPhi;
0211 }
0212 if (iEta < 1) {
0213 return 0;
0214 }
0215 if (iEta > nBinsEta) {
0216 return 0;
0217 }
0218 return caloGrid_->GetBinContent(iEta, iPhi);
0219 }
0220
0221 void Phase1L1TJetProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0222 edm::Handle<edm::View<reco::Candidate>> inputCollectionHandle;
0223 iEvent.getByToken(inputCollectionTag_, inputCollectionHandle);
0224
0225
0226 std::vector<std::vector<reco::CandidatePtr>> inputsInRegions = prepareInputsIntoRegions<>(inputCollectionHandle);
0227
0228
0229 caloGrid_->Reset();
0230 for (unsigned int iInputRegion = 0; iInputRegion < inputsInRegions.size(); ++iInputRegion) {
0231 fillCaloGrid<>(*(caloGrid_), inputsInRegions[iInputRegion], iInputRegion);
0232 }
0233
0234
0235 const auto& seedsVector = findSeeds(seedPtThreshold_);
0236
0237 auto l1jetVector =
0238 puSubtraction_ ? buildJetsFromSeedsWithPUSubtraction(seedsVector, vetoZeroPt_) : buildJetsFromSeeds(seedsVector);
0239
0240
0241 std::sort(l1jetVector.begin(), l1jetVector.end(), [](const reco::CaloJet& jet1, const reco::CaloJet& jet2) {
0242 return jet1.pt() > jet2.pt();
0243 });
0244
0245 auto l1jetVectorPtr = std::make_unique<std::vector<reco::CaloJet>>(l1jetVector);
0246 iEvent.put(std::move(l1jetVectorPtr), outputCollectionName_);
0247
0248
0249 l1t::EtSum lMET = computeMET(metAbsEtaCut_, l1t::EtSum::EtSumType::kMissingEt);
0250 l1t::EtSum lMETHF = computeMET(metHFAbsEtaCut_, l1t::EtSum::EtSumType::kMissingEtHF);
0251 std::unique_ptr<std::vector<l1t::EtSum>> lSumVectorPtr(new std::vector<l1t::EtSum>(0));
0252 lSumVectorPtr->push_back(lMET);
0253 lSumVectorPtr->push_back(lMETHF);
0254 iEvent.put(std::move(lSumVectorPtr), this->outputCollectionName_ + "MET");
0255
0256 return;
0257 }
0258
0259 void Phase1L1TJetProducer::subtract9x9Pileup(reco::CaloJet& jet) const {
0260
0261 float topBandPt = 0;
0262 float leftBandPt = 0;
0263 float rightBandPt = 0;
0264 float bottomBandPt = 0;
0265 float pileUpEnergy;
0266
0267
0268 int xCenter, yCenter, zCenter;
0269
0270 caloGrid_->GetBinXYZ(caloGrid_->FindFixBin(jet.eta(), jet.phi()), xCenter, yCenter, zCenter);
0271
0272
0273 for (int x = x_scroll_min; x <= x_scroll_max; x++) {
0274 for (int y = y_scroll_min; y < y_scroll_max; y++) {
0275
0276
0277 topBandPt += getTowerEnergy(xCenter + x, yCenter + (5 + y));
0278
0279
0280 leftBandPt += getTowerEnergy(xCenter - (5 + y), yCenter + x);
0281
0282
0283 rightBandPt += getTowerEnergy(xCenter + (5 + y), yCenter + x);
0284
0285
0286 bottomBandPt += getTowerEnergy(xCenter + x, yCenter - (5 + y));
0287 }
0288 }
0289
0290 pileUpEnergy = topBandPt + leftBandPt + rightBandPt + bottomBandPt -
0291 std::max(topBandPt, std::max(leftBandPt, std::max(rightBandPt, bottomBandPt)));
0292
0293
0294 reco::Candidate::PolarLorentzVector ptVector;
0295
0296 float ptAfterPUSubtraction = jet.pt() - pileUpEnergy;
0297 ptVector.SetPt((ptAfterPUSubtraction > 0) ? ptAfterPUSubtraction : 0);
0298 ptVector.SetEta(jet.eta());
0299 ptVector.SetPhi(jet.phi());
0300
0301 jet.setP4(ptVector);
0302 jet.setPileup(pileUpEnergy);
0303 return;
0304 }
0305
0306 std::vector<std::tuple<int, int>> Phase1L1TJetProducer::findSeeds(float seedThreshold) const {
0307 int nBinsX = caloGrid_->GetNbinsX();
0308 int nBinsY = caloGrid_->GetNbinsY();
0309
0310 std::vector<std::tuple<int, int>> seeds;
0311
0312 int etaHalfSize = (int)jetIEtaSize_ / 2;
0313 int phiHalfSize = (int)jetIPhiSize_ / 2;
0314
0315
0316
0317
0318
0319
0320 for (int iPhi = 1; iPhi <= nBinsY; iPhi++) {
0321 for (int iEta = 1; iEta <= nBinsX; iEta++) {
0322 float centralPt = caloGrid_->GetBinContent(iEta, iPhi);
0323 if (centralPt < seedThreshold)
0324 continue;
0325 bool isLocalMaximum = true;
0326
0327
0328 for (int etaIndex = -etaHalfSize; etaIndex <= etaHalfSize; etaIndex++) {
0329 for (int phiIndex = -phiHalfSize; phiIndex <= phiHalfSize; phiIndex++) {
0330 if (trimmedGrid_) {
0331 if (trimTower(etaIndex, phiIndex))
0332 continue;
0333 }
0334
0335 if ((etaIndex == 0) && (phiIndex == 0))
0336 continue;
0337 if (phiIndex > 0) {
0338 if (phiIndex > -etaIndex) {
0339 isLocalMaximum = ((isLocalMaximum) && (centralPt > getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
0340 } else {
0341 isLocalMaximum = ((isLocalMaximum) && (centralPt >= getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
0342 }
0343 } else {
0344 if (phiIndex >= -etaIndex) {
0345 isLocalMaximum = ((isLocalMaximum) && (centralPt > getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
0346 } else {
0347 isLocalMaximum = ((isLocalMaximum) && (centralPt >= getTowerEnergy(iEta + etaIndex, iPhi + phiIndex)));
0348 }
0349 }
0350 }
0351 }
0352 if (isLocalMaximum) {
0353 seeds.emplace_back(iEta, iPhi);
0354 }
0355 }
0356 }
0357
0358 return seeds;
0359 }
0360
0361 reco::CaloJet Phase1L1TJetProducer::buildJetFromSeed(const std::tuple<int, int>& seed) const {
0362 int iEta = std::get<0>(seed);
0363 int iPhi = std::get<1>(seed);
0364
0365 int etaHalfSize = (int)jetIEtaSize_ / 2;
0366 int phiHalfSize = (int)jetIPhiSize_ / 2;
0367
0368 float ptSum = 0;
0369
0370 for (int etaIndex = -etaHalfSize; etaIndex <= etaHalfSize; etaIndex++) {
0371 for (int phiIndex = -phiHalfSize; phiIndex <= phiHalfSize; phiIndex++) {
0372 if (trimmedGrid_) {
0373 if (trimTower(etaIndex, phiIndex))
0374 continue;
0375 }
0376 ptSum += getTowerEnergy(iEta + etaIndex, iPhi + phiIndex);
0377 }
0378 }
0379
0380
0381 reco::Candidate::PolarLorentzVector ptVector;
0382 ptVector.SetPt(ptSum);
0383 ptVector.SetEta(caloGrid_->GetXaxis()->GetBinCenter(iEta));
0384 ptVector.SetPhi(caloGrid_->GetYaxis()->GetBinCenter(iPhi));
0385 reco::CaloJet jet;
0386 jet.setP4(ptVector);
0387 return jet;
0388 }
0389
0390 std::vector<reco::CaloJet> Phase1L1TJetProducer::buildJetsFromSeedsWithPUSubtraction(
0391 const std::vector<std::tuple<int, int>>& seeds, bool killZeroPt) const {
0392
0393
0394 std::vector<reco::CaloJet> jets;
0395 for (const auto& seed : seeds) {
0396 reco::CaloJet jet = buildJetFromSeed(seed);
0397 subtract9x9Pileup(jet);
0398
0399 if ((vetoZeroPt_) && (jet.pt() <= 0))
0400 continue;
0401 jets.push_back(jet);
0402 }
0403 return jets;
0404 }
0405
0406 std::vector<reco::CaloJet> Phase1L1TJetProducer::buildJetsFromSeeds(
0407 const std::vector<std::tuple<int, int>>& seeds) const {
0408
0409
0410 std::vector<reco::CaloJet> jets;
0411 for (const auto& seed : seeds) {
0412 reco::CaloJet jet = buildJetFromSeed(seed);
0413 jets.push_back(jet);
0414 }
0415 return jets;
0416 }
0417
0418 template <class Container>
0419 void Phase1L1TJetProducer::fillCaloGrid(TH2F& caloGrid,
0420 const Container& triggerPrimitives,
0421 const unsigned int regionIndex) {
0422
0423 for (const auto& primitiveIterator : triggerPrimitives) {
0424
0425 std::pair<float, float> digi_EtaPhi =
0426 getCandidateDigiEtaPhi(primitiveIterator->eta(), primitiveIterator->phi(), regionIndex);
0427
0428 caloGrid.Fill(static_cast<float>(digi_EtaPhi.first),
0429 static_cast<float>(digi_EtaPhi.second),
0430 static_cast<float>(primitiveIterator->pt()));
0431 }
0432 }
0433
0434 std::pair<float, float> Phase1L1TJetProducer::getCandidateDigiEtaPhi(const float eta,
0435 const float phi,
0436 const unsigned int regionIndex) const {
0437 std::pair<double, double> regionLowEdges = regionEtaPhiLowEdges(regionIndex);
0438
0439 int digitisedEta = floor((eta - regionLowEdges.second) / etalsb_);
0440 int digitisedPhi = floor((phi - regionLowEdges.first) / philsb_);
0441
0442
0443
0444
0445
0446 TAxis* etaAxis = caloGrid_->GetXaxis();
0447 std::pair<double, double> regionUpEdges = regionEtaPhiUpEdges(regionIndex);
0448 int digiEtaEdgeLastBinUp = floor((regionUpEdges.second - regionLowEdges.second) / etalsb_);
0449
0450
0451
0452 if (digitisedEta >= digiEtaEdgeLastBinUp) {
0453 digitisedEta = digiEtaEdgeLastBinUp - 1;
0454 } else {
0455 for (int i = 0; i < etaAxis->GetNbins(); ++i) {
0456 if (etaAxis->GetBinUpEdge(i) < regionLowEdges.second)
0457 continue;
0458 int digiEdgeBinUp = floor((etaAxis->GetBinUpEdge(i) - regionLowEdges.second) / etalsb_);
0459 if (digiEdgeBinUp == digitisedEta) {
0460 digitisedEta += 1;
0461 }
0462 }
0463 }
0464
0465
0466 TAxis* phiAxis = caloGrid_->GetYaxis();
0467 int digiPhiEdgeLastBinUp = floor((regionUpEdges.first - regionLowEdges.first) / philsb_);
0468 if (digitisedPhi >= digiPhiEdgeLastBinUp) {
0469 digitisedPhi = digiPhiEdgeLastBinUp - 1;
0470 } else {
0471 for (int i = 0; i < phiAxis->GetNbins(); ++i) {
0472 if (phiAxis->GetBinUpEdge(i) < regionLowEdges.first)
0473 continue;
0474 int digiEdgeBinUp = floor((phiAxis->GetBinUpEdge(i) - regionLowEdges.first) / philsb_);
0475 if (digiEdgeBinUp == digitisedPhi) {
0476 digitisedPhi += 1;
0477 }
0478 }
0479 }
0480
0481
0482 float floatDigitisedEta = (digitisedEta + 0.5) * etalsb_ + regionLowEdges.second;
0483 float floatDigitisedPhi = (digitisedPhi + 0.5) * philsb_ + regionLowEdges.first;
0484
0485 return std::pair<float, float>{floatDigitisedEta, floatDigitisedPhi};
0486 }
0487
0488 void Phase1L1TJetProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0489 edm::ParameterSetDescription desc;
0490 desc.add<edm::InputTag>("inputCollectionTag", edm::InputTag("l1pfCandidates", "Puppi"));
0491 desc.add<std::vector<double>>("etaBinning");
0492 desc.add<unsigned int>("nBinsPhi", 72);
0493 desc.add<double>("phiLow", -M_PI);
0494 desc.add<double>("phiUp", M_PI);
0495 desc.add<unsigned int>("jetIEtaSize", 7);
0496 desc.add<unsigned int>("jetIPhiSize", 7);
0497 desc.add<bool>("trimmedGrid", false);
0498 desc.add<double>("seedPtThreshold", 5);
0499 desc.add<double>("ptlsb", 0.25), desc.add<double>("philsb", 0.0043633231), desc.add<double>("etalsb", 0.0043633231),
0500 desc.add<bool>("puSubtraction", false);
0501 desc.add<string>("outputCollectionName", "UncalibratedPhase1L1TJetFromPfCandidates");
0502 desc.add<bool>("vetoZeroPt", true);
0503 desc.add<std::vector<double>>("etaRegions");
0504 desc.add<std::vector<double>>("phiRegions");
0505 desc.add<unsigned int>("maxInputsPerRegion", 18);
0506 desc.add<std::vector<double>>("sinPhi");
0507 desc.add<std::vector<double>>("cosPhi");
0508 desc.add<double>("metAbsEtaCut", 3);
0509 desc.add<double>("metHFAbsEtaCut", 5);
0510 descriptions.add("Phase1L1TJetProducer", desc);
0511 }
0512
0513 template <class Handle>
0514 std::vector<std::vector<edm::Ptr<reco::Candidate>>> Phase1L1TJetProducer::prepareInputsIntoRegions(
0515 const Handle triggerPrimitives) {
0516 std::vector<std::vector<reco::CandidatePtr>> inputsInRegions{etaRegionEdges_.size() * (phiRegionEdges_.size() - 1)};
0517
0518 for (unsigned int i = 0; i < triggerPrimitives->size(); ++i) {
0519 reco::CandidatePtr tp(triggerPrimitives, i);
0520
0521 if (tp->phi() < phiRegionEdges_.front() || tp->phi() >= phiRegionEdges_.back() ||
0522 tp->eta() < etaRegionEdges_.front() || tp->eta() >= etaRegionEdges_.back())
0523 continue;
0524
0525
0526 auto it_phi = phiRegionEdges_.begin();
0527 it_phi = std::upper_bound(phiRegionEdges_.begin(), phiRegionEdges_.end(), tp->phi()) - 1;
0528
0529
0530 auto it_eta = etaRegionEdges_.begin();
0531 it_eta = std::upper_bound(etaRegionEdges_.begin(), etaRegionEdges_.end(), tp->eta()) - 1;
0532
0533 if (it_phi != phiRegionEdges_.end() && it_eta != etaRegionEdges_.end()) {
0534 auto phiRegion = it_phi - phiRegionEdges_.begin();
0535 auto etaRegion = it_eta - etaRegionEdges_.begin();
0536 inputsInRegions[getRegionIndex(phiRegion, etaRegion)].emplace_back(tp);
0537 }
0538 }
0539
0540
0541 for (auto& inputs : inputsInRegions) {
0542 if (inputs.size() > maxInputsPerRegion_) {
0543 inputs.resize(maxInputsPerRegion_);
0544 }
0545 }
0546
0547 return inputsInRegions;
0548 }
0549
0550 unsigned int Phase1L1TJetProducer::getRegionIndex(const unsigned int phiRegion, const unsigned int etaRegion) const {
0551 return etaRegion * (phiRegionEdges_.size() - 1) + phiRegion;
0552 }
0553
0554 std::pair<double, double> Phase1L1TJetProducer::regionEtaPhiLowEdges(const unsigned int regionIndex) const {
0555 unsigned int phiRegion = regionIndex % (phiRegionEdges_.size() - 1);
0556 unsigned int etaRegion = (regionIndex - phiRegion) / (phiRegionEdges_.size() - 1);
0557 return std::pair<double, double>{phiRegionEdges_.at(phiRegion), etaRegionEdges_.at(etaRegion)};
0558 }
0559
0560 std::pair<double, double> Phase1L1TJetProducer::regionEtaPhiUpEdges(const unsigned int regionIndex) const {
0561 unsigned int phiRegion = regionIndex % (phiRegionEdges_.size() - 1);
0562 unsigned int etaRegion = (regionIndex - phiRegion) / (phiRegionEdges_.size() - 1);
0563 if (phiRegion == phiRegionEdges_.size() - 1) {
0564 return std::pair<double, double>{phiRegionEdges_.at(phiRegion), etaRegionEdges_.at(etaRegion + 1)};
0565 } else if (etaRegion == etaRegionEdges_.size() - 1) {
0566 return std::pair<double, double>{phiRegionEdges_.at(phiRegion + 1), etaRegionEdges_.at(etaRegion)};
0567 }
0568
0569 return std::pair<double, double>{phiRegionEdges_.at(phiRegion + 1), etaRegionEdges_.at(etaRegion + 1)};
0570 }
0571
0572 l1t::EtSum Phase1L1TJetProducer::computeMET(const double etaCut, l1t::EtSum::EtSumType sumType) const {
0573 const auto lowEtaBin = caloGrid_->GetXaxis()->FindBin(-1.0 * etaCut);
0574 const auto highEtaBin = caloGrid_->GetXaxis()->FindBin(etaCut) - 1;
0575 const auto phiProjection = caloGrid_->ProjectionY("temp", lowEtaBin, highEtaBin);
0576
0577
0578 int totalDigiPx{0};
0579 int totalDigiPy{0};
0580
0581 for (int i = 1; i < phiProjection->GetNbinsX() + 1; ++i) {
0582 double pt = phiProjection->GetBinContent(i);
0583 totalDigiPx += trunc(floor(pt / ptlsb_) * cosPhi_[i - 1]);
0584 totalDigiPy += trunc(floor(pt / ptlsb_) * sinPhi_[i - 1]);
0585 }
0586
0587 double lMET = floor(sqrt(totalDigiPx * totalDigiPx + totalDigiPy * totalDigiPy)) * ptlsb_;
0588
0589 math::PtEtaPhiMLorentzVector lMETVector(lMET, 0, acos(totalDigiPx / (lMET / ptlsb_)), 0);
0590 l1t::EtSum lMETSum(lMETVector, sumType, 0, 0, 0, 0);
0591 return lMETSum;
0592 }
0593
0594 bool Phase1L1TJetProducer::trimTower(const int etaIndex, const int phiIndex) const {
0595 int etaHalfSize = jetIEtaSize_ / 2;
0596 int phiHalfSize = jetIPhiSize_ / 2;
0597
0598 if (etaIndex == -etaHalfSize || etaIndex == etaHalfSize) {
0599 if (phiIndex <= -phiHalfSize + 1 || phiIndex >= phiHalfSize - 1) {
0600 return true;
0601 }
0602 } else if (etaIndex == -etaHalfSize + 1 || etaIndex == etaHalfSize - 1) {
0603 if (phiIndex == -phiHalfSize || phiIndex == phiHalfSize) {
0604 return true;
0605 }
0606 }
0607
0608 return false;
0609 }
0610 DEFINE_FWK_MODULE(Phase1L1TJetProducer);