Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:12:54

0001 #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLConfigReader.h"
0002 #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPattern.h"
0003 #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternWithStat.h"
0004 #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h"
0005 #include "L1Trigger/RPCTrigger/interface/RPCConst.h"
0006 
0007 #include "CondFormats/L1TObjects/interface/L1TMuonOverlapParams.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 
0010 #include <iostream>
0011 #include <cmath>
0012 #include <algorithm>
0013 #include <utility>
0014 #include <array>
0015 
0016 #include "xercesc/framework/StdOutFormatTarget.hpp"
0017 #include "xercesc/framework/LocalFileFormatTarget.hpp"
0018 #include "xercesc/parsers/XercesDOMParser.hpp"
0019 #include "xercesc/dom/DOM.hpp"
0020 #include "xercesc/dom/DOMException.hpp"
0021 #include "xercesc/dom/DOMImplementation.hpp"
0022 #include "xercesc/sax/HandlerBase.hpp"
0023 #include "xercesc/util/XMLString.hpp"
0024 #include "xercesc/util/PlatformUtils.hpp"
0025 #include "xercesc/util/XercesDefs.hpp"
0026 
0027 #include <boost/multiprecision/integer.hpp>
0028 
0029 XERCES_CPP_NAMESPACE_USE
0030 
0031 //////////////////////////////////
0032 // XMLConfigReader
0033 //////////////////////////////////
0034 inline std::string _toString(XMLCh const *toTranscode) {
0035   std::string tmp(xercesc::XMLString::transcode(toTranscode));
0036   return tmp;
0037 }
0038 
0039 inline XMLCh *_toDOMS(std::string temp) {
0040   XMLCh *buff = XMLString::transcode(temp.c_str());
0041   return buff;
0042 }
0043 ////////////////////////////////////
0044 ////////////////////////////////////
0045 XMLConfigReader::XMLConfigReader() {}
0046 
0047 XMLConfigReader::~XMLConfigReader() {}
0048 //////////////////////////////////////////////////
0049 //////////////////////////////////////////////////
0050 void XMLConfigReader::readLUTs(std::vector<l1t::LUT *> luts,
0051                                const L1TMuonOverlapParams &aConfig,
0052                                const std::vector<std::string> &types) {
0053   ///Fill payload string
0054   auto aGPs = readPatterns<GoldenPattern>(aConfig, patternsFiles, true);
0055 
0056   edm::LogVerbatim("OMTFReconstruction") << "XMLConfigReader::readLUTs: aGPs.size() " << aGPs.size()
0057                                          << " L1TMuonOverlapParams::nGoldenPatterns() " << aConfig.nGoldenPatterns()
0058                                          << std::endl;
0059 
0060   if ((int)aGPs.size() != aConfig.nGoldenPatterns()) {
0061     throw cms::Exception(
0062         "XMLConfigReader::readLUTs: aGPs.size() != aConfig.nGoldenPatterns(). Fix nGoldenPatterns in the "
0063         "hwToLogicLayer_0x000x.xml");
0064   }
0065 
0066   bool useMeanDistPhi1 = false;
0067   //if false, only getMeanDistPhi()[iLayer][iRefLayer][0]
0068   //if true,  also getMeanDistPhi()[iLayer][iRefLayer][1]
0069 
0070   for (unsigned int i = 0; i < luts.size(); i++) {
0071     l1t::LUT *lut = luts[i];
0072     const std::string &type = types[i];
0073 
0074     std::stringstream strStream;
0075 
0076     //totalInWidth and outWidth are initialized here for the type == "iCharge", "iEta", "iPt"
0077     //i.e. the global pattern parameters
0078     //Number of bits used to address LUT,
0079     int totalInWidth = boost::multiprecision::msb(aGPs.size()) + 1;  //=7 in run2 and run3 patterns
0080     //Number of bits used to store LUT value
0081     int outWidth = 6;
0082 
0083     if (type == "iCharge")
0084       outWidth = 1;
0085     if (type == "iEta")
0086       outWidth = 2;
0087     if (type == "iPt")
0088       outWidth = 9;
0089     if (type == "meanDistPhi") {
0090       outWidth = aConfig.nPhiBits();
0091 
0092       int meanDistPhiValCnt =
0093           aGPs.size() * aGPs.at(0)->getMeanDistPhi().size() * aGPs.at(0)->getMeanDistPhi()[0].size();
0094 
0095       totalInWidth = boost::multiprecision::msb(meanDistPhiValCnt) + 1;  //totalInWidth = 14;
0096       //the index of msb is zero-based, so +1 is needed to have the number of bits
0097 
0098       if (useMeanDistPhi1)
0099         totalInWidth = totalInWidth + 1;
0100       //if two meanDistPhi values for each gp, iLayer,iRefLayer, are used - we need one bit more for the address
0101 
0102       edm::LogVerbatim("OMTFReconstruction")
0103           << "XMLConfigReader::readLUTs: meanDistPhi LUT address width: " << totalInWidth
0104           << " meanDistPhiValCnt: " << meanDistPhiValCnt << " useMeanDistPhi1 " << useMeanDistPhi1 << std::endl;
0105     }
0106     if (type == "pdf") {
0107       outWidth = aConfig.nPdfValBits();
0108       int pdfValCnt = aGPs.size() * aGPs.at(0)->getPdf().num_elements();
0109       totalInWidth = boost::multiprecision::msb(pdfValCnt) + 1;  //totalInWidth = 21;
0110       //the index of msb is zero-based, so +1 is needed to have the number of bits
0111 
0112       edm::LogVerbatim("OMTFReconstruction") << "XMLConfigReader::readLUTs: pdf LUT address width: " << totalInWidth
0113                                              << " pdfValCnt: " << pdfValCnt << std::endl;
0114     }
0115     if (type == "selDistPhiShift") {
0116       outWidth = 2;
0117 
0118       int distPhiShiftValCnt =
0119           aGPs.size() * aGPs.at(0)->getMeanDistPhi().size() * aGPs.at(0)->getMeanDistPhi()[0].size();
0120       //distPhiShiftValCnt = aGPs.size() * omtfConfig->nLayers() * omtfConfig->nRefLayers() - should give the same as above
0121 
0122       totalInWidth = boost::multiprecision::msb(distPhiShiftValCnt) + 1;  //totalInWidth = 14;
0123       //the index of msb is zero-based, so +1 is needed to have the number of bits
0124 
0125       edm::LogVerbatim("OMTFReconstruction")
0126           << "XMLConfigReader::readLUTs: distPhiShift LUT address width: " << totalInWidth
0127           << " distPhiShiftValCnt: " << distPhiShiftValCnt << std::endl;
0128     }
0129 
0130     ///Prepare the header
0131     strStream << "#<header> V1 " << totalInWidth << " " << outWidth << " </header> " << std::endl;
0132 
0133     unsigned int in = 0;
0134     int out = 0;
0135     for (auto &it : aGPs) {
0136       if (type == "iCharge")
0137         out = it->key().theCharge == -1 ? 0 : 1;
0138       //changing only -1 (negative charge) to 0 (to avoid negative numbers in LUT?) -N.B. that this is not the uGMT charge convention!!!!
0139       if (type == "iEta")
0140         out = it->key().theEtaCode;
0141       if (type == "iPt")
0142         out = it->key().thePt;
0143       if (type == "meanDistPhi") {
0144         int meanDistPhiSize = aConfig.nGoldenPatterns() * aConfig.nLayers() * aConfig.nRefLayers();
0145         for (unsigned int iLayer = 0; iLayer < (unsigned)aConfig.nLayers(); ++iLayer) {
0146           for (unsigned int iRefLayer = 0; iRefLayer < (unsigned)aConfig.nRefLayers(); ++iRefLayer) {
0147             out = (1 << (outWidth - 1)) + it->getMeanDistPhi()[iLayer][iRefLayer][0];
0148             //making the LUT values positive - it is needed because the outWidth is not 32 and the dataMask_ in LUT affects the negative values. Would be better to just use outWidth=32
0149             strStream << in << " " << out << std::endl;
0150 
0151             if (useMeanDistPhi1) {
0152               out = (1 << (outWidth - 1)) + it->getMeanDistPhi()[iLayer][iRefLayer][1];
0153               //making the LUT values positive - it is needed because the outWidth is not 32 and the dataMask_ in LUT affects the negative values. Would be better to just use outWidth=32
0154               strStream << (in + meanDistPhiSize) << " " << out << std::endl;
0155               //writing the second value of the getMeanDistPhi at the position (in+meanDistPhiSize)
0156             }
0157             ++in;
0158           }
0159         }
0160       }
0161       if (type == "selDistPhiShift") {
0162         for (unsigned int iLayer = 0; iLayer < (unsigned)aConfig.nLayers(); ++iLayer) {
0163           for (unsigned int iRefLayer = 0; iRefLayer < (unsigned)aConfig.nRefLayers(); ++iRefLayer) {
0164             out = it->getDistPhiBitShift(iLayer, iRefLayer);
0165             strStream << in << " " << out << std::endl;
0166             ++in;
0167           }
0168         }
0169       }
0170 
0171       //edm::LogVerbatim("OMTFReconstruction")<<"serializing pattern "<<it->key()<<std::endl;
0172       if (type == "pdf") {
0173         for (unsigned int iLayer = 0; iLayer < (unsigned)aConfig.nLayers(); ++iLayer) {
0174           for (unsigned int iRefLayer = 0; iRefLayer < (unsigned)aConfig.nRefLayers(); ++iRefLayer) {
0175             for (unsigned int iPdf = 0; iPdf < exp2(aConfig.nPdfAddrBits()); ++iPdf) {
0176               out = it->pdfValue(iLayer, iRefLayer, iPdf);
0177               strStream << in << " " << out << std::endl;
0178               //edm::LogVerbatim("OMTFReconstruction")<<" iLayer "<<iLayer<<" iRefLayer "<<iRefLayer<<" iPdf "<<iPdf << " address "<<in<<" value "<<out<<std::endl;
0179               ++in;
0180             }
0181           }
0182         }
0183       }
0184       if (type != "meanDistPhi" && type != "pdf" && type != "selDistPhiShift") {
0185         strStream << in << " " << out << std::endl;
0186         ++in;
0187       }
0188     }
0189 
0190     ///Read the data into LUT
0191     int result = lut->read(strStream);
0192 
0193     if (result != l1t::LUT::SUCCESS) {
0194       throw cms::Exception(
0195           "OMTF::XMLConfigReader::readLUTs: lut->read(strStream) did not returned l1t::LUT::SUCCESS but " +
0196           std::to_string(result));
0197     }
0198   }
0199 }
0200 //////////////////////////////////////////////////
0201 //////////////////////////////////////////////////
0202 unsigned int XMLConfigReader::getPatternsVersion() const {
0203   if (patternsFiles.empty())
0204     return 0;
0205   std::string patternsFile = patternsFiles[0];
0206   if (patternsFile.empty())
0207     return 0;
0208 
0209   unsigned int version = 0;
0210   XMLPlatformUtils::Initialize();
0211   {
0212     XercesDOMParser parser;
0213     parser.setValidationScheme(XercesDOMParser::Val_Auto);
0214     parser.setDoNamespaces(false);
0215 
0216     parser.parse(patternsFile.c_str());
0217     xercesc::DOMDocument *doc = parser.getDocument();
0218     assert(doc);
0219 
0220     XMLCh *xmlOmtf = _toDOMS("OMTF");
0221     XMLCh *xmlVersion = _toDOMS("version");
0222     DOMNode *aNode = doc->getElementsByTagName(xmlOmtf)->item(0);
0223     DOMElement *aOMTFElement = static_cast<DOMElement *>(aNode);
0224 
0225     version = std::stoul(_toString(aOMTFElement->getAttribute(xmlVersion)), nullptr, 16);
0226     XMLString::release(&xmlOmtf);
0227     XMLString::release(&xmlVersion);
0228     parser.resetDocumentPool();
0229   }
0230   XMLPlatformUtils::Terminate();
0231 
0232   return version;
0233 }
0234 //////////////////////////////////////////////////
0235 //////////////////////////////////////////////////
0236 template <class GoldenPatternType>
0237 GoldenPatternVec<GoldenPatternType> XMLConfigReader::readPatterns(const L1TMuonOverlapParams &aConfig,
0238                                                                   const std::string &patternsFile,
0239                                                                   bool buildEmptyPatterns,
0240                                                                   bool resetNumbering) {
0241   GoldenPatternVec<GoldenPatternType> aGPs;
0242   aGPs.clear();
0243 
0244   XMLPlatformUtils::Initialize();
0245 
0246   if (resetNumbering) {
0247     iGPNumber = 0;
0248     iPatternGroup = 0;
0249   }
0250 
0251   XMLCh *xmlGP = _toDOMS("GP");
0252   std::array<XMLCh *, 4> xmliPt = {{_toDOMS("iPt1"), _toDOMS("iPt2"), _toDOMS("iPt3"), _toDOMS("iPt4")}};
0253 
0254   {
0255     XercesDOMParser parser;
0256     parser.setValidationScheme(XercesDOMParser::Val_Auto);
0257     parser.setDoNamespaces(false);
0258 
0259     parser.parse(patternsFile.c_str());
0260     xercesc::DOMDocument *doc = parser.getDocument();
0261     assert(doc);
0262 
0263     unsigned int nElem = doc->getElementsByTagName(xmlGP)->getLength();
0264     if (nElem < 1) {
0265       edm::LogError("critical") << "Problem parsing XML file " << patternsFile << std::endl;
0266       edm::LogError("critical") << "No GoldenPattern items: GP found" << std::endl;
0267       return aGPs;
0268     }
0269 
0270     DOMNode *aNode = nullptr;
0271     DOMElement *aGPElement = nullptr;
0272     //unsigned int iGPNumber=0;
0273 
0274     for (unsigned int iItem = 0; iItem < nElem; ++iItem, ++iPatternGroup) {
0275       aNode = doc->getElementsByTagName(xmlGP)->item(iItem);
0276       aGPElement = static_cast<DOMElement *>(aNode);
0277 
0278       for (unsigned int index = 1; index < 5; ++index) {
0279         ///Patterns XML format backward compatibility. Can use both packed by 4, or by 1 XML files.
0280         if (aGPElement->getAttributeNode(xmliPt[index - 1])) {
0281           std::unique_ptr<GoldenPatternType> aGP =
0282               buildGP<GoldenPatternType>(aGPElement, aConfig, iPatternGroup, index, iGPNumber);
0283           if (aGP && (aGP->key().thePt || buildEmptyPatterns)) {
0284             aGPs.emplace_back(std::move(aGP));
0285             iGPNumber++;
0286           }
0287         } else {
0288           std::unique_ptr<GoldenPatternType> aGP = buildGP<GoldenPatternType>(aGPElement, aConfig, iPatternGroup);
0289           if (aGP && (aGP->key().thePt || buildEmptyPatterns)) {
0290             aGPs.emplace_back(std::move(aGP));
0291             iGPNumber++;
0292           }
0293           break;
0294         }
0295       }
0296     }
0297 
0298     // Reset the documents vector pool and release all the associated memory back to the system.
0299     //parser->resetDocumentPool();
0300     parser.resetDocumentPool();
0301   }
0302   XMLString::release(&xmlGP);
0303   XMLString::release(&xmliPt[0]);
0304   XMLString::release(&xmliPt[1]);
0305   XMLString::release(&xmliPt[2]);
0306   XMLString::release(&xmliPt[3]);
0307 
0308   XMLPlatformUtils::Terminate();
0309 
0310   return aGPs;
0311 }
0312 //////////////////////////////////////////////////
0313 //////////////////////////////////////////////////
0314 template <class GoldenPatternType>
0315 GoldenPatternVec<GoldenPatternType> XMLConfigReader::readPatterns(const L1TMuonOverlapParams &aConfig,
0316                                                                   const std::vector<std::string> &patternsFiles,
0317                                                                   bool buildEmptyPatterns) {
0318   iGPNumber = 0;
0319   iPatternGroup = 0;
0320   GoldenPatternVec<GoldenPatternType> aGPs;
0321   for (const auto &aPatternsFile : patternsFiles) {
0322     auto tmpGPs = readPatterns<GoldenPatternType>(aConfig, aPatternsFile, buildEmptyPatterns, false);
0323     for (auto &gp : tmpGPs)
0324       aGPs.push_back(std::move(gp));
0325   }
0326   return aGPs;
0327 }
0328 //////////////////////////////////////////////////
0329 //////////////////////////////////////////////////
0330 template <class GoldenPatternType>
0331 std::unique_ptr<GoldenPatternType> XMLConfigReader::buildGP(DOMElement *aGPElement,
0332                                                             const L1TMuonOverlapParams &aConfig,
0333                                                             unsigned int patternGroup,
0334                                                             unsigned int index,
0335                                                             unsigned int aGPNumber) {
0336   XMLCh *xmliEta = _toDOMS("iEta");
0337   //index 0 means no number at the end
0338   std::ostringstream stringStr;
0339   if (index > 0)
0340     stringStr << "iPt" << index;
0341   else
0342     stringStr.str("iPt");
0343   XMLCh *xmliPt = _toDOMS(stringStr.str());
0344   stringStr.str("");
0345 
0346   if (index > 0)
0347     stringStr << "value" << index;
0348   else
0349     stringStr.str("value");
0350   XMLCh *xmlValue = _toDOMS(stringStr.str());
0351 
0352   XMLCh *xmliCharge = _toDOMS("iCharge");
0353   XMLCh *xmlLayer = _toDOMS("Layer");
0354   XMLCh *xmlRefLayer = _toDOMS("RefLayer");
0355   XMLCh *xmlmeanDistPhi = _toDOMS("meanDistPhi");  //for old version
0356 
0357   XMLCh *xmlmeanDistPhi0 = _toDOMS("meanDistPhi0");  //for new version
0358   XMLCh *xmlmeanDistPhi1 = _toDOMS("meanDistPhi1");  //for new version
0359 
0360   XMLCh *xmlSelDistPhiShift = _toDOMS("selDistPhiShift");
0361 
0362   XMLCh *xmlPDF = _toDOMS("PDF");
0363 
0364   unsigned int iPt = std::atoi(_toString(aGPElement->getAttribute(xmliPt)).c_str());
0365   int iEta = std::atoi(_toString(aGPElement->getAttribute(xmliEta)).c_str());
0366   int iCharge = std::atoi(_toString(aGPElement->getAttribute(xmliCharge)).c_str());
0367   unsigned int nLayers = aGPElement->getElementsByTagName(xmlLayer)->getLength();
0368 
0369   if (nLayers)
0370     assert(nLayers == (unsigned)aConfig.nLayers());
0371 
0372   DOMNode *aNode = nullptr;
0373   DOMElement *aLayerElement = nullptr;
0374   DOMElement *aItemElement = nullptr;
0375 
0376   if (iPt == 0) {  ///Build empty GP
0377     Key aKey(iEta, iPt, iCharge, aGPNumber);
0378     auto aGP =
0379         std::make_unique<GoldenPatternType>(aKey, aConfig.nLayers(), aConfig.nRefLayers(), aConfig.nPdfAddrBits());
0380     return aGP;
0381   }
0382 
0383   stringStr.str("");
0384   XMLCh *xmlRefLayerThresh = _toDOMS("RefLayerThresh");
0385   if (index > 0)
0386     stringStr << "tresh" << index;
0387   else
0388     stringStr.str("tresh");
0389   XMLCh *xmlTresh = _toDOMS(stringStr.str());
0390   stringStr.str("");
0391 
0392   std::vector<PdfValueType> thresholds(aConfig.nRefLayers(), 0);
0393   unsigned int nItems = aGPElement->getElementsByTagName(xmlRefLayerThresh)->getLength();
0394   if (nItems > 0 && nItems != thresholds.size()) {
0395     throw cms::Exception("OMTF::XMLConfigReader: nItems != thresholds.size()");
0396   }
0397   for (unsigned int iItem = 0; iItem < nItems; ++iItem) {
0398     aNode = aGPElement->getElementsByTagName(xmlRefLayerThresh)->item(iItem);
0399     aItemElement = dynamic_cast<DOMElement *>(aNode);
0400     if (aItemElement == nullptr)
0401       throw cms::Exception("OMTF::XMLConfigReader: aItemElement is 0");
0402     std::string strVal = _toString(aItemElement->getAttribute(xmlTresh));
0403     thresholds[iItem] = std::stof(strVal);
0404     //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" strVal "<<strVal<<" thresholds[iItem] "<<thresholds[iItem]<<std::endl;
0405   }
0406 
0407   ///Loop over layers
0408   Key aKey(iEta, iPt, iCharge, aGPNumber);
0409   aKey.theGroup = patternGroup;
0410   aKey.theIndexInGroup = index;
0411   auto aGP = std::make_unique<GoldenPatternType>(aKey, aConfig.nLayers(), aConfig.nRefLayers(), aConfig.nPdfAddrBits());
0412   if (dynamic_cast<GoldenPatternWithThresh *>(aGP.get())) {
0413     dynamic_cast<GoldenPatternWithThresh *>(aGP.get())->setThresholds(thresholds);
0414   }
0415   for (unsigned int iLayer = 0; iLayer < nLayers; ++iLayer) {
0416     aNode = aGPElement->getElementsByTagName(xmlLayer)->item(iLayer);
0417     aLayerElement = static_cast<DOMElement *>(aNode);
0418     ///MeanDistPhi vector
0419     unsigned int nItems = aLayerElement->getElementsByTagName(xmlRefLayer)->getLength();
0420     assert(nItems == (unsigned)aConfig.nRefLayers());
0421     for (unsigned int iItem = 0; iItem < nItems; ++iItem) {
0422       aNode = aLayerElement->getElementsByTagName(xmlRefLayer)->item(iItem);
0423       aItemElement = static_cast<DOMElement *>(aNode);
0424 
0425       std::string strVal = _toString(aItemElement->getAttribute(xmlmeanDistPhi));
0426       if (!strVal.empty()) {
0427         aGP->setMeanDistPhiValue(std::stoi(strVal), iLayer, iItem, 0);
0428       } else {
0429         strVal = _toString(aItemElement->getAttribute(xmlmeanDistPhi0));
0430         aGP->setMeanDistPhiValue(std::stoi(strVal), iLayer, iItem, 0);
0431         strVal = _toString(aItemElement->getAttribute(xmlmeanDistPhi1));
0432         aGP->setMeanDistPhiValue(std::stoi(strVal), iLayer, iItem, 1);
0433       }
0434 
0435       strVal = _toString(aItemElement->getAttribute(xmlSelDistPhiShift));
0436       if (!strVal.empty()) {
0437         aGP->setDistPhiBitShift(std::stoi(strVal), iLayer, iItem);
0438       }
0439     }
0440 
0441     ///PDF vector
0442     nItems = aLayerElement->getElementsByTagName(xmlPDF)->getLength();
0443 
0444     //debug
0445     //if(nItems!=aConfig.nRefLayers()*exp2(aConfig.nPdfAddrBits()))
0446     //LogTrace("l1tOmtfEventPrint")<<" iPt "<<iPt<<" iLayer "<<iLayer<<" nLayers "<<nLayers<<" nItems "<<nItems<<" nRefLayers "<<aConfig.nRefLayers()<<" nPdfAddrBits "<<aConfig.nPdfAddrBits()<<std::endl;
0447 
0448     assert(nItems == aConfig.nRefLayers() * exp2(aConfig.nPdfAddrBits()));
0449     for (unsigned int iRefLayer = 0; iRefLayer < (unsigned)aConfig.nRefLayers(); ++iRefLayer) {
0450       for (unsigned int iPdf = 0; iPdf < exp2(aConfig.nPdfAddrBits()); ++iPdf) {
0451         aNode = aLayerElement->getElementsByTagName(xmlPDF)->item(iRefLayer * exp2(aConfig.nPdfAddrBits()) + iPdf);
0452         aItemElement = static_cast<DOMElement *>(aNode);
0453         PdfValueType val = std::atof(_toString(aItemElement->getAttribute(xmlValue)).c_str());
0454         aGP->setPdfValue(val, iLayer, iRefLayer, iPdf);
0455       }
0456     }
0457   }
0458   XMLString::release(&xmliEta);
0459   XMLString::release(&xmliPt);
0460   XMLString::release(&xmliCharge);
0461   XMLString::release(&xmlLayer);
0462   XMLString::release(&xmlRefLayer);
0463   XMLString::release(&xmlmeanDistPhi);
0464   XMLString::release(&xmlPDF);
0465   XMLString::release(&xmlValue);
0466 
0467   return aGP;
0468 }
0469 //////////////////////////////////////////////////
0470 //////////////////////////////////////////////////
0471 std::vector<std::vector<int> > XMLConfigReader::readEvent(unsigned int iEvent, unsigned int iProcessor, bool readEta) {
0472   return std::vector<std::vector<int> >();
0473 }
0474 //////////////////////////////////////////////////
0475 //////////////////////////////////////////////////
0476 void XMLConfigReader::readConfig(L1TMuonOverlapParams *aConfig) const {
0477   XMLPlatformUtils::Initialize();
0478   {
0479     XercesDOMParser parser;
0480     parser.setValidationScheme(XercesDOMParser::Val_Auto);
0481     parser.setDoNamespaces(false);
0482 
0483     XMLCh *xmlOMTF = _toDOMS("OMTF");
0484     XMLCh *xmlversion = _toDOMS("version");
0485     XMLCh *xmlGlobalData = _toDOMS("GlobalData");
0486     XMLCh *xmlnPdfAddrBits = _toDOMS("nPdfAddrBits");
0487     XMLCh *xmlnPdfValBits = _toDOMS("nPdfValBits");
0488     XMLCh *xmlnPhiBits = _toDOMS("nPhiBits");
0489     XMLCh *xmlnPhiBins = _toDOMS("nPhiBins");
0490     XMLCh *xmlnProcessors = _toDOMS("nProcessors");
0491     XMLCh *xmlnLogicRegions = _toDOMS("nLogicRegions");
0492     XMLCh *xmlnInputs = _toDOMS("nInputs");
0493     XMLCh *xmlnLayers = _toDOMS("nLayers");
0494     XMLCh *xmlnRefLayers = _toDOMS("nRefLayers");
0495     XMLCh *xmliProcessor = _toDOMS("iProcessor");
0496     XMLCh *xmlbarrelMin = _toDOMS("barrelMin");
0497     XMLCh *xmlbarrelMax = _toDOMS("barrelMax");
0498     XMLCh *xmlendcap10DegMin = _toDOMS("endcap10DegMin");
0499     XMLCh *xmlendcap10DegMax = _toDOMS("endcap10DegMax");
0500     XMLCh *xmlendcap20DegMin = _toDOMS("endcap20DegMin");
0501     XMLCh *xmlendcap20DegMax = _toDOMS("endcap20DegMax");
0502     XMLCh *xmlLayerMap = _toDOMS("LayerMap");
0503     XMLCh *xmlhwNumber = _toDOMS("hwNumber");
0504     XMLCh *xmllogicNumber = _toDOMS("logicNumber");
0505     XMLCh *xmlbendingLayer = _toDOMS("bendingLayer");
0506     XMLCh *xmlconnectedToLayer = _toDOMS("connectedToLayer");
0507     XMLCh *xmlRefLayerMap = _toDOMS("RefLayerMap");
0508     XMLCh *xmlrefLayer = _toDOMS("refLayer");
0509     XMLCh *xmlProcessor = _toDOMS("Processor");
0510     XMLCh *xmlRefLayer = _toDOMS("RefLayer");
0511     XMLCh *xmliRefLayer = _toDOMS("iRefLayer");
0512     XMLCh *xmliGlobalPhiStart = _toDOMS("iGlobalPhiStart");
0513     XMLCh *xmlRefHit = _toDOMS("RefHit");
0514     XMLCh *xmliRefHit = _toDOMS("iRefHit");
0515     XMLCh *xmliPhiMin = _toDOMS("iPhiMin");
0516     XMLCh *xmliPhiMax = _toDOMS("iPhiMax");
0517     XMLCh *xmliInput = _toDOMS("iInput");
0518     XMLCh *xmliRegion = _toDOMS("iRegion");
0519     XMLCh *xmlLogicRegion = _toDOMS("LogicRegion");
0520     XMLCh *xmlLayer = _toDOMS("Layer");
0521     XMLCh *xmliLayer = _toDOMS("iLayer");
0522     XMLCh *xmliFirstInput = _toDOMS("iFirstInput");
0523     XMLCh *xmlnHitsPerLayer = _toDOMS("nHitsPerLayer");
0524     XMLCh *xmlnRefHits = _toDOMS("nRefHits");
0525     XMLCh *xmlnTestRefHits = _toDOMS("nTestRefHits");
0526     XMLCh *xmlnGoldenPatterns = _toDOMS("nGoldenPatterns");
0527     XMLCh *xmlConnectionMap = _toDOMS("ConnectionMap");
0528     parser.parse(configFile.c_str());
0529     xercesc::DOMDocument *doc = parser.getDocument();
0530     assert(doc);
0531     unsigned int nElem = doc->getElementsByTagName(xmlOMTF)->getLength();
0532     if (nElem != 1) {
0533       edm::LogError("critical") << "Problem parsing XML file " << configFile << std::endl;
0534       assert(nElem == 1);
0535     }
0536     DOMNode *aNode = doc->getElementsByTagName(xmlOMTF)->item(0);
0537     DOMElement *aOMTFElement = static_cast<DOMElement *>(aNode);
0538 
0539     unsigned int version = std::stoul(_toString(aOMTFElement->getAttribute(xmlversion)), nullptr, 16);
0540     aConfig->setFwVersion(version);
0541 
0542     ///Addresing bits numbers
0543     nElem = aOMTFElement->getElementsByTagName(xmlGlobalData)->getLength();
0544     assert(nElem == 1);
0545     aNode = aOMTFElement->getElementsByTagName(xmlGlobalData)->item(0);
0546     DOMElement *aElement = static_cast<DOMElement *>(aNode);
0547 
0548     unsigned int nPdfAddrBits = std::atoi(_toString(aElement->getAttribute(xmlnPdfAddrBits)).c_str());
0549     unsigned int nPdfValBits = std::atoi(_toString(aElement->getAttribute(xmlnPdfValBits)).c_str());
0550     unsigned int nHitsPerLayer = std::atoi(_toString(aElement->getAttribute(xmlnHitsPerLayer)).c_str());
0551     unsigned int nPhiBits = std::atoi(_toString(aElement->getAttribute(xmlnPhiBits)).c_str());
0552     unsigned int nPhiBins = std::atoi(_toString(aElement->getAttribute(xmlnPhiBins)).c_str());
0553 
0554     unsigned int nRefHits = std::atoi(_toString(aElement->getAttribute(xmlnRefHits)).c_str());
0555     unsigned int nTestRefHits = std::atoi(_toString(aElement->getAttribute(xmlnTestRefHits)).c_str());
0556     unsigned int nProcessors = std::atoi(_toString(aElement->getAttribute(xmlnProcessors)).c_str());
0557     unsigned int nLogicRegions = std::atoi(_toString(aElement->getAttribute(xmlnLogicRegions)).c_str());
0558     unsigned int nInputs = std::atoi(_toString(aElement->getAttribute(xmlnInputs)).c_str());
0559     unsigned int nLayers = std::atoi(_toString(aElement->getAttribute(xmlnLayers)).c_str());
0560     unsigned int nRefLayers = std::atoi(_toString(aElement->getAttribute(xmlnRefLayers)).c_str());
0561     unsigned int nGoldenPatterns = std::atoi(_toString(aElement->getAttribute(xmlnGoldenPatterns)).c_str());
0562 
0563     std::vector<int> paramsVec(L1TMuonOverlapParams::GENERAL_NCONFIG);
0564     paramsVec[L1TMuonOverlapParams::GENERAL_ADDRBITS] = nPdfAddrBits;
0565     paramsVec[L1TMuonOverlapParams::GENERAL_VALBITS] = nPdfValBits;
0566     paramsVec[L1TMuonOverlapParams::GENERAL_HITSPERLAYER] = nHitsPerLayer;
0567     paramsVec[L1TMuonOverlapParams::GENERAL_PHIBITS] = nPhiBits;
0568     paramsVec[L1TMuonOverlapParams::GENERAL_PHIBINS] = nPhiBins;
0569     paramsVec[L1TMuonOverlapParams::GENERAL_NREFHITS] = nRefHits;
0570     paramsVec[L1TMuonOverlapParams::GENERAL_NTESTREFHITS] = nTestRefHits;
0571     paramsVec[L1TMuonOverlapParams::GENERAL_NPROCESSORS] = nProcessors;
0572     paramsVec[L1TMuonOverlapParams::GENERAL_NLOGIC_REGIONS] = nLogicRegions;
0573     paramsVec[L1TMuonOverlapParams::GENERAL_NINPUTS] = nInputs;
0574     paramsVec[L1TMuonOverlapParams::GENERAL_NLAYERS] = nLayers;
0575     paramsVec[L1TMuonOverlapParams::GENERAL_NREFLAYERS] = nRefLayers;
0576     paramsVec[L1TMuonOverlapParams::GENERAL_NGOLDENPATTERNS] = nGoldenPatterns;
0577     aConfig->setGeneralParams(paramsVec);
0578 
0579     ///Chamber sectors connections to logic processors.
0580     ///Start/End values for all processors, and chamber types are put into a single vector
0581     std::vector<int> sectorsStart(3 * nProcessors), sectorsEnd(3 * nProcessors);
0582     nElem = aOMTFElement->getElementsByTagName(xmlConnectionMap)->getLength();
0583     DOMElement *aConnectionElement = nullptr;
0584     for (unsigned int i = 0; i < nElem; ++i) {
0585       aNode = aOMTFElement->getElementsByTagName(xmlConnectionMap)->item(i);
0586       aConnectionElement = static_cast<DOMElement *>(aNode);
0587       unsigned int iProcessor = std::atoi(_toString(aConnectionElement->getAttribute(xmliProcessor)).c_str());
0588       unsigned int barrelMin = std::atoi(_toString(aConnectionElement->getAttribute(xmlbarrelMin)).c_str());
0589       unsigned int barrelMax = std::atoi(_toString(aConnectionElement->getAttribute(xmlbarrelMax)).c_str());
0590       unsigned int endcap10DegMin = std::atoi(_toString(aConnectionElement->getAttribute(xmlendcap10DegMin)).c_str());
0591       unsigned int endcap10DegMax = std::atoi(_toString(aConnectionElement->getAttribute(xmlendcap10DegMax)).c_str());
0592       unsigned int endcap20DegMin = std::atoi(_toString(aConnectionElement->getAttribute(xmlendcap20DegMin)).c_str());
0593       unsigned int endcap20DegMax = std::atoi(_toString(aConnectionElement->getAttribute(xmlendcap20DegMax)).c_str());
0594 
0595       sectorsStart[iProcessor] = barrelMin;
0596       sectorsStart[iProcessor + nProcessors] = endcap10DegMin;
0597       sectorsStart[iProcessor + 2 * nProcessors] = endcap20DegMin;
0598 
0599       sectorsEnd[iProcessor] = barrelMax;
0600       sectorsEnd[iProcessor + nProcessors] = endcap10DegMax;
0601       sectorsEnd[iProcessor + 2 * nProcessors] = endcap20DegMax;
0602     }
0603     aConfig->setConnectedSectorsStart(sectorsStart);
0604     aConfig->setConnectedSectorsEnd(sectorsEnd);
0605 
0606     ///hw <-> logic numbering map
0607     std::vector<L1TMuonOverlapParams::LayerMapNode> aLayerMapVec;
0608     L1TMuonOverlapParams::LayerMapNode aLayerMapNode;
0609 
0610     nElem = aOMTFElement->getElementsByTagName(xmlLayerMap)->getLength();
0611     DOMElement *aLayerElement = nullptr;
0612     for (unsigned int i = 0; i < nElem; ++i) {
0613       aNode = aOMTFElement->getElementsByTagName(xmlLayerMap)->item(i);
0614       aLayerElement = static_cast<DOMElement *>(aNode);
0615       unsigned int hwNumber = std::atoi(_toString(aLayerElement->getAttribute(xmlhwNumber)).c_str());
0616       unsigned int logicNumber = std::atoi(_toString(aLayerElement->getAttribute(xmllogicNumber)).c_str());
0617       unsigned int isBendingLayer = std::atoi(_toString(aLayerElement->getAttribute(xmlbendingLayer)).c_str());
0618       unsigned int iConnectedLayer = std::atoi(_toString(aLayerElement->getAttribute(xmlconnectedToLayer)).c_str());
0619       aLayerMapNode.logicNumber = logicNumber;
0620       aLayerMapNode.hwNumber = hwNumber;
0621       aLayerMapNode.connectedToLayer = iConnectedLayer;
0622       aLayerMapNode.bendingLayer = isBendingLayer;
0623       aLayerMapVec.push_back(aLayerMapNode);
0624     }
0625     aConfig->setLayerMap(aLayerMapVec);
0626 
0627     ///ref<->logic numberig map
0628     std::vector<L1TMuonOverlapParams::RefLayerMapNode> aRefLayerMapVec;
0629     L1TMuonOverlapParams::RefLayerMapNode aRefLayerNode;
0630 
0631     nElem = aOMTFElement->getElementsByTagName(xmlRefLayerMap)->getLength();
0632     DOMElement *aRefLayerElement = nullptr;
0633     for (unsigned int i = 0; i < nElem; ++i) {
0634       aNode = aOMTFElement->getElementsByTagName(xmlRefLayerMap)->item(i);
0635       aRefLayerElement = static_cast<DOMElement *>(aNode);
0636       unsigned int refLayer = std::atoi(_toString(aRefLayerElement->getAttribute(xmlrefLayer)).c_str());
0637       unsigned int logicNumber = std::atoi(_toString(aRefLayerElement->getAttribute(xmllogicNumber)).c_str());
0638       aRefLayerNode.refLayer = refLayer;
0639       aRefLayerNode.logicNumber = logicNumber;
0640       aRefLayerMapVec.push_back(aRefLayerNode);
0641     }
0642     aConfig->setRefLayerMap(aRefLayerMapVec);
0643 
0644     std::vector<int> aGlobalPhiStartVec(nProcessors * nRefLayers);
0645 
0646     std::vector<L1TMuonOverlapParams::RefHitNode> aRefHitMapVec(nProcessors * nRefHits);
0647     L1TMuonOverlapParams::RefHitNode aRefHitNode;
0648 
0649     std::vector<L1TMuonOverlapParams::LayerInputNode> aLayerInputMapVec(nProcessors * nLogicRegions * nLayers);
0650     L1TMuonOverlapParams::LayerInputNode aLayerInputNode;
0651 
0652     nElem = aOMTFElement->getElementsByTagName(xmlProcessor)->getLength();
0653     assert(nElem == nProcessors);
0654     DOMElement *aProcessorElement = nullptr;
0655     for (unsigned int i = 0; i < nElem; ++i) {
0656       aNode = aOMTFElement->getElementsByTagName(xmlProcessor)->item(i);
0657       aProcessorElement = static_cast<DOMElement *>(aNode);
0658       unsigned int iProcessor = std::atoi(_toString(aProcessorElement->getAttribute(xmliProcessor)).c_str());
0659       unsigned int nElem1 = aProcessorElement->getElementsByTagName(xmlRefLayer)->getLength();
0660       assert(nElem1 == nRefLayers);
0661       DOMElement *aRefLayerElement = nullptr;
0662       for (unsigned int ii = 0; ii < nElem1; ++ii) {
0663         aNode = aProcessorElement->getElementsByTagName(xmlRefLayer)->item(ii);
0664         aRefLayerElement = static_cast<DOMElement *>(aNode);
0665         unsigned int iRefLayer = std::atoi(_toString(aRefLayerElement->getAttribute(xmliRefLayer)).c_str());
0666         int iPhi = std::atoi(_toString(aRefLayerElement->getAttribute(xmliGlobalPhiStart)).c_str());
0667         aGlobalPhiStartVec[iRefLayer + iProcessor * nRefLayers] = iPhi;
0668       }
0669       ///////////
0670       nElem1 = aProcessorElement->getElementsByTagName(xmlRefHit)->getLength();
0671       assert((iProcessor == 0 && nElem1 == nRefHits) || (iProcessor != 0 && nElem1 == 0));
0672       DOMElement *aRefHitElement = nullptr;
0673       for (unsigned int ii = 0; ii < nElem1; ++ii) {
0674         aNode = aProcessorElement->getElementsByTagName(xmlRefHit)->item(ii);
0675         aRefHitElement = static_cast<DOMElement *>(aNode);
0676         unsigned int iRefHit = std::atoi(_toString(aRefHitElement->getAttribute(xmliRefHit)).c_str());
0677         int iPhiMin = std::atoi(_toString(aRefHitElement->getAttribute(xmliPhiMin)).c_str());
0678         int iPhiMax = std::atoi(_toString(aRefHitElement->getAttribute(xmliPhiMax)).c_str());
0679         unsigned int iInput = std::atoi(_toString(aRefHitElement->getAttribute(xmliInput)).c_str());
0680         unsigned int iRegion = std::atoi(_toString(aRefHitElement->getAttribute(xmliRegion)).c_str());
0681         unsigned int iRefLayer = std::atoi(_toString(aRefHitElement->getAttribute(xmliRefLayer)).c_str());
0682 
0683         aRefHitNode.iRefHit = iRefHit;
0684         aRefHitNode.iPhiMin = iPhiMin;
0685         aRefHitNode.iPhiMax = iPhiMax;
0686         aRefHitNode.iInput = iInput;
0687         aRefHitNode.iRegion = iRegion;
0688         aRefHitNode.iRefLayer = iRefLayer;
0689         for (unsigned int iProcessor = 0; iProcessor < nProcessors; iProcessor++)
0690           aRefHitMapVec[iRefHit + iProcessor * nRefHits] = aRefHitNode;
0691       }
0692       ///////////
0693       unsigned int nElem2 = aProcessorElement->getElementsByTagName(xmlLogicRegion)->getLength();
0694       assert((iProcessor == 0 && nElem2 == nLogicRegions) || (iProcessor != 0 && nElem2 == 0));
0695       DOMElement *aRegionElement = nullptr;
0696       for (unsigned int ii = 0; ii < nElem2; ++ii) {
0697         aNode = aProcessorElement->getElementsByTagName(xmlLogicRegion)->item(ii);
0698         aRegionElement = static_cast<DOMElement *>(aNode);
0699         unsigned int iRegion = std::atoi(_toString(aRegionElement->getAttribute(xmliRegion)).c_str());
0700         unsigned int nElem3 = aRegionElement->getElementsByTagName(xmlLayer)->getLength();
0701         assert(nElem3 == nLayers);
0702         DOMElement *aLayerElement = nullptr;
0703         for (unsigned int iii = 0; iii < nElem3; ++iii) {
0704           aNode = aRegionElement->getElementsByTagName(xmlLayer)->item(iii);
0705           aLayerElement = static_cast<DOMElement *>(aNode);
0706           unsigned int iLayer = std::atoi(_toString(aLayerElement->getAttribute(xmliLayer)).c_str());
0707           unsigned int iFirstInput = std::atoi(_toString(aLayerElement->getAttribute(xmliFirstInput)).c_str());
0708           unsigned int nInputs = std::atoi(_toString(aLayerElement->getAttribute(xmlnInputs)).c_str());
0709           aLayerInputNode.iLayer = iLayer;
0710           aLayerInputNode.iFirstInput = iFirstInput;
0711           aLayerInputNode.nInputs = nInputs;
0712           for (unsigned int iProcessor = 0; iProcessor < nProcessors; ++iProcessor)
0713             aLayerInputMapVec[iLayer + iRegion * nLayers + iProcessor * nLayers * nLogicRegions] = aLayerInputNode;
0714         }
0715       }
0716     }
0717 
0718     aConfig->setGlobalPhiStartMap(aGlobalPhiStartVec);
0719     aConfig->setLayerInputMap(aLayerInputMapVec);
0720     aConfig->setRefHitMap(aRefHitMapVec);
0721 
0722     // Reset the documents vector pool and release all the associated memory back to the system.
0723     parser.resetDocumentPool();
0724 
0725     XMLString::release(&xmlOMTF);
0726     XMLString::release(&xmlversion);
0727     XMLString::release(&xmlGlobalData);
0728     XMLString::release(&xmlnPdfAddrBits);
0729     XMLString::release(&xmlnPdfValBits);
0730     XMLString::release(&xmlnPhiBits);
0731     XMLString::release(&xmlnPhiBins);
0732     XMLString::release(&xmlnProcessors);
0733     XMLString::release(&xmlnLogicRegions);
0734     XMLString::release(&xmlnInputs);
0735     XMLString::release(&xmlnLayers);
0736     XMLString::release(&xmlnRefLayers);
0737     XMLString::release(&xmliProcessor);
0738     XMLString::release(&xmlbarrelMin);
0739     XMLString::release(&xmlbarrelMax);
0740     XMLString::release(&xmlendcap10DegMin);
0741     XMLString::release(&xmlendcap10DegMax);
0742     XMLString::release(&xmlendcap20DegMin);
0743     XMLString::release(&xmlendcap20DegMax);
0744     XMLString::release(&xmlLayerMap);
0745     XMLString::release(&xmlhwNumber);
0746     XMLString::release(&xmllogicNumber);
0747     XMLString::release(&xmlbendingLayer);
0748     XMLString::release(&xmlconnectedToLayer);
0749     XMLString::release(&xmlRefLayerMap);
0750     XMLString::release(&xmlrefLayer);
0751     XMLString::release(&xmlProcessor);
0752     XMLString::release(&xmlRefLayer);
0753     XMLString::release(&xmliRefLayer);
0754     XMLString::release(&xmliGlobalPhiStart);
0755     XMLString::release(&xmlRefHit);
0756     XMLString::release(&xmliRefHit);
0757     XMLString::release(&xmliPhiMin);
0758     XMLString::release(&xmliPhiMax);
0759     XMLString::release(&xmliInput);
0760     XMLString::release(&xmliRegion);
0761     XMLString::release(&xmlLogicRegion);
0762     XMLString::release(&xmlLayer);
0763     XMLString::release(&xmliLayer);
0764     XMLString::release(&xmliFirstInput);
0765     XMLString::release(&xmlnHitsPerLayer);
0766     XMLString::release(&xmlnRefHits);
0767     XMLString::release(&xmlnTestRefHits);
0768     XMLString::release(&xmlnGoldenPatterns);
0769     XMLString::release(&xmlConnectionMap);
0770   }
0771   XMLPlatformUtils::Terminate();
0772 }
0773 //////////////////////////////////////////////////
0774 //////////////////////////////////////////////////
0775 
0776 template GoldenPatternVec<GoldenPattern> XMLConfigReader::readPatterns<GoldenPattern>(
0777     const L1TMuonOverlapParams &aConfig,
0778     const std::string &patternsFile,
0779     bool buildEmptyPatterns,
0780     bool resetNumbering = true);
0781 
0782 template GoldenPatternVec<GoldenPattern> XMLConfigReader::readPatterns<GoldenPattern>(
0783     const L1TMuonOverlapParams &aConfig, const std::vector<std::string> &patternsFiles, bool buildEmptyPatterns);
0784 
0785 template GoldenPatternVec<GoldenPatternWithStat> XMLConfigReader::readPatterns<GoldenPatternWithStat>(
0786     const L1TMuonOverlapParams &aConfig,
0787     const std::string &patternsFile,
0788     bool buildEmptyPatterns,
0789     bool resetNumbering = true);
0790 
0791 template GoldenPatternVec<GoldenPatternWithStat> XMLConfigReader::readPatterns<GoldenPatternWithStat>(
0792     const L1TMuonOverlapParams &aConfig, const std::vector<std::string> &patternsFiles, bool buildEmptyPatterns);