CMS 3D CMS Logo

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