CMS 3D CMS Logo

StandaloneTrackerTopology.cc
Go to the documentation of this file.
2 
3 #include "tinyxml2.h"
6 
7 namespace {
8  // split into tokens and convert them to uint32_t
9  inline std::vector<uint32_t> split_string_to_uints(const std::string& str) {
10  std::vector<uint32_t> out{};
11  std::size_t iStart{str.find_first_not_of(" ,\n")}, iEnd{};
12  while (std::string::npos != iStart) {
13  iEnd = str.find_first_of(" ,\n", iStart);
14  out.push_back(std::stoul(str.substr(iStart, iEnd), nullptr, 0));
15  iStart = str.find_first_not_of(" ,\n", iEnd);
16  }
17  return out;
18  }
19 
20  class TrackerTopologyExtractor : public tinyxml2::XMLVisitor {
21  public:
22  bool VisitEnter(const tinyxml2::XMLElement& elem, const tinyxml2::XMLAttribute*) override {
23  if (std::strcmp(elem.Value(), "Vector") == 0) {
24  const std::string att_type{elem.Attribute("type")};
25  if (att_type == "numeric") {
26  const std::string att_name{elem.Attribute("name")};
27  if (0 == att_name.compare(0, SubdetName.size(), SubdetName)) { // starts with
28  const std::string att_nEntries{elem.Attribute("nEntries")};
29  const std::size_t nEntries = att_nEntries.empty() ? 0 : std::stoul(att_nEntries);
30  const auto vals = split_string_to_uints(elem.GetText());
31 
32  if (nEntries != vals.size()) {
33  throw cms::Exception(
34  "StandaloneTrackerTopology",
35  ("Problem parsing element with name '" + att_name + "': " + "'nEntries' attribute claims " +
36  std::to_string(nEntries) + " elements, but parsed " + std::to_string(vals.size())));
37  }
38  const auto subDet = std::stoi(att_name.substr(SubdetName.size()));
39  switch (subDet) {
40  case PixelSubdetector::PixelBarrel: // layer, ladder module
41 
42  /*
43  In the case of the phase-2 IT there is an additional layer of hierarcy, due ot split sensors in Layer 1
44  What follows is a ugly hack, but at least is consistent with TrackerTopologyEP.cc
45  */
46 
47  if (vals.size() > 6) { // Phase 2: extra hierarchy level for 3D sensors
48  pxbVals_.layerStartBit_ = vals[0];
49  pxbVals_.ladderStartBit_ = vals[1];
50  pxbVals_.moduleStartBit_ = vals[2];
51  pxbVals_.doubleStartBit_ = vals[3];
52 
53  pxbVals_.layerMask_ = vals[4];
54  pxbVals_.ladderMask_ = vals[5];
55  pxbVals_.moduleMask_ = vals[6];
56  pxbVals_.doubleMask_ = vals[7];
57  } else { // Phase-0 or Phase-1
58  pxbVals_.layerStartBit_ = vals[0];
59  pxbVals_.ladderStartBit_ = vals[1];
60  pxbVals_.moduleStartBit_ = vals[2];
61 
62  pxbVals_.layerMask_ = vals[3];
63  pxbVals_.ladderMask_ = vals[4];
64  pxbVals_.moduleMask_ = vals[5];
65  }
66 
67  foundPXB = true;
68  break;
69 
70  case PixelSubdetector::PixelEndcap: // side, disk, blade, panel, module
71  pxfVals_.sideStartBit_ = vals[0];
72  pxfVals_.diskStartBit_ = vals[1];
73  pxfVals_.bladeStartBit_ = vals[2];
74  pxfVals_.panelStartBit_ = vals[3];
75  pxfVals_.moduleStartBit_ = vals[4];
76 
77  pxfVals_.sideMask_ = vals[5];
78  pxfVals_.diskMask_ = vals[6];
79  pxfVals_.bladeMask_ = vals[7];
80  pxfVals_.panelMask_ = vals[8];
81  pxfVals_.moduleMask_ = vals[9];
82 
83  foundPXF = true;
84  break;
85 
86  case StripSubdetector::TIB: // layer, str_fw_bw, str_int_ext, str, module, ster
87  tibVals_.layerStartBit_ = vals[0];
88  tibVals_.str_fw_bwStartBit_ = vals[1];
89  tibVals_.str_int_extStartBit_ = vals[2];
90  tibVals_.strStartBit_ = vals[3];
91  tibVals_.moduleStartBit_ = vals[4];
92  tibVals_.sterStartBit_ = vals[5];
93 
94  tibVals_.layerMask_ = vals[6];
95  tibVals_.str_fw_bwMask_ = vals[7];
96  tibVals_.str_int_extMask_ = vals[8];
97  tibVals_.strMask_ = vals[9];
98  tibVals_.moduleMask_ = vals[10];
99  tibVals_.sterMask_ = vals[11];
100 
101  foundTIB = true;
102  break;
103 
104  case StripSubdetector::TID: // side, wheel, ring, module_fw_bw, module, ster
105  tidVals_.sideStartBit_ = vals[0];
106  tidVals_.wheelStartBit_ = vals[1];
107  tidVals_.ringStartBit_ = vals[2];
108  tidVals_.module_fw_bwStartBit_ = vals[3];
109  tidVals_.moduleStartBit_ = vals[4];
110  tidVals_.sterStartBit_ = vals[5];
111 
112  tidVals_.sideMask_ = vals[6];
113  tidVals_.wheelMask_ = vals[7];
114  tidVals_.ringMask_ = vals[8];
115  tidVals_.module_fw_bwMask_ = vals[9];
116  tidVals_.moduleMask_ = vals[10];
117  tidVals_.sterMask_ = vals[11];
118 
119  foundTID = true;
120  break;
121 
122  case StripSubdetector::TOB: // layer, rod_fw_bw, rod, module, ster
123  tobVals_.layerStartBit_ = vals[0];
124  tobVals_.rod_fw_bwStartBit_ = vals[1];
125  tobVals_.rodStartBit_ = vals[2];
126  tobVals_.moduleStartBit_ = vals[3];
127  tobVals_.sterStartBit_ = vals[4];
128 
129  tobVals_.layerMask_ = vals[5];
130  tobVals_.rod_fw_bwMask_ = vals[6];
131  tobVals_.rodMask_ = vals[7];
132  tobVals_.moduleMask_ = vals[8];
133  tobVals_.sterMask_ = vals[9];
134 
135  foundTOB = true;
136  break;
137 
138  case StripSubdetector::TEC: // side, wheel, petal_fw_bw, petal, ring, module, ster
139  tecVals_.sideStartBit_ = vals[0];
140  tecVals_.wheelStartBit_ = vals[1];
141  tecVals_.petal_fw_bwStartBit_ = vals[2];
142  tecVals_.petalStartBit_ = vals[3];
143  tecVals_.ringStartBit_ = vals[4];
144  tecVals_.moduleStartBit_ = vals[5];
145  tecVals_.sterStartBit_ = vals[6];
146 
147  tecVals_.sideMask_ = vals[7];
148  tecVals_.wheelMask_ = vals[8];
149  tecVals_.petal_fw_bwMask_ = vals[9];
150  tecVals_.petalMask_ = vals[10];
151  tecVals_.ringMask_ = vals[11];
152  tecVals_.moduleMask_ = vals[12];
153  tecVals_.sterMask_ = vals[13];
154 
155  foundTEC = true;
156  break;
157  }
158  }
159  }
160  }
161  return true;
162  }
163 
164  TrackerTopology getTrackerTopology() const {
165  if (!(foundPXB && foundPXF && foundTIB && foundTID && foundTOB && foundTEC)) {
166  throw cms::Exception("StandaloneTrackerTopology", "Could not find parameters for all tracker subdetectors");
167  }
168  return TrackerTopology(pxbVals_, pxfVals_, tecVals_, tibVals_, tidVals_, tobVals_);
169  }
170 
171  private:
178 
179  bool foundPXB = false, foundPXF = false, foundTIB = false, foundTID = false, foundTOB = false, foundTEC = false;
180 
181  const std::string SubdetName = "Subdetector";
182  };
183 } // namespace
184 
185 namespace StandaloneTrackerTopology {
187  tinyxml2::XMLDocument xmlDoc;
188  xmlDoc.LoadFile(xmlFileName.c_str());
189  if (!xmlDoc.Error()) {
190  TrackerTopologyExtractor extr{};
191  xmlDoc.Accept(&extr);
192  return extr.getTrackerTopology();
193  } else {
194  throw cms::Exception("StandaloneTrackerTopology",
195  std::string{"Failed to parse file "} + xmlFileName + ": " + xmlDoc.ErrorStr());
196  }
197  }
199  tinyxml2::XMLDocument xmlDoc;
200  xmlDoc.Parse(xmlContent.c_str());
201  if (!xmlDoc.Error()) {
202  TrackerTopologyExtractor extr{};
203  xmlDoc.Accept(&extr);
204  return extr.getTrackerTopology();
205  } else {
206  throw cms::Exception("StandaloneTrackerTopology", std::string{"Error while parsing XML: "} + xmlDoc.ErrorStr());
207  }
208  }
209 } // namespace StandaloneTrackerTopology
static constexpr auto TEC
static std::string to_string(const XMLCh *ch)
static constexpr auto TOB
static constexpr auto TIB
TrackerTopology fromTrackerParametersXMLFile(const std::string &xmlFileName)
TrackerTopology fromTrackerParametersXMLString(const std::string &xmlContent)
#define str(s)
static constexpr auto TID