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<L1TCaloStage2ParamsRcd>().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  // Sanity check scale factors exist
90  if ( useCalib && (ecalSF.size()==0 || hcalSF.size()==0 || hfSF.size()==0) ) {
91  edm::LogError("L1TCaloLayer1FetchLUTs") << "Layer 1 calibrations requested (useCalib = True) but there are missing scale factors in CaloParams! Please check conditions setup.";
92  return false;
93  }
94  // get energy scale to convert input from ECAL - this should be linear with LSB = 0.5 GeV
95  const double ecalLSB = 0.5;
96 
97  // get energy scale to convert input from HCAL
99  iSetup.get<CaloTPGRecord>().get(decoder);
100  if ( decoder.product() == nullptr ) {
101  edm::LogError("L1TCaloLayer1FetchLUTs") << "Missing CaloTPGTranscoder object! Check Global Tag, etc.";
102  return false;
103  }
104 
105  // TP compression scale is always phi symmetric
106  // We default to 3 since HF has no ieta=41 iphi=1,2
107  auto decodeHcalEt = [&decoder](int iEta, uint32_t compressedEt, uint32_t iPhi=3) -> double {
108  HcalTriggerPrimitiveSample sample(compressedEt);
109  HcalTrigTowerDetId id(iEta, iPhi);
110  if ( std::abs(iEta) >= 30 ) {
111  id.setVersion(1);
112  }
113  return decoder->hcaletValue(id, sample);
114  };
115 
116 
117  // Make ECal LUT
118  for(int absCaloEta = 1; absCaloEta <= 28; absCaloEta++) {
119  uint32_t iEta = absCaloEta - 1;
120  for(uint32_t fb = 0; fb < 2; fb++) {
121  for(uint32_t ecalInput = 0; ecalInput <= 0xFF; ecalInput++) {
122  uint32_t value = ecalInput;
123  if(useECALLUT) {
124  double linearizedECalInput = ecalInput*ecalLSB; // in GeV
125 
126  uint32_t etBin = 0;
127  for(; etBin < ecalScaleETBins.size(); etBin++) {
128  if(linearizedECalInput < ecalScaleETBins[etBin]) break;
129  }
130  if ( etBin >= ecalScaleETBins.size() ) etBin = ecalScaleETBins.size()-1;
131 
132  double calibratedECalInput = linearizedECalInput;
133  if (useCalib) calibratedECalInput *= ecalSF.at(etBin*28 + iEta);
134  if (useLSB) calibratedECalInput /= caloLSB;
135 
136  value = calibratedECalInput;
137  if(value > 0xFF) {
138  value = 0xFF;
139  }
140  }
141  if(value == 0) {
142  value = (1 << 11);
143  }
144  else {
145  uint32_t et_log2 = ((uint32_t) log2(value)) & 0x7;
146  value |= (et_log2 << 12);
147  }
148  value |= (fb << 10);
149  eLUT[iEta][fb][ecalInput] = value;
150  }
151  }
152  }
153 
154  // Make HCal LUT
155  for(int absCaloEta = 1; absCaloEta <= 28; absCaloEta++) {
156  uint32_t iEta = absCaloEta - 1;
157  for(uint32_t fb = 0; fb < 2; fb++) {
158  for(uint32_t hcalInput = 0; hcalInput <= 0xFF; hcalInput++) {
159  uint32_t value = hcalInput;
160  if(useHCALLUT) {
161  // hcaletValue defined in L137 of CalibCalorimetry/CaloTPG/src/CaloTPGTranscoderULUT.cc
162  double linearizedHcalInput = decodeHcalEt(absCaloEta, hcalInput); // in GeV
163  if(linearizedHcalInput != decodeHcalEt(-absCaloEta, hcalInput)) {
164  edm::LogError("L1TCaloLayer1FetchLUTs") << "L1TCaloLayer1FetchLUTs - hcal scale factors are different for positive and negative eta ! :(" << std::endl;
165  }
166 
167  uint32_t etBin = 0;
168  for(; etBin < hcalScaleETBins.size(); etBin++) {
169  if(linearizedHcalInput < hcalScaleETBins[etBin]) break;
170  }
171  if ( etBin >= hcalScaleETBins.size() ) etBin = hcalScaleETBins.size()-1;
172 
173  double calibratedHcalInput = linearizedHcalInput;
174  if(useCalib) calibratedHcalInput *= hcalSF.at(etBin*28 + iEta);
175  if(useLSB) calibratedHcalInput /= caloLSB;
176 
177  value = calibratedHcalInput;
178  if(value > 0xFF) {
179  value = 0xFF;
180  }
181  }
182  if(value == 0) {
183  value = (1 << 11);
184  }
185  else {
186  uint32_t et_log2 = ((uint32_t) log2(value)) & 0x7;
187  value |= (et_log2 << 12);
188  }
189  value |= (fb << 10);
190  hLUT[iEta][fb][hcalInput] = value;
191  }
192  }
193  }
194 
195  // Make HF LUT
196  for(uint32_t etaBin = 0; etaBin < 12; etaBin++) {
197  for(uint32_t etCode = 0; etCode < 256; etCode++) {
198  uint32_t value = etCode;
199  if(useHFLUT) {
200 
201  double linearizedHFInput = 0;
202  if (hfValid){
203  linearizedHFInput = decodeHcalEt(30+etaBin, value); // in GeV
204  if(linearizedHFInput != decodeHcalEt(-30-etaBin, value)) {
205  edm::LogError("L1TCaloLayer1FetchLUTs") << "L1TCaloLayer1FetchLUTs - HF scale factors are different for positive and negative eta ! :(" << std::endl;
206  }
207  }
208 
209  uint32_t etBin = 0;
210  for(; etBin < hfScaleETBins.size(); etBin++) {
211  if(linearizedHFInput < hfScaleETBins[etBin]) break;
212  }
213  if ( etBin >= hfScaleETBins.size() ) etBin = hfScaleETBins.size()-1;
214 
215  double calibratedHFInput = linearizedHFInput;
216  if(useCalib) calibratedHFInput *= hfSF.at(etBin*12+etaBin);
217  if(useLSB) calibratedHFInput /= caloLSB;
218 
219  value = calibratedHFInput;
220  if(value > 0xFF) {
221  value = 0xFF;
222  }
223  }
224  hfLUT[etaBin][etCode] = value;
225  }
226  }
227  return true;
228 }
229 /* 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)