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>
31 
32 const float HcaluLUTTPGCoder::lsb_=1./16;
33 
37 
38 
39 HcaluLUTTPGCoder::HcaluLUTTPGCoder(const HcalTopology* top) : topo_(top), LUTGenerationMode_(true), bitToMask_(0), allLinear_(false), linearLSB_QIE8_(1.), linearLSB_QIE11_(1.) {
55  size_t nluts= (size_t)(sizeHB_+sizeHE_+sizeHF_+1);
56  inputLUT_ = std::vector<HcaluLUTTPGCoder::Lut>(nluts);
57  gain_ = std::vector<float>(nluts, 0.);
58  ped_ = std::vector<float>(nluts, 0.);
59 }
60 
61 void HcaluLUTTPGCoder::compress(const IntegerCaloSamples& ics, const std::vector<bool>& featureBits, HcalTriggerPrimitiveDigi& tp) const {
62  throw cms::Exception("PROBLEM: This method should never be invoked!");
63 }
64 
66 }
67 
68 int HcaluLUTTPGCoder::getLUTId(HcalSubdetector id, int ieta, int iphi, int depth) const {
69  int retval(0);
70  if (id == HcalBarrel) {
71  retval = (depth-1)+maxDepthHB_*(iphi-1);
72  if (ieta>0) retval+=maxDepthHB_*nFi_*(ieta-firstHBEta_);
73  else retval+=maxDepthHB_*nFi_*(ieta+lastHBEta_+nHBEta_);
74  } else if (id == HcalEndcap) {
75  retval = sizeHB_;
76  retval+= (depth-1)+maxDepthHE_*(iphi-1);
77  if (ieta>0) retval+=maxDepthHE_*nFi_*(ieta-firstHEEta_);
78  else retval+=maxDepthHE_*nFi_*(ieta+lastHEEta_+nHEEta_);
79  } else if (id == HcalForward) {
80  retval = sizeHB_+sizeHE_;
81  retval+= (depth-1)+maxDepthHF_*(iphi-1);
82  if (ieta>0) retval+=maxDepthHF_*nFi_*(ieta-firstHFEta_);
83  else retval+=maxDepthHF_*nFi_*(ieta+lastHFEta_+nHFEta_);
84  }
85  return retval;
86 }
87 
88 int HcaluLUTTPGCoder::getLUTId(uint32_t rawid) const {
89  HcalDetId detid(rawid);
90  return getLUTId(detid.subdet(), detid.ieta(), detid.iphi(), detid.depth());
91 }
92 
93 int HcaluLUTTPGCoder::getLUTId(const HcalDetId& detid) const {
94  return getLUTId(detid.subdet(), detid.ieta(), detid.iphi(), detid.depth());
95 }
96 
97 void HcaluLUTTPGCoder::update(const char* filename, bool appendMSB) {
98 
99  std::ifstream file(filename, std::ios::in);
100  assert(file.is_open());
101 
102  std::vector<HcalSubdetector> subdet;
104 
105  // Drop first (comment) line
106  std::getline(file, buffer);
107  std::getline(file, buffer);
108 
109  unsigned int index = buffer.find("H", 0);
110  while (index < buffer.length()){
111  std::string subdetStr = buffer.substr(index, 2);
112  if (subdetStr == "HB") subdet.push_back(HcalBarrel);
113  else if (subdetStr == "HE") subdet.push_back(HcalEndcap);
114  else if (subdetStr == "HF") subdet.push_back(HcalForward);
115  //TODO Check subdet
116  //else exception
117  index += 2;
118  index = buffer.find("H", index);
119  }
120 
121  // Get upper/lower ranges for ieta/iphi/depth
122  size_t nCol = subdet.size();
123  assert(nCol > 0);
124 
125  std::vector<int> ietaU;
126  std::vector<int> ietaL;
127  std::vector<int> iphiU;
128  std::vector<int> iphiL;
129  std::vector<int> depU;
130  std::vector<int> depL;
131  std::vector< Lut > lutFromFile(nCol);
132  LutElement lutValue;
133 
134  for (size_t i=0; i<nCol; ++i) {
135  int ieta;
136  file >> ieta;
137  ietaL.push_back(ieta);
138  }
139 
140  for (size_t i=0; i<nCol; ++i) {
141  int ieta;
142  file >> ieta;
143  ietaU.push_back(ieta);
144  }
145 
146  for (size_t i=0; i<nCol; ++i) {
147  int iphi;
148  file >> iphi;
149  iphiL.push_back(iphi);
150  }
151 
152  for (size_t i=0; i<nCol; ++i) {
153  int iphi;
154  file >> iphi;
155  iphiU.push_back(iphi);
156  }
157 
158  for (size_t i=0; i<nCol; ++i) {
159  int dep;
160  file >> dep;
161  depL.push_back(dep);
162  }
163 
164  for (size_t i=0; i<nCol; ++i) {
165  int dep;
166  file >> dep;
167  depU.push_back(dep);
168  }
169 
170  // Read Lut Entry
171  for (size_t i=0; file >> lutValue; i = (i+1) % nCol){
172  lutFromFile[i].push_back(lutValue);
173  }
174 
175  // Check lut size
176  for (size_t i=0; i<nCol; ++i) assert(lutFromFile[i].size() == INPUT_LUT_SIZE);
177 
178  for (size_t i=0; i<nCol; ++i){
179  for (int ieta = ietaL[i]; ieta <= ietaU[i]; ++ieta){
180  for (int iphi = iphiL[i]; iphi <= iphiU[i]; ++iphi){
181  for (int depth = depL[i]; depth <= depU[i]; ++depth){
182 
183  HcalDetId id(subdet[i], ieta, iphi, depth);
184  if (!topo_->valid(id)) continue;
185 
186  int lutId = getLUTId(id);
187  for (size_t adc = 0; adc < INPUT_LUT_SIZE; ++adc){
188  if (appendMSB){
189  // Append FG bit LUT to MSB
190  // MSB = Most Significant Bit = bit 10
191  // Overwrite bit 10
192  LutElement msb = (lutFromFile[i][adc] != 0 ? QIE8_LUT_MSB : 0);
193  inputLUT_[lutId][adc] = (msb | (inputLUT_[lutId][adc] & QIE8_LUT_BITMASK));
194  }
195  else inputLUT_[lutId][adc] = lutFromFile[i][adc];
196  }// for adc
197  }// for depth
198  }// for iphi
199  }// for ieta
200  }// for nCol
201 }
202 
204  LutXml * _xml = new LutXml(filename);
205  _xml->create_lut_map();
207  for (int ieta = -HcalDetId::kHcalEtaMask2;
208  ieta <= HcalDetId::kHcalEtaMask2; ++ieta) {
209  for (int iphi = 0; iphi <= HcalDetId::kHcalPhiMask2; ++iphi) {
210  for (int depth = 1; depth < HcalDetId::kHcalDepthMask2; ++depth) {
211  for (int isub=0; isub<3; ++isub) {
212  HcalDetId detid(subdet[isub], ieta, iphi, depth);
213  if (!topo_->valid(detid)) continue;
214  int id = getLUTId(subdet[isub], ieta, iphi, depth);
215  std::vector<unsigned int>* lut = _xml->getLutFast(detid);
216  if (lut==nullptr) throw cms::Exception("PROBLEM: No inputLUT_ in xml file for ") << detid << std::endl;
217  if (lut->size()!=INPUT_LUT_SIZE) throw cms::Exception ("PROBLEM: Wrong inputLUT_ size in xml file for ") << detid << std::endl;
218  for (unsigned int i=0; i<INPUT_LUT_SIZE; ++i) inputLUT_[id][i] = (LutElement)lut->at(i);
219  }
220  }
221  }
222  }
223  delete _xml;
225 }
226 
227 void HcaluLUTTPGCoder::update(const HcalDbService& conditions) {
228 
230  const HcalLutMetadata *metadata = conditions.getHcalLutMetadata();
231  assert(metadata !=nullptr);
232  float nominalgain_ = metadata->getNominalGain();
233 
234  HcalTrigTowerGeometry triggeo(topo_);
235  std::map<int, float> cosh_ieta;
236  for (int i = 1; i <= firstHFEta_; ++i) {
237  double eta_low = 0., eta_high = 0.;
238  triggeo.towerEtaBounds(i, 0, eta_low, eta_high);
239  cosh_ieta[i] = fabs(cosh((eta_low + eta_high)/2.));
240  }
241  for (int i = firstHFEta_; i <= lastHFEta_; ++i){
242  std::pair<double,double> etas = topo_->etaRange(HcalForward,i);
243  double eta1 = etas.first;
244  double eta2 = etas.second;
245  cosh_ieta[i] = cosh((eta1 + eta2)/2.);
246  }
247 
248  for (const auto& id: metadata->getAllChannels()) {
249 
250  if (not (id.det() == DetId::Hcal and topo_->valid(id))) continue;
251 
252  HcalDetId cell(id);
253  HcalSubdetector subdet = cell.subdet();
254 
255  if (subdet != HcalBarrel and subdet != HcalEndcap and subdet != HcalForward) continue;
256 
257  const HcalQIECoder* channelCoder = conditions.getHcalCoder (cell);
258  const HcalQIEShape* shape = conditions.getHcalShape(cell);
259  HcalCoderDb coder (*channelCoder, *shape);
260  const HcalLutMetadatum *meta = metadata->getValues(cell);
261 
262  unsigned int mipMax = 0;
263  unsigned int mipMin = 0;
264 
267  topo_->dddConstants()->isPlan1(cell)) {
268  const HcalTPChannelParameter *channelParameters = conditions.getHcalTPChannelParameter(cell);
269  mipMax = channelParameters->getFGBitInfo() >> 16;
270  mipMin = channelParameters->getFGBitInfo() & 0xFFFF;
271  }
272 
273  int lutId = getLUTId(cell);
274  Lut &lut=inputLUT_[lutId];
275  float ped = 0;
276  float gain = 0;
277  uint32_t status = 0;
278 
279  if (LUTGenerationMode_){
280  const HcalCalibrations& calibrations = conditions.getHcalCalibrations(cell);
281  for (auto capId : {0,1,2,3}){
282  ped += calibrations.pedestal(capId);
283  gain += calibrations.LUTrespcorrgain(capId);
284  }
285  ped /= 4.0;
286  gain /= 4.0;
287 
288  //Get Channel Quality
289  const HcalChannelStatus* channelStatus = conditions.getHcalChannelStatus(cell);
290  status = channelStatus->getValue();
291 
292  } else {
293  const HcalL1TriggerObject* myL1TObj = conditions.getHcalL1TriggerObject(cell);
294  ped = myL1TObj->getPedestal();
295  gain = myL1TObj->getRespGain();
296  status = myL1TObj->getFlag();
297  } // LUTGenerationMode_
298 
299  ped_[lutId] = ped;
300  gain_[lutId] = gain;
301  bool isMasked = ( (status & bitToMask_) > 0 );
302  float rcalib = meta->getRCalib();
303 
304  auto adc2fC = [channelCoder, shape](unsigned int adc){
305  float fC = 0;
306  for (auto capId : {0,1,2,3}) fC += channelCoder->charge(*shape, adc, capId);
307  return fC/4;
308  };
309 
310  int qieType =conditions.getHcalQIEType(cell)->getValue();
311 
312  const size_t SIZE = qieType==QIE8 ? INPUT_LUT_SIZE : UPGRADE_LUT_SIZE;
313  const int MASK = qieType==QIE8 ? QIE8_LUT_BITMASK :
315  double linearLSB = linearLSB_QIE8_;
316  if (qieType == QIE11 and cell.ietaAbs() == topo_->lastHBRing())
317  linearLSB = linearLSB_QIE11Overlap_;
318  else if (qieType == QIE11)
319  linearLSB = linearLSB_QIE11_;
320 
321  lut.resize(SIZE, 0);
322 
323  // Input LUT for HB/HE/HF
324  if (subdet == HcalBarrel || subdet == HcalEndcap){
325 
326  int granularity = meta->getLutGranularity();
327 
328  for (unsigned int adc = 0; adc < SIZE; ++adc) {
329  if (isMasked) lut[adc] = 0;
330  else {
331  double nonlinearityCorrection = 1.0;
332  if(qieType==QIE11) {
333  const HcalSiPMParameter& siPMParameter(*conditions.getHcalSiPMParameter(cell));
334  HcalSiPMnonlinearity corr(conditions.getHcalSiPMCharacteristics()->getNonLinearities(siPMParameter.getType()));
335  const double fcByPE = siPMParameter.getFCByPE();
336  const double effectivePixelsFired = adc2fC(adc)/fcByPE;
337  nonlinearityCorrection = corr.getRecoCorrectionFactor(effectivePixelsFired);
338  }
339  if (allLinear_)
340  lut[adc] = (LutElement) std::min(std::max(0, int((adc2fC(adc) - ped) * gain * rcalib * nonlinearityCorrection / linearLSB / cosh_ieta[cell.ietaAbs()])), MASK);
341  else
342  lut[adc] = (LutElement) std::min(std::max(0, int((adc2fC(adc) - ped) * gain * rcalib * nonlinearityCorrection / nominalgain_ / granularity)), MASK);
343 
344  if(qieType==QIE11){
345  if (adc >= mipMin and adc < mipMax) lut[adc] |= QIE11_LUT_MSB0;
346  else if (adc >= mipMax) lut[adc] |= QIE11_LUT_MSB1;
347  }
348  }
349  }
350  }
351  else if (subdet == HcalForward){
352  for (unsigned int adc = 0; adc < SIZE; ++adc) {
353  if (isMasked) lut[adc] = 0;
354  else {
355  lut[adc] = std::min(std::max(0,int((adc2fC(adc) - ped) * gain * rcalib / lsb_ / cosh_ieta[cell.ietaAbs()] )), MASK);
357  }
358  }
359  }
360  }
361 }
362 
364  int lutId = getLUTId(df.id());
365  const Lut& lut = inputLUT_.at(lutId);
366  for (int i=0; i<df.size(); i++){
367  ics[i] = (lut.at(df[i].adc()) & QIE8_LUT_BITMASK);
368  }
369 }
370 
372  int lutId = getLUTId(df.id());
373  const Lut& lut = inputLUT_.at(lutId);
374  for (int i=0; i<df.size(); i++){
375  ics[i] = (lut.at(df[i].adc()) & QIE8_LUT_BITMASK);
376  }
377 }
378 
380  int lutId = getLUTId(HcalDetId(df.id()));
381  const Lut& lut = inputLUT_.at(lutId);
382  for (int i=0; i<df.samples(); i++){
383  ics[i] = (lut.at(df[i].adc()) & QIE10_LUT_BITMASK);
384  }
385 }
386 
388  int lutId = getLUTId(HcalDetId(df.id()));
389  const Lut& lut = inputLUT_.at(lutId);
390  for (int i=0; i<df.samples(); i++){
391  ics[i] = (lut.at(df[i].adc()) & QIE11_LUT_BITMASK);
392  }
393 }
394 
396  int lutId = getLUTId(id);
397  return ((inputLUT_.at(lutId)).at(sample.adc()) & QIE8_LUT_BITMASK);
398 }
399 
401  int lutId = getLUTId(id);
402  return ped_.at(lutId);
403 }
404 
406  int lutId = getLUTId(id);
407  return gain_.at(lutId);
408 }
409 
410 std::vector<unsigned short> HcaluLUTTPGCoder::getLinearizationLUT(HcalDetId id) const{
411  int lutId = getLUTId(id);
412  return inputLUT_.at(lutId);
413 }
414 
415 void HcaluLUTTPGCoder::lookupMSB(const HBHEDataFrame& df, std::vector<bool>& msb) const{
416  msb.resize(df.size());
417  for (int i=0; i<df.size(); ++i)
418  msb[i] = getMSB(df.id(), df.sample(i).adc());
419 }
420 
421 bool HcaluLUTTPGCoder::getMSB(const HcalDetId& id, int adc) const{
422  int lutId = getLUTId(id);
423  const Lut& lut = inputLUT_.at(lutId);
424  return (lut.at(adc) & QIE8_LUT_MSB);
425 }
426 
427 void HcaluLUTTPGCoder::lookupMSB(const QIE10DataFrame& df, std::vector<bool>& msb) const{
428  msb.resize(df.samples());
429  int lutId = getLUTId(HcalDetId(df.id()));
430  const Lut& lut = inputLUT_.at(lutId);
431  for (int i = 0; i < df.samples(); ++i) {
432  msb[i] = lut.at(df[i].adc()) & QIE10_LUT_MSB;
433  }
434 }
435 
436 void
437 HcaluLUTTPGCoder::lookupMSB(const QIE11DataFrame& df, std::vector<std::bitset<2>>& msb) const
438 {
439  int lutId = getLUTId(HcalDetId(df.id()));
440  const Lut& lut = inputLUT_.at(lutId);
441  for (int i = 0; i < df.samples(); ++i) {
442  msb[i][0] = lut.at(df[i].adc()) & QIE11_LUT_MSB0;
443  msb[i][1] = lut.at(df[i].adc()) & QIE11_LUT_MSB1;
444  }
445 }
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:167
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
double linearLSB_QIE11Overlap_
static const int QIE11_LUT_MSB1
static const int QIE11_LUT_BITMASK
const HcalChannelStatus * getHcalChannelStatus(const HcalGenericDetId &fId) const
Definition: HcalQIENum.h:4
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
void towerEtaBounds(int ieta, int version, double &eta1, double &eta2) const
where this tower begins and ends in eta
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:108
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
JetCorrectorParameters corr
Definition: classes.h:5
static const int QIE10_LUT_BITMASK
int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.cc:98
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:103
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 HcalSiPMCharacteristics * getHcalSiPMCharacteristics() const
const HcalQIECoder * getHcalCoder(const HcalGenericDetId &fId) const
std::vector< float > getNonLinearities(int type) const
get nonlinearity constants
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
const HcalSiPMParameter * getHcalSiPMParameter(const HcalGenericDetId &fId) const
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