CMS 3D CMS Logo

mkLumiAveragedPlots.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 import sys
3 argv = sys.argv
4 sys.argv = argv[:1]
5 
6 import argparse
7 import os
8 import json
9 import yaml
10 import csv
11 import ROOT
12 
13 def log(log_type="",text=""):
14 
21 
22  v = int(sys.version_info[0])
23  source = "mkLumiAveragedPlots: "
24  text = str(text)
25  if v == 3:
26  if "i" in log_type:
27  print(source,"[INFO] ",text)
28  elif "n" in log_type:
29  print(" ",text)
30  elif "w" in log_type:
31  print(source,"[WARNING] ",text)
32  elif "e" in log_type:
33  print(source,"[ERROR] ",text)
34  elif "f" in log_type:
35  print(source,"[FATAL] ",text)
36  else:
37  print(text)
38 
39 def isNumber(this):
40  try:
41  int(this)
42  return True
43  except ValueError:
44  return False
45 
46 def decodeLine(line,index,type):
47  if "txt" in type:
48  return line.strip('\n').split(" ")[index]
49  elif "csv" in type:
50  return line.strip('\r\n').replace("\t"," ").split(" ")[index]
51 
52 def getLumiPerIoV(start_run,end_run = 0):
53 
55  lumi = 0.0
56  foundStartRun = False
57  if end_run > 0:
58  for lumifile in lumiPerRun:
59  f = open(lumifile, "r") for line in f:
60  if int(decodeLine(line,0,lumifile)) in range(start_run,end_run):
61  #log(line.strip('\n').split(" ")[0],lumi,line.strip('\n').split(" ")[1])
62  lumi += float(decodeLine(line,1,lumifile))
63  if int(decodeLine(line,0,lumifile)) == start_run:
64  foundStartRun = True
65  f.close()
66  elif end_run < 0:
67  for lumifile in lumiPerRun:
68  f = open(lumifile, "r")
69  for line in f:
70  if int(decodeLine(line,0,lumifile)) >= start_run:
71  #log(line.strip('\n').split(" ")[0],lumi,line.strip('\n').split(" ")[1])
72  lumi += float(decodeLine(line,1,lumifile))
73  if int(decodeLine(line,0,lumifile)) == start_run:
74  foundStartRun = True
75  f.close()
76  elif end_run == 0:
77  for lumifile in lumiPerIoV:
78  f = open(lumifile, "r")
79  for line in f:
80  first = decodeLine(line,0,lumifile)
81  try:
82  if int(first) == start_run:
83  lumi = float(decodeLine(line,1,lumifile))
84  foundStartRun = True
85  except ValueError:
86  if str(first) == str(start_run):
87  lumi = float(decodeLine(line,1,lumifile))
88  foundStartRun = True
89  f.close()
90 
91  if not foundStartRun:
92  if lumi == 0.0:
93  log("w","Lumi per IoV: "+str(start_run)+" not found.")
94  return 11112
95  return lumi
96 
97 def getLumiPerRun(run):
98 
102 
103  lumi = 0.0
104  foundRun = False
105  for lumifile in lumiPerRun:
106  f = open(lumifile, "r") for line in f:
107  if int(decodeLine(line,0,lumifile)) == run:
108  #log(line.strip('\n').split(" ")[0],lumi,line.strip('\n').split(" ")[1])
109  lumi = float(decodeLine(line,1,lumifile))
110  foundRun = True
111  f.close()
112  if not foundRun:
113  log("w","Lumi per run: "+str(run)+" not found.")
114  return 11112
115  return lumi
116 
117 def getTuples(inputDir, filterNumbers=[]):
118 
123 
124  tuples = []
125  if isDMR:
126  valid_files = 0
127  for dirpath,dirs,files in os.walk(inputDir):
128  if len(dirs) == 0: dirs = [""] #needed for finalization jobs
129  for n_dir in dirs:
130  if len(filterNumbers)!=0 and (n_dir not in filterNumbers or not isNumber(n_dir)): continue
131  _number = 0
132  if isNumber(n_dir):
133  _number = int(n_dir)
134  n_dir = n_dir+"/"
135  else:
136  if len(n_dir) > 0:
137  _number = n_dir
138  n_dir = n_dir+"/"
139  else:
140  _number = os.path.join(dirpath,"OfflineValidationSummary.root")
141  if os.path.isfile(os.path.join(dirpath,n_dir+"OfflineValidationSummary.root")):
142  test_root = ROOT.TFile(os.path.join(dirpath,n_dir+"OfflineValidationSummary.root"),"READ")
143  if test_root.IsZombie():
144  log("w",os.path.join(dirpath,n_dir+"OfflineValidationSummary.root")+" is ZOMBIE!")
145  tuples.append({'file' : "invalid.root",
146  'number' : _number,
147  'lumi' : 11111
148  })
149  continue
150  test_root.Close()
151  tuples.append({'file' : os.path.join(dirpath,n_dir+"OfflineValidationSummary.root"),
152  'number' : _number,
153  'lumi' : 0
154  })
155  valid_files += 1
156  else:
157  log("w",os.path.join(dirpath,n_dir+"OfflineValidationSummary.root")+" NOT found! Directory is empty?")
158  tuples.append({'file' : "invalid.root",
159  'number' : _number,
160  'lumi' : 11111
161  })
162  if (valid_files < 2 and config['mode'] != "finalize") or (valid_files < 1 and config['mode'] == "finalize"):
163  log("f","Check input directory. Less than two valid files to merge recognized.")
164  sys.exit(0)
165 
166  elif isPV:
167  for dirpath,dirs,files in os.walk(inputDir):
168  for n_file in files:
169  if "PVValidation" in n_file: #if pass this condition then file exists TODO: check for zombie
170  if isNumber((n_file.split("_")[-1]).split(".")[0]) and os.path.isfile(os.path.join(dirpath,n_file)):
171  tuples.append({'file' : os.path.join(dirpath,n_file),
172  'number' : int((n_file.split("_")[-1]).split(".")[0]),
173  'lumi' : 0
174  })
175  else:
176  log("f","Format for run by run PV results NOT recognised!")
177  sys.exit(0)
178 
179  #sort list based on IoV number and calculate luminosity per IoV (from lumiPerRun or directly from lumiPerIoV)
180  if config['mode'] != "finalize":
181  tuples.sort(key=lambda tuple: tuple['number'])
182  if len(lumiPerRun)!=0:
183  if isDMR:
184  valid_tuples = []
185  for ituple,tuple in enumerate(tuples):
186  if ituple != len(tuples)-1 or len(config['validation']['firstFromNext']) != 0:
187  if int(tuple['lumi']) != 11111: #input is not empty/zombie
188  if ituple == len(tuples)-1:
189  tuple['lumi'] += getLumiPerIoV(tuples[ituple]['number'],int(config['validation']['firstFromNext'][0]))
190  else:
191  tuple['lumi'] += getLumiPerIoV(tuples[ituple]['number'],tuples[ituple+1]['number'])
192  else:
193  _ituple = ituple
194  while _ituple > 0 and int(tuples[_ituple-1]['lumi']) in [11111,11112]:
195  _ituple -= 1
196  if _ituple != 0:
197  if ituple == len(tuples)-1:
198  dLumi = getLumiPerIoV(tuples[ituple]['number'],int(config['validation']['firstFromNext'][0]))
199  else:
200  dLumi = getLumiPerIoV(tuples[ituple]['number'],tuples[ituple+1]['number'])
201  if int(dLumi) not in [11111,11112]: #TODO loop until dLumi is OK
202  tuples[_ituple-1]['lumi'] += dLumi
203  else:
204  dLumi = 0.
205  log("w","Effectively adding luminosity of IoV: "+str(tuples[ituple]['number'])+"(missing file with "+str(dLumi)+") to IoV: "+str(tuples[_ituple-1]['number']))
206  else:
207  __ituple = ituple
208  while __ituple < len(tuples)-1 and int(tuples[__ituple+1]['lumi']) in [11111,11112]:
209  __ituple += 1
210  if __ituple != len(tuples)-1:
211  dLumi = getLumiPerIoV(tuples[ituple]['number'],tuples[ituple+1]['number'])
212  if int(dLumi) not in [11111,11112]: #TODO loop until dLumi is OK
213  tuples[__ituple+1]['lumi'] += dLumi
214  else:
215  dLumi = 0.
216  log("w","Effectively adding luminosity of IoV: "+str(tuples[ituple]['number'])+"(missing file with "+str(dLumi)+") to IoV: "+str(tuples[__ituple+1]['number']))
217  else:
218  if skipLast:
219  log("i","User requested to skip IoV: "+str(tuples[ituple]['number']))
220  else:
221  if int(tuple['lumi']) != 11111: #input is not empty/zombie
222  tuple['lumi'] += getLumiPerIoV(tuples[ituple]['number'],-1)
223  else:
224  _ituple = ituple
225  while _ituple > 0 and int(tuples[_ituple-1]['lumi']) in [11111,11112]:
226  _ituple -= 1
227  if _ituple != 0:
228  dLumi = getLumiPerIoV(tuples[ituple]['number'],-1)
229  if int(dLumi) not in [11111,11112]: #TODO loop until dLumi is OK
230  tuples[_ituple-1]['lumi'] += dLumi
231  else:
232  dLumi = 0.
233  log("w","Effectively adding luminosity of IoV: "+str(tuples[ituple]['number'])+"(missing file with "+str(dLumi)+") to IoV: "+str(tuples[_ituple-1]['number']))
234  else:
235  log("w","No more IOVs in the list to add luminosity from missing IOV"+str(tuples[ituple]['number'])+".")
236 
237  if skipLast:
238  valid_tuples = [ tuple for ituple,tuple in enumerate(tuples) if int(tuple['lumi']) not in [11111,11112] and ituple != len(tuples)-1 ]
239  else:
240  valid_tuples = [ tuple for tuple in tuples if int(tuple['lumi']) not in [11111,11112] ]
241  tuples = valid_tuples
242 
243  elif isPV:
244  for ituple,tuple in enumerate(tuples):
245  tuple['lumi'] = getLumiPerRun(tuple['number'])
246 
247  elif len(lumiPerIoV)!=0 and isDMR:
248  #This will work for finalization jobs as well
249  valid_tuples = []
250  for ituple,tuple in enumerate(tuples):
251  if tuple['lumi'] != 11111: #empty input will not contribute to total average
252  tuple['lumi'] = getLumiPerIoV(tuple['number'])
253  valid_tuples.append(tuple)
254  tuples = valid_tuples
255 
256  return tuples
257 
258 def getTuplesMC(inputDir):
259 
265 
266  tuples = {}
267  if isPV:
268  for dirpath,dirs,files in os.walk(inputDir):
269  for file in files:
270  if "PVValidation" in file:
271  if len(file.split("_")) == 3:
272  period = file.split("_")[1]
273  if period not in tuples:
274  tuples[period] = []
275  tuples[period].append({ 'file' : os.path.join(dirpath,file),
276  'lumi' : 1
277  })
278  else:
279  tuples[period].append({ 'file' : os.path.join(dirpath,file),
280  'lumi' : 1
281  })
282  elif len(file.split("_")) == 2:
283  if ".root" in file.split("_")[1]:
284  period = file.split("_")[1].replace(".root","")
285  if period not in tuples:
286  tuples[period] = []
287  tuples[period].append({ 'file' : os.path.join(dirpath,file),
288  'lumi' : 1
289  })
290  else:
291  tuples[period].append({ 'file' : os.path.join(dirpath,file),
292  'lumi' : 1
293  })
294  else:
295  log("e","No extension found for PV MC input files.")
296  sys.exit(0)
297  else:
298  log("w","Incorrect format for <period> tag inside PV MC input-file names. Char \"_\" is not allowed inside tag.")
299  elif isDMR:
300  inputFile = os.path.join(inputDir,"OfflineValidationSummary.root")
301  period = (inputDir.split("/")[-2])
302  tuples[period] = []
303  if os.path.isfile(inputFile):
304  tuples[period].append({ 'file' : inputFile,
305  'lumi' : 1})
306  else:
307  tuples[period].append({ 'file' : "invalid.root",
308  'lumi' : 11111})
309 
310  return tuples
311 
312 
313 def makeAveragedFile(tuples,intLumi,objName=""):
314 
319 
320  fileArgument = ""
321  weightArgument = ""
322  haddwsDir = ""
323  #cmd_bare = ""
324 
325  countTest = 0.0
326  for ituple,tuple in enumerate(tuples):
327  if str(tuple['lumi']) not in ['11111','11112']: #will not include 11111=non-existing input,11112=non-existing lumi record
328  if tuple['lumi']/intLumi > -1.:#1e-6: #will not include 'almost zero' lumi input (not digestible by haddws)
329  fileArgument += tuple['file']+" "
330  weightArgument += str(format(tuple['lumi']/intLumi,'.20f'))+" "
331  #cmd_bare += tuple['file']+" "+str(format(tuple['lumi']/intLumi,'.20f'))+"\n"
332  countTest += tuple['lumi']/intLumi
333  else:
334  log("i","Not including IOV "+str(tuple['number'])+" for weighting: "+str(tuple['lumi']))
335 
336  if countTest < 1.0:
337  log("w","Normalization factor: "+str(format(countTest,'.20f'))+" is less than 1.")
338  if len(weightArgument.split(" ")) != len(fileArgument.split(" ")):
339  log("e","There is "+str(len(fileArgument.split(" ")))+"rootfiles but "+str(len(weightArgument.split(" ")))+" weights.")
340  else:
341  log("i","Real number of files to merge is: "+str(len(fileArgument.split(" "))-1))
342 
343  #f = open("haddws_command.txt", "w")
344  #f.write(cmd_bare)
345  #f.close()
346  #sys.exit(0)
347 
348  cmd = haddwsDir+"haddws "+fileArgument+weightArgument+" > haddws.out 2> haddws.err"
349  log("i","Running haddws.C")
350  os.system(cmd)
351 
352  #Store result file in output
353  outFileName = ""
354  if isDMR:
355  if objName != "" and not objName.startswith("_"): objName = "_"+objName
356  outFileName = os.path.join(config['output'],"OfflineValidationSummary"+objName+".root")
357  elif isPV:
358  outFileName = os.path.join(config['output'],"result"+objName+".root")
359  if os.path.isfile("./result.root"):
360  os.system("mv result.root "+outFileName)
361 
362 def getIntLumi(tuples):
363 
366 
367  intLumi = 0.0
368  for tuple in tuples:
369  if tuple['lumi'] not in [11111,11112]:
370  intLumi += tuple['lumi']
371  return intLumi
372 
373 def parser():
374  sys.argv = argv
375  parser = argparse.ArgumentParser(description = "run the python plots for the AllInOneTool validations", formatter_class=argparse.RawTextHelpFormatter)
376  parser.add_argument("config", metavar='config', type=str, action="store", help="Averager AllInOneTool config (json/yaml format)")
377  parser.add_argument("-b", "--batch", action = "store_true", help ="Batch mode")
378 
379  #sys.argv.append('-b')
380  #ROOT.gROOT.SetBatch()
381  return parser.parse_args()
382 
383 if __name__ == '__main__':
384 
391 
392  args = parser()
393  with open(args.config, "r") as configFile: if args.config.split(".")[-1] == "json":
394  config = json.load(configFile)
395  elif args.config.split(".")[-1] == "yaml":
396  config = yaml.load(configFile, Loader=yaml.Loader)
397  else:
398  raise Exception("Unknown config extension '{}'. Please use json/yaml format!".format(args.config.split(".")[-1]))
399 
400  log(' ----- All-in-one Averager -----')
401  log(' type: '+config['type'])
402  log(' mode: '+config['mode'])
403  log(' isData: '+str(config['isData']))
404  log(' isMC: '+str(not config['isData']))
405  if config['mode'] == "finalize":
406  nFiles = len(config['validation']['mergeFile'])
407  elif config['mode'] == "plot":
408  nFiles = len(config['plot']['inputData'])+len(config['plot']['inputMC'])
409  else:
410  nFiles = len(config['validation']['IOV'])
411  log(' nFiles: '+str(nFiles))
412  log(' -------------------------------')
413 
414  #BASIC SANITY CHECKS
415 
418  inputDirData = []
419  inputDirMC = []
420  IOVs = []
421  if config['mode'] == "merge":
422  #DATA
423  if config['isData']:
424  if len(config['validation']['IOV']) == 0:
425  log("f","No input DATA found. List of IOVs needs to contain at least one number.")
426  sys.exit(0)
427  elif len(config['validation']['IOV']) != 0:
428  _dir = config['validation']['mergeFile'].replace("{}","")
429  if os.path.isdir(_dir):
430  log("i","Will average "+str(len(config['validation']['IOV']))+" DATA files from directory(ies): ")
431  log("i",_dir)
432  subDirMissing = False
433  for IOV in config['validation']['IOV']:
434  IOVs.append(str(IOV))
435  if not os.path.isdir(config['validation']['mergeFile'].replace("{}",str(IOV))):
436  log("f","Subdir not found "+str(IOV)+"!")
437  subDirMissing = True
438  if subDirMissing:
439  sys.exit(0)
440  else:
441  inputDirData.append(_dir)
442  #MC
443  elif not config['isData']:
444  if len(config['validation']['IOV']) != 1 \
445  or (len(config['validation']['IOV']) == 1 and str(config['validation']['IOV'][0]) != "1"):
446  log("f","MC validation configuration error: IOV!=1")
447  sys.exit(0)
448  else:
449  IOVs.append(str(config['validation']['IOV'][0]))
450  if len(config['validation']['mergeFile']) == 0:
451  log("f", "No input MC found.")
452  sys.exit(0)
453  else:
454  log("i","Will scale and merge "+str(len(config['validation']['mergeFile']))+" MC directory(ies): ")
455  for _dir in config['validation']['mergeFile']:
456  basedir = _dir.replace("{}","")
457  subdir = _dir.replace("{}",str(config['validation']['IOV'][0]))
458  if os.path.isdir(basedir) and os.path.isdir(subdir):
459  log("i",subdir)
460  inputDirMC.append(subdir)
461  else:
462  log("f","Directory not found "+subdir)
463  sys.exit(0)
464  elif config['mode'] == "finalize":
465  #DATA FINALIZE
466  if config['isData']:
467  if len(config['validation']['mergeFile']) == 0:
468  log("f", "No files found to finalize.")
469  sys.exit(0)
470  log("i","Will finalize average job for "+str(len(config['validation']['mergeFile']))+" parts:")
471  for partFile in config['validation']['mergeFile']:
472  if os.path.isdir(partFile):
473  inputDirData.append(partFile)
474  log("i","---> "+partFile)
475  else: log("w","Missing partial input: "+partFile)
476  if len(inputDirData) != len(config['validation']['mergeFile']):
477  log("e","Some input was not found for DATA finalization job.")
478  sys.exit(0)
479  #NO FINALIZE FOR MC
480  elif not config['isData']:
481  log("f", "Nothing to finalize for MC.")
482  sys.exit(0)
483  elif config['mode'] == "plot":
484  if len(config['plot']['inputData'])+len(config['plot']['inputMC']) == 0:
485  log("f", "No files found for plotting!")
486  sys.exit(0)
487  log("i", "Will attempt to plot objects from "+str(nFiles)+" source files.")
488  for inputDir in config['plot']['inputData']:
489  if os.path.isdir(inputDir):
490  inputDirData.append(inputDir)
491  for inputDir in config['plot']['inputMC']:
492  if os.path.isdir(inputDir):
493  inputDirMC.append(inputDir)
494 
495 
496 
499  isPV = (config['type'] == "PV")
500  isDMR = (config['type'] == "DMR")
501  if config['mode'] != "plot":
502  lumiPerRun = config['validation']['lumiPerRun']
503  lumiPerIoV = config['validation']['lumiPerIoV']
504  lumiMC = config['validation']['lumiMC']
505  else:
506  lumiPerRun = []
507  lumiPerIoV = []
508  lumiMC = []
509  if config['mode'] != "plot":
510  if isPV and len(lumiPerIoV)!=0:
511  log("w","Are you sure you have run PV validation in IoV by IoV mode?")
512  if (isPV or isDMR) and len(lumiPerRun)==0 and len(lumiPerIoV)==0 and len(inputDirData) != 0:
513  log("e","Use option 'lumiPerRun' or 'lumiPerIoV' to specify luminosity files.")
514  sys.exit(0)
515  if (isPV or isDMR) and len(lumiPerIoV)==0:
516  if len(lumiPerRun) != 0:
517  if config['mode'] == "finalize":
518  log("i","Integrated Luminosity per intermediate files found.")
519  else:
520  log("w","Lumi per run list will be processed to get Lumi per IoV list (applies for DATA).")
521  elif len(inputDirMC) != 0 and len(inputDirData) == 0:
522  log("i", "MC will be scaled per period to given integrated luminosity.")
523  if len(inputDirMC) != 0 and len(lumiMC) == 0:
524  log("w","MC object(s) found on input but lumi per period not specified.")
525  _lumiMC = {}
526  for formatLumi in lumiMC:
527  if "::" in formatLumi:
528  try:
529  float(formatLumi.split("::")[-1])
530  except ValueError:
531  log("e","Wrong lumi per period for MC formatting. USAGE: <object>::<merge>::<lumi> or <merge>::<lumi> for single MC object (alignment).")
532  sys.exit(0)
533  if len(formatLumi.split("::")) == 2:
534  _lumiMC[formatLumi.split("::")[0]] = { 'lumi' : float(formatLumi.split("::")[-1]), 'group' : 0}
535  elif len(formatLumi.split("::")) == 3:
536  _lumiMC[formatLumi.split("::")[1]] = { 'lumi' : float(formatLumi.split("::")[-1]), 'group' : formatLumi.split("::")[0]}
537  else:
538  log("e","Wrong lumi per period for MC formatting. USAGE: <object>::<merge>::<lumi> or <merge>::<lumi> for single MC object (alignment).")
539  sys.exit(0)
540  lumiMC = _lumiMC
541  skipLast = False
542  if isDMR and config['isData']:
543  if len(config['validation']['firstFromNext']) == 0: skipLast = True
545 
548  if config['mode'] == "plot":
549  if len(config['plot']['colors']) < len(config['plot']['objects']):
550  log("e","Please specify color code for each object.")
551  sys.exit(0)
552  if len(config['plot']['styles']) < len(config['plot']['objects']):
553  log("e","Please specify line style for each object.")
554  sys.exit(0)
555  if len(config['plot']['objects']) != 0:
556  for obj in config['plot']['objects']:
557  if len(obj.split(" ")) != 1:
558  log("e","No space in object name is allowed. Use \"_\" instead.")
559  sys.exit(0)
560  if len(config['plot']['objects']) != 0 and len(config['plot']['labels']) == 0:
561  log("i","Object labels will be generated automatically.")
562  if 'plotGlobal' not in config.keys():
563  log("w","Global plotting settings not found. Fallback to default.")
564  config['plotGlobal'] = {}
565 
566 
569  if config['mode'] == "plot":
570  if config['plot']['showMeanError'] and not config['plot']['showMean']:
571  log("w","Cannot show mean error without showing mean.")
572  config['plot']['showMeanError'] = False
573  if config['plot']['showRMSError'] and not config['plot']['showRMS']:
574  log("w","Cannot show RMS error without showing RMS.")
575  config['plot']['showRMSError'] = False
576  if config['plot']['useFitError'] and not config['plot']['useFit']:
577  log("w","Cannot show fit parameters error without fitting.")
578  config['plot']['useFitError'] = False
579 
580 
583  whichValidation = ""
584  if isDMR: whichValidation = "DMR"
585  elif isPV: whichValidation = "PV"
587 
591  tuples_total = []
592  if config['mode'] == "merge":
593  for inputDir in inputDirData:
594 
598  tuples = getTuples(inputDir,IOVs)
599  intLumi = getIntLumi(tuples)
600  if len(tuples) == 0:
601  log("e","Zero "+whichValidation+" files to merge detected.")
602  sys.exit(0)
603  log("i","Attempting to average "+str(len(tuples))+" "+whichValidation+" files with (partial) integrated luminosity "+str(intLumi)+".")
604  outFileName = ""
605  objName = ""
606  if isDMR:
607  outFileName = os.path.join(config['output'],"OfflineValidationSummary"+objName+".root")
608  elif isPV:
609  objName = inputDir.split("/")[-1]
610  outFileName = os.path.join(config['output'],"result"+objName+".root")
611  tuples_total.append({ 'file' : outFileName,
612  'lumi' : intLumi
613  })
614  makeAveragedFile(tuples,intLumi,objName)
615  elif config['mode'] == "finalize":
616  tuples = []
617  intLumi = 0.0
618  for inputDir in inputDirData:
619 
623  tupleFinal = getTuples(inputDir)
624  tuples += tupleFinal
625  intLumi += getIntLumi(tupleFinal)
626  if len(tuples) == 0:
627  log("e","Zero final "+whichValidation+" files to merge detected.")
628  sys.exit(0)
629  log("i","Attempting to average final "+str(len(tuples))+" "+whichValidation+" files with overall integrated luminosity "+str(intLumi)+".")
630  objName = ""
631  makeAveragedFile(tuples,intLumi,objName)
632 
633 
636  if config['mode'] == "merge":
637  with open(os.path.join(config['output'],'lumiPerFile.csv'), 'a') as csvfile:
638  csvwriter = csv.writer(csvfile, delimiter=' ')
639  for tuple in tuples_total:
640  csvwriter.writerow([tuple['file'],str(tuple['lumi'])])
642 
646  tupleGroupsMC = {}
647  if config['mode'] == "merge":
648  for inputDir in inputDirMC:
649  tuples = getTuplesMC(inputDir)
650  for period, _list in tuples.items():
651  tuple = _list[0]
652  if period in lumiMC.keys():
653  tuple['lumi'] = lumiMC[period]['lumi']
654  log("i","Group N."+str(lumiMC[period]['group'])+" <-- "+str(tuple['lumi']))
655  if lumiMC[period]['group'] not in tupleGroupsMC.keys():
656  tupleGroupsMC[lumiMC[period]['group']] = []
657  tupleGroupsMC[lumiMC[period]['group']].append(tuple)
658  else:
659  tupleGroupsMC[lumiMC[period]['group']].append(tuple)
660  else:
661  log("w","Period "+str(period)+" not recognised in lumiMC list.")
662  for group, tuples in tupleGroupsMC.items():
663  log("i","Detected MC N."+str(group)+" group to be merged.")
664  intLumi = getIntLumi(tuples)
665  makeAveragedFile(tuples,intLumi,"_merged"+str(group))
666 
667 
670  if isDMR and config['mode'] == "plot":
671  #import plotting class
672  from Alignment.OfflineValidation.TkAlAllInOneTool.DMRplotter import DMRplotter
673 
674  #initialize plotting class with proper options
675  plotInfo = {}
676  plotInfo['outputDir'] = config['output']
677  for key in ['objects','labels','colors','styles', \
678  'useFit','useFitError','showMean','showMeanError','showRMS','showRMSError']:
679  plotInfo[key] = config['plot'][key]
680  if 'plotGlobal' in config.keys():
681  if 'CMSlabel' in config['plotGlobal'].keys():
682  plotInfo['CMSlabel'] = config['plotGlobal']['CMSlabel']
683  else:
684  plotInfo['CMSlabel'] = ""
685  if 'Rlabel' in config['plotGlobal'].keys():
686  plotInfo['Rlabel'] = config['plotGlobal']['Rlabel']
687  else:
688  plotInfo['Rlabel'] = "single muon (2016+2017+2018)"
689  plotter = DMRplotter(plotInfo)
690 
691  #add input files
692  for inputDir in inputDirData:
693  plotter.addDATA(inputDir)
694  for inputDir in inputDirMC:
695  plotter.addDirMC(inputDir)
696 
697  #plot&save
698  plotter.plot()
699 
700  log("i","All done.")
701 
def decodeLine(line, index, type)
def replace(string, replacements)
def makeAveragedFile(tuples, intLumi, objName="")
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def getLumiPerIoV(start_run, end_run=0)
def getTuples(inputDir, filterNumbers=[])
def log(log_type="", text="")
#define str(s)