3 import sys, optparse, re, math
4 from Alignment.MuonAlignment.geometryXMLparser
import MuonGeometry
6 usage =
"""./%prog GeomGlobal.xml AbsConstrints.[phiy|phipos|phiz] frameName
8 Calculates constraints from AbsConstraints relative to GeomGlobal for
9 use in CSCOverlapsAlignmentAlgorithm. Assumes that constraints (including
10 chamber names) are properly formatted.
12 GeomGlobal CSC geometry represented as a relativeto="none" XML file
13 (standard format--- must be MuonGeometryDBConverter output)
14 AbsConstrints text file listing absolute phiy, phipos, or phiz constraints
15 as "chambername measuredvalue uncertainty"
16 frameName name of coordinate system frame (all constraints are
17 relative to this coordinate system"""
19 parser = optparse.OptionParser(usage)
20 parser.add_option(
"--scaleErrors",
21 help=
"factor to scale errors: 1 is default, 10 *weakens* constraint by a factor of 10, etc.",
25 parser.add_option(
"--disks",
26 help=
"align whole disks, rather than individual rings",
31 raise SystemError(
"Too few arguments.\n\n"+parser.format_help())
33 if sys.argv[2][-5:] ==
".phiy": mode =
"phiy"
34 elif sys.argv[2][-7:] ==
".phipos": mode =
"phipos"
35 elif sys.argv[2][-5:] ==
".phiz": mode =
"phiz"
38 geometry = MuonGeometry(sys.argv[1])
39 constraints =
file(sys.argv[2])
40 frameName = sys.argv[3]
42 options, args = parser.parse_args(sys.argv[4:])
43 options.scaleErrors = float(options.scaleErrors)
46 byRing = {
"ME+1/1": [],
"ME+1/2": [],
"ME+2/1": [],
"ME+2/2": [],
"ME+3/1": [],
"ME+3/2": [],
"ME+4/1": [],
"ME+4/2": [],
"ME-1/1": [],
"ME-1/2": [],
"ME-2/1": [],
"ME-2/2": [],
"ME-3/1": [],
"ME-3/2": [],
"ME-4/1": [],
"ME-4/2": []}
47 if options.disks: byRing = {
"ME+1/1": [],
"YE+1": [],
"YE+2": [],
"ME+4/1": [],
"ME+4/2": [],
"ME-1/1": [],
"YE-1": [],
"YE-2": [],
"ME-4/1": [],
"ME-4/2": []}
49 for line
in constraints.readlines():
50 match = re.match(
r"(ME[\+\-/0-9]+)\s+([\+\-\.eE0-9]+)\s+([\+\-\.eE0-9]+)", line)
52 chamber, value, error = match.groups()
53 ringName = chamber[0:6]
55 error = float(error) * options.scaleErrors
58 if ringName
in (
"ME+1/2",
"ME+1/3"): ringName =
"YE+1"
59 elif ringName
in (
"ME+2/1",
"ME+2/2",
"ME+3/1",
"ME+3/2"): ringName =
"YE+2"
60 elif ringName
in (
"ME-1/2",
"ME-1/3"): ringName =
"YE-1"
61 elif ringName
in (
"ME-2/1",
"ME-2/2",
"ME-3/1",
"ME-3/2"): ringName =
"YE-2"
63 if chamber[2] ==
"+": endcap = 1
64 elif chamber[2] ==
"-": endcap = 2
66 station = int(chamber[3])
67 ring = int(chamber[5])
68 cham = int(chamber[7:9])
71 geom = geometry.csc[endcap, station, ring, cham].phiy
72 elif mode ==
"phipos":
73 geom = math.atan2(geometry.csc[endcap, station, ring, cham].y, geometry.csc[endcap, station, ring, cham].x)
75 geom = geometry.csc[endcap, station, ring, cham].phiz
77 relative = value - geom
79 if mode
in (
"phiy",
"phipos",
"phiz"):
80 while relative > math.pi: relative -= 2.*math.pi
81 while relative <= -math.pi: relative += 2.*math.pi
83 if ringName
in byRing:
84 byRing[ringName].
append(
"""cms.PSet(i = cms.string("%(frameName)s"), j = cms.string("%(chamber)s"), value = cms.double(%(relative)g), error = cms.double(%(error)g))""" % vars())
90 print "for fitter in process.looper.algoConfig.fitters:"
92 if len(byRing[ringName]) > 0:
93 print " if fitter.name.value() == \"%(ringName)s\":" % vars()
94 print " fitter.alignables.append(\"%(frameName)s\")" % vars()
95 for line
in byRing[ringName]:
96 print " fitter.constraints.append(%(line)s)" % vars()
boost::dynamic_bitset append(const boost::dynamic_bitset<> &bs1, const boost::dynamic_bitset<> &bs2)
this method takes two bitsets bs1 and bs2 and returns result of bs2 appended to the end of bs1 ...