CMS 3D CMS Logo

geometryXMLparser.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # XML must come from MuonGeometryDBConverter; not hand-made
4 # Example configuration that will work
5 #
6 # PSet outputXML = {
7 # string fileName = "tmp.xml"
8 # string relativeto = "container" # keep in mind which relativeto you used when interpreting positions and angles!
9 # bool survey = false # important: survey must be false
10 # bool rawIds = false # important: rawIds must be false
11 # bool eulerAngles = false
12 # int32 precision = 10
13 # }
14 
15 def dtorder(a, b):
16  for ai, bi, name in zip(list(a) + [0]*(5 - len(a)), \
17  list(b) + [0]*(5 - len(b)), \
18  ("wheel", "station", "sector", "superlayer", "layer")):
19  exec("a%s = %d" % (name, ai))
20  exec("b%s = %d" % (name, bi))
21 
22  if awheel == bwheel and astation == bstation:
23 
24  if asector != bsector:
25  if astation == 4: sectororder = [0, 1, 2, 3, 4, 13, 5, 6, 7, 8, 9, 10, 14, 11, 12]
26  elif awheel == 0: sectororder = [0, 1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]
27  else: sectororder = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
28  return cmp(sectororder.index(asector), sectororder.index(bsector))
29 
30  elif asuperlayer != bsuperlayer:
31  superlayerorder = [0, 1, 3, 2]
32  return cmp(superlayerorder.index(asuperlayer), superlayerorder.index(bsuperlayer))
33 
34  return cmp(a, b)
35 
36 def cscorder(a, b):
37  for ai, bi, name in zip(list(a) + [0]*(5 - len(a)), \
38  list(b) + [0]*(5 - len(b)), \
39  ("endcap", "station", "ring", "chamber", "layer")):
40  exec("a%s = %d" % (name, ai))
41  exec("b%s = %d" % (name, bi))
42 
43  if astation == 1 and aring == 3: return cmp(a, b)
44 
45  elif aendcap == bendcap and astation == bstation and aring == bring and achamber != bchamber:
46  if achamber == 0: return -1 # upper hierarchy comes first
47  if bchamber == 0: return 1 # upper hierarchy comes first
48  if achamber % 2 == 1 and bchamber % 2 == 0: return -1 # odds come first
49  elif achamber % 2 == 0 and bchamber % 2 == 1: return 1 # evens come after
50 
51  return cmp(a, b)
52 
53 # External libraries (standard in Python >= 2.4, at least)
54 import xml.sax
55 
56 class Alignable:
57  def pos(self):
58  return self.x, self.y, self.z
59  def covariance(self):
60  return (self.xx, self.xy, self.xz, self.xa, self.xb, self.xc), (self.xy, self.yy, self.yz, self.ya, self.yb, self.yc), (self.xz, self.yz, self.zz, self.za, self.zb, self.zc), (self.xa, self.ya, self.za, self.aa, self.ab, self.ac), (self.xb, self.yb, self.zb, self.ab, self.bb, self.bc), (self.xc, self.yc, self.zc, self.ac, self.ac, self.cc)
61 
63  def index(self):
64  i = []
65  try: i.append(self.wheel)
66  except AttributeError: pass
67  try: i.append(self.station)
68  except AttributeError: pass
69  try: i.append(self.sector)
70  except AttributeError: pass
71  try: i.append(self.superlayer)
72  except AttributeError: pass
73  try: i.append(self.layer)
74  except AttributeError: pass
75  return tuple(i)
76 
78  def index(self):
79  i = []
80  try: i.append(self.endcap)
81  except AttributeError: pass
82  try: i.append(self.station)
83  except AttributeError: pass
84  try: i.append(self.ring)
85  except AttributeError: pass
86  try: i.append(self.chamber)
87  except AttributeError: pass
88  try: i.append(self.layer)
89  except AttributeError: pass
90  return tuple(i)
91 
92 class Operation:
93  def __init__(self):
94  self.chambers = []
95  self.setposition = {}
96  self.setape = {}
97 
98 # This class is a subclass of something which knows how to parse XML
99 class MuonGeometry(xml.sax.handler.ContentHandler):
100  def __init__(self, stream=None):
101  self.dt = {}
102  self.csc = {}
103  self._operation = None
104 
105  if stream is not None:
106  parser = xml.sax.make_parser()
107  parser.setContentHandler(self)
108  parser.parse(stream)
109 
110  # what to do when you get to a <startelement>
111  def startElement(self, tag, attrib):
112  attrib = dict(attrib.items())
113  if "rawId" in attrib: raise Exception("Please use \"rawIds = false\"")
114  if "aa" in attrib: raise Exception("Please use \"survey = false\"")
115 
116  if tag == "MuonAlignment": pass
117 
118  elif tag == "collection": raise NotImplementedError("<collection /> and <collection> blocks aren't implemented yet")
119 
120  elif tag == "operation":
121  self._operation = Operation()
122 
123  elif self._operation is None: raise Exception("All chambers and positions must be enclosed in <operation> blocks")
124 
125  elif tag == "setposition":
126  self._operation.setposition["relativeto"] = str(attrib["relativeto"])
127 
128  for name in "x", "y", "z":
129  self._operation.setposition[name] = float(attrib[name])
130  try:
131  for name in "phix", "phiy", "phiz":
132  self._operation.setposition[name] = float(attrib[name])
133  except KeyError:
134  for name in "alpha", "beta", "gamma":
135  self._operation.setposition[name] = float(attrib[name])
136 
137  elif tag == "setape":
138  for name in "xx", "xy", "xz", "xa", "xb", "xc", "yy", "yz", "ya", "yb", "yc", "zz", "za", "zb", "zc", "aa", "ab", "ac", "bb", "bc", "cc":
139  self._operation.setposition[name] = float(attrib[name])
140 
141  elif tag[0:2] == "DT":
142  alignable = DTAlignable()
143  for name in "wheel", "station", "sector", "superlayer", "layer":
144  if name in attrib:
145  alignable.__dict__[name] = int(attrib[name])
146  self._operation.chambers.append(alignable)
147 
148  # <CSC...>: print endcap/station/ring/chamber/layer
149  elif tag[0:3] == "CSC":
150  alignable = CSCAlignable()
151  for name in "endcap", "station", "ring", "chamber", "layer":
152  if name in attrib:
153  alignable.__dict__[name] = int(attrib[name])
154  self._operation.chambers.append(alignable)
155 
156  # what to do when you get to an </endelement>
157  def endElement(self, tag):
158  if tag == "operation":
159  if self._operation is None: raise Exception("Unbalanced <operation></operation>")
160  for c in self._operation.chambers:
161  c.__dict__.update(self._operation.setposition)
162  c.__dict__.update(self._operation.setape)
163  if isinstance(c, DTAlignable): self.dt[c.index()] = c
164  elif isinstance(c, CSCAlignable): self.csc[c.index()] = c
165 
166  # writing back to xml
167  def xml(self, stream=None, precision=10):
168  if precision == None: format = "%g"
169  else: format = "%." + str(precision) + "f"
170 
171  if stream == None:
172  output = []
173  writeline = lambda x: output.append(x)
174  else:
175  writeline = lambda x: stream.write(x)
176 
177  writeline("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
178  writeline("<?xml-stylesheet type=\"text/xml\" href=\"MuonAlignment.xsl\"?>\n")
179  writeline("<MuonAlignment>\n\n")
180 
181  dtkeys = self.dt.keys()
182  dtkeys.sort(dtorder)
183  csckeys = self.csc.keys()
184  csckeys.sort(cscorder)
185 
186  def f(number): return format % number
187 
188  def position_ape(ali, attributes):
189  writeline(" <%s%s />\n" % (level, attributes))
190  writeline(" <setposition relativeto=\"%s\" x=\"%s\" y=\"%s\" z=\"%s\" phix=\"%s\" phiy=\"%s\" phiz=\"%s\" />\n" % \
191  (ali.relativeto, f(ali.x), f(ali.y), f(ali.z), f(ali.phix), f(ali.phiy), f(ali.phiz)))
192 
193  if "xx" in ali.__dict__:
194  writeline(" <setape xx=\"%s\" xy=\"%s\" xz=\"%s\" xa=\"%s\" xb=\"%s\" xc=\"%s\" yy=\"%s\" yz=\"%s\" ya=\"%s\" yb=\"%s\" yc=\"%s\" zz=\"%s\" za=\"%s\" zb=\"%s\" zc=\"%s\" aa=\"%s\" ab=\"%s\" ac=\"%s\" bb=\"%s\" bc=\"%s\" cc=\"%s\" />\n" % \
195  (f(ali.xx), f(ali.xy), f(ali.xz), f(ali.xa), f(ali.xb), f(ali.xc), f(ali.yy), f(ali.yz), f(ali.ya), f(ali.yb), f(ali.yc), f(ali.zz), f(ali.za), f(ali.zb), f(ali.zc), f(ali.aa), f(ali.ab), f(ali.ac), f(ali.bb), f(ali.bc), f(ali.cc)))
196 
197  for key in dtkeys:
198  writeline("<operation>\n")
199 
200  if len(key) == 0: level = "DTBarrel"
201  elif len(key) == 1: level = "DTWheel "
202  elif len(key) == 2: level = "DTStation "
203  elif len(key) == 3: level = "DTChamber "
204  elif len(key) == 4: level = "DTSuperLayer "
205  elif len(key) == 5: level = "DTLayer "
206 
207  ali = self.dt[key]
208  attributes = " ".join(["%s=\"%d\"" % (name, value) for name, value in zip(("wheel", "station", "sector", "superlayer", "layer"), key)])
209  position_ape(ali, attributes)
210 
211  writeline("</operation>\n\n")
212 
213  for key in csckeys:
214  writeline("<operation>\n")
215 
216  if len(key) == 1: level = "CSCEndcap "
217  elif len(key) == 2: level = "CSCStation "
218  elif len(key) == 3: level = "CSCRing "
219  elif len(key) == 4: level = "CSCChamber "
220  elif len(key) == 5: level = "CSCLayer "
221 
222  ali = self.csc[key]
223  attributes = " ".join(["%s=\"%d\"" % (name, value) for name, value in zip(("endcap", "station", "ring", "chamber", "layer"), key)])
224  position_ape(ali, attributes)
225 
226  writeline("</operation>\n\n")
227 
228  writeline("</MuonAlignment>\n")
229  if stream == None: return "".join(output)
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float zip(ConstView const &tracks, int32_t i)
Definition: TracksSoA.h:90
double f[11][100]
def xml(self, stream=None, precision=10)
def __init__(self, stream=None)
def startElement(self, tag, attrib)
static std::string join(char **cmd)
Definition: RemoteFile.cc:19
#define str(s)