Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-11-04 03:24:54

0001 /**
0002  * \class L1GetHistLimits
0003  *
0004  *
0005  * Description: use L1 scales to define histogram limits for L1 trigger objects.
0006  *
0007  * Implementation:
0008  *    <TODO: enter implementation details>
0009  *
0010  * \author: Vasile Mihai Ghete   - HEPHY Vienna
0011  *
0012  *
0013  */
0014 
0015 // this class header
0016 #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GetHistLimits.h"
0017 
0018 // system include files
0019 #include <iostream>
0020 #include <iomanip>
0021 #include <string>
0022 
0023 // user include files
0024 #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1PhiConversion.h"
0025 #include "DataFormats/Math/interface/normalizedPhi.h"
0026 
0027 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctEtMiss.h"
0028 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctEtTotal.h"
0029 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctEtHad.h"
0030 
0031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0032 
0033 L1GetHistLimits::Tokens::Tokens(edm::ConsumesCollector iC, bool doEtaOrPhi)
0034     : m_muPTScaleToken(iC.esConsumes<edm::Transition::BeginRun>()),
0035       m_etScaleToken(iC.esConsumes<edm::Transition::BeginRun>()),
0036       m_jetScaleToken(iC.esConsumes<edm::Transition::BeginRun>()),
0037       m_jetFinderParamsToken(iC.esConsumes<edm::Transition::BeginRun>()),
0038       m_htMissScaleToken(iC.esConsumes<edm::Transition::BeginRun>()),
0039       m_hfRingEtScaleToken(iC.esConsumes<edm::Transition::BeginRun>()) {
0040   if (doEtaOrPhi) {
0041     m_muScalesToken = iC.esConsumes<edm::Transition::BeginRun>();
0042     m_caloGeomESHToken = iC.esConsumes<edm::Transition::BeginRun>();
0043   }
0044 }
0045 
0046 // constructor
0047 L1GetHistLimits::L1GetHistLimits(const Tokens& tokens, const edm::EventSetup& evSetup)
0048     : m_tokens(tokens), m_evSetup(evSetup) {
0049   //
0050 }
0051 
0052 // destructor
0053 L1GetHistLimits::~L1GetHistLimits() {
0054   // empty
0055 }
0056 
0057 void L1GetHistLimits::getHistLimits(const L1GtObject& l1GtObject, const std::string& quantity) {
0058   m_l1HistLimits.nrBins = 0;
0059   m_l1HistLimits.lowerBinValue = 0;
0060   m_l1HistLimits.upperBinValue = 0;
0061   m_l1HistLimits.binThresholds.clear();
0062 
0063   // number of objects is independent of the object type
0064   // and hardcoded in the actual version
0065   if (quantity == "NrObjects") {
0066     m_l1HistLimits.nrBins = 15;
0067     m_l1HistLimits.lowerBinValue = -0.5;
0068     m_l1HistLimits.upperBinValue = 14.5;
0069 
0070     m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0071 
0072     for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0073       m_l1HistLimits.binThresholds[iBin] =
0074           m_l1HistLimits.lowerBinValue +
0075           iBin * (m_l1HistLimits.upperBinValue - m_l1HistLimits.lowerBinValue) / m_l1HistLimits.nrBins;
0076     }
0077 
0078     // set last bin upper edge
0079     m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0080 
0081     return;
0082   }
0083 
0084   switch (l1GtObject) {
0085     case Mu: {
0086       if (quantity == "PT") {
0087         const L1MuTriggerPtScale& muPtScale = m_evSetup.getData(m_tokens.m_muPTScaleToken);
0088 
0089         m_l1HistLimits.nrBins = muPtScale.getPtScale()->getNBins();
0090         m_l1HistLimits.lowerBinValue = muPtScale.getPtScale()->getScaleMin();
0091         m_l1HistLimits.upperBinValue = muPtScale.getPtScale()->getScaleMax();
0092 
0093         m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0094 
0095         for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0096           m_l1HistLimits.binThresholds[iBin] = muPtScale.getPtScale()->getValue(iBin);
0097         }
0098 
0099         // last limit for muon is set too high (10^6) - resize the last bin
0100 
0101         float lastBinSize = m_l1HistLimits.upperBinValue - m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins - 1];
0102 
0103         // limit the size of the last bin to maximum 200 GeV
0104         float maxLaxtBinsize = 200;
0105         if (lastBinSize >= maxLaxtBinsize) {
0106           m_l1HistLimits.upperBinValue = m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins - 1] +
0107                                          2. * (m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins - 1] -
0108                                                m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins - 2]);
0109           LogDebug("L1GetHistLimits") << "\n L1ExtraMuon: PT histogram"
0110                                       << "\nm_l1HistLimits.upperBinValue truncated to = "
0111                                       << m_l1HistLimits.upperBinValue << std::endl;
0112         }
0113 
0114         // set last bin upper edge
0115         m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0116 
0117       } else if (quantity == "eta" || quantity == "phi") {
0118         const L1MuTriggerScales& muScales = m_evSetup.getData(m_tokens.m_muScalesToken);
0119 
0120         if (quantity == "eta") {
0121           // eta scale defined for positive values - need to be symmetrized
0122           int histNrBinsHalf = muScales.getGMTEtaScale()->getNBins();
0123           m_l1HistLimits.lowerBinValue = muScales.getGMTEtaScale()->getScaleMin();
0124           m_l1HistLimits.upperBinValue = muScales.getGMTEtaScale()->getScaleMax();
0125 
0126           m_l1HistLimits.nrBins = 2 * histNrBinsHalf;
0127           m_l1HistLimits.lowerBinValue = -m_l1HistLimits.upperBinValue;
0128 
0129           m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0130 
0131           int iBin = 0;
0132           for (int j = histNrBinsHalf; j > 0; j--, iBin++) {
0133             m_l1HistLimits.binThresholds[iBin] = (-1) * muScales.getGMTEtaScale()->getValue(j);
0134           }
0135           for (int j = 0; j <= histNrBinsHalf; j++, iBin++) {
0136             m_l1HistLimits.binThresholds[iBin] = muScales.getGMTEtaScale()->getValue(j);
0137           }
0138 
0139           // set last bin upper edge
0140           m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0141 
0142         } else {
0143           m_l1HistLimits.nrBins = muScales.getPhiScale()->getNBins();
0144           m_l1HistLimits.lowerBinValue = rad2deg(muScales.getPhiScale()->getScaleMin());
0145           m_l1HistLimits.upperBinValue = rad2deg(muScales.getPhiScale()->getScaleMax());
0146 
0147           m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0148 
0149           for (int iBin = 0; iBin <= m_l1HistLimits.nrBins; iBin++) {
0150             m_l1HistLimits.binThresholds[iBin] = rad2deg(muScales.getPhiScale()->getValue(iBin));
0151           }
0152 
0153           // set last bin upper edge
0154           m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0155         }
0156       }
0157 
0158     } break;
0159     case NoIsoEG:
0160     case IsoEG: {
0161       // common scales for NoIsoEG and IsoEG
0162       if (quantity == "ET") {
0163         const L1CaloEtScale& emScale = m_evSetup.getData(m_tokens.m_etScaleToken);
0164 
0165         std::vector<double> emThresholds = emScale.getThresholds();
0166         m_l1HistLimits.nrBins = emThresholds.size();
0167         m_l1HistLimits.lowerBinValue = emThresholds.at(0);
0168 
0169         // FIXME high edge retrieval in the scale definition
0170         // now, last bin has the same width like the last but one
0171         m_l1HistLimits.upperBinValue =
0172             emThresholds[m_l1HistLimits.nrBins - 1] +
0173             (emThresholds[m_l1HistLimits.nrBins - 1] - emThresholds[m_l1HistLimits.nrBins - 2]);
0174 
0175         m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0176 
0177         for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0178           m_l1HistLimits.binThresholds[iBin] = static_cast<float>(emThresholds[iBin]);
0179         }
0180 
0181         // set last bin upper edge
0182         m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0183 
0184       } else if (quantity == "eta" || quantity == "phi") {
0185         const L1CaloGeometry* caloGeomScales = &m_evSetup.getData(m_tokens.m_caloGeomESHToken);
0186 
0187         if (quantity == "eta") {
0188           m_l1HistLimits.nrBins =
0189               2 * (caloGeomScales->numberGctCentralEtaBinsPerHalf() + caloGeomScales->numberGctForwardEtaBinsPerHalf());
0190           m_l1HistLimits.lowerBinValue = caloGeomScales->globalEtaBinLowEdge(0);
0191           m_l1HistLimits.upperBinValue = caloGeomScales->globalEtaBinHighEdge(m_l1HistLimits.nrBins - 1);
0192 
0193           m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0194 
0195           for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0196             m_l1HistLimits.binThresholds[iBin] = caloGeomScales->globalEtaBinLowEdge(iBin);
0197           }
0198 
0199           // set last bin upper edge
0200           m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0201 
0202         } else {
0203           m_l1HistLimits.nrBins = caloGeomScales->numberGctEmJetPhiBins();
0204           m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0205 
0206           for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0207             m_l1HistLimits.binThresholds[iBin] = rad2deg(caloGeomScales->emJetPhiBinLowEdge(iBin));
0208 
0209             // treat correctly the 10 deg anti-clockwise rotation
0210             if (rad2deg(caloGeomScales->emJetPhiBinHighEdge(iBin)) < m_l1HistLimits.binThresholds[iBin]) {
0211               m_l1HistLimits.binThresholds[iBin] = m_l1HistLimits.binThresholds[iBin] - 360.;
0212             }
0213           }
0214 
0215           m_l1HistLimits.lowerBinValue = m_l1HistLimits.binThresholds[0];
0216 
0217           // last bin upper limit
0218           m_l1HistLimits.upperBinValue = rad2deg(caloGeomScales->emJetPhiBinHighEdge(m_l1HistLimits.nrBins - 1));
0219 
0220           m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0221         }
0222       }
0223 
0224     } break;
0225     case CenJet:
0226     case ForJet:
0227     case TauJet: {
0228       // common scales for all jets
0229       if (quantity == "ET") {
0230         const L1CaloEtScale& jetScale = m_evSetup.getData(m_tokens.m_jetScaleToken);
0231 
0232         std::vector<double> jetThresholds = jetScale.getThresholds();
0233         m_l1HistLimits.nrBins = jetThresholds.size();
0234         m_l1HistLimits.lowerBinValue = jetThresholds.at(0);
0235 
0236         // FIXME high edge retrieval in the scale definition
0237         // now, last bin has the same width like the last but one
0238         m_l1HistLimits.upperBinValue =
0239             jetThresholds[m_l1HistLimits.nrBins - 1] +
0240             (jetThresholds[m_l1HistLimits.nrBins - 1] - jetThresholds[m_l1HistLimits.nrBins - 2]);
0241 
0242         m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0243 
0244         for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0245           m_l1HistLimits.binThresholds[iBin] = static_cast<float>(jetThresholds[iBin]);
0246         }
0247 
0248         // set last bin upper edge
0249         m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0250 
0251       } else if (quantity == "eta" || quantity == "phi") {
0252         const L1CaloGeometry* caloGeomScales = &m_evSetup.getData(m_tokens.m_caloGeomESHToken);
0253 
0254         if (quantity == "eta") {
0255           m_l1HistLimits.nrBins =
0256               2 * (caloGeomScales->numberGctCentralEtaBinsPerHalf() + caloGeomScales->numberGctForwardEtaBinsPerHalf());
0257           m_l1HistLimits.lowerBinValue = caloGeomScales->globalEtaBinLowEdge(0);
0258           m_l1HistLimits.upperBinValue = caloGeomScales->globalEtaBinHighEdge(m_l1HistLimits.nrBins - 1);
0259 
0260           m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0261 
0262           for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0263             m_l1HistLimits.binThresholds[iBin] = caloGeomScales->globalEtaBinLowEdge(iBin);
0264           }
0265 
0266           // set last bin upper edge
0267           m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0268 
0269         } else {
0270           m_l1HistLimits.nrBins = caloGeomScales->numberGctEmJetPhiBins();
0271           m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0272 
0273           for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0274             m_l1HistLimits.binThresholds[iBin] = rad2deg(caloGeomScales->emJetPhiBinLowEdge(iBin));
0275 
0276             // treat correctly the 10 deg anti-clockwise rotation
0277             if (rad2deg(caloGeomScales->emJetPhiBinHighEdge(iBin)) < m_l1HistLimits.binThresholds[iBin]) {
0278               m_l1HistLimits.binThresholds[iBin] = m_l1HistLimits.binThresholds[iBin] - 360.;
0279             }
0280           }
0281 
0282           m_l1HistLimits.lowerBinValue = m_l1HistLimits.binThresholds[0];
0283 
0284           // last bin upper limit
0285           m_l1HistLimits.upperBinValue = rad2deg(caloGeomScales->emJetPhiBinHighEdge(m_l1HistLimits.nrBins - 1));
0286 
0287           m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0288         }
0289       }
0290     } break;
0291     case ETM: {
0292       if (quantity == "ET") {
0293         const L1CaloEtScale& etMissScale = m_evSetup.getData(m_tokens.m_jetScaleToken);
0294 
0295         const double etSumLSB = etMissScale.linearLsb();
0296 
0297         m_l1HistLimits.nrBins = L1GctEtMiss::kEtMissMaxValue;
0298 
0299         m_l1HistLimits.lowerBinValue = 0;
0300         m_l1HistLimits.upperBinValue = (m_l1HistLimits.nrBins + 1) * etSumLSB;
0301 
0302         m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0303 
0304         for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0305           m_l1HistLimits.binThresholds[iBin] = iBin * etSumLSB;
0306         }
0307 
0308         // set last bin upper edge
0309         m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0310 
0311       } else if (quantity == "eta" || quantity == "phi") {
0312         const L1CaloGeometry* caloGeomScales = &m_evSetup.getData(m_tokens.m_caloGeomESHToken);
0313 
0314         if (quantity == "eta") {
0315           // do nothing, eta is not defined for ETM
0316 
0317         } else {
0318           m_l1HistLimits.nrBins = caloGeomScales->numberGctEtSumPhiBins();
0319           m_l1HistLimits.lowerBinValue = rad2deg(caloGeomScales->etSumPhiBinLowEdge(0));
0320           m_l1HistLimits.upperBinValue = rad2deg(caloGeomScales->etSumPhiBinHighEdge(m_l1HistLimits.nrBins - 1));
0321 
0322           m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0323 
0324           for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0325             m_l1HistLimits.binThresholds[iBin] = rad2deg(caloGeomScales->etSumPhiBinLowEdge(iBin));
0326           }
0327 
0328           // last bin upper limit
0329           m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0330         }
0331       }
0332 
0333     } break;
0334     case ETT: {
0335       if (quantity == "ET") {
0336         const L1CaloEtScale& etMissScale = m_evSetup.getData(m_tokens.m_jetScaleToken);
0337 
0338         const double etSumLSB = etMissScale.linearLsb();
0339 
0340         m_l1HistLimits.nrBins = L1GctEtTotal::kEtTotalMaxValue;
0341 
0342         m_l1HistLimits.lowerBinValue = 0;
0343         m_l1HistLimits.upperBinValue = (m_l1HistLimits.nrBins + 1) * etSumLSB;
0344 
0345         m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0346 
0347         for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0348           m_l1HistLimits.binThresholds[iBin] = iBin * etSumLSB;
0349         }
0350 
0351         // set last bin upper edge
0352         m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0353 
0354       } else if (quantity == "eta" || quantity == "phi") {
0355         // do nothing, eta and phi are not defined for ETT
0356       }
0357 
0358     } break;
0359     case HTT: {
0360       if (quantity == "ET") {
0361         const L1GctJetFinderParams& jetFinderParams = m_evSetup.getData(m_tokens.m_jetFinderParamsToken);
0362         double htSumLSB = jetFinderParams.getHtLsbGeV();
0363 
0364         m_l1HistLimits.nrBins = L1GctEtHad::kEtHadMaxValue;
0365 
0366         m_l1HistLimits.lowerBinValue = 0;
0367         m_l1HistLimits.upperBinValue = (m_l1HistLimits.nrBins + 1) * htSumLSB;
0368 
0369         m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0370 
0371         for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0372           m_l1HistLimits.binThresholds[iBin] = iBin * htSumLSB;
0373         }
0374 
0375         // set last bin upper edge
0376         m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0377 
0378       } else if (quantity == "eta" || quantity == "phi") {
0379         // do nothing, eta and phi are not defined for HTT
0380       }
0381     } break;
0382     case HTM: {
0383       if (quantity == "ET") {
0384         const L1CaloEtScale& htMissScale = m_evSetup.getData(m_tokens.m_htMissScaleToken);
0385 
0386         const std::vector<double>& htThresholds = htMissScale.getThresholds();
0387         m_l1HistLimits.nrBins = htThresholds.size();
0388         m_l1HistLimits.lowerBinValue = htThresholds[0];
0389 
0390         // FIXME high edge retrieval in the scale definition
0391         // now, last bin has the same width like the last but one
0392         m_l1HistLimits.upperBinValue =
0393             htThresholds[m_l1HistLimits.nrBins - 1] +
0394             (htThresholds[m_l1HistLimits.nrBins - 1] - htThresholds[m_l1HistLimits.nrBins - 2]);
0395 
0396         m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0397 
0398         for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0399           m_l1HistLimits.binThresholds[iBin] = static_cast<float>(htThresholds[iBin]);
0400         }
0401 
0402         // set last bin upper edge
0403         m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0404 
0405       } else if (quantity == "eta" || quantity == "phi") {
0406         const L1CaloGeometry* caloGeomScales = &m_evSetup.getData(m_tokens.m_caloGeomESHToken);
0407 
0408         if (quantity == "eta") {
0409           // do nothing, eta is not defined for HTM
0410 
0411         } else {
0412           m_l1HistLimits.nrBins = caloGeomScales->numberGctHtSumPhiBins();
0413           m_l1HistLimits.lowerBinValue = rad2deg(caloGeomScales->htSumPhiBinLowEdge(0));
0414           m_l1HistLimits.upperBinValue = rad2deg(caloGeomScales->htSumPhiBinHighEdge(m_l1HistLimits.nrBins - 1));
0415 
0416           m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0417 
0418           for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0419             m_l1HistLimits.binThresholds[iBin] = rad2deg(caloGeomScales->htSumPhiBinLowEdge(iBin));
0420           }
0421 
0422           // last bin upper limit
0423           m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0424         }
0425       }
0426     } break;
0427     case JetCounts: {
0428     } break;
0429     case HfBitCounts: {
0430       // there are no scales for HfBitCounts, so one implements a fixed scale
0431       // use same values as GCT for 3 bits
0432       const unsigned int R3BINS = 8;
0433       const float R3MIN = -0.5;
0434       const float R3MAX = 7.5;
0435 
0436       m_l1HistLimits.nrBins = R3BINS;
0437       m_l1HistLimits.lowerBinValue = R3MIN;
0438       m_l1HistLimits.upperBinValue = R3MAX;
0439 
0440       m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0441 
0442       for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0443         m_l1HistLimits.binThresholds[iBin] = R3MIN + iBin * (R3MAX - R3MIN) / R3BINS;
0444       }
0445 
0446       // last bin upper limit
0447       m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0448 
0449     } break;
0450     case HfRingEtSums: {
0451       if (quantity == "ET") {
0452         const L1CaloEtScale& hfRingEtScale = m_evSetup.getData(m_tokens.m_hfRingEtScaleToken);
0453 
0454         const std::vector<double>& hfRingEtThresholds = hfRingEtScale.getThresholds();
0455         m_l1HistLimits.nrBins = hfRingEtThresholds.size();
0456         m_l1HistLimits.lowerBinValue = hfRingEtThresholds[0];
0457 
0458         // FIXME high edge retrieval in the scale definition
0459         // now, last bin has the same width like the last but one
0460         m_l1HistLimits.upperBinValue =
0461             hfRingEtThresholds[m_l1HistLimits.nrBins - 1] +
0462             (hfRingEtThresholds[m_l1HistLimits.nrBins - 1] - hfRingEtThresholds[m_l1HistLimits.nrBins - 2]);
0463 
0464         m_l1HistLimits.binThresholds.resize(m_l1HistLimits.nrBins + 1);
0465 
0466         for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0467           m_l1HistLimits.binThresholds[iBin] = static_cast<float>(hfRingEtThresholds[iBin]);
0468         }
0469 
0470         // set last bin upper edge
0471         m_l1HistLimits.binThresholds[m_l1HistLimits.nrBins] = m_l1HistLimits.upperBinValue;
0472 
0473       } else if (quantity == "eta" || quantity == "phi") {
0474         // do nothing, eta and phi are not defined for HfRingEtSums
0475       }
0476     } break;
0477     case TechTrig:
0478     case Castor:
0479     case BPTX:
0480     default: {
0481       // do nothing, for these cases ET/PT, eta and phi are not defined
0482 
0483     } break;
0484   }
0485 }
0486 
0487 const L1GetHistLimits::L1HistLimits& L1GetHistLimits::l1HistLimits(const L1GtObject& l1GtObject,
0488                                                                    const std::string& quantity) {
0489   getHistLimits(l1GtObject, quantity);
0490 
0491   if (edm::isDebugEnabled()) {
0492     LogDebug("L1GetHistLimits") << "\n Histogram limits for L1GtObject " << l1GtObject << " and quantity " << quantity
0493                                 << "\n  Number of bins:           " << m_l1HistLimits.nrBins
0494                                 << "\n  Lower limit of first bin: " << m_l1HistLimits.lowerBinValue
0495                                 << "\n  Upper limit of last bin:  " << m_l1HistLimits.upperBinValue << std::endl;
0496 
0497     int binThreshSize = static_cast<int>(m_l1HistLimits.binThresholds.size());
0498 
0499     if (binThreshSize != (m_l1HistLimits.nrBins + 1)) {
0500       LogTrace("L1GetHistLimits") << "\n Warning: inconsistent nrBins and binThresholds size"
0501                                   << "\n   Number of bins nrBins = " << m_l1HistLimits.nrBins
0502                                   << "\n   binThresholds size =    " << binThreshSize
0503                                   << "\n Please fix the L1GetLimits class.\n\n"
0504                                   << std::endl;
0505     }
0506 
0507     for (int iBin = 0; iBin < binThreshSize; ++iBin) {
0508       LogTrace("L1GetHistLimits") << " Bin " << std::right << std::setw(5) << iBin << ":  "
0509                                   << m_l1HistLimits.binThresholds[iBin] << std::endl;
0510     }
0511   }
0512 
0513   return m_l1HistLimits;
0514 }
0515 
0516 const L1GetHistLimits::L1HistLimits& L1GetHistLimits::l1HistLimits(const L1GtObject& l1GtObject,
0517                                                                    const std::string& quantity,
0518                                                                    const double histMinValue,
0519                                                                    const double histMaxValue) {
0520   getHistLimits(l1GtObject, quantity);
0521 
0522   bool foundLowerBinValue = false;
0523   bool foundUpperBinValue = false;
0524 
0525   for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0526     if (m_l1HistLimits.binThresholds[iBin] <= histMinValue) {
0527       m_l1HistLimits.lowerBinValue = m_l1HistLimits.binThresholds[iBin];
0528       foundLowerBinValue = true;
0529       break;
0530     }
0531   }
0532 
0533   for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0534     if (m_l1HistLimits.binThresholds[iBin] > histMaxValue) {
0535       m_l1HistLimits.upperBinValue = m_l1HistLimits.binThresholds[iBin];
0536       foundUpperBinValue = true;
0537       break;
0538     }
0539   }
0540 
0541   if (foundLowerBinValue && foundUpperBinValue) {
0542     int countBins = -1;
0543     std::vector<float> binThresh;
0544     binThresh.reserve(m_l1HistLimits.binThresholds.size());
0545 
0546     for (int iBin = 0; iBin < m_l1HistLimits.nrBins; ++iBin) {
0547       if ((m_l1HistLimits.binThresholds[iBin] >= histMinValue) && m_l1HistLimits.binThresholds[iBin] < histMaxValue) {
0548         m_l1HistLimits.upperBinValue = m_l1HistLimits.binThresholds[iBin];
0549 
0550         countBins++;
0551         binThresh.push_back(m_l1HistLimits.binThresholds[iBin]);
0552       }
0553     }
0554 
0555     m_l1HistLimits.nrBins = countBins;
0556     m_l1HistLimits.binThresholds.clear();
0557     m_l1HistLimits.binThresholds = binThresh;
0558 
0559     // FIXME last bin untested.
0560 
0561   } else {
0562     m_l1HistLimits.nrBins = 0;
0563     m_l1HistLimits.lowerBinValue = 0;
0564     m_l1HistLimits.upperBinValue = 0;
0565     m_l1HistLimits.binThresholds.clear();
0566 
0567     LogDebug("L1GetHistLimits") << "\n Histogram limits for L1GtObject" << l1GtObject << " and quantity " << quantity
0568                                 << " within the required range [" << histMinValue << ", " << histMaxValue
0569                                 << "] not found."
0570                                 << "\n The range is not included in the original histogram range." << std::endl;
0571 
0572     return m_l1HistLimits;
0573   }
0574 
0575   if (edm::isDebugEnabled()) {
0576     LogDebug("L1GetHistLimits") << "\n Histogram limits for L1GtObject" << l1GtObject << " and quantity " << quantity
0577                                 << "\n  Number of bins:           " << m_l1HistLimits.nrBins
0578                                 << "\n  Lower limit of first bin: " << m_l1HistLimits.lowerBinValue
0579                                 << "\n  Upper limit of last bin:  " << m_l1HistLimits.upperBinValue << std::endl;
0580 
0581     int binThreshSize = static_cast<int>(m_l1HistLimits.binThresholds.size());
0582 
0583     if (binThreshSize != (m_l1HistLimits.nrBins + 1)) {
0584       LogTrace("L1GetHistLimits") << "\n Warning: inconsistent nrBins and binThresholds size"
0585                                   << "\n   Number of bins nrBins = " << m_l1HistLimits.nrBins
0586                                   << "\n   binThresholds size =    " << binThreshSize
0587                                   << "\n Please fix the L1GetLimits class.\n\n"
0588                                   << std::endl;
0589     }
0590 
0591     for (int iBin = 0; iBin < binThreshSize; ++iBin) {
0592       LogTrace("L1GetHistLimits") << " Bin " << std::right << std::setw(5) << iBin << ":  "
0593                                   << m_l1HistLimits.binThresholds[iBin] << std::endl;
0594     }
0595   }
0596 
0597   return m_l1HistLimits;
0598 }
0599 
0600 const int L1GetHistLimits::l1HistNrBins(const L1GtObject& l1GtObject, const std::string& quantity) {
0601   getHistLimits(l1GtObject, quantity);
0602   return m_l1HistLimits.nrBins;
0603 }
0604 
0605 const double L1GetHistLimits::l1HistLowerBinValue(const L1GtObject& l1GtObject, const std::string& quantity) {
0606   getHistLimits(l1GtObject, quantity);
0607   return m_l1HistLimits.lowerBinValue;
0608 }
0609 
0610 const double L1GetHistLimits::l1HistUpperBinValue(const L1GtObject& l1GtObject, const std::string& quantity) {
0611   getHistLimits(l1GtObject, quantity);
0612   return m_l1HistLimits.upperBinValue;
0613 }
0614 
0615 const std::vector<float>& L1GetHistLimits::l1HistBinThresholds(const L1GtObject& l1GtObject,
0616                                                                const std::string& quantity) {
0617   getHistLimits(l1GtObject, quantity);
0618   return m_l1HistLimits.binThresholds;
0619 }