3 from __future__
import print_function
4 import sys, optparse, re, math
5 from Alignment.MuonAlignment.geometryXMLparser
import MuonGeometry
7 usage =
"""./%prog GeomGlobal.xml AbsConstrints.[phiy|phipos|phiz] frameName
9 Calculates constraints from AbsConstraints relative to GeomGlobal for
10 use in CSCOverlapsAlignmentAlgorithm. Assumes that constraints (including
11 chamber names) are properly formatted.
13 GeomGlobal CSC geometry represented as a relativeto="none" XML file
14 (standard format--- must be MuonGeometryDBConverter output)
15 AbsConstrints text file listing absolute phiy, phipos, or phiz constraints
16 as "chambername measuredvalue uncertainty"
17 frameName name of coordinate system frame (all constraints are
18 relative to this coordinate system"""
20 parser = optparse.OptionParser(usage)
21 parser.add_option(
"--scaleErrors",
22 help=
"factor to scale errors: 1 is default, 10 *weakens* constraint by a factor of 10, etc.",
26 parser.add_option(
"--disks",
27 help=
"align whole disks, rather than individual rings",
32 raise SystemError(
"Too few arguments.\n\n"+parser.format_help())
34 if sys.argv[2][-5:] ==
".phiy": mode =
"phiy"
35 elif sys.argv[2][-7:] ==
".phipos": mode =
"phipos"
36 elif sys.argv[2][-5:] ==
".phiz": mode =
"phiz"
39 geometry = MuonGeometry(sys.argv[1])
40 constraints =
file(sys.argv[2])
41 frameName = sys.argv[3]
43 options, args = parser.parse_args(sys.argv[4:])
44 options.scaleErrors = float(options.scaleErrors)
47 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": []}
48 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": []}
50 for line
in constraints.readlines():
51 match = re.match(
r"(ME[\+\-/0-9]+)\s+([\+\-\.eE0-9]+)\s+([\+\-\.eE0-9]+)", line)
53 chamber, value, error = match.groups()
54 ringName = chamber[0:6]
56 error = float(error) * options.scaleErrors
59 if ringName
in (
"ME+1/2",
"ME+1/3"): ringName =
"YE+1"
60 elif ringName
in (
"ME+2/1",
"ME+2/2",
"ME+3/1",
"ME+3/2"): ringName =
"YE+2"
61 elif ringName
in (
"ME-1/2",
"ME-1/3"): ringName =
"YE-1"
62 elif ringName
in (
"ME-2/1",
"ME-2/2",
"ME-3/1",
"ME-3/2"): ringName =
"YE-2"
64 if chamber[2] ==
"+": endcap = 1
65 elif chamber[2] ==
"-": endcap = 2
67 station = int(chamber[3])
68 ring = int(chamber[5])
69 cham = int(chamber[7:9])
72 geom = geometry.csc[endcap, station, ring, cham].phiy
73 elif mode ==
"phipos":
74 geom = math.atan2(geometry.csc[endcap, station, ring, cham].y, geometry.csc[endcap, station, ring, cham].x)
76 geom = geometry.csc[endcap, station, ring, cham].phiz
78 relative = value - geom
80 if mode
in (
"phiy",
"phipos",
"phiz"):
81 while relative > math.pi: relative -= 2.*math.pi
82 while relative <= -math.pi: relative += 2.*math.pi
84 if ringName
in byRing:
85 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())
89 keys = sorted(byRing.keys())
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 ...
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)