Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:00:01

0001 #include "CalibTracker/StandaloneTrackerTopology/interface/StandaloneTrackerTopology.h"
0002 
0003 #include "tinyxml2.h"
0004 #include "FWCore/Utilities/interface/Exception.h"
0005 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0006 
0007 namespace {
0008   // split into tokens and convert them to uint32_t
0009   inline std::vector<uint32_t> split_string_to_uints(const std::string& str) {
0010     std::vector<uint32_t> out{};
0011     std::size_t iStart{str.find_first_not_of(" ,\n")}, iEnd{};
0012     while (std::string::npos != iStart) {
0013       iEnd = str.find_first_of(" ,\n", iStart);
0014       out.push_back(std::stoul(str.substr(iStart, iEnd), nullptr, 0));
0015       iStart = str.find_first_not_of(" ,\n", iEnd);
0016     }
0017     return out;
0018   }
0019 
0020   class TrackerTopologyExtractor : public tinyxml2::XMLVisitor {
0021   public:
0022     bool VisitEnter(const tinyxml2::XMLElement& elem, const tinyxml2::XMLAttribute*) override {
0023       if (std::strcmp(elem.Value(), "Vector") == 0) {
0024         const std::string att_type{elem.Attribute("type")};
0025         if (att_type == "numeric") {
0026           const std::string att_name{elem.Attribute("name")};
0027           if (0 == att_name.compare(0, SubdetName.size(), SubdetName)) {  // starts with
0028             const std::string att_nEntries{elem.Attribute("nEntries")};
0029             const std::size_t nEntries = att_nEntries.empty() ? 0 : std::stoul(att_nEntries);
0030             const auto vals = split_string_to_uints(elem.GetText());
0031 
0032             if (nEntries != vals.size()) {
0033               throw cms::Exception(
0034                   "StandaloneTrackerTopology",
0035                   ("Problem parsing element with name '" + att_name + "': " + "'nEntries' attribute claims " +
0036                    std::to_string(nEntries) + " elements, but parsed " + std::to_string(vals.size())));
0037             }
0038             const auto subDet = std::stoi(att_name.substr(SubdetName.size()));
0039             switch (subDet) {
0040               case PixelSubdetector::PixelBarrel:  // layer, ladder module
0041 
0042                 /*
0043           In the case of the phase-2 IT there is an additional layer of hierarcy, due ot split sensors in Layer 1
0044           What follows is a ugly hack, but at least is consistent with TrackerTopologyEP.cc
0045         */
0046 
0047                 if (vals.size() > 6) {  // Phase 2: extra hierarchy level for 3D sensors
0048                   pxbVals_.layerStartBit_ = vals[0];
0049                   pxbVals_.ladderStartBit_ = vals[1];
0050                   pxbVals_.moduleStartBit_ = vals[2];
0051                   pxbVals_.doubleStartBit_ = vals[3];
0052 
0053                   pxbVals_.layerMask_ = vals[4];
0054                   pxbVals_.ladderMask_ = vals[5];
0055                   pxbVals_.moduleMask_ = vals[6];
0056                   pxbVals_.doubleMask_ = vals[7];
0057                 } else {  // Phase-0 or Phase-1
0058                   pxbVals_.layerStartBit_ = vals[0];
0059                   pxbVals_.ladderStartBit_ = vals[1];
0060                   pxbVals_.moduleStartBit_ = vals[2];
0061 
0062                   pxbVals_.layerMask_ = vals[3];
0063                   pxbVals_.ladderMask_ = vals[4];
0064                   pxbVals_.moduleMask_ = vals[5];
0065                 }
0066 
0067                 foundPXB = true;
0068                 break;
0069 
0070               case PixelSubdetector::PixelEndcap:  // side, disk, blade, panel, module
0071                 pxfVals_.sideStartBit_ = vals[0];
0072                 pxfVals_.diskStartBit_ = vals[1];
0073                 pxfVals_.bladeStartBit_ = vals[2];
0074                 pxfVals_.panelStartBit_ = vals[3];
0075                 pxfVals_.moduleStartBit_ = vals[4];
0076 
0077                 pxfVals_.sideMask_ = vals[5];
0078                 pxfVals_.diskMask_ = vals[6];
0079                 pxfVals_.bladeMask_ = vals[7];
0080                 pxfVals_.panelMask_ = vals[8];
0081                 pxfVals_.moduleMask_ = vals[9];
0082 
0083                 foundPXF = true;
0084                 break;
0085 
0086               case StripSubdetector::TIB:  // layer, str_fw_bw, str_int_ext, str, module, ster
0087                 tibVals_.layerStartBit_ = vals[0];
0088                 tibVals_.str_fw_bwStartBit_ = vals[1];
0089                 tibVals_.str_int_extStartBit_ = vals[2];
0090                 tibVals_.strStartBit_ = vals[3];
0091                 tibVals_.moduleStartBit_ = vals[4];
0092                 tibVals_.sterStartBit_ = vals[5];
0093 
0094                 tibVals_.layerMask_ = vals[6];
0095                 tibVals_.str_fw_bwMask_ = vals[7];
0096                 tibVals_.str_int_extMask_ = vals[8];
0097                 tibVals_.strMask_ = vals[9];
0098                 tibVals_.moduleMask_ = vals[10];
0099                 tibVals_.sterMask_ = vals[11];
0100 
0101                 foundTIB = true;
0102                 break;
0103 
0104               case StripSubdetector::TID:  // side, wheel, ring, module_fw_bw, module, ster
0105                 tidVals_.sideStartBit_ = vals[0];
0106                 tidVals_.wheelStartBit_ = vals[1];
0107                 tidVals_.ringStartBit_ = vals[2];
0108                 tidVals_.module_fw_bwStartBit_ = vals[3];
0109                 tidVals_.moduleStartBit_ = vals[4];
0110                 tidVals_.sterStartBit_ = vals[5];
0111 
0112                 tidVals_.sideMask_ = vals[6];
0113                 tidVals_.wheelMask_ = vals[7];
0114                 tidVals_.ringMask_ = vals[8];
0115                 tidVals_.module_fw_bwMask_ = vals[9];
0116                 tidVals_.moduleMask_ = vals[10];
0117                 tidVals_.sterMask_ = vals[11];
0118 
0119                 foundTID = true;
0120                 break;
0121 
0122               case StripSubdetector::TOB:  // layer, rod_fw_bw, rod, module, ster
0123                 tobVals_.layerStartBit_ = vals[0];
0124                 tobVals_.rod_fw_bwStartBit_ = vals[1];
0125                 tobVals_.rodStartBit_ = vals[2];
0126                 tobVals_.moduleStartBit_ = vals[3];
0127                 tobVals_.sterStartBit_ = vals[4];
0128 
0129                 tobVals_.layerMask_ = vals[5];
0130                 tobVals_.rod_fw_bwMask_ = vals[6];
0131                 tobVals_.rodMask_ = vals[7];
0132                 tobVals_.moduleMask_ = vals[8];
0133                 tobVals_.sterMask_ = vals[9];
0134 
0135                 foundTOB = true;
0136                 break;
0137 
0138               case StripSubdetector::TEC:  // side, wheel, petal_fw_bw, petal, ring, module, ster
0139                 tecVals_.sideStartBit_ = vals[0];
0140                 tecVals_.wheelStartBit_ = vals[1];
0141                 tecVals_.petal_fw_bwStartBit_ = vals[2];
0142                 tecVals_.petalStartBit_ = vals[3];
0143                 tecVals_.ringStartBit_ = vals[4];
0144                 tecVals_.moduleStartBit_ = vals[5];
0145                 tecVals_.sterStartBit_ = vals[6];
0146 
0147                 tecVals_.sideMask_ = vals[7];
0148                 tecVals_.wheelMask_ = vals[8];
0149                 tecVals_.petal_fw_bwMask_ = vals[9];
0150                 tecVals_.petalMask_ = vals[10];
0151                 tecVals_.ringMask_ = vals[11];
0152                 tecVals_.moduleMask_ = vals[12];
0153                 tecVals_.sterMask_ = vals[13];
0154 
0155                 foundTEC = true;
0156                 break;
0157             }
0158           }
0159         }
0160       }
0161       return true;
0162     }
0163 
0164     TrackerTopology getTrackerTopology() const {
0165       if (!(foundPXB && foundPXF && foundTIB && foundTID && foundTOB && foundTEC)) {
0166         throw cms::Exception("StandaloneTrackerTopology", "Could not find parameters for all tracker subdetectors");
0167       }
0168       return TrackerTopology(pxbVals_, pxfVals_, tecVals_, tibVals_, tidVals_, tobVals_);
0169     }
0170 
0171   private:
0172     TrackerTopology::PixelBarrelValues pxbVals_;
0173     TrackerTopology::PixelEndcapValues pxfVals_;
0174     TrackerTopology::TIBValues tibVals_;
0175     TrackerTopology::TIDValues tidVals_;
0176     TrackerTopology::TOBValues tobVals_;
0177     TrackerTopology::TECValues tecVals_;
0178 
0179     bool foundPXB = false, foundPXF = false, foundTIB = false, foundTID = false, foundTOB = false, foundTEC = false;
0180 
0181     const std::string SubdetName = "Subdetector";
0182   };
0183 }  // namespace
0184 
0185 namespace StandaloneTrackerTopology {
0186   TrackerTopology fromTrackerParametersXMLFile(const std::string& xmlFileName) {
0187     tinyxml2::XMLDocument xmlDoc;
0188     xmlDoc.LoadFile(xmlFileName.c_str());
0189     if (!xmlDoc.Error()) {
0190       TrackerTopologyExtractor extr{};
0191       xmlDoc.Accept(&extr);
0192       return extr.getTrackerTopology();
0193     } else {
0194       throw cms::Exception("StandaloneTrackerTopology",
0195                            std::string{"Failed to parse file "} + xmlFileName + ": " + xmlDoc.ErrorStr());
0196     }
0197   }
0198   TrackerTopology fromTrackerParametersXMLString(const std::string& xmlContent) {
0199     tinyxml2::XMLDocument xmlDoc;
0200     xmlDoc.Parse(xmlContent.c_str());
0201     if (!xmlDoc.Error()) {
0202       TrackerTopologyExtractor extr{};
0203       xmlDoc.Accept(&extr);
0204       return extr.getTrackerTopology();
0205     } else {
0206       throw cms::Exception("StandaloneTrackerTopology", std::string{"Error while parsing XML: "} + xmlDoc.ErrorStr());
0207     }
0208   }
0209 }  // namespace StandaloneTrackerTopology