CMS 3D CMS Logo

alignment.py
Go to the documentation of this file.
1 import collections
2 import os
3 import re
4 
5 import configTemplates
6 from helperFunctions import conddb, parsecolor, parsestyle, replaceByMap
7 from TkAlExceptions import AllInOneError
8 
10  condShorts = {
11  "TrackerAlignmentErrorExtendedRcd": {
12  "zeroAPE_phase0": {
13  "connectString":("frontier://FrontierProd"
14  "/CMS_CONDITIONS"),
15  "tagName": "TrackerIdealGeometryErrorsExtended210_mc",
16  "labelName": ""
17  },
18  "zeroAPE_phase1": {
19  "connectString":("frontier://FrontierProd"
20  "/CMS_CONDITIONS"),
21  "tagName": "TrackerAlignmentErrorsExtended_Upgrade2017_design_v0",
22  "labelName": ""
23  },
24  },
25  "TrackerSurfaceDeformationRcd": {
26  "zeroDeformations": {
27  "connectString":("frontier://FrontierProd"
28  "/CMS_CONDITIONS"),
29  "tagName": "TrackerSurfaceDeformations_zero",
30  "labelName": ""
31  },
32  },
33  }
34  def __init__(self, name, config, runGeomComp = "1"):
35  section = "alignment:%s"%name
36  if not config.has_section( section ):
37  raise AllInOneError("section %s not found. Please define the "
38  "alignment!"%section)
39  config.checkInput(section,
40  knownSimpleOptions = ['globaltag', 'style', 'color', 'title', 'mp', 'mp_alignments', 'mp_deformations', 'hp', 'hp_alignments', 'hp_deformations', 'sm', 'sm_alignments', 'sm_deformations'],
41  knownKeywords = ['condition'])
42  self.name = name
43  if config.exists(section,"title"):
44  self.title = config.get(section,"title")
45  else:
46  self.title = self.name
47  if (int(runGeomComp) != 1):
48  self.name += "_run" + runGeomComp
49  self.title += " run " + runGeomComp
50  if "|" in self.title or "," in self.title or '"' in self.title:
51  msg = "The characters '|', '\"', and ',' cannot be used in the alignment title!"
52  raise AllInOneError(msg)
53  self.runGeomComp = runGeomComp
54  self.globaltag = config.get( section, "globaltag" )
55  self.conditions = self.__getConditions( config, section )
56 
57  self.color = config.get(section,"color")
58  self.style = config.get(section,"style")
59 
60  self.color = str(parsecolor(self.color))
61  self.style = str(parsestyle(self.style))
62 
63  def __shorthandExists(self, theRcdName, theShorthand):
64  """Method which checks, if `theShorthand` is a valid shorthand for the
65  given `theRcdName`.
66 
67  Arguments:
68  - `theRcdName`: String which specifies the database record.
69  - `theShorthand`: String which specifies the shorthand to check.
70  """
71 
72  if (theRcdName in self.condShorts) and \
73  (theShorthand in self.condShorts[theRcdName]):
74  return True
75  else:
76  return False
77 
78  def __getConditions( self, theConfig, theSection ):
79  conditions = []
80  for option in theConfig.options( theSection ):
81  if option in ("mp", "mp_alignments", "mp_deformations", "hp", "hp_alignments", "hp_deformations", "sm", "sm_alignments", "sm_deformations"):
82  matches = [re.match(_, option) for _ in ("^(..)$", "^(..)_alignments$", "^(..)_deformations$")]
83  assert sum(bool(_) for _ in matches) == 1, option
84  condPars = theConfig.get(theSection, option).split(",")
85  condPars = [_.strip() for _ in condPars]
86  if matches[0]:
87  alignments = True
88  deformations = True
89  elif matches[1]:
90  alignments = True
91  deformations = False
92  option = matches[1].group(1)
93  elif matches[2]:
94  alignments = False
95  deformations = True
96  option = matches[2].group(1)
97  else:
98  assert False
99 
100  if option == "mp":
101  if len(condPars) == 1:
102  number, = condPars
103  jobm = None
104  elif len(condPars) == 2:
105  number, jobm = condPars
106  else:
107  raise AllInOneError("Up to 2 arguments accepted for {} (job number, and optionally jobm index)".format(option))
108 
109  folder = "/afs/cern.ch/cms/CAF/CMSALCA/ALCA_TRACKERALIGN/MP/MPproduction/{}{}/".format(option, number)
110  if not os.path.exists(folder):
111  raise AllInOneError(folder+" does not exist.")
112  folder = os.path.join(folder, "jobData")
113  jobmfolders = set()
114  if jobm is None:
115  for filename in os.listdir(folder):
116  if re.match("jobm([0-9]*)", filename) and os.path.isdir(os.path.join(folder, filename)):
117  jobmfolders.add(filename)
118  if len(jobmfolders) == 0:
119  raise AllInOneError("No jobm or jobm(number) folder in {}".format(folder))
120  elif len(jobmfolders) == 1:
121  folder = os.path.join(folder, jobmfolders.pop())
122  else:
123  raise AllInOneError(
124  "Multiple jobm or jobm(number) folders in {}\n".format(folder)
125  + ", ".join(jobmfolders) + "\n"
126  + "Please specify 0 for jobm, or a number for one of the others."
127  )
128  elif jobm == "0":
129  folder = os.path.join(folder, "jobm")
130  if os.path.exists(folder + "0"):
131  raise AllInOneError("Not set up to handle a folder named jobm0")
132  else:
133  folder = os.path.join(folder, "jobm{}".format(jobm))
134 
135  dbfile = os.path.join(folder, "alignments_MP.db")
136  if not os.path.exists(dbfile):
137  raise AllInOneError("No file {}. Maybe your alignment folder is corrupted, or maybe you specified the wrong jobm?".format(dbfile))
138 
139  elif option in ("hp", "sm"):
140  if len(condPars) == 1:
141  number, = condPars
142  iteration = None
143  elif len(condPars) == 2:
144  number, iteration = condPars
145  else:
146  raise AllInOneError("Up to 2 arguments accepted for {} (job number, and optionally iteration)".format(option))
147  folder = "/afs/cern.ch/cms/CAF/CMSALCA/ALCA_TRACKERALIGN2/HipPy/alignments/{}{}".format(option, number)
148  if not os.path.exists(folder):
149  raise AllInOneError(folder+" does not exist.")
150  if iteration is None:
151  for filename in os.listdir(folder):
152  match = re.match("alignments_iter([0-9]*).db", filename)
153  if match:
154  if iteration is None or int(match.group(1)) > iteration:
155  iteration = int(match.group(1))
156  if iteration is None:
157  raise AllInOneError("No alignments in {}".format(folder))
158  dbfile = os.path.join(folder, "alignments_iter{}.db".format(iteration))
159  if not os.path.exists(dbfile):
160  raise AllInOneError("No file {}.".format(dbfile))
161 
162  if "\nDeformations" not in conddb("--db", dbfile, "listTags"):
163  deformations = False #so that hp = XXXX works whether or not deformations were aligned
164  if not alignments: #then it's specified with hp_deformations, which is a mistake
165  raise AllInOneError("{}{} has no deformations".format(option, number))
166 
167  else:
168  assert False, option
169 
170  if alignments:
171  conditions.append({"rcdName": "TrackerAlignmentRcd",
172  "connectString": "sqlite_file:"+dbfile,
173  "tagName": "Alignments",
174  "labelName": ""})
175  if deformations:
176  conditions.append({"rcdName": "TrackerSurfaceDeformationRcd",
177  "connectString": "sqlite_file:"+dbfile,
178  "tagName": "Deformations",
179  "labelName": ""})
180 
181  elif option.startswith( "condition " ):
182  rcdName = option.split( "condition " )[1]
183  condPars = theConfig.get( theSection, option ).split( "," )
184  if len(condPars) == 1:
185  if len(condPars[0])==0:
186  msg = ("In section [%s]: '%s' is used with too few "
187  "arguments. A connect_string and a tag are "
188  "required!"%(theSection, option))
189  raise AllInOneError(msg)
190  elif self.__shorthandExists(rcdName, condPars[0]):
191  shorthand = condPars[0]
192  condPars = [
193  self.condShorts[rcdName][shorthand]["connectString"],
194  self.condShorts[rcdName][shorthand]["tagName"],
195  self.condShorts[rcdName][shorthand]["labelName"]]
196  elif rcdName == "TrackerAlignmentErrorExtendedRcd" and condPars[0] == "zeroAPE":
197  raise AllInOneError("Please specify either zeroAPE_phase0 or zeroAPE_phase1")
198  #can probably make zeroAPE an alias of zeroAPE_phase1 at some point,
199  #but not sure if now is the time
200  else:
201  msg = ("In section [%s]: '%s' is used with '%s', "
202  "which is an unknown shorthand for '%s'. Either "
203  "provide at least a connect_string and a tag or "
204  "use a known shorthand.\n"
205  %(theSection, option, condPars[0], rcdName))
206  if rcdName in self.condShorts:
207  msg += "Known shorthands for '%s':\n"%(rcdName)
208  theShorts = self.condShorts[rcdName]
209  knownShorts = [("\t"+key+": "
210  +theShorts[key]["connectString"]+","
211  +theShorts[key]["tagName"]+","
212  +theShorts[key]["labelName"]) \
213  for key in theShorts]
214  msg+="\n".join(knownShorts)
215  else:
216  msg += ("There are no known shorthands for '%s'."
217  %(rcdName))
218  raise AllInOneError(msg)
219  if len( condPars ) == 2:
220  condPars.append( "" )
221  if len(condPars) > 3:
222  msg = ("In section [%s]: '%s' is used with too many "
223  "arguments. A maximum of 3 arguments is allowed."
224  %(theSection, option))
225  raise AllInOneError(msg)
226  conditions.append({"rcdName": rcdName.strip(),
227  "connectString": condPars[0].strip(),
228  "tagName": condPars[1].strip(),
229  "labelName": condPars[2].strip()})
230 
231  rcdnames = collections.Counter(condition["rcdName"] for condition in conditions)
232  if rcdnames and max(rcdnames.values()) >= 2:
233  raise AllInOneError("Some conditions are specified multiple times (possibly through mp or hp options)!\n"
234  + ", ".join(rcdname for rcdname, count in rcdnames.iteritems() if count >= 2))
235 
236  for condition in conditions:
237  self.__testDbExist(condition["connectString"], condition["tagName"])
238 
239  return conditions
240 
241  def __testDbExist(self, dbpath, tagname):
242  if dbpath.startswith("sqlite_file:"):
243  if not os.path.exists( dbpath.split("sqlite_file:")[1] ):
244  raise AllInOneError("could not find file: '%s'"%dbpath.split("sqlite_file:")[1])
245  elif "\n"+tagname not in conddb("--db", dbpath.split("sqlite_file:")[1], "listTags"):
246  raise AllInOneError("{} does not exist in {}".format(tagname, dbpath))
247 
248  def restrictTo( self, restriction ):
249  result = []
250  if not restriction == None:
251  for mode in self.mode:
252  if mode in restriction:
253  result.append( mode )
254  self.mode = result
255 
256  def getRepMap( self ):
257  result = {
258  "name": self.name,
259  "title": self.title,
260  "color": self.color,
261  "style": self.style,
262  "runGeomComp": self.runGeomComp,
263  "GlobalTag": self.globaltag
264  }
265  return result
266 
267  def getConditions(self):
268  """This function creates the configuration snippet to override
269  global tag conditions.
270  """
271  if len( self.conditions ):
272  loadCond = ("\nimport CalibTracker.Configuration."
273  "Common.PoolDBESSource_cfi\n")
274  for cond in self.conditions:
275  if not cond["labelName"] == "":
276  temp = configTemplates.conditionsTemplate.replace(
277  "tag = cms.string('.oO[tagName]Oo.')",
278  ("tag = cms.string('.oO[tagName]Oo.'),"
279  "\nlabel = cms.untracked.string('.oO[labelName]Oo.')"))
280  else:
281  temp = configTemplates.conditionsTemplate
282  loadCond += replaceByMap( temp, cond )
283  else:
284  loadCond = ""
285  return loadCond
dictionary condShorts
Definition: alignment.py:10
def __getConditions(self, theConfig, theSection)
Definition: alignment.py:78
def parsestyle(style)
def __testDbExist(self, dbpath, tagname)
Definition: alignment.py:241
def restrictTo(self, restriction)
Definition: alignment.py:248
def __shorthandExists(self, theRcdName, theShorthand)
Definition: alignment.py:63
def replaceByMap(target, the_map)
— Helpers —############################
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def parsecolor(color)
def getRepMap(self)
Definition: alignment.py:256
double split
Definition: MVATrainer.cc:139
def __init__(self, name, config, runGeomComp="1")
Definition: alignment.py:34
def getConditions(self)
Definition: alignment.py:267