CMS 3D CMS Logo

DMR.py
Go to the documentation of this file.
1 import copy
2 import os
3 
4 def DMR(config, validationDir):
5 
6  jobs = []
7  dmrType = "single"
8 
9 
10  IOVs = {}
11 
12 
13  isDataMerged = {}
14 
15 
16  if not dmrType in config["validations"]["DMR"]:
17  raise Exception("No 'single' key word in config for DMR")
18 
19  for singleName in config["validations"]["DMR"][dmrType]:
20  aux_IOV = config["validations"]["DMR"][dmrType][singleName]["IOV"]
21  if not isinstance(aux_IOV, list) and aux_IOV.endswith(".txt"):
22  config["validations"]["DMR"][dmrType][singleName]["IOV"] = []
23  with open(aux_IOV, 'r') as IOVfile: for line in IOVfile.readlines():
24  if len(line) != 0: config["validations"]["DMR"][dmrType][singleName]["IOV"].append(int(line))
25  for IOV in config["validations"]["DMR"][dmrType][singleName]["IOV"]:
26 
27  if singleName not in IOVs.keys():
28  IOVs[singleName] = []
29  if IOV not in IOVs[singleName]:
30  IOVs[singleName].append(IOV)
31 
32  for alignment in config["validations"]["DMR"][dmrType][singleName]["alignments"]:
33 
34  workDir = "{}/DMR/{}/{}/{}/{}".format(validationDir, dmrType, singleName, alignment, IOV)
35 
36 
37  local = {}
38  local["output"] = "{}/{}/DMR/{}/{}/{}/{}".format(config["LFS"], config["name"], dmrType, alignment, singleName, IOV)
39  local["alignment"] = copy.deepcopy(config["alignments"][alignment])
40  local["validation"] = copy.deepcopy(config["validations"]["DMR"][dmrType][singleName])
41  local["validation"].pop("alignments")
42  local["validation"]["IOV"] = IOV
43  if "dataset" in local["validation"]:
44  local["validation"]["dataset"] = local["validation"]["dataset"].format(IOV)
45  if "goodlumi" in local["validation"]:
46  local["validation"]["goodlumi"] = local["validation"]["goodlumi"].format(IOV)
47 
48 
49  job = {
50  "name": "DMR_{}_{}_{}_{}".format(dmrType, alignment, singleName, IOV),
51  "dir": workDir,
52  "exe": "cmsRun",
53  "cms-config": "{}/src/Alignment/OfflineValidation/python/TkAlAllInOneTool/DMR_cfg.py".format(os.environ["CMSSW_BASE"]),
54  "run-mode": "Condor",
55  "dependencies": [],
56  "config": local,
57  }
58 
59  jobs.append(job)
60 
61 
62  if "merge" in config["validations"]["DMR"]:
63 
64  mergeJobs = []
65  dmrType = "merge"
66 
67 
68  for mergeName in config["validations"]["DMR"][dmrType]:
69 
70  singlesMC = []
71  for singleName in config["validations"]["DMR"][dmrType][mergeName]['singles']:
72  if len(IOVs[singleName]) == 1 and int(IOVs[singleName][0]) == 1: singlesMC.append(singleName)
73  isMConly = (len(singlesMC) == len(config["validations"]["DMR"][dmrType][mergeName]['singles']))
74  if isMConly:
75  isDataMerged[mergeName] = 0
76  elif len(singlesMC) == 0:
77  isDataMerged[mergeName] = 1
78  else:
79  isDataMerged[mergeName] = -1
80 
81 
82  for iname,singleName in enumerate(config["validations"]["DMR"][dmrType][mergeName]['singles']):
83  isMC = (singleName in singlesMC)
84  if isMConly and iname > 0: continue #special case for MC only comparison
85  elif isMConly: singlesMC.pop(singlesMC.index(singleName))
86 
87  for IOV in IOVs[singleName]:
88  if isMC and not isMConly: continue #ignore IOV=1 as it is automatically added to each DATA IOV unless MC only comparison
89 
90 
91  workDir = "{}/DMR/{}/{}/{}".format(validationDir, dmrType, mergeName, IOV) #Different (DATA) single jobs must contain different set of IOVs
92 
93 
94  local = {}
95 
96  job = {
97  "name": "DMR_{}_{}_{}".format(dmrType, mergeName, IOV),
98  "dir": workDir,
99  "exe": "DMRmerge",
100  "run-mode": "Condor",
101  "dependencies": [],
102  "config": local,
103  }
104 
105 
106  for alignment in config["alignments"]:
107  idxIncrement = 0
108  local.setdefault("alignments", {})
109  if alignment in config["validations"]["DMR"]["single"][singleName]["alignments"]: #Cover all DATA validations
110  local["alignments"][alignment] = copy.deepcopy(config["alignments"][alignment])
111  local["alignments"][alignment]['index'] = config["validations"]["DMR"]["single"][singleName]["alignments"].index(alignment)
112  for singleMCname in singlesMC:
113  if alignment in config["validations"]["DMR"]["single"][singleMCname]["alignments"]: #Add MC objects
114  local["alignments"][alignment] = copy.deepcopy(config["alignments"][alignment])
115  local["alignments"][alignment]['index'] = len(config["validations"]["DMR"]["single"][singleName]["alignments"])
116  local["alignments"][alignment]['index'] += idxIncrement + config["validations"]["DMR"]["single"][singleMCname]["alignments"].index(alignment)
117  idxIncrement += len(config["validations"]["DMR"]["single"][singleMCname]["alignments"])
118  local["validation"] = copy.deepcopy(config["validations"]["DMR"][dmrType][mergeName])
119  local["validation"]["IOV"] = IOV #is it really needed here?
120  if "customrighttitle" in local["validation"].keys():
121  if "IOV" in local["validation"]["customrighttitle"]:
122  local["validation"]["customrighttitle"] = local["validation"]["customrighttitle"].replace("IOV",str(IOV))
123  local["output"] = "{}/{}/DMR/{}/{}/{}".format(config["LFS"], config["name"], dmrType, mergeName, IOV)
124 
125 
126  if "style" in config.keys():
127  if "DMR" in config['style'].keys():
128  if dmrType in config['style']['DMR'].keys():
129  local["style"] = copy.deepcopy(config["style"]["DMR"][dmrType])
130  if "Rlabel" in local["style"] and "customrighttitle" in local["validation"].keys():
131  print("WARNING: custom right label is overwritten by global settings")
132 
133 
134  for singleJob in jobs:
135 
136  _alignment, _singleName, _singleIOV = singleJob["name"].split("_")[2:]
137  if _singleName in config["validations"]["DMR"][dmrType][mergeName]["singles"]:
138  if int(_singleIOV) == IOV or (int(_singleIOV) == 1 and _singleName in singlesMC): #matching DATA job or any MC single job
139  local["alignments"][_alignment]["file"] = singleJob["config"]["output"]
140  job["dependencies"].append(singleJob["name"])
141 
142 
143  mergeJobs.append(job)
144 
145 
146  jobs.extend(mergeJobs)
147 
148  if "trends" in config["validations"]["DMR"]:
149 
150 
151  trendJobs = []
152  dmrType = "trends"
153 
154  for trendName in config["validations"]["DMR"][dmrType]:
155  #print("trendName = {}".format(trendName))
156 
157  workDir = "{}/DMR/{}/{}".format(validationDir, dmrType, trendName)
158 
159 
160  local = {}
161  job = {
162  "name": "DMR_{}_{}".format(dmrType, trendName),
163  "dir": workDir,
164  "exe": "DMRtrends",
165  "run-mode": "Condor",
166  "dependencies": [],
167  "config": local,
168  }
169 
170 
171  mergesDATA = []
172  for mergeName in config["validations"]["DMR"][dmrType][trendName]["merges"]:
173 
174  if isDataMerged[mergeName] < 0:
175  raise Exception("Trend jobs cannot process merge jobs containing both DATA and MC objects.")
176  elif isDataMerged[mergeName] == 1:
177  mergesDATA.append(mergeName)
178  else:
179  if "doUnitTest" in config["validations"]["DMR"][dmrType][trendName].keys() and config["validations"]["DMR"][dmrType][trendName]["doUnitTest"]:
180  local.setdefault("alignments", {})
181  continue
182  else:
183  raise Exception("Trend jobs are not implemented for treating MC.")
184 
185 
186  trendIOVs = []
187  _mergeFiles = []
188  for mergeName in mergesDATA:
189  for iname,singleName in enumerate(config["validations"]["DMR"]['merge'][mergeName]['singles']):
190  trendIOVs += [IOV for IOV in IOVs[singleName]]
191 
192  for alignment in config["alignments"]:
193  local.setdefault("alignments", {})
194  if alignment in config["validations"]["DMR"]["single"][singleName]["alignments"]: #Cover all DATA validations
195  local["alignments"][alignment] = copy.deepcopy(config["alignments"][alignment])
196  local["alignments"][alignment]['index'] = config["validations"]["DMR"]["single"][singleName]["alignments"].index(alignment)
197  _mergeFiles.append("{}/{}/DMR/{}/{}/{}".format(config["LFS"], config["name"], "merge", mergeName, "{}"))
198  trendIOVs.sort()
199  local["validation"] = copy.deepcopy(config["validations"]["DMR"][dmrType][trendName])
200  if len(_mergeFiles) == 1:
201  local["validation"]["mergeFile"] = _mergeFiles[0]
202  else:
203  local["validation"]["mergeFile"] = _mergeFiles #FIXME for multiple merge files in backend
204  local["validation"]["IOV"] = trendIOVs
205  local["output"] = "{}/{}/DMR/{}/{}/".format(config["LFS"], config["name"], dmrType, trendName)
206  if "style" in config.keys() and "trends" in config["style"].keys():
207  local["style"] = copy.deepcopy(config["style"])
208  if "DMR" in local["style"].keys(): local["style"].pop("DMR")
209  if "CMSlabel" in config["style"]["trends"].keys(): local["style"]["CMSlabel"] = config["style"]["trends"]["CMSlabel"]
210  if "Rlabel" in config["style"]["trends"].keys():
211  local["style"]["trends"].pop("Rlabel")
212  local["style"]["trends"]["TitleCanvas"] = config["style"]["trends"]["Rlabel"]
213  else:
214  raise Exception("You want to create 'trends' jobs, but there are no 'lines' section in the config for pixel updates!")
215 
216  #Loop over all merge jobs
217  for mergeName in mergesDATA:
218  for mergeJob in mergeJobs:
219  alignment, mergeJobName, mergeIOV = mergeJob["name"].split("_")[1:]
220  if mergeJobName == mergeName and int(mergeIOV) in trendIOVs:
221  job["dependencies"].append(mergeJob["name"])
222 
223  trendJobs.append(job)
224 
225  jobs.extend(trendJobs)
226 
227  if "averaged" in config["validations"]["DMR"]:
228 
229 
230  avpJobs = []
231  dmrType = "averaged"
232  for avpName in config["validations"]["DMR"][dmrType]:
233 
234  workDir = "{}/DMR/{}/{}".format(validationDir, dmrType, avpName)
235  output = "{}/{}/DMR/{}/{}".format(config["LFS"], config["name"], dmrType, avpName)
236 
237 
238  mergesDATA = []
239  mergesMC = []
240  for mergeName in config["validations"]["DMR"][dmrType][avpName]["merges"]:
241 
242  if isDataMerged[mergeName] < 0:
243  raise Exception("Average jobs cannot process merge jobs containing both DATA and MC objects.")
244  elif isDataMerged[mergeName] == 1:
245  mergesDATA.append(mergeName)
246  else:
247  mergesMC.append(mergeName)
248  if "moduleFilterFile" not in config["validations"]["DMR"]["merge"][mergeName]:
249  raise Exception("Value for 'moduleFilterFile' is required for the 'merge' step if the 'averaged' step is requested.")
250  if "maxBadLumiPixel" not in config["validations"]["DMR"]["merge"][mergeName]:
251  print("WARNING: Default value for the 'maxBadLumiPixel' is used.")
252  if "maxBadLumiStrip" not in config["validations"]["DMR"]["merge"][mergeName]:
253  print("WARNING: Default value for the 'maxBadLumiStrip' is used.")
254  #Validate single step within merge step
255  for singleName in config["validations"]["DMR"]["merge"][mergeName]['singles']:
256  if "maxEntriesPerModuleForDmr" not in config["validations"]["DMR"]["single"][singleName]:
257  raise Exception("Value for 'maxEntriesPerModuleForDmr' is required for the 'single' step if the 'averaged' step is requested.")
258 
259  lumiPerRun = []
260  lumiPerIoV = []
261  lumiMC = []
262  if len(mergesDATA) > 0:
263  if "lumiPerRun" in config["validations"]["DMR"][dmrType][avpName].keys():
264  for lumifile in config["validations"]["DMR"][dmrType][avpName]['lumiPerRun']:
265  if lumifile.split(".")[-1] in ["txt","csv"]:
266  lumiPerRun.append(lumifile)
267  if "lumiPerIoV" in config["validations"]["DMR"][dmrType][avpName].keys():
268  for lumifile in config["validations"]["DMR"][dmrType][avpName]['lumiPerIoV']:
269  if lumifile.split(".")[-1] in ["txt","csv"]:
270  lumiPerIoV.append(lumifile)
271  if len(lumiPerRun) == 0 and len(lumiPerIoV) == 0:
272  raise Exception("No lumi per run/IoV file found or not specified in .csv/.txt format.")
273  if len(mergesMC) > 0:
274  if 'lumiMC' in config["validations"]["DMR"][dmrType][avpName].keys():
275  lumiMC = config["validations"]["DMR"][dmrType][avpName]['lumiMC']
276 
277 
278  plotJob = {}
279  plotJob['workdir'] = "{}/{}".format(workDir,"plots")
280  plotJob['output'] = "{}/{}".format(output,"plots")
281  plotJob['inputData'] = []
282  plotJob['inputMC'] = []
283  plotJob['dependencies'] = []
284 
285 
286  for mergeName in mergesDATA:
287 
288  workDirMerge = "{}/{}".format(workDir, mergeName)
289  outputMerge = "{}/{}".format(output, mergeName)
290 
291 
292  local = {}
293  local["type"] = "DMR"
294  local["mode"] = "merge"
295  local["isData"] = True
296  local["isMC"] = False
297 
298 
299  for alignment in config["alignments"]:
300  local.setdefault("alignments", {})
301  for singleName in config["validations"]["DMR"]["merge"][mergeName]["singles"]:
302  if alignment in config["validations"]["DMR"]["single"][singleName]['alignments']:
303  local["alignments"][alignment] = copy.deepcopy(config["alignments"][alignment])
304  local["validation"] = copy.deepcopy(config["validations"]["DMR"][dmrType][avpName])
305  local["validation"]["mergeFile"] = "{}/{}/DMR/{}/{}/{}".format(config["LFS"], config["name"], "merge", mergeName, "{}")
306  local["validation"]["lumiPerRun"] = lumiPerRun
307  local["validation"]["lumiPerIoV"] = lumiPerIoV
308  local["validation"]["lumiMC"] = lumiMC
309  local["validation"]["firstFromNext"] = []
310 
311 
312  IOVsPerMergeStep = []
313  for singleName in config["validations"]["DMR"]["merge"][mergeName]["singles"]:
314  for IOV in IOVs[singleName]:
315  if IOV not in IOVsPerMergeStep:
316  IOVsPerMergeStep.append(IOV)
317  IOVsPerMergeStep.sort()
318 
319 
320  extra_part = 0
321  maxfiles = int(config["validations"]["DMR"][dmrType][avpName]['maxfiles'])
322  if len(IOVsPerMergeStep)%maxfiles >= 2:
323  extra_part = 1
324  parts = extra_part+len(IOVsPerMergeStep)//maxfiles
325 
326  subJob = {'name' : [], 'output' : [], 'lumiPerFile' : []}
327  for ipart in range(0,parts):
328  #Adapt workdir per each subjob
329  workDirSub = workDirMerge+"_"+str(ipart)
330  outputSub = outputMerge+"_"+str(ipart)
331 
332  #Define IOV group
333  IOVGroup = []
334  lastIndex = 0
335  for iIOV,IOV in enumerate(IOVsPerMergeStep):
336  if (iIOV//maxfiles == ipart) or (ipart == parts-1 and iIOV//maxfiles > ipart):
337  IOVGroup.append(IOV)
338  lastIndex = iIOV
339  firstFromNext = []
340  if lastIndex != len(IOVsPerMergeStep)-1:
341  firstFromNext.append(IOVsPerMergeStep[lastIndex+1])
342 
343  #Write job info
344  _local = copy.deepcopy(local)
345  _local["output"] = outputSub
346  _local["validation"]["IOV"] = IOVGroup
347  _local["validation"]["firstFromNext"] = firstFromNext
348  job = {
349  "name": "DMR_{}_{}_{}".format(dmrType, avpName, mergeName+"_"+str(ipart)),
350  "dir": workDirSub,
351  "exe": "mkLumiAveragedPlots.py",
352  "run-mode": "Condor",
353  "dependencies": [],
354  "config": _local,
355  }
356  subJob['output'].append(outputSub)
357  subJob['name'].append("DMR_{}_{}_{}".format(dmrType, avpName, mergeName+"_"+str(ipart)))
358  subJob['lumiPerFile'].append(os.path.join(outputSub,"lumiPerFile.csv"))
359  if parts == 1:
360  plotJob['inputData'].append(outputSub)
361  plotJob['dependencies'].append(job['name'])
362 
363  #Set average job dependencies from the list of all merge jobs
364  for mergeJob in mergeJobs:
365  alignment, mergeJobName, mergeIOV = mergeJob["name"].split("_")[1:]
366  if mergeJobName == mergeName and int(mergeIOV) in IOVGroup:
367  job["dependencies"].append(mergeJob["name"])
368  #if mergeJobName in config["validations"]["DMR"][dmrType][avpName]["merges"]:
369  # job["dependencies"].append(mergeJob["name"])
370 
371  #Add to queue
372  avpJobs.append(job)
373 
374 
375  if parts > 1:
376  localFinalize = copy.deepcopy(local)
377  localFinalize['mode'] = "finalize"
378  localFinalize['output'] = outputMerge
379  localFinalize["validation"]["IOV"] = []
380  localFinalize["validation"]["mergeFile"] = subJob['output']
381  localFinalize["validation"]["lumiPerRun"] = []
382  localFinalize["validation"]["lumiPerIoV"] = subJob['lumiPerFile']
383  job = {
384  "name": "DMR_{}_{}_{}".format(dmrType, avpName, mergeName+"_finalize"),
385  "dir": workDirMerge,
386  "exe": "mkLumiAveragedPlots.py",
387  "run-mode": "Condor",
388  "dependencies": subJob['name'],
389  "config": localFinalize,
390  }
391  avpJobs.append(job)
392  plotJob['inputData'].append(outputMerge)
393  plotJob['dependencies'].append(job['name'])
394 
395  #Second create one averager job per all MC merge jobs
396  if len(mergesMC) != 0:
397 
398  workDirMerge = "{}/{}".format(workDir, "MC")
399  outputMerge = "{}/{}".format(output, "MC")
400 
401 
402  local = {}
403  local["type"] = "DMR"
404  local["mode"] = "merge"
405  local["isData"] = False
406  local["isMC"] = True
407  local["output"] = outputMerge
408 
409 
410  local["validation"] = copy.deepcopy(config["validations"]["DMR"][dmrType][avpName])
411  local["validation"]["mergeFile"] = []
412  for mergeName in mergesMC:
413  for alignment in config["alignments"]:
414  local.setdefault("alignments", {})
415  for singleName in config["validations"]["DMR"]["merge"][mergeName]["singles"]:
416  if alignment in config["validations"]["DMR"]["single"][singleName]['alignments']:
417  local["alignments"][alignment] = copy.deepcopy(config["alignments"][alignment])
418  local["validation"]["mergeFile"].append("{}/{}/DMR/{}/{}/{}".format(config["LFS"], config["name"], "merge", mergeName, "{}"))
419  local["validation"]["lumiPerRun"] = lumiPerRun
420  local["validation"]["lumiPerIoV"] = lumiPerIoV
421  local["validation"]["lumiMC"] = lumiMC
422  local["validation"]["IOV"] = [1]
423 
424 
425  job = {
426  "name": "DMR_{}_{}_{}".format(dmrType, avpName, mergeName+"_MC"),
427  "dir": workDirMerge,
428  "exe": "mkLumiAveragedPlots.py",
429  "run-mode": "Condor",
430  "dependencies": [],
431  "config": local,
432  }
433  plotJob['inputMC'].append(outputMerge)
434  plotJob['dependencies'].append(job['name'])
435 
436 
437  for mergeJob in mergeJobs:
438  alignment, mergeJobName, mergeIOV = mergeJob["name"].split("_")[1:]
439  if mergeJobName in mergesMC:
440  job["dependencies"].append(mergeJob["name"])
441 
442 
443  avpJobs.append(job)
444 
445 
446  if len(plotJob['inputData'])+len(plotJob['inputMC']) > 0:
447  local = {}
448  local["type"] = "DMR"
449  local["mode"] = "plot"
450  local["isData"] = True if len(plotJob['inputData']) > 0 else False
451  local["isMC"] = True if len(plotJob['inputMC']) > 0 else False
452  local["output"] = plotJob['output']
453  local["plot"] = { "inputData" : plotJob['inputData'],
454  "inputMC" : plotJob['inputMC'],
455  "alignments" : [],
456  "objects" : [],
457  "labels" : [],
458  "colors" : [],
459  "styles" : [],
460  "useFit" : True,
461  "useFitError" : False,
462  "showMean" : True,
463  "showMeanError" : False,
464  "showRMS" : False,
465  "showRMSError" : False}
466 
467  for mergeName in mergesDATA+mergesMC:
468  for singleName in config["validations"]["DMR"]["merge"][mergeName]["singles"]:
469  for alignment in config["validations"]["DMR"]["single"][singleName]['alignments']:
470  if alignment in config['alignments'] and alignment not in local["plot"]["alignments"]:
471  local["plot"]["alignments"].append(alignment)
472  objectName = config["alignments"][alignment]["title"].replace(" ","_")
473  if objectName not in local["plot"]["objects"]: #can happen for MC
474  local["plot"]["objects"].append(objectName)
475  local["plot"]["labels"].append(config["alignments"][alignment]["title"])
476  local["plot"]["colors"].append(config["alignments"][alignment]["color"])
477  local["plot"]["styles"].append(config["alignments"][alignment]["style"])
478 
479  for extraKey in ["objects","labels","colors","styles","useFit","useFitError","showMean","showMeamError","showRMS","showRMSError"]:
480  if extraKey in config["validations"]["DMR"][dmrType][avpName].keys():
481  local["plot"][extraKey] = config["validations"]["DMR"][dmrType][avpName][extraKey]
482 
483  if "style" in config.keys():
484  if "DMR" in config['style'].keys():
485  if dmrType in config['style']['DMR'].keys():
486  local["plotGlobal"] = copy.deepcopy(config["style"]['DMR'][dmrType])
487 
488 
489  job = {
490  "name": "DMR_{}_{}_{}".format(dmrType, avpName, "plot"),
491  "dir": plotJob['workdir'],
492  "exe": "mkLumiAveragedPlots.py",
493  "run-mode": "Condor",
494  "dependencies": plotJob['dependencies'],
495  "config": local,
496  }
497  avpJobs.append(job)
498 
499  #Finally extend main job collection
500  jobs.extend(avpJobs)
501 
502  return jobs
503 
def replace(string, replacements)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def DMR(config, validationDir)
Definition: DMR.py:4
#define str(s)