Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:58:10

0001 // -*- C++ -*-
0002 //
0003 // Package:     CaloOnlineTools/HcalOnlineDb
0004 // Class  :     LutXml
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Gena Kukartsev, kukarzev@fnal.gov
0010 //         Created:  Tue Mar 18 14:30:20 CDT 2008
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/HcalTrigTowerDetId.h"
0027 
0028 using namespace std;
0029 XERCES_CPP_NAMESPACE_USE
0030 
0031 LutXml::Config::_Config() {
0032   infotype = "LUT";
0033   ieta = -1000;
0034   iphi = -1000;
0035   depth = -1;
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   // Default to keeping veto disabled
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 // checksums_xml is 0 by default
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) {  // linearizer LUT
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) {  // compression LUT or HE feature bit LUT
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     // Special coded veto threshold value of zero disables vetoing in PFA1'
0119     if (_config.codedvetothreshold > 0) {
0120       // A valid coded value here is in the range (1, 2048) inclusive
0121       if (_config.codedvetothreshold <= 2048) {
0122         // The coded value of 2048 means to do vetoing with no threshold
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) {  // channel masks
0132     addParameter("MASK_TYPE", "string", "TRIGGERCHANMASK");
0133     addData(to_string(_config.mask.size()), "hex", _config.mask);
0134   } else if (_config.lut_type == 6) {  // adc threshold for tdc mask
0135     addParameter("THRESH_TYPE", "string", "TRIGINTIME");
0136     addData(to_string(_config.mask.size()), "hex", _config.mask);
0137   } else if (_config.lut_type == 7) {  // tdc mask
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 // do MD5 checksum
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   // linearizer LUT:
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   // compression LUT:
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   // HE fine grain LUT
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 HcalSubdetector LutXml::subdet_from_crate(int crate_, int slot, int fiber) {
0318   // HBHE: 0,1,4,5,10,11,14,15,17 (+20)
0319   // HF: 2,9,12  (+20)
0320   // HO: 3,6,7,13,18  (+20)
0321   int crate = crate_ < 20 ? crate_ : crate_ - 20;
0322   if (crate == 2 || crate == 9 || crate == 12)
0323     return HcalForward;
0324   else if (crate == 3 || crate == 6 || crate == 7 || crate == 13 || crate == 18)
0325     return HcalOuter;
0326   else if (crate == 0 || crate == 1 || crate == 4 || crate == 5 || crate == 10 || crate == 11 || crate == 14 ||
0327            crate == 15 || crate == 17) {
0328     if (slot % 3 == 1)
0329       return HcalBarrel;
0330     else if (slot % 3 == 0)
0331       return HcalEndcap;
0332     else if (fiber < 12)
0333       return HcalBarrel;
0334     else
0335       return HcalEndcap;
0336   }
0337   edm::LogWarning("LutXml::subdet_from_crate") << "crate " << crate_ << " is not accounted for";
0338   return HcalEmpty;
0339 }
0340 
0341 int LutXml::a_to_i(char *inbuf) {
0342   int result;
0343   sscanf(inbuf, "%d", &result);
0344   return result;
0345 }
0346 
0347 // organize all LUTs in XML into a map for fast access
0348 //
0349 // FIXME: uses hardcoded CRATE-to-subdetector mapping
0350 // FIXME: it would be better to use some official map
0351 //
0352 int LutXml::create_lut_map(void) {
0353   //delete lut_map;
0354   lut_map.clear();
0355   //lut_map = new std::map<uint32_t,std::vector<unsigned int> >();
0356 
0357   if (document) {
0358     //DOMElement * rootElem =
0359     DOMNodeList *brick_list = document->getDocumentElement()->getElementsByTagName(brick);
0360     int n_of_bricks = brick_list->getLength();
0361     for (int i = 0; i != n_of_bricks; i++) {
0362       DOMElement *aBrick = (DOMElement *)(brick_list->item(i));
0363       DOMNodeList *par_list = aBrick->getElementsByTagName(XMLString::transcode("Parameter"));
0364       int n_of_par = par_list->getLength();
0365       int ieta = -99;
0366       int iphi = -99;
0367       int depth = -99;
0368       int crate = -99;
0369       int slot = -99;
0370       int fiber = -99;
0371       int lut_type = -99;
0372       int slb = -99;
0373       HcalSubdetector subdet;
0374       for (int j = 0; j != n_of_par; j++) {
0375         DOMElement *aPar = (DOMElement *)(par_list->item(j));
0376         char *aName = XMLString::transcode(aPar->getAttribute(XMLProcessor::_toXMLCh("name")));
0377         if (strcmp(aName, "IETA") == 0)
0378           ieta = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0379         if (strcmp(aName, "IPHI") == 0)
0380           iphi = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0381         if (strcmp(aName, "DEPTH") == 0)
0382           depth = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0383         if (strcmp(aName, "CRATE") == 0)
0384           crate = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0385         if (strcmp(aName, "SLOT") == 0)
0386           slot = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0387         if (strcmp(aName, "FIBER") == 0)
0388           fiber = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0389         if (strcmp(aName, "LUT_TYPE") == 0)
0390           lut_type = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0391         if (strcmp(aName, "SLB") == 0)
0392           slb = a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
0393       }
0394       subdet = subdet_from_crate(crate, slot, fiber);
0395       DOMElement *_data = (DOMElement *)(aBrick->getElementsByTagName(XMLString::transcode("Data"))->item(0));
0396       char *_str = XMLString::transcode(_data->getFirstChild()->getNodeValue());
0397 
0398       // get the LUT vector
0399       int _string_length = strlen(_str);
0400       std::vector<unsigned int> _lut;
0401       unsigned int _base = 16;
0402       unsigned int _item = 0;
0403       for (int i = 0; i != _string_length; i++) {
0404         bool _range = false;
0405         char ch_cur = _str[i];
0406         if (_base == 16)
0407           _range = (ch_cur >= '0' and ch_cur <= '9') || (ch_cur >= 'a' and ch_cur <= 'f') ||
0408                    (ch_cur >= 'A' and ch_cur <= 'F');
0409         else if (_base == 10)
0410           _range = (ch_cur >= '0' and ch_cur <= '9');
0411         if (_range) {
0412           if (ch_cur >= 'a' and ch_cur <= 'f')
0413             ch_cur += 10 - 'a';
0414           else if (ch_cur >= 'A' and ch_cur <= 'F')
0415             ch_cur += 10 - 'A';
0416           else if (ch_cur >= '0' and ch_cur <= '9')
0417             ch_cur += -'0';
0418           _item = _item * _base;
0419           _item += ch_cur;
0420           bool last_digit = false;
0421           if ((i + 1) == _string_length)
0422             last_digit = true;
0423           else {
0424             char ch_next = _str[i + 1];
0425             bool _range_next = false;
0426             if (_base == 16)
0427               _range_next = (ch_next >= '0' and ch_next <= '9') || (ch_next >= 'a' and ch_next <= 'f') ||
0428                             (ch_next >= 'A' and ch_next <= 'F');
0429             else if (_base == 10)
0430               _range_next = (ch_next >= '0' and ch_next <= '9');
0431             if (!_range_next)
0432               last_digit = true;
0433           }
0434           if (last_digit) {
0435             _lut.push_back(_item);
0436             _item = 0;
0437           }
0438         }
0439       }
0440       // filling the map
0441       uint32_t _key = 0;
0442       if (lut_type == 1) {
0443         HcalDetId _id(subdet, ieta, iphi, depth);
0444         _key = _id.rawId();
0445       } else if (lut_type == 2) {
0446         int version = (abs(ieta) > 29 && slb != 12 && crate > 20) ? 1 : 0;
0447         HcalTrigTowerDetId _id(ieta, iphi, 10 * version);
0448         _key = _id.rawId();
0449       } else
0450         continue;
0451       lut_map.insert(std::pair<uint32_t, std::vector<unsigned int> >(_key, _lut));
0452     }
0453   } else {
0454     edm::LogError("LutXml") << "XML file with LUTs is not loaded, cannot create map!";
0455   }
0456 
0457   return 0;
0458 }
0459 
0460 LutXml::const_iterator LutXml::begin() const { return lut_map.begin(); }
0461 
0462 LutXml::const_iterator LutXml::end() const { return lut_map.end(); }
0463 
0464 LutXml::const_iterator LutXml::find(uint32_t id) const { return lut_map.find(id); }