CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch2/src/Alignment/MuonAlignment/python/geometryXMLparser.py

Go to the documentation of this file.
00001 #!/usr/bin/python
00002 
00003 # XML must come from MuonGeometryDBConverter; not hand-made
00004 # Example configuration that will work
00005 # 
00006 # PSet outputXML = {
00007 #     string fileName = "tmp.xml"
00008 #     string relativeto = "container"   # keep in mind which relativeto you used when interpreting positions and angles!
00009 #     bool survey = false               # important: survey must be false
00010 #     bool rawIds = false               # important: rawIds must be false
00011 #     bool eulerAngles = false
00012 #     int32 precision = 10
00013 # }
00014 
00015 def dtorder(a, b):
00016   for ai, bi, name in zip(list(a) + [0]*(5 - len(a)), \
00017                           list(b) + [0]*(5 - len(b)), \
00018                           ("wheel", "station", "sector", "superlayer", "layer")):
00019     exec("a%s = %d" % (name, ai))
00020     exec("b%s = %d" % (name, bi))
00021 
00022   if awheel == bwheel and astation == bstation:
00023 
00024     if asector != bsector:
00025       if astation == 4: sectororder = [0, 1, 2, 3, 4, 13, 5, 6, 7, 8, 9, 10, 14, 11, 12]
00026       elif awheel == 0: sectororder = [0, 1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]
00027       else: sectororder = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
00028       return cmp(sectororder.index(asector), sectororder.index(bsector))
00029 
00030     elif asuperlayer != bsuperlayer:
00031       superlayerorder = [0, 1, 3, 2]
00032       return cmp(superlayerorder.index(asuperlayer), superlayerorder.index(bsuperlayer))
00033 
00034   return cmp(a, b)
00035 
00036 def cscorder(a, b):
00037   for ai, bi, name in zip(list(a) + [0]*(5 - len(a)), \
00038                           list(b) + [0]*(5 - len(b)), \
00039                           ("endcap", "station", "ring", "chamber", "layer")):
00040     exec("a%s = %d" % (name, ai))
00041     exec("b%s = %d" % (name, bi))
00042 
00043   if astation == 1 and aring == 3: return cmp(a, b)
00044 
00045   elif aendcap == bendcap and astation == bstation and aring == bring and achamber != bchamber:
00046     if achamber == 0: return -1 # upper hierarchy comes first
00047     if bchamber == 0: return  1 # upper hierarchy comes first
00048     if achamber % 2 == 1 and bchamber % 2 == 0: return -1  # odds come first
00049     elif achamber % 2 == 0 and bchamber % 2 == 1: return 1 # evens come after
00050 
00051   return cmp(a, b)
00052 
00053 # External libraries (standard in Python >= 2.4, at least)
00054 import xml.sax
00055 
00056 class Alignable:
00057     def pos(self):
00058         return self.x, self.y, self.z
00059     def covariance(self):
00060         return (self.xx, self.xy, self.xz), (self.xy, self.yy, self.yz), (self.xz, self.yz, self.zz)
00061 
00062 class DTAlignable:
00063     def index(self):
00064         i = []
00065         try: i.append(self.wheel)
00066         except AttributeError: pass
00067         try: i.append(self.station)
00068         except AttributeError: pass
00069         try: i.append(self.sector)
00070         except AttributeError: pass
00071         try: i.append(self.superlayer)
00072         except AttributeError: pass
00073         try: i.append(self.layer)
00074         except AttributeError: pass
00075         return tuple(i)
00076 
00077 class CSCAlignable:
00078     def index(self):
00079         i = []
00080         try: i.append(self.endcap)
00081         except AttributeError: pass
00082         try: i.append(self.station)
00083         except AttributeError: pass
00084         try: i.append(self.ring)
00085         except AttributeError: pass
00086         try: i.append(self.chamber)
00087         except AttributeError: pass
00088         try: i.append(self.layer)
00089         except AttributeError: pass
00090         return tuple(i)
00091 
00092 class Operation:
00093     def __init__(self):
00094         self.chambers = []
00095         self.setposition = {}
00096         self.setape = {}
00097 
00098 # This class is a subclass of something which knows how to parse XML
00099 class MuonGeometry(xml.sax.handler.ContentHandler):
00100     def __init__(self, stream=None):
00101         self.dt = {}
00102         self.csc = {}
00103         self._operation = None
00104 
00105         if stream is not None:
00106           parser = xml.sax.make_parser()
00107           parser.setContentHandler(self)
00108           parser.parse(stream)
00109 
00110     # what to do when you get to a <startelement>
00111     def startElement(self, tag, attrib):
00112         attrib = dict(attrib.items())
00113         if "rawId" in attrib: raise Exception, "Please use \"rawIds = false\""
00114         if "aa" in attrib: raise Exception, "Please use \"survey = false\""
00115 
00116         if tag == "MuonAlignment": pass
00117 
00118         elif tag == "collection": raise NotImplementedError, "<collection /> and <collection> blocks aren't implemented yet"
00119 
00120         elif tag == "operation":
00121             self._operation = Operation()
00122 
00123         elif self._operation is None: raise Exception, "All chambers and positions must be enclosed in <operation> blocks"
00124 
00125         elif tag == "setposition":
00126             self._operation.setposition["relativeto"] = str(attrib["relativeto"])
00127 
00128             for name in "x", "y", "z":
00129                 self._operation.setposition[name] = float(attrib[name])
00130             try:
00131                 for name in "phix", "phiy", "phiz":
00132                     self._operation.setposition[name] = float(attrib[name])
00133             except KeyError:
00134                 for name in "alpha", "beta", "gamma":
00135                     self._operation.setposition[name] = float(attrib[name])
00136 
00137         elif tag == "setape":
00138             for name in "xx", "xy", "xz", "yy", "yz", "zz":
00139                 self._operation.setposition[name] = float(attrib[name])
00140 
00141         elif tag[0:2] == "DT":
00142             alignable = DTAlignable()
00143             for name in "wheel", "station", "sector", "superlayer", "layer":
00144                 if name in attrib:
00145                     alignable.__dict__[name] = int(attrib[name])
00146             self._operation.chambers.append(alignable)
00147 
00148         # <CSC...>: print endcap/station/ring/chamber/layer
00149         elif tag[0:3] == "CSC":
00150             alignable = CSCAlignable()
00151             for name in "endcap", "station", "ring", "chamber", "layer":
00152                 if name in attrib:
00153                     alignable.__dict__[name] = int(attrib[name])
00154             self._operation.chambers.append(alignable)
00155 
00156     # what to do when you get to an </endelement>
00157     def endElement(self, tag):
00158         if tag == "operation":
00159             if self._operation is None: raise Exception, "Unbalanced <operation></operation>"
00160             for c in self._operation.chambers:
00161                 c.__dict__.update(self._operation.setposition)
00162                 c.__dict__.update(self._operation.setape)
00163                 if isinstance(c, DTAlignable): self.dt[c.index()] = c
00164                 elif isinstance(c, CSCAlignable): self.csc[c.index()] = c
00165 
00166     # writing back to xml
00167     def xml(self, stream=None, precision=10):
00168       if precision == None: format = "%g"
00169       else: format = "%." + str(precision) + "f"
00170 
00171       if stream == None:
00172         output = []
00173         writeline = lambda x: output.append(x)
00174       else:
00175         writeline = lambda x: stream.write(x)
00176 
00177       writeline("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
00178       writeline("<?xml-stylesheet type=\"text/xml\" href=\"MuonAlignment.xsl\"?>\n")
00179       writeline("<MuonAlignment>\n\n")
00180 
00181       dtkeys = self.dt.keys()
00182       dtkeys.sort(dtorder)
00183       csckeys = self.csc.keys()
00184       csckeys.sort(cscorder)
00185 
00186       def f(number): return format % number
00187 
00188       def position_ape(ali, attributes):
00189         writeline("  <%s%s />\n" % (level, attributes))
00190         writeline("  <setposition relativeto=\"%s\" x=\"%s\" y=\"%s\" z=\"%s\" phix=\"%s\" phiy=\"%s\" phiz=\"%s\" />\n" % \
00191                   (ali.relativeto, f(ali.x), f(ali.y), f(ali.z), f(ali.phix), f(ali.phiy), f(ali.phiz)))
00192 
00193         if "xx" in ali.__dict__:
00194           writeline("  <setape xx=\"%s\" xy=\"%s\" xz=\"%s\" yy=\"%s\" yz=\"%s\" zz=\"%s\" />\n" % \
00195                     (f(ali.xx), f(ali.xy), f(ali.xz), f(ali.yy), f(ali.yz), f(ali.zz)))
00196 
00197       for key in dtkeys:
00198         writeline("<operation>\n")
00199 
00200         if len(key) == 0: level = "DTBarrel"
00201         elif len(key) == 1: level = "DTWheel "
00202         elif len(key) == 2: level = "DTStation "
00203         elif len(key) == 3: level = "DTChamber "
00204         elif len(key) == 4: level = "DTSuperLayer "
00205         elif len(key) == 5: level = "DTLayer "
00206 
00207         ali = self.dt[key]
00208         attributes = " ".join(["%s=\"%d\"" % (name, value) for name, value in zip(("wheel", "station", "sector", "superlayer", "layer"), key)])
00209         position_ape(ali, attributes)
00210 
00211         writeline("</operation>\n\n")
00212 
00213       for key in csckeys:
00214         writeline("<operation>\n")
00215 
00216         if len(key) == 1: level = "CSCEndcap "
00217         elif len(key) == 2: level = "CSCStation "
00218         elif len(key) == 3: level = "CSCRing "
00219         elif len(key) == 4: level = "CSCChamber "
00220         elif len(key) == 5: level = "CSCLayer "
00221 
00222         ali = self.csc[key]
00223         attributes = " ".join(["%s=\"%d\"" % (name, value) for name, value in zip(("endcap", "station", "ring", "chamber", "layer"), key)])
00224         position_ape(ali, attributes)
00225 
00226         writeline("</operation>\n\n")
00227 
00228       writeline("</MuonAlignment>\n")
00229       if stream == None: return "".join(output)