CMS 3D CMS Logo

HcaluLUTTPGCoder.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <fstream>
3 #include <cmath>
4 #include <string>
28 
29 const float HcaluLUTTPGCoder::lsb_=1./16;
30 
34 
35 
36 HcaluLUTTPGCoder::HcaluLUTTPGCoder(const HcalTopology* top) : topo_(top), LUTGenerationMode_(true), bitToMask_(0) {
52  size_t nluts= (size_t)(sizeHB_+sizeHE_+sizeHF_+1);
53  inputLUT_ = std::vector<HcaluLUTTPGCoder::Lut>(nluts);
54  gain_ = std::vector<float>(nluts, 0.);
55  ped_ = std::vector<float>(nluts, 0.);
56 }
57 
58 void HcaluLUTTPGCoder::compress(const IntegerCaloSamples& ics, const std::vector<bool>& featureBits, HcalTriggerPrimitiveDigi& tp) const {
59  throw cms::Exception("PROBLEM: This method should never be invoked!");
60 }
61 
63 }
64 
65 int HcaluLUTTPGCoder::getLUTId(HcalSubdetector id, int ieta, int iphi, int depth) const {
66  int retval(0);
67  if (id == HcalBarrel) {
68  retval = (depth-1)+maxDepthHB_*(iphi-1);
69  if (ieta>0) retval+=maxDepthHB_*nFi_*(ieta-firstHBEta_);
70  else retval+=maxDepthHB_*nFi_*(ieta+lastHBEta_+nHBEta_);
71  } else if (id == HcalEndcap) {
72  retval = sizeHB_;
73  retval+= (depth-1)+maxDepthHE_*(iphi-1);
74  if (ieta>0) retval+=maxDepthHE_*nFi_*(ieta-firstHEEta_);
75  else retval+=maxDepthHE_*nFi_*(ieta+lastHEEta_+nHEEta_);
76  } else if (id == HcalForward) {
77  retval = sizeHB_+sizeHE_;
78  retval+= (depth-1)+maxDepthHF_*(iphi-1);
79  if (ieta>0) retval+=maxDepthHF_*nFi_*(ieta-firstHFEta_);
80  else retval+=maxDepthHF_*nFi_*(ieta+lastHFEta_+nHFEta_);
81  }
82  return retval;
83 }
84 
85 int HcaluLUTTPGCoder::getLUTId(uint32_t rawid) const {
86  HcalDetId detid(rawid);
87  return getLUTId(detid.subdet(), detid.ieta(), detid.iphi(), detid.depth());
88 }
89 
90 int HcaluLUTTPGCoder::getLUTId(const HcalDetId& detid) const {
91  return getLUTId(detid.subdet(), detid.ieta(), detid.iphi(), detid.depth());
92 }
93 
94 void HcaluLUTTPGCoder::update(const char* filename, bool appendMSB) {
95 
96  std::ifstream file(filename, std::ios::in);
97  assert(file.is_open());
98 
99  std::vector<HcalSubdetector> subdet;
101 
102  // Drop first (comment) line
103  std::getline(file, buffer);
104  std::getline(file, buffer);
105 
106  unsigned int index = buffer.find("H", 0);
107  while (index < buffer.length()){
108  std::string subdetStr = buffer.substr(index, 2);
109  if (subdetStr == "HB") subdet.push_back(HcalBarrel);
110  else if (subdetStr == "HE") subdet.push_back(HcalEndcap);
111  else if (subdetStr == "HF") subdet.push_back(HcalForward);
112  //TODO Check subdet
113  //else exception
114  index += 2;
115  index = buffer.find("H", index);
116  }
117 
118  // Get upper/lower ranges for ieta/iphi/depth
119  size_t nCol = subdet.size();
120  assert(nCol > 0);
121 
122  std::vector<int> ietaU;
123  std::vector<int> ietaL;
124  std::vector<int> iphiU;
125  std::vector<int> iphiL;
126  std::vector<int> depU;
127  std::vector<int> depL;
128  std::vector< Lut > lutFromFile(nCol);
129  LutElement lutValue;
130 
131  for (size_t i=0; i<nCol; ++i) {
132  int ieta;
133  file >> ieta;
134  ietaL.push_back(ieta);
135  }
136 
137  for (size_t i=0; i<nCol; ++i) {
138  int ieta;
139  file >> ieta;
140  ietaU.push_back(ieta);
141  }
142 
143  for (size_t i=0; i<nCol; ++i) {
144  int iphi;
145  file >> iphi;
146  iphiL.push_back(iphi);
147  }
148 
149  for (size_t i=0; i<nCol; ++i) {
150  int iphi;
151  file >> iphi;
152  iphiU.push_back(iphi);
153  }
154 
155  for (size_t i=0; i<nCol; ++i) {
156  int dep;
157  file >> dep;
158  depL.push_back(dep);
159  }
160 
161  for (size_t i=0; i<nCol; ++i) {
162  int dep;
163  file >> dep;
164  depU.push_back(dep);
165  }
166 
167  // Read Lut Entry
168  for (size_t i=0; file >> lutValue; i = (i+1) % nCol){
169  lutFromFile[i].push_back(lutValue);
170  }
171 
172  // Check lut size
173  for (size_t i=0; i<nCol; ++i) assert(lutFromFile[i].size() == INPUT_LUT_SIZE);
174 
175  for (size_t i=0; i<nCol; ++i){
176  for (int ieta = ietaL[i]; ieta <= ietaU[i]; ++ieta){
177  for (int iphi = iphiL[i]; iphi <= iphiU[i]; ++iphi){
178  for (int depth = depL[i]; depth <= depU[i]; ++depth){
179 
180  HcalDetId id(subdet[i], ieta, iphi, depth);
181  if (!topo_->valid(id)) continue;
182 
183  int lutId = getLUTId(id);
184  for (size_t adc = 0; adc < INPUT_LUT_SIZE; ++adc){
185  if (appendMSB){
186  // Append FG bit LUT to MSB
187  // MSB = Most Significant Bit = bit 10
188  // Overwrite bit 10
189  LutElement msb = (lutFromFile[i][adc] != 0 ? QIE8_LUT_MSB : 0);
190  inputLUT_[lutId][adc] = (msb | (inputLUT_[lutId][adc] & QIE8_LUT_BITMASK));
191  }
192  else inputLUT_[lutId][adc] = lutFromFile[i][adc];
193  }// for adc
194  }// for depth
195  }// for iphi
196  }// for ieta
197  }// for nCol
198 }
199 
201  LutXml * _xml = new LutXml(filename);
202  _xml->create_lut_map();
204  for (int ieta = -HcalDetId::kHcalEtaMask2;
205  ieta <= HcalDetId::kHcalEtaMask2; ++ieta) {
206  for (int iphi = 0; iphi <= HcalDetId::kHcalPhiMask2; ++iphi) {
207  for (int depth = 1; depth < HcalDetId::kHcalDepthMask2; ++depth) {
208  for (int isub=0; isub<3; ++isub) {
209  HcalDetId detid(subdet[isub], ieta, iphi, depth);
210  if (!topo_->valid(detid)) continue;
211  int id = getLUTId(subdet[isub], ieta, iphi, depth);
212  std::vector<unsigned int>* lut = _xml->getLutFast(detid);
213  if (lut==nullptr) throw cms::Exception("PROBLEM: No inputLUT_ in xml file for ") << detid << std::endl;
214  if (lut->size()!=INPUT_LUT_SIZE) throw cms::Exception ("PROBLEM: Wrong inputLUT_ size in xml file for ") << detid << std::endl;
215  for (unsigned int i=0; i<INPUT_LUT_SIZE; ++i) inputLUT_[id][i] = (LutElement)lut->at(i);
216  }
217  }
218  }
219  }
220  delete _xml;
222 }
223 
224 void HcaluLUTTPGCoder::update(const HcalDbService& conditions) {
225 
227  const HcalLutMetadata *metadata = conditions.getHcalLutMetadata();
228  assert(metadata !=nullptr);
229  float nominalgain_ = metadata->getNominalGain();
230 
231  std::map<int, float> cosh_ieta;
232  for (int i = firstHFEta_; i <= lastHFEta_; ++i){
233  std::pair<double,double> etas = topo_->etaRange(HcalForward,i);
234  double eta1 = etas.first;
235  double eta2 = etas.second;
236  cosh_ieta[i] = cosh((eta1 + eta2)/2.);
237  }
238 
239  for (const auto& id: metadata->getAllChannels()) {
240 
241  if (not (id.det() == DetId::Hcal and topo_->valid(id))) continue;
242 
243  HcalDetId cell(id);
244  HcalSubdetector subdet = cell.subdet();
245 
246  if (subdet != HcalBarrel and subdet != HcalEndcap and subdet != HcalForward) continue;
247 
248  const HcalQIECoder* channelCoder = conditions.getHcalCoder (cell);
249  const HcalQIEShape* shape = conditions.getHcalShape(cell);
250  HcalCoderDb coder (*channelCoder, *shape);
251  const HcalLutMetadatum *meta = metadata->getValues(cell);
252 
253  unsigned int mipMax = 0;
254  unsigned int mipMin = 0;
255 
258  topo_->dddConstants()->isPlan1(cell)) {
259  const HcalTPChannelParameter *channelParameters = conditions.getHcalTPChannelParameter(cell);
260  mipMax = channelParameters->getFGBitInfo() >> 16;
261  mipMin = channelParameters->getFGBitInfo() & 0xFFFF;
262  }
263 
264  int lutId = getLUTId(cell);
265  Lut &lut=inputLUT_[lutId];
266  float ped = 0;
267  float gain = 0;
268  uint32_t status = 0;
269 
270  if (LUTGenerationMode_){
271  const HcalCalibrations& calibrations = conditions.getHcalCalibrations(cell);
272  for (auto capId : {0,1,2,3}){
273  ped += calibrations.pedestal(capId);
274  gain += calibrations.LUTrespcorrgain(capId);
275  }
276  ped /= 4.0;
277  gain /= 4.0;
278 
279  //Get Channel Quality
280  const HcalChannelStatus* channelStatus = conditions.getHcalChannelStatus(cell);
281  status = channelStatus->getValue();
282 
283  } else {
284  const HcalL1TriggerObject* myL1TObj = conditions.getHcalL1TriggerObject(cell);
285  ped = myL1TObj->getPedestal();
286  gain = myL1TObj->getRespGain();
287  status = myL1TObj->getFlag();
288  } // LUTGenerationMode_
289 
290  ped_[lutId] = ped;
291  gain_[lutId] = gain;
292  bool isMasked = ( (status & bitToMask_) > 0 );
293  float rcalib = meta->getRCalib();
294 
295  auto adc2fC = [channelCoder, shape](unsigned int adc){
296  float fC = 0;
297  for (auto capId : {0,1,2,3}) fC += channelCoder->charge(*shape, adc, capId);
298  return fC/4;
299  };
300 
301  int QIEtype =conditions.getHcalQIEType(cell)->getValue();
302 
303  const size_t SIZE = QIEtype==0 ? INPUT_LUT_SIZE : UPGRADE_LUT_SIZE;
304  const int MASK = QIEtype==0 ? QIE8_LUT_BITMASK :
305  QIEtype==1 ? QIE10_LUT_BITMASK : QIE11_LUT_BITMASK;
306 
307  lut.resize(SIZE, 0);
308 
309  // Input LUT for HB/HE/HF
310  if (subdet == HcalBarrel || subdet == HcalEndcap){
311 
312  int granularity = meta->getLutGranularity();
313 
314  for (unsigned int adc = 0; adc < SIZE; ++adc) {
315  if (isMasked) lut[adc] = 0;
316  else {
317  lut[adc] = (LutElement) std::min(std::max(0, int((adc2fC(adc) - ped) * gain * rcalib / nominalgain_ / granularity)), MASK);
318  if(QIEtype==2){
319  if (adc >= mipMin and adc < mipMax) lut[adc] |= QIE11_LUT_MSB0;
320  else if (adc >= mipMax) lut[adc] |= QIE11_LUT_MSB1;
321  }
322  }
323  }
324  }
325  else if (subdet == HcalForward){
326  for (unsigned int adc = 0; adc < SIZE; ++adc) {
327  if (isMasked) lut[adc] = 0;
328  else {
329  lut[adc] = std::min(std::max(0,int((adc2fC(adc) - ped) * gain * rcalib / lsb_ / cosh_ieta[cell.ietaAbs()] )), MASK);
331  }
332  }
333  }
334  }
335 }
336 
338  int lutId = getLUTId(df.id());
339  const Lut& lut = inputLUT_.at(lutId);
340  for (int i=0; i<df.size(); i++){
341  ics[i] = (lut.at(df[i].adc()) & QIE8_LUT_BITMASK);
342  }
343 }
344 
346  int lutId = getLUTId(df.id());
347  const Lut& lut = inputLUT_.at(lutId);
348  for (int i=0; i<df.size(); i++){
349  ics[i] = (lut.at(df[i].adc()) & QIE8_LUT_BITMASK);
350  }
351 }
352 
354  int lutId = getLUTId(HcalDetId(df.id()));
355  const Lut& lut = inputLUT_.at(lutId);
356  for (int i=0; i<df.samples(); i++){
357  ics[i] = (lut.at(df[i].adc()) & QIE10_LUT_BITMASK);
358  }
359 }
360 
362  int lutId = getLUTId(HcalDetId(df.id()));
363  const Lut& lut = inputLUT_.at(lutId);
364  for (int i=0; i<df.samples(); i++){
365  ics[i] = (lut.at(df[i].adc()) & QIE11_LUT_BITMASK);
366  }
367 }
368 
370  int lutId = getLUTId(id);
371  return ((inputLUT_.at(lutId)).at(sample.adc()) & QIE8_LUT_BITMASK);
372 }
373 
375  int lutId = getLUTId(id);
376  return ped_.at(lutId);
377 }
378 
380  int lutId = getLUTId(id);
381  return gain_.at(lutId);
382 }
383 
384 std::vector<unsigned short> HcaluLUTTPGCoder::getLinearizationLUT(HcalDetId id) const{
385  int lutId = getLUTId(id);
386  return inputLUT_.at(lutId);
387 }
388 
389 void HcaluLUTTPGCoder::lookupMSB(const HBHEDataFrame& df, std::vector<bool>& msb) const{
390  msb.resize(df.size());
391  for (int i=0; i<df.size(); ++i)
392  msb[i] = getMSB(df.id(), df.sample(i).adc());
393 }
394 
395 bool HcaluLUTTPGCoder::getMSB(const HcalDetId& id, int adc) const{
396  int lutId = getLUTId(id);
397  const Lut& lut = inputLUT_.at(lutId);
398  return (lut.at(adc) & QIE8_LUT_MSB);
399 }
400 
401 void HcaluLUTTPGCoder::lookupMSB(const QIE10DataFrame& df, std::vector<bool>& msb) const{
402  msb.resize(df.samples());
403  int lutId = getLUTId(HcalDetId(df.id()));
404  const Lut& lut = inputLUT_.at(lutId);
405  for (int i = 0; i < df.samples(); ++i) {
406  msb[i] = lut.at(df[i].adc()) & QIE10_LUT_MSB;
407  }
408 }
409 
410 void
411 HcaluLUTTPGCoder::lookupMSB(const QIE11DataFrame& df, std::vector<std::bitset<2>>& msb) const
412 {
413  int lutId = getLUTId(HcalDetId(df.id()));
414  const Lut& lut = inputLUT_.at(lutId);
415  for (int i = 0; i < df.samples(); ++i) {
416  msb[i][0] = lut.at(df[i].adc()) & QIE11_LUT_MSB0;
417  msb[i][1] = lut.at(df[i].adc()) & QIE11_LUT_MSB1;
418  }
419 }
int adc(sample_type sample)
get the ADC sample (12 bits)
int samples() const
total number of samples in the digi
size
Write out results.
uint32_t getFlag() const
int firstHFRing() const
Definition: HcalTopology.h:91
float getPedestal() const
static const int nFi_
void adc2Linear(const HBHEDataFrame &df, IntegerCaloSamples &ics) const override
const HcalDDDRecConstants * dddConstants() const
Definition: HcalTopology.h:161
int getValue() const
Definition: HcalQIEType.h:20
Definition: LutXml.h:27
HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:49
const HcalTPChannelParameter * getHcalTPChannelParameter(const HcalGenericDetId &fId) const
bool valid(const DetId &id) const override
static const int QIE11_LUT_MSB1
static const int QIE11_LUT_BITMASK
const HcalChannelStatus * getHcalChannelStatus(const HcalGenericDetId &fId) const
float getLUTGain(HcalDetId id) const override
int adc() const
get the ADC sample
Definition: HcalQIESample.h:22
int size() const
total number of samples in the digi
Definition: HBHEDataFrame.h:26
int create_lut_map(void)
Definition: LutXml.cc:375
const HcalTopology * topo_
int firstHBRing() const
Definition: HcalTopology.h:87
edm::DataFrame::id_type id() const
int lastHBRing() const
Definition: HcalTopology.h:88
static const int QIE11_LUT_MSB0
static const float lsb_
double pedestal(int fCapId) const
get pedestal for capid=0..3
const Item * getValues(DetId fId, bool throwOnFail=true) const
static const int QIE8_LUT_BITMASK
uint8_t getLutGranularity() const
HcalTopologyMode::TriggerMode triggerMode() const
Definition: HcalTopology.h:32
unsigned short LutElement
void update(const HcalDbService &conditions)
static const int kHcalDepthMask2
Definition: HcalDetId.h:26
void updateXML(const char *filename)
static const int QIE10_LUT_MSB
static const size_t UPGRADE_LUT_SIZE
int depth() const
get the tower depth
Definition: HcalDetId.cc:129
void lookupMSB(const HBHEDataFrame &df, std::vector< bool > &msb) const
int getLUTId(HcalSubdetector id, int ieta, int iphi, int depth) const
float getRespGain() const
int terminate(void)
std::vector< DetId > getAllChannels() const
int maxDepth(HcalSubdetector subdet) const
float getNominalGain() const
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
float getRCalib() const
const HcalL1TriggerObject * getHcalL1TriggerObject(const HcalGenericDetId &fId) const
int ieta() const
get the cell ieta
Definition: HcalDetId.h:56
int lastHFRing() const
Definition: HcalTopology.h:92
edm::DataFrame::id_type id() const
HcalSubdetector
Definition: HcalAssistant.h:31
const HcalLutMetadata * getHcalLutMetadata() const
unsigned int FG_HF_threshold_
T min(T a, T b)
Definition: MathUtil.h:58
static const int QIE8_LUT_MSB
static const int QIE10_LUT_BITMASK
int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.cc:119
const HcalQIEType * getHcalQIEType(const HcalGenericDetId &fId) const
double const adc2fC[256]
Definition: Constants.h:272
int iphi() const
get the cell iphi
Definition: HcalDetId.cc:124
static const int kHcalPhiMask2
Definition: HcalDetId.h:16
double LUTrespcorrgain(int fCapId) const
get LUT corrected and response corrected gain for capid=0..3
std::vector< float > ped_
std::vector< float > gain_
int size() const
total number of samples in the digi
Definition: HFDataFrame.h:26
const HcalQIESample & sample(int i) const
access a sample
Definition: HBHEDataFrame.h:39
~HcaluLUTTPGCoder() override
int firstHERing() const
Definition: HcalTopology.h:89
const HcalQIECoder * getHcalCoder(const HcalGenericDetId &fId) const
const HcalQIEShape * getHcalShape(const HcalGenericDetId &fId) const
std::vector< unsigned int > * getLutFast(uint32_t det_id)
Definition: LutXml.cc:88
static const size_t INPUT_LUT_SIZE
std::pair< double, double > etaRange(HcalSubdetector subdet, int ieta) const
HcaluLUTTPGCoder(const HcalTopology *topo)
bool getMSB(const HcalDetId &id, int adc) const
float getLUTPedestal(HcalDetId id) const override
static const int kHcalEtaMask2
Definition: HcalDetId.h:20
uint32_t getFGBitInfo() const
get FG bit information
const HcalDetId & id() const
Definition: HBHEDataFrame.h:22
bool isPlan1(const HcalDetId &id) const
const HcalDetId & id() const
Definition: HFDataFrame.h:22
uint32_t getValue() const
const HcalCalibrations & getHcalCalibrations(const HcalGenericDetId &fId) const
int samples() const
total number of samples in the digi
static XMLProcessor * getInstance()
Definition: XMLProcessor.h:145
int lastHERing() const
Definition: HcalTopology.h:90
Definition: Lut.h:32
void compress(const IntegerCaloSamples &ics, const std::vector< bool > &featureBits, HcalTriggerPrimitiveDigi &tp) const override
std::vector< unsigned short > getLinearizationLUT(HcalDetId id) const override
Get the full linearization LUT (128 elements). Default implementation just uses adc2Linear to get all...
std::vector< Lut > inputLUT_
float charge(const HcalQIEShape &fShape, unsigned fAdc, unsigned fCapId) const
ADC [0..127] + capid [0..3] -> fC conversion.
Definition: HcalQIECoder.cc:22