CMS 3D CMS Logo

MCScenario_CRAFT1_22X.py
Go to the documentation of this file.
1 # To use this script:
2 # it's an ordinary Python script, not a CMSSW configuration file (though it writes and runs CMSSW configuration files)
3 # * you MUST have an inertGlobalPositionRcd.db in your working directory
4 # * you MUST NOT have an MCScenario_CRAFT1_22X.db
5 #
6 # to make the inertGlobalPositionRcd:
7 # cmsRun Alignment/MuonAlignment/python/makeGlobalPositionRcd_cfg.py
8 #
9 # to get rid of the MCScenario_CRAFT1_22X.db:
10 # rm MCScenario_CRAFT1_22X.db (naturally)
11 #
12 # to run this script:
13 # python MCScenario_CRAFT1_22X.py
14 #
15 # it will create
16 # * MCScenario_CRAFT1_22X.xml the XML file with randomly-distributed values, created directly by define_scenario()
17 # * convert_cfg.py the conversion configuration file
18 # * MCScenario_CRAFT1_22X.db the SQLite database created from the XML
19 # * check_cfg.py configuration file that converts the SQLite file back into XML
20 # * MCScenario_CRAFT1_22X_CHECKME.xml converted back, so that we can check the values that were saved to the database
21 #
22 # to check the output in Excel, do this
23 # ./Alignment/MuonAlignment/python/geometryXMLtoCSV.py < MCScenario_CRAFT1_22X_CHECKME.xml > MCScenario_CRAFT1_22X_CHECKME.csv
24 # and then open MCScenario_CRAFT1_22X_CHECKME.csv in Excel
25 
26 from builtins import range
27 import random, os
28 from math import *
29 
30 # set the initial seed for reproducibility!
31 random.seed(123456)
32 
33 
35  scenario = define_scenario()
36  write_xml(scenario, "MCScenario_CRAFT1_22X.xml")
37  write_conversion_cfg("convert_cfg.py", "MCScenario_CRAFT1_22X.xml", "MCScenario_CRAFT1_22X.db")
38  cmsRun("convert_cfg.py")
39  write_check_cfg("check_cfg.py", "MCScenario_CRAFT1_22X.db", "MCScenario_CRAFT1_22X_CHECKME.xml")
40  cmsRun("check_cfg.py")
41 
42 
43 def write_conversion_cfg(fileName, xmlFileName, dbFileName):
44  outfile = file(fileName, "w")
45  outfile.write("""
46 from Alignment.MuonAlignment.convertXMLtoSQLite_cfg import *
47 process.MuonGeometryDBConverter.fileName = "%(xmlFileName)s"
48 process.PoolDBOutputService.connect = "sqlite_file:%(dbFileName)s"
49 """ % vars())
50 
51 def write_check_cfg(fileName, dbFileName, xmlFileName):
52  outfile = file(fileName, "w")
53  outfile.write("""
54 from Alignment.MuonAlignment.convertSQLitetoXML_cfg import *
55 process.PoolDBESSource.connect = "sqlite_file:%(dbFileName)s"
56 process.MuonGeometryDBConverter.outputXML.fileName = "%(xmlFileName)s"
57 process.MuonGeometryDBConverter.outputXML.relativeto = "ideal"
58 process.MuonGeometryDBConverter.outputXML.suppressDTChambers = False
59 process.MuonGeometryDBConverter.outputXML.suppressDTSuperLayers = False
60 process.MuonGeometryDBConverter.outputXML.suppressDTLayers = True
61 process.MuonGeometryDBConverter.outputXML.suppressCSCChambers = False
62 process.MuonGeometryDBConverter.outputXML.suppressCSCLayers = False
63 """ % vars())
64 
65 def cmsRun(fileName):
66  os.system("cmsRun %(fileName)s" % vars())
67 
68 
69 
70 # only needed to make the output XML readable
71 DTpreferred_order = {"wheel":1, "station":2, "sector":3, "superlayer":4, "layer":5}
72 CSCpreferred_order = {"endcap":1, "station":2, "ring":3, "chamber":4, "layer":5}
73 def DTsorter(a, b): return cmp(DTpreferred_order[a], DTpreferred_order[b])
74 def CSCsorter(a, b): return cmp(CSCpreferred_order[a], CSCpreferred_order[b])
75 
76 # an instance of this class corresponds to one <DTChamber ... /> or <CSCStation ... />, etc.
77 class Alignable:
78  def __init__(self, alignabletype, **location):
79  self.alignabletype = alignabletype
80  self.location = location
81 
82  def writeXML(self):
83  parameters = self.location.keys()
84  if self.alignabletype[0:2] == "DT":
85  parameters.sort(DTsorter)
86  else:
87  parameters.sort(CSCsorter)
88 
89  output = ["<", self.alignabletype, " "]
90  for parameter in parameters:
91  output.extend([parameter, "=\"", str(self.location[parameter]), "\" "])
92  output.append("/>")
93 
94  return "".join(output)
95 
96 preferred_order = {"x":1, "y":2, "z":3, "phix":4, "phiy":5, "phiz":6}
97 def sorter(a, b): return cmp(preferred_order[a], preferred_order[b])
98 
99 # an instance of this class corresponds to one <setposition ... />
100 class Position:
101  def __init__(self, **location):
102  self.location = location
103 
104  def writeXML(self):
105  parameters = self.location.keys()
106  parameters.sort(sorter)
107 
108  output = ["<setposition relativeto=\"ideal\" "]
109  for parameter in parameters:
110  output.extend([parameter, "=\"", str(self.location[parameter]), "\" "])
111  output.append("/>")
112 
113  return "".join(output)
114 
115 # an instance of this class corresponds to one <operation> ... </operation> in the XML file
116 class Operation:
117  def __init__(self, alignable, position):
118  self.alignable = alignable
119  self.position = position
120 
121  def writeXML(self):
122  output = ["<operation> ", self.alignable.writeXML(), " ", self.position.writeXML(), " </operation>\n"]
123  return "".join(output)
124 
125 def write_xml(scenario, fileName):
126  # a scenario is an ordered list of Operations
127  XMLlist = ["<MuonAlignment>\n"]
128  for operation in scenario:
129  XMLlist.append(operation.writeXML())
130  XMLlist.append("</MuonAlignment>\n")
131  XMLstring = "".join(XMLlist)
132 
133  outfile = file(fileName, "w")
134  outfile.write(XMLstring)
135 
136 class DTChamber:
137  def __init__(self, **location):
138  self.__dict__.update(location)
139 
141  def __init__(self, **location):
142  self.__dict__.update(location)
143 
144 
145 
146 # this is the interesting part: where we define a scenario for CRAFT1 MC
148  # this will be a list of operations to write to an XML file
149  scenario = []
150 
151  # Uncertainty in DT chamber positions comes in two parts:
152  # 1. positions within sectors
153  # 2. positions of the sector-groups
154 
155  # Aligned chambers (wheels -1, 0, +1 except sectors 1 and 7)
156  # uncertainty within sectors:
157  # x: 0.08 cm (from segment-matching) phix: 0.0007 rad (from MC)
158  # y: 0.10 cm (from MC) phiy: 0.0007 rad (from segment-matching)
159  # z: 0.10 cm (from MC) phiz: 0.0003 rad (from MC)
160  # uncertainty of sector-groups (depends on choice of pT cut, not well understood):
161  # x: 0.05 cm
162 
163  # Unaligned chambers uncertainty within sectors:
164  # x: 0.08 cm (same as above) phix: 0.0016 rad
165  # y: 0.24 cm phiy: 0.0021 rad
166  # z: 0.42 cm with a -0.35 cm bias phiz: 0.0010 rad
167  # uncertainty of sector-groups:
168  # x: 0.65 cm
169  # These come from actual alignments measured in the aligned
170  # chambers (we assume that the unaligned chambers have
171  # misalignments on the same scale)
172 
173  # Also, superlayer z uncertainty is 0.054 cm
174 
175  # Before starting, let's build a list of chambers
176  DTchambers = []
177  for wheel in -2, -1, 0, 1, 2:
178  for station in 1, 2, 3, 4:
179  if station == 4: nsectors = 14
180  else: nsectors = 12
181  for sector in range(1, nsectors+1):
182  DTchambers.append(DTChamber(wheel = wheel, station = station, sector = sector))
183 
184  # the superlayers
185  for dtchamber in DTchambers:
186  for superlayer in 1, 2, 3:
187  if superlayer == 2 and dtchamber.station == 4: continue
188 
189  alignable = Alignable("DTSuperLayer", wheel = dtchamber.wheel, station = dtchamber.station, sector = dtchamber.sector, superlayer = superlayer)
190  position = Position(x = 0, y = 0, z = random.gauss(0, 0.054), phix = 0, phiy = 0, phiz = 0)
191  scenario.append(Operation(alignable, position))
192 
193  sector_errx = {}
194 
195  # sector-groups for aligned chambers:
196  for wheel in -1, 0, 1:
197  for sector in 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14:
198  sector_errx[wheel, sector] = random.gauss(0., 0.05)
199 
200  # sector-groups for unaligned chambers:
201  for wheel in -1, 0, 1:
202  for sector in 1, 7:
203  sector_errx[wheel, sector] = random.gauss(0., 0.65)
204  for wheel in -2, 2:
205  for sector in 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14:
206  sector_errx[wheel, sector] = random.gauss(0., 0.65)
207 
208  for dtchamber in DTchambers:
209  # within sectors for aligned chambers:
210  if dtchamber.wheel in (-1, 0, 1) and dtchamber.sector in (2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14):
211  errx = random.gauss(0, 0.08)
212  erry = random.gauss(0, 0.10)
213  errz = random.gauss(0, 0.10)
214  errphix = random.gauss(0, 0.0007)
215  errphiy = random.gauss(0, 0.0007)
216  errphiz = random.gauss(0, 0.0003)
217 
218  # within sectors for unaligned chambers:
219  else:
220  errx = random.gauss(0, 0.08)
221  erry = random.gauss(0, 0.24)
222  errz = random.gauss(-0.35, 0.42)
223  errphix = random.gauss(0, 0.0016)
224  errphiy = random.gauss(0, 0.0021)
225  errphiz = random.gauss(0, 0.0010)
226 
227  errx += sector_errx[dtchamber.wheel, dtchamber.sector]
228 
229  # now turn this into an operation
230  alignable = Alignable("DTChamber", wheel = dtchamber.wheel, station = dtchamber.station, sector = dtchamber.sector)
231  position = Position(x = errx, y = erry, z = errz, phix = errphix, phiy = errphiy, phiz = errphiz)
232  scenario.append(Operation(alignable, position))
233 
234  # Uncertainty in CSC chamber positions comes in 5 parts:
235  # 1. 0.0092 cm layer x misalignments observed with beam-halo tracks
236  # 2. isotropic photogrammetry uncertainty of 0.03 cm (x, y, z) and 0.00015 rad in phiz
237  # 3. 0.0023 rad phiy misalignment observed with beam-halo tracks
238  # 4. 0.1438 cm z and 0.00057 rad phix uncertainty between rings from SLM (from comparison in 0T data with PG)
239  # 5. 0.05 cm (x, y, z) disk misalignments and 0.0001 rad rotation around beamline
240 
241  # Before starting, let's build a list of chambers
242  CSCchambers = []
243  for endcap in 1, 2:
244  for station, ring in (1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (3, 1), (3, 2), (4, 1):
245  if station > 1 and ring == 1:
246  nchambers = 18
247  else:
248  nchambers = 36
249 
250  for chamber in range(1, nchambers+1):
251  CSCchambers.append(CSCChamber(endcap = endcap, station = station, ring = ring, chamber = chamber))
252 
253  # First, the layer uncertainties: x only for simplicity, observed 0.0092 cm in overlaps alignment test
254  for chamber in CSCchambers:
255  for layer in 1, 2, 3, 4, 5, 6:
256  alignable = Alignable("CSCLayer", endcap = chamber.endcap, station = chamber.station, ring = chamber.ring, chamber = chamber.chamber, layer = layer)
257  position = Position(x = random.gauss(0, 0.0092), y = 0, z = 0, phix = 0, phiy = 0, phiz = 0)
258  scenario.append(Operation(alignable, position))
259 
260  # Next, the ring errors from DCOPS (derived from comparison with photogrammetry)
261  CSCrings = []
262  for endcap in 1, 2:
263  for station, ring in (1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (3, 1), (3, 2), (4, 1):
264  CSCrings.append(CSCChamber(endcap = endcap, station = station, ring = ring, z = random.gauss(0, 0.1438), phix = random.gauss(0, 0.00057)))
265 
266  # Next, the chamber errors
267  for chamber in CSCchambers:
268  errx = random.gauss(0, 0.03)
269  erry = random.gauss(0, 0.03)
270  errz = random.gauss(0, 0.03)
271  errphix = random.gauss(0, 0.00057)
272  errphiy = random.gauss(0, 0.0023)
273  errphiz = random.gauss(0, 0.00015)
274 
275  for ring in CSCrings:
276  if ring.endcap == chamber.endcap and ring.station == chamber.station and ring.ring == chamber.ring:
277  errz += ring.z
278  errphix += ring.phix
279  break
280 
281  alignable = Alignable("CSCChamber", endcap = chamber.endcap, station = chamber.station, ring = chamber.ring, chamber = chamber.chamber)
282  position = Position(x = errx, y = erry, z = errz, phix = errphix, phiy = errphiy, phiz = errphiz)
283  scenario.append(Operation(alignable, position))
284 
285  # Finally, the disk errors
286  for endcap in 1, 2:
287  for station in 1, 2, 3, 4:
288  alignable = Alignable("CSCStation", endcap = endcap, station = station)
289  position = Position(x = random.gauss(0, 0.05), y = random.gauss(0, 0.05), z = random.gauss(0, 0.05), phix = 0., phiy = 0., phiz = random.gauss(0, 0.0001))
290  scenario.append(Operation(alignable, position))
291 
292  return scenario
293 
294 # run it all!
def __init__(self, alignabletype, location)
def make_scenario_sqlite()
called once at the end of this script
def write_conversion_cfg(fileName, xmlFileName, dbFileName)
that&#39;s it! everything this uses is defined below
def __init__(self, alignable, position)
def write_xml(scenario, fileName)
static std::string join(char **cmd)
Definition: RemoteFile.cc:21
#define update(a, b)
#define str(s)
def write_check_cfg(fileName, dbFileName, xmlFileName)