CMS 3D CMS Logo

Functions
L1TCaloLayer1FetchLUTs.cc File Reference
#include <vector>
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "L1Trigger/L1TCalorimeter/interface/CaloParamsHelper.h"
#include "CondFormats/L1TObjects/interface/CaloParams.h"
#include "CondFormats/DataRecord/interface/L1TCaloParamsRcd.h"
#include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h"
#include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h"
#include "DataFormats/HcalDetId/interface/HcalTrigTowerDetId.h"
#include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveSample.h"
#include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveDigi.h"
#include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
#include "Geometry/Records/interface/CaloGeometryRecord.h"
#include "L1TCaloLayer1FetchLUTs.hh"
#include "UCTLogging.hh"

Go to the source code of this file.

Functions

bool L1TCaloLayer1FetchLUTs (const edm::EventSetup &iSetup, std::vector< std::array< std::array< std::array< uint32_t, nEtBins >, nCalSideBins >, nCalEtaBins > > &eLUT, std::vector< std::array< std::array< std::array< uint32_t, nEtBins >, nCalSideBins >, nCalEtaBins > > &hLUT, std::vector< std::array< std::array< uint32_t, nEtBins >, nHfEtaBins > > &hfLUT, std::vector< unsigned int > &ePhiMap, std::vector< unsigned int > &hPhiMap, std::vector< unsigned int > &hfPhiMap, bool useLSB, bool useCalib, bool useECALLUT, bool useHCALLUT, bool useHFLUT, int fwVersion)
 

Function Documentation

bool L1TCaloLayer1FetchLUTs ( const edm::EventSetup iSetup,
std::vector< std::array< std::array< std::array< uint32_t, nEtBins >, nCalSideBins >, nCalEtaBins > > &  eLUT,
std::vector< std::array< std::array< std::array< uint32_t, nEtBins >, nCalSideBins >, nCalEtaBins > > &  hLUT,
std::vector< std::array< std::array< uint32_t, nEtBins >, nHfEtaBins > > &  hfLUT,
std::vector< unsigned int > &  ePhiMap,
std::vector< unsigned int > &  hPhiMap,
std::vector< unsigned int > &  hfPhiMap,
bool  useLSB,
bool  useCalib,
bool  useECALLUT,
bool  useHCALLUT,
bool  useHFLUT,
int  fwVersion 
)

Definition at line 29 of file L1TCaloLayer1FetchLUTs.cc.

References funct::abs(), SoftLeptonByDistance_cfi::distance, conversionPostprocessing_cfi::etaBin, conversionPostprocessing_cfi::etBin, benchmark_cfg::fb, spr::find(), edm::EventSetup::get(), CaloTPGTranscoder::hcaletValue(), triggerObjects_cff::id, nullptr, conversionPostprocessing_cfi::phiBin, edm::ESHandle< T >::product(), simplePhotonAnalyzer_cfi::sample, l1t::CaloParamsHelper::towerLsbSum(), HcalTrigTowerGeometry::use1x1(), and relativeConstraints::value.

Referenced by L1TCaloLayer1::beginRun().

41  {
42 
43  int hfValid = 1;
45  iSetup.get<CaloGeometryRecord>().get(pG);
46  if (! pG->use1x1()){
47  edm::LogError("L1TCaloLayer1FetchLUTs") << "Using Stage2-Layer1 but HCAL Geometry has use1x1 = 0! HF will be suppressed. Check Global Tag, etc.";
48  hfValid = 0;
49  }
50 
51  // CaloParams contains all persisted parameters for Layer 1
52  edm::ESHandle<l1t::CaloParams> paramsHandle;
53  iSetup.get<L1TCaloParamsRcd>().get(paramsHandle);
54  if ( paramsHandle.product() == nullptr ) {
55  edm::LogError("L1TCaloLayer1FetchLUTs") << "Missing CaloParams object! Check Global Tag, etc.";
56  return false;
57  }
58  l1t::CaloParamsHelper caloParams(*paramsHandle.product());
59 
60  // Calo Trigger Layer1 output LSB Real ET value
61  double caloLSB = caloParams.towerLsbSum();
62  if ( caloLSB != 0.5 ) {
63  // Lots of things expect this, better give fair warning if not
64  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloLSB (caloParams.towerLsbSum()) != 0.5, actually = " << caloLSB;
65  }
66 
67  // ECal/HCal scale factors will be a x*y*28 array:
68  // ieta = 28 eta scale factors (1 .. 28)
69  // etBin = size of Real ET Bins vector
70  // phiBin = max(Real Phi Bins vector)
71  // So, index = phiBin*etBin*28+etBin*28+ieta
72  auto ecalScaleETBins = caloParams.layer1ECalScaleETBins();
73  auto ecalScalePhiBins = caloParams.layer1ECalScalePhiBins();
74  if ( ecalScalePhiBins.empty() ) {
75  // Backwards-compatibility (no phi binning)
76  ecalScalePhiBins.resize(36, 0);
77  }
78  else if ( ecalScalePhiBins.size() % 36 != 0 ) {
79  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1ECalScaleETBins().size() is not multiple of 36 !!";
80  return false;
81  }
82  size_t numEcalPhiBins = (*std::max_element(ecalScalePhiBins.begin(), ecalScalePhiBins.end())) + 1;
83  auto ecalSF = caloParams.layer1ECalScaleFactors();
84  if ( ecalSF.size() != ecalScaleETBins.size()*numEcalPhiBins*28 ) {
85  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1ECalScaleFactors().size() != caloParams.layer1ECalScaleETBins().size()*numEcalPhiBins*28 !!";
86  return false;
87  }
88  auto hcalScaleETBins = caloParams.layer1HCalScaleETBins();
89  auto hcalScalePhiBins = caloParams.layer1HCalScalePhiBins();
90  if ( hcalScalePhiBins.empty() ) {
91  hcalScalePhiBins.resize(36, 0);
92  }
93  else if ( hcalScalePhiBins.size() % 36 != 0 ) {
94  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1HCalScaleETBins().size() is not multiple of 36 !!";
95  return false;
96  }
97  size_t numHcalPhiBins = (*std::max_element(hcalScalePhiBins.begin(), hcalScalePhiBins.end())) + 1;
98  auto hcalSF = caloParams.layer1HCalScaleFactors();
99  if ( hcalSF.size() != hcalScaleETBins.size()*numHcalPhiBins*28 ) {
100  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1HCalScaleFactors().size() != caloParams.layer1HCalScaleETBins().size()*numHcalPhiBins*28 !!";
101  return false;
102  }
103 
104  // HF 1x1 scale factors will be a x*y*12 array:
105  // ieta = 12 eta scale factors (30 .. 41)
106  // etBin = size of Real ET Bins vector
107  // phiBin = max(Real Phi Bins vector)
108  // So, index = phiBin*etBin*12+etBin*12+ieta
109  auto hfScaleETBins = caloParams.layer1HFScaleETBins();
110  auto hfScalePhiBins = caloParams.layer1HFScalePhiBins();
111  if ( hfScalePhiBins.empty() ) {
112  hfScalePhiBins.resize(36, 0);
113  }
114  else if ( hfScalePhiBins.size() % 36 != 0 ) {
115  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1HFScaleETBins().size() is not multiple of 36 !!";
116  return false;
117  }
118  size_t numHFPhiBins = (*std::max_element(hfScalePhiBins.begin(), hfScalePhiBins.end())) + 1;
119  auto hfSF = caloParams.layer1HFScaleFactors();
120  if ( hfSF.size() != hfScaleETBins.size()*numHFPhiBins*12 ) {
121  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1HFScaleFactors().size() != caloParams.layer1HFScaleETBins().size()*numHFPhiBins*12 !!";
122  return false;
123  }
124 
125  // Sanity check scale factors exist
126  if ( useCalib && (ecalSF.empty() || hcalSF.empty() || hfSF.empty()) ) {
127  edm::LogError("L1TCaloLayer1FetchLUTs") << "Layer 1 calibrations requested (useCalib = True) but there are missing scale factors in CaloParams! Please check conditions setup.";
128  return false;
129  }
130  // get energy scale to convert input from ECAL - this should be linear with LSB = 0.5 GeV
131  const double ecalLSB = 0.5;
132 
133  // get energy scale to convert input from HCAL
135  iSetup.get<CaloTPGRecord>().get(decoder);
136  if ( decoder.product() == nullptr ) {
137  edm::LogError("L1TCaloLayer1FetchLUTs") << "Missing CaloTPGTranscoder object! Check Global Tag, etc.";
138  return false;
139  }
140 
141  // TP compression scale is always phi symmetric
142  // We default to 3 since HF has no ieta=41 iphi=1,2
143  auto decodeHcalEt = [&decoder](int iEta, uint32_t compressedEt, uint32_t iPhi=3) -> double {
144  HcalTriggerPrimitiveSample sample(compressedEt);
145  HcalTrigTowerDetId id(iEta, iPhi);
146  if ( std::abs(iEta) >= 30 ) {
147  id.setVersion(1);
148  }
149  return decoder->hcaletValue(id, sample);
150  };
151 
152 
153  // Make ECal LUT
154  for(uint32_t phiBin=0; phiBin<numEcalPhiBins; phiBin++) {
155  std::array< std::array< std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> phiLUT;
156  eLUT.push_back(phiLUT);
157  for(uint32_t etaBin = 0; etaBin < nCalEtaBins; etaBin++) {
158  for(uint32_t fb = 0; fb < nCalSideBins; fb++) {
159  for(uint32_t ecalInput = 0; ecalInput <= 0xFF; ecalInput++) {
160  uint32_t value = ecalInput;
161  if(useECALLUT) {
162  double linearizedECalInput = ecalInput*ecalLSB; // in GeV
163 
164  uint32_t etBin = 0;
165  for(; etBin < ecalScaleETBins.size(); etBin++) {
166  if(linearizedECalInput < ecalScaleETBins[etBin]) break;
167  }
168  if ( etBin >= ecalScaleETBins.size() ) etBin = ecalScaleETBins.size()-1;
169 
170  double calibratedECalInput = linearizedECalInput;
171  if (useCalib) calibratedECalInput *= ecalSF.at(phiBin*ecalScaleETBins.size()*28 + etBin*28 + etaBin);
172  if (useLSB) calibratedECalInput /= caloLSB;
173 
174  value = calibratedECalInput;
175  if ( fwVersion > 2 ) {
176  // Saturate if either decompressed value is over 127.5 GeV or input saturated
177  // (meaningless for ecal, since ecalLSB == caloLSB)
178  if(value > 0xFF || ecalInput == 0xFF) {
179  value = 0xFF;
180  }
181  }
182  else {
183  if(value > 0xFF) {
184  value = 0xFF;
185  }
186  }
187  }
188  if(value == 0) {
189  value = (1 << 11);
190  }
191  else {
192  uint32_t et_log2 = ((uint32_t) log2(value)) & 0x7;
193  value |= (et_log2 << 12);
194  }
195  value |= (fb << 10);
196  eLUT[phiBin][etaBin][fb][ecalInput] = value;
197  }
198  }
199  }
200  }
201 
202  // Make HCal LUT
203  for(uint32_t phiBin=0; phiBin<numHcalPhiBins; phiBin++) {
204  std::array< std::array< std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> phiLUT;
205  hLUT.push_back(phiLUT);
206  for(uint32_t etaBin = 0; etaBin < nCalEtaBins; etaBin++) {
207  int caloEta = etaBin+1;
208  int iPhi = 3;
209  auto pos = std::find(hcalScalePhiBins.begin(), hcalScalePhiBins.end(), phiBin);
210  if (pos!=hcalScalePhiBins.end()) {
211  // grab an iPhi bin
212  auto index = std::distance(hcalScalePhiBins.begin(),pos);
213  if (index<18) {
214  caloEta*=-1;
215  iPhi = index*4+1;
216  }
217  else {
218  iPhi = (index-18)*4+1;
219  }
220  }
221  for(uint32_t fb = 0; fb < nCalSideBins; fb++) {
222  for(uint32_t hcalInput = 0; hcalInput <= 0xFF; hcalInput++) {
223  uint32_t value = hcalInput;
224  if(useHCALLUT) {
225  // hcaletValue defined in L137 of CalibCalorimetry/CaloTPG/src/CaloTPGTranscoderULUT.cc
226  double linearizedHcalInput = decodeHcalEt(caloEta, hcalInput, iPhi); // in GeV
227 
228  uint32_t etBin = 0;
229  for(; etBin < hcalScaleETBins.size(); etBin++) {
230  if(linearizedHcalInput < hcalScaleETBins[etBin]) break;
231  }
232  if ( etBin >= hcalScaleETBins.size() ) etBin = hcalScaleETBins.size()-1;
233 
234  double calibratedHcalInput = linearizedHcalInput;
235  if(useCalib) calibratedHcalInput *= hcalSF.at(phiBin*hcalScaleETBins.size()*28 + etBin*28 + etaBin);
236  if(useLSB) calibratedHcalInput /= caloLSB;
237 
238  value = calibratedHcalInput;
239  if ( fwVersion > 2 ) {
240  // Saturate if either decompressed value is over 127.5 GeV or input saturated
241  if(value > 0xFF || hcalInput == 0xFF) {
242  value = 0xFF;
243  }
244  }
245  else {
246  if(value > 0xFF) {
247  value = 0xFF;
248  }
249  }
250  }
251  if(value == 0) {
252  value = (1 << 11);
253  }
254  else {
255  uint32_t et_log2 = ((uint32_t) log2(value)) & 0x7;
256  value |= (et_log2 << 12);
257  }
258  value |= (fb << 10);
259  hLUT[phiBin][etaBin][fb][hcalInput] = value;
260  }
261  }
262  }
263  }
264 
265  // Make HF LUT
266  for(uint32_t phiBin=0; phiBin<numHFPhiBins; phiBin++) {
267  std::array< std::array<uint32_t, nEtBins>, nHfEtaBins> phiLUT;
268  hfLUT.push_back(phiLUT);
269  for(uint32_t etaBin = 0; etaBin < nHfEtaBins; etaBin++) {
270  int caloEta = etaBin+30;
271  int iPhi = 3;
272  auto pos = std::find(hfScalePhiBins.begin(), hfScalePhiBins.end(), phiBin);
273  if (pos!=hfScalePhiBins.end()) {
274  auto index = std::distance(hfScalePhiBins.begin(),pos);
275  if (index<18) {
276  caloEta*=-1;
277  iPhi = index*4-1;
278  }
279  else {
280  iPhi = (index-18)*4-1;
281  }
282  if (iPhi < 0) iPhi = 71;
283  }
284  for(uint32_t etCode = 0; etCode < nEtBins; etCode++) {
285  uint32_t value = etCode;
286  if(useHFLUT) {
287 
288  double linearizedHFInput = 0;
289  if (hfValid){
290  linearizedHFInput = decodeHcalEt(caloEta, value, iPhi); // in GeV
291  }
292 
293  uint32_t etBin = 0;
294  for(; etBin < hfScaleETBins.size(); etBin++) {
295  if(linearizedHFInput < hfScaleETBins[etBin]) break;
296  }
297  if ( etBin >= hfScaleETBins.size() ) etBin = hfScaleETBins.size()-1;
298 
299  double calibratedHFInput = linearizedHFInput;
300  if(useCalib) calibratedHFInput *= hfSF.at(phiBin*hfScalePhiBins.size()*12+etBin*12+etaBin);
301  if(useLSB) calibratedHFInput /= caloLSB;
302 
303  if ( fwVersion > 2 ) {
304  uint32_t absCaloEta = std::abs(caloEta);
305  if(absCaloEta > 29 && absCaloEta < 40) {
306  // Divide by two (since two duplicate towers are sent)
307  calibratedHFInput *= 0.5;
308  }
309  else if(absCaloEta == 40 || absCaloEta == 41) {
310  // Divide by four
311  calibratedHFInput *= 0.25;
312  }
313  value = calibratedHFInput;
314  // Saturate if either decompressed value is over 127.5 GeV or input saturated
315  if(value >= 0xFF || etCode == 0xFF) {
316  value = 0x1FD;
317  }
318  }
319  else {
320  value = calibratedHFInput;
321  if(value > 0xFF) {
322  value = 0xFF;
323  }
324  }
325  }
326  hfLUT[phiBin][etaBin][etCode] = value;
327  }
328  }
329  }
330 
331  // plus/minus, 18 CTP7, 4 iPhi each
332  for(uint32_t isPos=0; isPos<2; isPos++) {
333  for(uint32_t iPhi=1; iPhi<=72; iPhi++) {
334  uint32_t card = floor((iPhi+1)/4);
335  if (card>17) card-=18;
336  ePhiMap[isPos*72+iPhi-1] = ecalScalePhiBins[isPos*18+card];
337  hPhiMap[isPos*72+iPhi-1] = hcalScalePhiBins[isPos*18+card];
338  hfPhiMap[isPos*72+iPhi-1] = hfScalePhiBins[isPos*18+card];
339  }
340  }
341 
342  return true;
343 }
#define nullptr
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Definition: value.py:1
const T & get() const
Definition: EventSetup.h:59
double towerLsbSum() const
virtual double hcaletValue(const int &ieta, const int &iphi, const int &version, const int &compressedValue) const =0
T const * product() const
Definition: ESHandle.h:86