File indexing completed on 2024-11-27 03:17:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <iostream>
0014 #include <string>
0015 #include <vector>
0016 #include <sstream>
0017 #include <iconv.h>
0018 #include <sys/time.h>
0019
0020 #include "CalibCalorimetry/HcalTPGAlgos/interface/LutXml.h"
0021 #include "CalibCalorimetry/HcalTPGAlgos/interface/XMLProcessor.h"
0022 #include "md5.h"
0023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0024 #include "CalibCalorimetry/HcalTPGAlgos/interface/HcalEmap.h"
0025 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0026 #include "DataFormats/HcalDetId/interface/HcalZDCDetId.h"
0027 #include "DataFormats/HcalDetId/interface/HcalTrigTowerDetId.h"
0028
0029 using namespace std;
0030 XERCES_CPP_NAMESPACE_USE
0031
0032 LutXml::Config::_Config() {
0033 infotype = "LUT";
0034 ieta = -1000;
0035 iphi = -1000;
0036 crate = -1;
0037 slot = -1;
0038 topbottom = -1;
0039 fiber = -1;
0040 fiberchan = -1;
0041 lut_type = -1;
0042 creationtag = "default_tag";
0043
0044 char timebuf[50];
0045 time_t _time = time(nullptr);
0046 strftime(timebuf, 50, "%Y-%m-%d %H:%M:%S", gmtime(&_time));
0047 creationstamp = timebuf;
0048
0049 formatrevision = "default_revision";
0050 targetfirmware = "default_revision";
0051 generalizedindex = -1;
0052 weight = -1;
0053
0054 codedvetothreshold = 0;
0055 }
0056
0057 LutXml::LutXml() : XMLDOMBlock("CFGBrickSet", 1) { init(); }
0058
0059 LutXml::LutXml(InputSource &_source) : XMLDOMBlock(_source) { init(); }
0060
0061 LutXml::LutXml(std::string filename) : XMLDOMBlock(filename) { init(); }
0062
0063 LutXml::~LutXml() {
0064 XMLString::release(&root);
0065 XMLString::release(&brick);
0066 }
0067
0068 void LutXml::init(void) {
0069 root = XMLString::transcode("CFGBrickSet");
0070 brick = XMLString::transcode("CFGBrick");
0071 brickElem = nullptr;
0072 }
0073
0074 std::vector<unsigned int> *LutXml::getLutFast(uint32_t det_id) {
0075 if (lut_map.find(det_id) != lut_map.end())
0076 return &(lut_map)[det_id];
0077 edm::LogError("LutXml") << "LUT not found, null pointer is returned";
0078 return nullptr;
0079 }
0080
0081
0082 void LutXml::addLut(LutXml::Config &_config, XMLDOMBlock *checksums_xml) {
0083 DOMElement *rootElem = document->getDocumentElement();
0084
0085 brickElem = document->createElement(XMLProcessor::_toXMLCh("CFGBrick"));
0086 rootElem->appendChild(brickElem);
0087
0088 addParameter("INFOTYPE", "string", _config.infotype);
0089 addParameter("CREATIONTAG", "string", _config.creationtag);
0090 addParameter("CREATIONSTAMP", "string", _config.creationstamp);
0091 addParameter("FORMATREVISION", "string", _config.formatrevision);
0092 addParameter("TARGETFIRMWARE", "string", _config.targetfirmware);
0093 addParameter("GENERALIZEDINDEX", "int", _config.generalizedindex);
0094 addParameter("CRATE", "int", _config.crate);
0095 addParameter("SLOT", "int", _config.slot);
0096
0097 if (checksums_xml) {
0098 addParameter("CHECKSUM", "string", get_checksum(_config.lut));
0099 }
0100
0101 if (_config.lut_type == 1) {
0102 addParameter("IETA", "int", _config.ieta);
0103 addParameter("IPHI", "int", _config.iphi);
0104 addParameter("TOPBOTTOM", "int", _config.topbottom);
0105 addParameter("LUT_TYPE", "int", _config.lut_type);
0106 addParameter("FIBER", "int", _config.fiber);
0107 addParameter("FIBERCHAN", "int", _config.fiberchan);
0108 addParameter("DEPTH", "int", _config.depth);
0109 addData(to_string(_config.lut.size()), "hex", _config.lut);
0110 } else if (_config.lut_type == 2 || _config.lut_type == 4) {
0111 addParameter("IETA", "int", _config.ieta);
0112 addParameter("IPHI", "int", _config.iphi);
0113 addParameter("TOPBOTTOM", "int", _config.topbottom);
0114 addParameter("LUT_TYPE", "int", _config.lut_type);
0115 addParameter("SLB", "int", _config.fiber);
0116 addParameter("SLBCHAN", "int", _config.fiberchan);
0117 addParameter("WEIGHT", "int", _config.weight);
0118
0119 if (_config.codedvetothreshold > 0) {
0120
0121 if (_config.codedvetothreshold <= 2048) {
0122
0123 int actualvetothreshold = _config.codedvetothreshold == 2048 ? 0 : _config.codedvetothreshold;
0124 addParameter("PREFIRE_VETO_THRESHOLD", "int", actualvetothreshold);
0125 } else {
0126 edm::LogWarning("LutXml") << "Positive veto threshold of " << _config.codedvetothreshold
0127 << " is not in range (1, 2048) ! Vetoing will not be done in PFA1' !";
0128 }
0129 }
0130 addData(to_string(_config.lut.size()), "hex", _config.lut);
0131 } else if (_config.lut_type == 5) {
0132 addParameter("MASK_TYPE", "string", "TRIGGERCHANMASK");
0133 addData(to_string(_config.mask.size()), "hex", _config.mask);
0134 } else if (_config.lut_type == 6) {
0135 addParameter("THRESH_TYPE", "string", "TRIGINTIME");
0136 addData(to_string(_config.mask.size()), "hex", _config.mask);
0137 } else if (_config.lut_type == 7) {
0138 addParameter("TDCMAP_TYPE", "string", "TRIGINTIME");
0139 addData(to_string(_config.mask.size()), "hex", _config.mask);
0140 } else {
0141 edm::LogError("LutXml") << "Unknown LUT type...produced XML will be incorrect";
0142 }
0143
0144 if (checksums_xml) {
0145 add_checksum(checksums_xml->getDocument(), _config);
0146 }
0147 }
0148
0149 template <typename T>
0150 DOMElement *LutXml::addData(std::string _elements, std::string _encoding, const T &_lut) {
0151 DOMElement *child = document->createElement(XMLProcessor::_toXMLCh("Data"));
0152 child->setAttribute(XMLProcessor::_toXMLCh("elements"), XMLProcessor::_toXMLCh(_elements));
0153 child->setAttribute(XMLProcessor::_toXMLCh("encoding"), XMLProcessor::_toXMLCh(_encoding));
0154
0155 std::stringstream buf;
0156
0157 for (const auto &iter : _lut) {
0158 char buf2[16];
0159 sprintf(buf2, "%lx", uint64_t(iter));
0160 buf << buf2 << " ";
0161 }
0162
0163 std::string _value = buf.str();
0164
0165 DOMText *data_value = document->createTextNode(XMLProcessor::_toXMLCh(_value));
0166 child->appendChild(data_value);
0167
0168 brickElem->appendChild(child);
0169
0170 return child;
0171 }
0172
0173 DOMElement *LutXml::add_checksum(DOMDocument *parent, Config &config) {
0174 DOMElement *child = parent->createElement(XMLProcessor::_toXMLCh("Data"));
0175 child->setAttribute(XMLProcessor::_toXMLCh("crate"), XMLProcessor::_toXMLCh(config.crate));
0176 child->setAttribute(XMLProcessor::_toXMLCh("slot"), XMLProcessor::_toXMLCh(config.slot));
0177 child->setAttribute(XMLProcessor::_toXMLCh("fpga"), XMLProcessor::_toXMLCh(config.topbottom));
0178 child->setAttribute(XMLProcessor::_toXMLCh("fiber"), XMLProcessor::_toXMLCh(config.fiber));
0179 child->setAttribute(XMLProcessor::_toXMLCh("fiberchan"), XMLProcessor::_toXMLCh(config.fiberchan));
0180 child->setAttribute(XMLProcessor::_toXMLCh("luttype"), XMLProcessor::_toXMLCh(config.lut_type));
0181 child->setAttribute(XMLProcessor::_toXMLCh("elements"), XMLProcessor::_toXMLCh("1"));
0182 child->setAttribute(XMLProcessor::_toXMLCh("encoding"), XMLProcessor::_toXMLCh("hex"));
0183 DOMText *checksum_value = parent->createTextNode(XMLProcessor::_toXMLCh(get_checksum(config.lut)));
0184 child->appendChild(checksum_value);
0185
0186 parent->getDocumentElement()->appendChild(child);
0187
0188 return child;
0189 }
0190
0191 DOMElement *LutXml::addParameter(std::string _name, std::string _type, std::string _value) {
0192 DOMElement *child = document->createElement(XMLProcessor::_toXMLCh("Parameter"));
0193 child->setAttribute(XMLProcessor::_toXMLCh("name"), XMLProcessor::_toXMLCh(_name));
0194 child->setAttribute(XMLProcessor::_toXMLCh("type"), XMLProcessor::_toXMLCh(_type));
0195 DOMText *parameter_value = document->createTextNode(XMLProcessor::_toXMLCh(_value));
0196 child->appendChild(parameter_value);
0197
0198 brickElem->appendChild(child);
0199
0200 return child;
0201 }
0202
0203 DOMElement *LutXml::addParameter(std::string _name, std::string _type, int _value) {
0204 char buf[128];
0205 sprintf(buf, "%d", _value);
0206 std::string str_value = buf;
0207 return addParameter(_name, _type, str_value);
0208 }
0209
0210 std::string &LutXml::getCurrentBrick(void) { return getString(brickElem); }
0211
0212
0213 std::string LutXml::get_checksum(std::vector<unsigned int> &lut) {
0214 std::stringstream result;
0215 md5_state_t md5er;
0216 md5_byte_t digest[16];
0217 md5_init(&md5er);
0218
0219 if (lut.size() == 128) {
0220 unsigned char tool[2];
0221 for (int i = 0; i < 128; i++) {
0222 tool[0] = lut[i] & 0xFF;
0223 tool[1] = (lut[i] >> 8) & 0xFF;
0224 md5_append(&md5er, tool, 2);
0225 }
0226 } else if (lut.size() == 256) {
0227 unsigned char tool[2];
0228 for (int i = 0; i < 256; i++) {
0229 tool[0] = lut[i] & 0xFF;
0230 tool[1] = (lut[i] >> 8) & 0xFF;
0231 md5_append(&md5er, tool, 2);
0232 }
0233 }
0234
0235 else if (lut.size() == 1024) {
0236 unsigned char tool;
0237 for (int i = 0; i < 1024; i++) {
0238 tool = lut[i] & 0xFF;
0239 md5_append(&md5er, &tool, 1);
0240 }
0241 } else if (lut.size() == 2048) {
0242 unsigned char tool;
0243 for (int i = 0; i < 2048; i++) {
0244 tool = lut[i] & 0xFF;
0245 md5_append(&md5er, &tool, 1);
0246 }
0247 }
0248
0249 else if (lut.size() == 4096) {
0250 unsigned char tool;
0251 for (int i = 0; i < 4096; i++) {
0252 tool = lut[i] & 0xFF;
0253 md5_append(&md5er, &tool, 1);
0254 }
0255 } else {
0256 edm::LogError("LutXml") << "Irregular LUT size, " << lut.size()
0257 << " , do not know how to compute checksum, exiting...";
0258 exit(-1);
0259 }
0260 md5_finish(&md5er, digest);
0261 for (int i = 0; i < 16; i++)
0262 result << std::hex << (((int)(digest[i])) & 0xFF);
0263
0264 return result.str();
0265 }
0266
0267 int LutXml::test_access(std::string filename) {
0268 edm::LogInfo("LutXml") << "Created map size: " << lut_map.size();
0269
0270 struct timeval _t;
0271 gettimeofday(&_t, nullptr);
0272 double _time = (double)(_t.tv_sec) + (double)(_t.tv_usec) / 1000000.0;
0273
0274 HcalEmap _emap("./backup/official_emap_v6.04_080905.txt");
0275 std::vector<HcalEmap::HcalEmapRow> &_map = _emap.get_map();
0276 edm::LogInfo("LutXml") << "HcalEmap contains " << _map.size() << " entries";
0277
0278 int _counter = 0;
0279 for (std::vector<HcalEmap::HcalEmapRow>::const_iterator row = _map.begin(); row != _map.end(); ++row) {
0280 if (row->subdet == "HB") {
0281 HcalDetId det_id(HcalBarrel, row->ieta, row->iphi, row->idepth);
0282 uint32_t raw_id = det_id.rawId();
0283 std::vector<unsigned int> *l = getLutFast(raw_id);
0284 if (l)
0285 _counter++;
0286 }
0287 if (row->subdet == "HE") {
0288 HcalDetId det_id(HcalEndcap, row->ieta, row->iphi, row->idepth);
0289 uint32_t raw_id = det_id.rawId();
0290 std::vector<unsigned int> *l = getLutFast(raw_id);
0291 if (l)
0292 _counter++;
0293 }
0294 if (row->subdet == "HF") {
0295 HcalDetId det_id(HcalForward, row->ieta, row->iphi, row->idepth);
0296 uint32_t raw_id = det_id.rawId();
0297 std::vector<unsigned int> *l = getLutFast(raw_id);
0298 if (l)
0299 _counter++;
0300 }
0301 if (row->subdet == "HO") {
0302 HcalDetId det_id(HcalOuter, row->ieta, row->iphi, row->idepth);
0303 uint32_t raw_id = det_id.rawId();
0304 std::vector<unsigned int> *l = getLutFast(raw_id);
0305 if (l)
0306 _counter++;
0307 }
0308 }
0309 gettimeofday(&_t, nullptr);
0310 edm::LogInfo("LutXml") << "access to " << _counter
0311 << " HCAL channels took: " << (double)(_t.tv_sec) + (double)(_t.tv_usec) / 1000000.0 - _time
0312 << "sec";
0313
0314 return 0;
0315 }
0316
0317 DetId LutXml::detid_from_crate(
0318 int crate, int slot, int fiber, int fiberch, bool isTrigger, const HcalElectronicsMap *emap) {
0319 HcalElectronicsId electronicsId = HcalElectronicsId(crate, slot, fiber, fiberch, isTrigger);
0320
0321 DetId detId = emap->lookup(electronicsId);
0322 if (detId.null()) {
0323 edm::LogWarning("LutXml") << "Invalid electronics ID or no mapping found for crate: " << crate << " slot: " << slot
0324 << " fiber: " << fiber << " fiberch: " << fiberch << std::endl;
0325 return 0;
0326 } else {
0327 return detId;
0328 }
0329 }
0330
0331 int LutXml::a_to_i(char *inbuf) {
0332 int result;
0333 sscanf(inbuf, "%d", &result);
0334 return result;
0335 }
0336
0337
0338 int LutXml::create_lut_map(const HcalElectronicsMap *emap) {
0339
0340 lut_map.clear();
0341
0342
0343 if (document) {
0344
0345 DOMNodeList *brick_list = document->getDocumentElement()->getElementsByTagName(brick);
0346 int n_of_bricks = brick_list->getLength();
0347 for (int i = 0; i != n_of_bricks; i++) {
0348 DOMElement *aBrick = (DOMElement *)(brick_list->item(i));
0349 DOMNodeList *par_list = aBrick->getElementsByTagName(XMLString::transcode("Parameter"));
0350 int n_of_par = par_list->getLength();
0351 int ieta = -99;
0352 int iphi = -99;
0353 int crate = -99;
0354 int slot = -99;
0355 int fiber = -99;
0356 int fiberch = -99;
0357 int slb = -99;
0358 int lut_type = -99;
0359 for (int j = 0; j != n_of_par; j++) {
0360 DOMElement *aPar = (DOMElement *)(par_list->item(j));
0361 char *aName = XMLString::transcode(aPar->getAttribute(XMLProcessor::_toXMLCh("name")));
0362 if (strcmp(aName, "IETA") == 0)
0363 ieta = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0364 if (strcmp(aName, "IPHI") == 0)
0365 iphi = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0366 if (strcmp(aName, "CRATE") == 0)
0367 crate = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0368 if (strcmp(aName, "SLOT") == 0)
0369 slot = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0370 if (strcmp(aName, "FIBERCHAN") == 0)
0371 fiberch = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0372 if (strcmp(aName, "FIBER") == 0)
0373 fiber = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0374 if (strcmp(aName, "SLB") == 0)
0375 slb = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0376 if (strcmp(aName, "LUT_TYPE") == 0)
0377 lut_type = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0378 }
0379
0380 DOMElement *_data = (DOMElement *)(aBrick->getElementsByTagName(XMLString::transcode("Data"))->item(0));
0381 char *_str = XMLString::transcode(_data->getFirstChild()->getNodeValue());
0382
0383
0384 int _string_length = strlen(_str);
0385 std::vector<unsigned int> _lut;
0386 unsigned int _base = 16;
0387 unsigned int _item = 0;
0388 for (int i = 0; i != _string_length; i++) {
0389 bool _range = false;
0390 char ch_cur = _str[i];
0391 if (_base == 16)
0392 _range = (ch_cur >= '0' and ch_cur <= '9') || (ch_cur >= 'a' and ch_cur <= 'f') ||
0393 (ch_cur >= 'A' and ch_cur <= 'F');
0394 else if (_base == 10)
0395 _range = (ch_cur >= '0' and ch_cur <= '9');
0396 if (_range) {
0397 if (ch_cur >= 'a' and ch_cur <= 'f')
0398 ch_cur += 10 - 'a';
0399 else if (ch_cur >= 'A' and ch_cur <= 'F')
0400 ch_cur += 10 - 'A';
0401 else if (ch_cur >= '0' and ch_cur <= '9')
0402 ch_cur += -'0';
0403 _item = _item * _base;
0404 _item += ch_cur;
0405 bool last_digit = false;
0406 if ((i + 1) == _string_length)
0407 last_digit = true;
0408 else {
0409 char ch_next = _str[i + 1];
0410 bool _range_next = false;
0411 if (_base == 16)
0412 _range_next = (ch_next >= '0' and ch_next <= '9') || (ch_next >= 'a' and ch_next <= 'f') ||
0413 (ch_next >= 'A' and ch_next <= 'F');
0414 else if (_base == 10)
0415 _range_next = (ch_next >= '0' and ch_next <= '9');
0416 if (!_range_next)
0417 last_digit = true;
0418 }
0419 if (last_digit) {
0420 _lut.push_back(_item);
0421 _item = 0;
0422 }
0423 }
0424 }
0425
0426
0427 uint32_t _key = 0;
0428 if (lut_type == 1) {
0429 DetId detId = detid_from_crate(crate, slot, fiber, fiberch, false, emap);
0430 if (detId.det() == DetId::Hcal) {
0431 HcalDetId _id(detId);
0432 _key = _id.rawId();
0433 } else if (detId.det() == DetId::Calo && detId.subdetId() == HcalZDCDetId::SubdetectorId) {
0434 HcalZDCDetId _id(detId);
0435 _key = _id.rawId();
0436 }
0437 } else if (lut_type == 2) {
0438 int version = (abs(ieta) > 29 && slb != 12 && crate > 20) ? 1 : 0;
0439 HcalTrigTowerDetId _id(ieta, iphi, 10 * version);
0440 _key = _id.rawId();
0441 } else
0442 continue;
0443 lut_map.insert(std::pair<uint32_t, std::vector<unsigned int> >(_key, _lut));
0444 }
0445 } else {
0446 edm::LogError("LutXml") << "XML file with LUTs is not loaded, cannot create map!";
0447 }
0448
0449 return 0;
0450 }
0451
0452 LutXml::const_iterator LutXml::begin() const { return lut_map.begin(); }
0453
0454 LutXml::const_iterator LutXml::end() const { return lut_map.end(); }
0455
0456 LutXml::const_iterator LutXml::find(uint32_t id) const { return lut_map.find(id); }