CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
L1TCaloLayer1FetchLUTs.cc
Go to the documentation of this file.
1 // This function fetches Layer1 ECAL and HCAL LUTs from CMSSW configuration
2 // It is provided as a global helper function outside of class structure
3 // so that it can be shared by L1CaloLayer1 and L1CaloLayer1Spy
4 
5 #include <vector>
6 
10 
14 
20 
23 
24 #include "L1TCaloLayer1FetchLUTs.hh"
25 #include "UCTLogging.hh"
26 
28  std::vector< std::vector< std::vector < uint32_t > > > &eLUT,
29  std::vector< std::vector< std::vector < uint32_t > > > &hLUT,
30  std::vector< std::vector< uint32_t > > &hfLUT,
31  bool useLSB,
32  bool useCalib,
33  bool useECALLUT,
34  bool useHCALLUT,
35  bool useHFLUT) {
36 
37  int hfValid = 1;
39  iSetup.get<CaloGeometryRecord>().get(pG);
40  if (! pG->use1x1()){
41  edm::LogError("L1TCaloLayer1FetchLUTs") << "Using Stage2-Layer1 but HCAL Geometry has use1x1 = 0! HF will be suppressed. Check Global Tag, etc.";
42  hfValid = 0;
43  }
44 
45  // CaloParams contains all persisted parameters for Layer 1
46  edm::ESHandle<l1t::CaloParams> paramsHandle;
47  iSetup.get<L1TCaloParamsRcd>().get(paramsHandle);
48  if ( paramsHandle.product() == nullptr ) {
49  edm::LogError("L1TCaloLayer1FetchLUTs") << "Missing CaloParams object! Check Global Tag, etc.";
50  return false;
51  }
52  l1t::CaloParamsHelper caloParams(*paramsHandle.product());
53 
54  // Calo Trigger Layer1 output LSB Real ET value
55  double caloLSB = caloParams.towerLsbSum();
56  if ( caloLSB != 0.5 ) {
57  // Lots of things expect this, better give fair warning if not
58  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloLSB (caloParams.towerLsbSum()) != 0.5, actually = " << caloLSB;
59  }
60 
61  // ECal/HCal scale factors will be a x*28 array:
62  // 28 eta scale factors (1-28)
63  // x = size of Real ET Bins vector
64  // So, index = etBin*28+ieta
65  auto ecalScaleETBins = caloParams.layer1ECalScaleETBins();
66  auto ecalSF = caloParams.layer1ECalScaleFactors();
67  if ( ecalSF.size() != ecalScaleETBins.size()*28 ) {
68  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1ECalScaleFactors().size() != caloParams.layer1ECalScaleETBins().size()*28 !!";
69  return false;
70  }
71  auto hcalScaleETBins = caloParams.layer1HCalScaleETBins();
72  auto hcalSF = caloParams.layer1HCalScaleFactors();
73  if ( hcalSF.size() != hcalScaleETBins.size()*28 ) {
74  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1HCalScaleFactors().size() != caloParams.layer1HCalScaleETBins().size()*28 !!";
75  return false;
76  }
77 
78  // HF 1x1 scale factors will be a x*12 array:
79  // 12 eta scale factors (30-41)
80  // x = size of Real ET Bins vector
81  // So, index = etBin*12+ietaHF
82  auto hfScaleETBins = caloParams.layer1HFScaleETBins();
83  auto hfSF = caloParams.layer1HFScaleFactors();
84  if ( hfSF.size() != hfScaleETBins.size()*12 ) {
85  edm::LogError("L1TCaloLayer1FetchLUTs") << "caloParams.layer1HFScaleFactors().size() != caloParams.layer1HFScaleETBins().size()*12 !!";
86  return false;
87  }
88 
89  // get energy scale to convert input from ECAL - this should be linear with LSB = 0.5 GeV
90  const double ecalLSB = 0.5;
91 
92  // get energy scale to convert input from HCAL
94  iSetup.get<CaloTPGRecord>().get(decoder);
95  if ( decoder.product() == nullptr ) {
96  edm::LogError("L1TCaloLayer1FetchLUTs") << "Missing CaloTPGTranscoder object! Check Global Tag, etc.";
97  return false;
98  }
99 
100  // TP compression scale is always phi symmetric
101  // We default to 3 since HF has no ieta=41 iphi=1,2
102  auto decodeHcalEt = [&decoder](uint32_t iEta, uint32_t compressedEt, uint32_t iPhi=3) -> double {
103  HcalTriggerPrimitiveSample sample(compressedEt);
104  HcalTrigTowerDetId id(iEta, iPhi);
105  if ( abs(iEta) >= 30 ) {
106  id.setVersion(1);
107  }
108  return decoder->hcaletValue(id, sample);
109  };
110 
111 
112  // Make ECal LUT
113  for(int absCaloEta = 1; absCaloEta <= 28; absCaloEta++) {
114  uint32_t iEta = absCaloEta - 1;
115  for(uint32_t fb = 0; fb < 2; fb++) {
116  for(uint32_t ecalInput = 0; ecalInput <= 0xFF; ecalInput++) {
117  uint32_t value = ecalInput;
118  if(useECALLUT) {
119  double linearizedECalInput = ecalInput*ecalLSB; // in GeV
120 
121  uint32_t etBin = 0;
122  for(; etBin < ecalScaleETBins.size(); etBin++) {
123  if(linearizedECalInput < ecalScaleETBins[etBin]) break;
124  }
125  if ( etBin >= ecalScaleETBins.size() ) etBin = ecalScaleETBins.size()-1;
126 
127  double calibratedECalInput = linearizedECalInput;
128  if (useCalib) calibratedECalInput *= ecalSF.at(etBin*28 + iEta);
129  if (useLSB) calibratedECalInput /= caloLSB;
130 
131  value = calibratedECalInput;
132  if(value > 0xFF) {
133  value = 0xFF;
134  }
135  }
136  if(value == 0) {
137  value = (1 << 11);
138  }
139  else {
140  uint32_t et_log2 = ((uint32_t) log2(value)) & 0x7;
141  value |= (et_log2 << 12);
142  }
143  value |= (fb << 10);
144  eLUT[iEta][fb][ecalInput] = value;
145  }
146  }
147  }
148 
149  // Make HCal LUT
150  for(int absCaloEta = 1; absCaloEta <= 28; absCaloEta++) {
151  uint32_t iEta = absCaloEta - 1;
152  for(uint32_t fb = 0; fb < 2; fb++) {
153  for(uint32_t hcalInput = 0; hcalInput <= 0xFF; hcalInput++) {
154  uint32_t value = hcalInput;
155  if(useHCALLUT) {
156  // hcaletValue defined in L137 of CalibCalorimetry/CaloTPG/src/CaloTPGTranscoderULUT.cc
157  double linearizedHcalInput = decodeHcalEt(absCaloEta, hcalInput); // in GeV
158  if(linearizedHcalInput != decodeHcalEt(-absCaloEta, hcalInput)) {
159  edm::LogError("L1TCaloLayer1FetchLUTs") << "L1TCaloLayer1FetchLUTs - hcal scale factors are different for positive and negative eta ! :(" << std::endl;
160  }
161 
162  uint32_t etBin = 0;
163  for(; etBin < hcalScaleETBins.size(); etBin++) {
164  if(linearizedHcalInput < hcalScaleETBins[etBin]) break;
165  }
166  if ( etBin >= hcalScaleETBins.size() ) etBin = hcalScaleETBins.size()-1;
167 
168  double calibratedHcalInput = linearizedHcalInput;
169  if(useCalib) calibratedHcalInput *= hcalSF.at(etBin*28 + iEta);
170  if(useLSB) calibratedHcalInput /= caloLSB;
171 
172  value = calibratedHcalInput;
173  if(value > 0xFF) {
174  value = 0xFF;
175  }
176  }
177  if(value == 0) {
178  value = (1 << 11);
179  }
180  else {
181  uint32_t et_log2 = ((uint32_t) log2(value)) & 0x7;
182  value |= (et_log2 << 12);
183  }
184  value |= (fb << 10);
185  hLUT[iEta][fb][hcalInput] = value;
186  }
187  }
188  }
189 
190  // Make HF LUT
191  for(uint32_t etaBin = 0; etaBin < 12; etaBin++) {
192  for(uint32_t etCode = 0; etCode < 256; etCode++) {
193  uint32_t value = etCode;
194  if(useHFLUT) {
195 
196  double linearizedHFInput = 0;
197  if (hfValid){
198  linearizedHFInput = decodeHcalEt(30+etaBin, value); // in GeV
199  if(linearizedHFInput != decodeHcalEt(-30-etaBin, value)) {
200  edm::LogError("L1TCaloLayer1FetchLUTs") << "L1TCaloLayer1FetchLUTs - HF scale factors are different for positive and negative eta ! :(" << std::endl;
201  }
202  }
203 
204  uint32_t etBin = 0;
205  for(; etBin < hfScaleETBins.size(); etBin++) {
206  if(linearizedHFInput < hfScaleETBins[etBin]) break;
207  }
208  if ( etBin >= hfScaleETBins.size() ) etBin = hfScaleETBins.size()-1;
209 
210  double calibratedHFInput = linearizedHFInput;
211  if(useCalib) calibratedHFInput *= hfSF.at(etBin*12+etaBin);
212  if(useLSB) calibratedHFInput /= caloLSB;
213 
214  value = calibratedHFInput;
215  if(value > 0xFF) {
216  value = 0xFF;
217  }
218  }
219  hfLUT[etaBin][etCode] = value;
220  }
221  }
222  return true;
223 }
224 /* vim: set ts=8 sw=2 tw=0 et :*/
#define nullptr
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const T & get() const
Definition: EventSetup.h:56
T const * product() const
Definition: ESHandle.h:86
bool L1TCaloLayer1FetchLUTs(const edm::EventSetup &iSetup, std::vector< std::vector< std::vector< uint32_t > > > &eLUT, std::vector< std::vector< std::vector< uint32_t > > > &hLUT, std::vector< std::vector< uint32_t > > &hfLUT, bool useLSB, bool useCalib, bool useECALLUT, bool useHCALLUT, bool useHFLUT)