CMS 3D CMS Logo

LutXml.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: CaloOnlineTools/HcalOnlineDb
4 // Class : LutXml
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Gena Kukartsev, kukarzev@fnal.gov
10 // Created: Tue Mar 18 14:30:20 CDT 2008
11 //
12 
13 #include <iostream>
14 #include <string>
15 #include <vector>
16 #include <sstream>
17 #include <iconv.h>
18 #include <sys/time.h>
19 
22 #include "md5.h"
27 
28 using namespace std;
30 
32  ieta = -1000;
33  iphi = -1000;
34  depth = -1;
35  crate = -1;
36  slot = -1;
37  topbottom = -1;
38  fiber = -1;
39  fiberchan = -1;
40  lut_type = -1;
41  creationtag = "default_tag";
42 
43  char timebuf[50];
44  time_t _time = time(nullptr);
45  strftime(timebuf, 50, "%Y-%m-%d %H:%M:%S", gmtime(&_time));
46  creationstamp = timebuf;
47 
48  formatrevision = "default_revision";
49  targetfirmware = "default_revision";
50  generalizedindex = -1;
51 }
52 
53 LutXml::LutXml() : XMLDOMBlock("CFGBrickSet", 1) { init(); }
54 
55 LutXml::LutXml(InputSource &_source) : XMLDOMBlock(_source) { init(); }
56 
58 
62 }
63 
64 void LutXml::init(void) {
65  root = XMLString::transcode("CFGBrickSet");
66  brick = XMLString::transcode("CFGBrick");
67  brickElem = nullptr;
68 }
69 
70 std::vector<unsigned int> *LutXml::getLutFast(uint32_t det_id) {
71  if (lut_map.find(det_id) != lut_map.end())
72  return &(lut_map)[det_id];
73  edm::LogError("LutXml") << "LUT not found, null pointer is returned";
74  return nullptr;
75 }
76 
77 // checksums_xml is 0 by default
78 void LutXml::addLut(LutXml::Config &_config, XMLDOMBlock *checksums_xml) {
79  DOMElement *rootElem = document->getDocumentElement();
80 
81  brickElem = document->createElement(XMLProcessor::_toXMLCh("CFGBrick"));
82  rootElem->appendChild(brickElem);
83 
84  addParameter("CREATIONTAG", "string", _config.creationtag);
85  addParameter("CREATIONSTAMP", "string", _config.creationstamp);
86  addParameter("FORMATREVISION", "string", _config.formatrevision);
87  addParameter("TARGETFIRMWARE", "string", _config.targetfirmware);
88  addParameter("GENERALIZEDINDEX", "int", _config.generalizedindex);
89  addParameter("CRATE", "int", _config.crate);
90  addParameter("SLOT", "int", _config.slot);
91 
92  if (checksums_xml) {
93  addParameter("CHECKSUM", "string", get_checksum(_config.lut));
94  }
95 
96  if (_config.lut_type == 1) { // linearizer LUT
97  addParameter("IETA", "int", _config.ieta);
98  addParameter("IPHI", "int", _config.iphi);
99  addParameter("TOPBOTTOM", "int", _config.topbottom);
100  addParameter("LUT_TYPE", "int", _config.lut_type);
101  addParameter("FIBER", "int", _config.fiber);
102  addParameter("FIBERCHAN", "int", _config.fiberchan);
103  addParameter("DEPTH", "int", _config.depth);
104  addData(to_string(_config.lut.size()), "hex", _config.lut);
105  } else if (_config.lut_type == 2 || _config.lut_type == 4) { // compression LUT or HE feature bit LUT
106  addParameter("IETA", "int", _config.ieta);
107  addParameter("IPHI", "int", _config.iphi);
108  addParameter("TOPBOTTOM", "int", _config.topbottom);
109  addParameter("LUT_TYPE", "int", _config.lut_type);
110  addParameter("SLB", "int", _config.fiber);
111  addParameter("SLBCHAN", "int", _config.fiberchan);
112  addData(to_string(_config.lut.size()), "hex", _config.lut);
113  } else if (_config.lut_type == 5) { // channel masks
114  addParameter("MASK_TYPE", "string", "TRIGGERCHANMASK");
115  addData(to_string(_config.mask.size()), "hex", _config.mask);
116  } else if (_config.lut_type == 6) { // adc threshold for tdc mask
117  addParameter("THRESH_TYPE", "string", "TRIGINTIME");
118  addData(to_string(_config.mask.size()), "hex", _config.mask);
119  } else if (_config.lut_type == 7) { // tdc mask
120  addParameter("TDCMAP_TYPE", "string", "TRIGINTIME");
121  addData(to_string(_config.mask.size()), "hex", _config.mask);
122  } else {
123  edm::LogError("LutXml") << "Unknown LUT type...produced XML will be incorrect";
124  }
125 
126  if (checksums_xml) {
127  add_checksum(checksums_xml->getDocument(), _config);
128  }
129 }
130 
131 template <typename T>
132 DOMElement *LutXml::addData(std::string _elements, std::string _encoding, const T &_lut) {
133  DOMElement *child = document->createElement(XMLProcessor::_toXMLCh("Data"));
134  child->setAttribute(XMLProcessor::_toXMLCh("elements"), XMLProcessor::_toXMLCh(_elements));
135  child->setAttribute(XMLProcessor::_toXMLCh("encoding"), XMLProcessor::_toXMLCh(_encoding));
136 
137  std::stringstream buf;
138 
139  for (const auto &iter : _lut) {
140  char buf2[16];
141  sprintf(buf2, "%lx", uint64_t(iter));
142  buf << buf2 << " ";
143  }
144 
145  std::string _value = buf.str();
146 
147  DOMText *data_value = document->createTextNode(XMLProcessor::_toXMLCh(_value));
148  child->appendChild(data_value);
149 
150  brickElem->appendChild(child);
151 
152  return child;
153 }
154 
155 DOMElement *LutXml::add_checksum(DOMDocument *parent, Config &config) {
156  DOMElement *child = parent->createElement(XMLProcessor::_toXMLCh("Data"));
157  child->setAttribute(XMLProcessor::_toXMLCh("crate"), XMLProcessor::_toXMLCh(config.crate));
158  child->setAttribute(XMLProcessor::_toXMLCh("slot"), XMLProcessor::_toXMLCh(config.slot));
159  child->setAttribute(XMLProcessor::_toXMLCh("fpga"), XMLProcessor::_toXMLCh(config.topbottom));
160  child->setAttribute(XMLProcessor::_toXMLCh("fiber"), XMLProcessor::_toXMLCh(config.fiber));
161  child->setAttribute(XMLProcessor::_toXMLCh("fiberchan"), XMLProcessor::_toXMLCh(config.fiberchan));
162  child->setAttribute(XMLProcessor::_toXMLCh("luttype"), XMLProcessor::_toXMLCh(config.lut_type));
163  child->setAttribute(XMLProcessor::_toXMLCh("elements"), XMLProcessor::_toXMLCh("1"));
164  child->setAttribute(XMLProcessor::_toXMLCh("encoding"), XMLProcessor::_toXMLCh("hex"));
165  DOMText *checksum_value = parent->createTextNode(XMLProcessor::_toXMLCh(get_checksum(config.lut)));
166  child->appendChild(checksum_value);
167 
168  parent->getDocumentElement()->appendChild(child);
169 
170  return child;
171 }
172 
173 DOMElement *LutXml::addParameter(std::string _name, std::string _type, std::string _value) {
174  DOMElement *child = document->createElement(XMLProcessor::_toXMLCh("Parameter"));
175  child->setAttribute(XMLProcessor::_toXMLCh("name"), XMLProcessor::_toXMLCh(_name));
176  child->setAttribute(XMLProcessor::_toXMLCh("type"), XMLProcessor::_toXMLCh(_type));
177  DOMText *parameter_value = document->createTextNode(XMLProcessor::_toXMLCh(_value));
178  child->appendChild(parameter_value);
179 
180  brickElem->appendChild(child);
181 
182  return child;
183 }
184 
185 DOMElement *LutXml::addParameter(std::string _name, std::string _type, int _value) {
186  char buf[128];
187  sprintf(buf, "%d", _value);
188  std::string str_value = buf;
189  return addParameter(_name, _type, str_value);
190 }
191 
193 
194 // do MD5 checksum
195 std::string LutXml::get_checksum(std::vector<unsigned int> &lut) {
196  std::stringstream result;
197  md5_state_t md5er;
198  md5_byte_t digest[16];
199  md5_init(&md5er);
200  // linearizer LUT:
201  if (lut.size() == 128) {
202  unsigned char tool[2];
203  for (int i = 0; i < 128; i++) {
204  tool[0] = lut[i] & 0xFF;
205  tool[1] = (lut[i] >> 8) & 0xFF;
206  md5_append(&md5er, tool, 2);
207  }
208  } else if (lut.size() == 256) {
209  unsigned char tool[2];
210  for (int i = 0; i < 256; i++) {
211  tool[0] = lut[i] & 0xFF;
212  tool[1] = (lut[i] >> 8) & 0xFF;
213  md5_append(&md5er, tool, 2);
214  }
215  }
216  // compression LUT:
217  else if (lut.size() == 1024) {
218  unsigned char tool;
219  for (int i = 0; i < 1024; i++) {
220  tool = lut[i] & 0xFF;
221  md5_append(&md5er, &tool, 1);
222  }
223  } else if (lut.size() == 2048) {
224  unsigned char tool;
225  for (int i = 0; i < 2048; i++) {
226  tool = lut[i] & 0xFF;
227  md5_append(&md5er, &tool, 1);
228  }
229  }
230  // HE fine grain LUT
231  else if (lut.size() == 4096) {
232  unsigned char tool;
233  for (int i = 0; i < 4096; i++) {
234  tool = lut[i] & 0xFF;
235  md5_append(&md5er, &tool, 1);
236  }
237  } else {
238  edm::LogError("LutXml") << "Irregular LUT size, " << lut.size()
239  << " , do not know how to compute checksum, exiting...";
240  exit(-1);
241  }
242  md5_finish(&md5er, digest);
243  for (int i = 0; i < 16; i++)
244  result << std::hex << (((int)(digest[i])) & 0xFF);
245 
246  return result.str();
247 }
248 
250  edm::LogInfo("LutXml") << "Created map size: " << lut_map.size();
251 
252  struct timeval _t;
253  gettimeofday(&_t, nullptr);
254  double _time = (double)(_t.tv_sec) + (double)(_t.tv_usec) / 1000000.0;
255 
256  HcalEmap _emap("./backup/official_emap_v6.04_080905.txt");
257  std::vector<HcalEmap::HcalEmapRow> &_map = _emap.get_map();
258  edm::LogInfo("LutXml") << "HcalEmap contains " << _map.size() << " entries";
259 
260  int _counter = 0;
261  for (std::vector<HcalEmap::HcalEmapRow>::const_iterator row = _map.begin(); row != _map.end(); ++row) {
262  if (row->subdet == "HB") {
263  HcalDetId det_id(HcalBarrel, row->ieta, row->iphi, row->idepth);
264  uint32_t raw_id = det_id.rawId();
265  std::vector<unsigned int> *l = getLutFast(raw_id);
266  if (l)
267  _counter++;
268  }
269  if (row->subdet == "HE") {
270  HcalDetId det_id(HcalEndcap, row->ieta, row->iphi, row->idepth);
271  uint32_t raw_id = det_id.rawId();
272  std::vector<unsigned int> *l = getLutFast(raw_id);
273  if (l)
274  _counter++;
275  }
276  if (row->subdet == "HF") {
277  HcalDetId det_id(HcalForward, row->ieta, row->iphi, row->idepth);
278  uint32_t raw_id = det_id.rawId();
279  std::vector<unsigned int> *l = getLutFast(raw_id);
280  if (l)
281  _counter++;
282  }
283  if (row->subdet == "HO") {
284  HcalDetId det_id(HcalOuter, row->ieta, row->iphi, row->idepth);
285  uint32_t raw_id = det_id.rawId();
286  std::vector<unsigned int> *l = getLutFast(raw_id);
287  if (l)
288  _counter++;
289  }
290  }
291  gettimeofday(&_t, nullptr);
292  edm::LogInfo("LutXml") << "access to " << _counter
293  << " HCAL channels took: " << (double)(_t.tv_sec) + (double)(_t.tv_usec) / 1000000.0 - _time
294  << "sec";
295 
296  return 0;
297 }
298 
301  // HBHE: 0,1,4,5,10,11,14,15,17
302  // HF: 2,9,12
303  // HO: 3,6,7,13
304  int crate = crate_ < 20 ? crate_ : crate_ - 20;
305 
306  if (crate == 2 || crate == 9 || crate == 12)
307  result = HcalForward;
308  else if (crate == 3 || crate == 6 || crate == 7 || crate == 13)
309  result = HcalOuter;
310  else if (crate == 0 || crate == 1 || crate == 4 || crate == 5 || crate == 10 || crate == 11 || crate == 14 ||
311  crate == 15 || crate == 17) {
312  if (eta < 16)
313  result = HcalBarrel;
314  else if (eta > 16)
315  result = HcalEndcap;
316  else if (eta == 16 && depth < 3)
317  result = HcalBarrel;
318  else if (eta == 16 && depth >= 3)
319  result = HcalEndcap;
320  else {
321  edm::LogError("LutXml") << "Impossible to determine HCAL subdetector!!!";
322  exit(-1);
323  }
324  } else {
325  edm::LogError("LutXml") << "Impossible to determine HCAL subdetector!!!";
326  exit(-1);
327  }
328 
329  return result;
330 }
331 
332 int LutXml::a_to_i(char *inbuf) {
333  int result;
334  sscanf(inbuf, "%d", &result);
335  return result;
336 }
337 
338 // organize all LUTs in XML into a map for fast access
339 //
340 // FIXME: uses hardcoded CRATE-to-subdetector mapping
341 // FIXME: it would be better to use some official map
342 //
344  //delete lut_map;
345  lut_map.clear();
346  //lut_map = new std::map<uint32_t,std::vector<unsigned int> >();
347 
348  if (document) {
349  //DOMElement * rootElem =
350  DOMNodeList *brick_list = document->getDocumentElement()->getElementsByTagName(brick);
351  int n_of_bricks = brick_list->getLength();
352  for (int i = 0; i != n_of_bricks; i++) {
353  DOMElement *aBrick = (DOMElement *)(brick_list->item(i));
354  DOMNodeList *par_list = aBrick->getElementsByTagName(XMLString::transcode("Parameter"));
355  int n_of_par = par_list->getLength();
356  int ieta = -99;
357  int iphi = -99;
358  int depth = -99;
359  int crate = -99;
360  int lut_type = -99;
361  int slb = -99;
362  HcalSubdetector subdet;
363  for (int j = 0; j != n_of_par; j++) {
364  DOMElement *aPar = (DOMElement *)(par_list->item(j));
365  char *aName = XMLString::transcode(aPar->getAttribute(XMLProcessor::_toXMLCh("name")));
366  if (strcmp(aName, "IETA") == 0)
367  ieta = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
368  if (strcmp(aName, "IPHI") == 0)
369  iphi = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
370  if (strcmp(aName, "DEPTH") == 0)
371  depth = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
372  if (strcmp(aName, "CRATE") == 0)
373  crate = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
374  if (strcmp(aName, "LUT_TYPE") == 0)
375  lut_type = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
376  if (strcmp(aName, "SLB") == 0)
377  slb = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
378  }
379  subdet = subdet_from_crate(crate, abs(ieta), depth);
380  DOMElement *_data = (DOMElement *)(aBrick->getElementsByTagName(XMLString::transcode("Data"))->item(0));
381  char *_str = XMLString::transcode(_data->getFirstChild()->getNodeValue());
382 
383  // get the LUT vector
384  int _string_length = strlen(_str);
385  std::vector<unsigned int> _lut;
386  unsigned int _base = 16;
387  unsigned int _item = 0;
388  for (int i = 0; i != _string_length; i++) {
389  bool _range = false;
390  char ch_cur = _str[i];
391  if (_base == 16)
392  _range = (ch_cur >= '0' and ch_cur <= '9') || (ch_cur >= 'a' and ch_cur <= 'f') ||
393  (ch_cur >= 'A' and ch_cur <= 'F');
394  else if (_base == 10)
395  _range = (ch_cur >= '0' and ch_cur <= '9');
396  if (_range) {
397  if (ch_cur >= 'a' and ch_cur <= 'f')
398  ch_cur += 10 - 'a';
399  else if (ch_cur >= 'A' and ch_cur <= 'F')
400  ch_cur += 10 - 'A';
401  else if (ch_cur >= '0' and ch_cur <= '9')
402  ch_cur += -'0';
403  _item = _item * _base;
404  _item += ch_cur;
405  bool last_digit = false;
406  if ((i + 1) == _string_length)
407  last_digit = true;
408  else {
409  char ch_next = _str[i + 1];
410  bool _range_next = false;
411  if (_base == 16)
412  _range_next = (ch_next >= '0' and ch_next <= '9') || (ch_next >= 'a' and ch_next <= 'f') ||
413  (ch_next >= 'A' and ch_next <= 'F');
414  else if (_base == 10)
415  _range_next = (ch_next >= '0' and ch_next <= '9');
416  if (!_range_next)
417  last_digit = true;
418  }
419  if (last_digit) {
420  _lut.push_back(_item);
421  _item = 0;
422  }
423  }
424  }
425  // filling the map
426  uint32_t _key = 0;
427  if (lut_type == 1) {
428  HcalDetId _id(subdet, ieta, iphi, depth);
429  _key = _id.rawId();
430  } else if (lut_type == 2) {
431  int version = (abs(ieta) > 29 && slb != 12 && crate > 20) ? 1 : 0;
432  HcalTrigTowerDetId _id(ieta, iphi, 10 * version);
433  _key = _id.rawId();
434  } else
435  continue;
436  lut_map.insert(std::pair<uint32_t, std::vector<unsigned int> >(_key, _lut));
437  }
438  } else {
439  edm::LogError("LutXml") << "XML file with LUTs is not loaded, cannot create map!";
440  }
441 
442  return 0;
443 }
444 
445 LutXml::const_iterator LutXml::begin() const { return lut_map.begin(); }
446 
447 LutXml::const_iterator LutXml::end() const { return lut_map.end(); }
448 
449 LutXml::const_iterator LutXml::find(uint32_t id) const { return lut_map.find(id); }
XERCES_CPP_NAMESPACE::DOMElement * addParameter(std::string _name, std::string _type, std::string _value)
Definition: LutXml.cc:173
XERCES_CPP_NAMESPACE::DOMDocument * document
Definition: XMLDOMBlock.h:117
std::string targetfirmware
Definition: LutXml.h:35
int generalizedindex
Definition: LutXml.h:36
void addLut(Config &_config, XMLDOMBlock *checksums_xml=nullptr)
Definition: LutXml.cc:78
HcalSubdetector subdet_from_crate(int crate, int eta, int depth)
Definition: LutXml.cc:299
static int slb(const HcalTriggerPrimitiveSample &theSample)
XERCES_CPP_NAMESPACE::DOMElement * add_checksum(XERCES_CPP_NAMESPACE::DOMDocument *parent, Config &config)
Definition: LutXml.cc:155
XERCES_CPP_NAMESPACE::DOMElement * addData(std::string _elements, std::string _encoding, const T &_lut)
int create_lut_map(void)
Definition: LutXml.cc:343
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
Definition: config.py:1
int a_to_i(char *inbuf)
Definition: LutXml.cc:332
std::string & getCurrentBrick(void)
Definition: LutXml.cc:192
~LutXml() override
Definition: LutXml.cc:59
int topbottom
Definition: LutXml.h:31
std::string & getString(void)
Definition: XMLDOMBlock.cc:419
std::vector< unsigned int > lut
Definition: LutXml.h:37
std::string creationtag
Definition: LutXml.h:32
XERCES_CPP_NAMESPACE::DOMDocument * getDocument(void)
Definition: XMLDOMBlock.cc:268
static std::string get_checksum(std::vector< unsigned int > &lut)
Definition: LutXml.cc:195
HcalSubdetector
Definition: HcalAssistant.h:31
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void init(void)
Definition: LutXml.cc:64
std::string formatrevision
Definition: LutXml.h:34
const_iterator find(uint32_t) const
Definition: LutXml.cc:449
std::map< uint32_t, std::vector< unsigned int > > lut_map
Definition: LutXml.h:90
unsigned long long uint64_t
Definition: Time.h:13
std::map< uint32_t, std::vector< unsigned int > >::const_iterator const_iterator
Definition: LutXml.h:71
std::vector< HcalEmap::HcalEmapRow > & get_map(void)
Definition: HcalEmap.cc:71
static XMLCh * _toXMLCh(std::string temp)
Definition: XMLProcessor.h:172
std::vector< unsigned int > * getLutFast(uint32_t det_id)
Definition: LutXml.cc:70
XMLCh * brick
Definition: LutXml.h:78
int test_access(std::string filename)
Definition: LutXml.cc:249
Definition: Config.py:1
long double T
XERCES_CPP_NAMESPACE::DOMElement * brickElem
Definition: LutXml.h:87
const_iterator begin() const
Definition: LutXml.cc:445
int lut_type
Definition: LutXml.h:31
std::string creationstamp
Definition: LutXml.h:33
int fiberchan
Definition: LutXml.h:31
LutXml()
Definition: LutXml.cc:53
Helper class to handle FWLite file input sources.
def exit(msg="")
std::vector< uint64_t > mask
Definition: LutXml.h:38
const_iterator end() const
Definition: LutXml.cc:447