File indexing completed on 2024-11-06 06:06:09
0001
0002
0003 import ROOT
0004 import os
0005 import sys
0006 from decimal import Decimal
0007
0008 class DMRplotter:
0009 def __init__(self, args):
0010 self.args = args
0011 self.dataFiles = []
0012 self.dataDirs = []
0013 self.mcFiles = []
0014 self.fileBaseName = "OfflineValidationSummary.root"
0015 self.outputDir = self.args['outputDir']
0016 self.cwd = os.getcwd()
0017 self.objNameList = []
0018 self.MCobjects = []
0019 self.objNameListMC = []
0020 self.segments = ["BPIX","FPIX","TEC","TID","TIB","TOB"]
0021 self.varsX = {}
0022 self.legendOffset = 1.5
0023 self.legendTextSize = 0.032
0024 self.statBoxTextSize = 0.0365
0025 self.segmentTextOffset = {'ymin' : 0.9, 'ymax' : 1.2 }
0026 self.maxEntriesPerColumn = 5
0027
0028 def __log__(self,log_type="",text=""):
0029
0030
0031
0032
0033
0034
0035
0036
0037 v = int(sys.version_info[0])
0038 source = "DMRplotter: "
0039 text = str(text)
0040 if v == 3:
0041 if "i" in log_type:
0042 print(source,"[INFO] ",text)
0043 elif "n" in log_type:
0044 print(" ",text)
0045 elif "w" in log_type:
0046 print(source,"[WARNING] ",text)
0047 elif "e" in log_type:
0048 print(source,"[ERROR] ",text)
0049 elif "f" in log_type:
0050 print(source,"[FATAL] ",text)
0051 else:
0052 print(text)
0053
0054 def _middleString(self, fullString):
0055
0056
0057
0058
0059 middleString = "_".join(fullString.split("_")[1:])
0060 if middleString.endswith("_y"): middleString = "_".join(middleString.split("_")[:-1])
0061 middleString = "_".join(middleString.split("_")[:-1])
0062 return middleString
0063
0064
0065 def _replaceMulti(self, mainString, toBeReplaced, newString):
0066
0067
0068
0069
0070
0071 for elem in toBeReplaced:
0072 if elem in mainString:
0073 mainString = mainString.replace(elem, newString)
0074 return mainString
0075
0076 def _styledTPaveText(self,x1,y1,x2,y2,var):
0077
0078
0079
0080
0081
0082 textBox = ROOT.TPaveText(x1,y1,x2,y2)
0083 textBox.SetFillColor(ROOT.kWhite)
0084 if "median" not in var or not self.args['useFit']:
0085 if self.args['showMeanError'] and self.args['showRMSError']:
0086 textBox.SetTextSize(self.statBoxTextSize-0.008)
0087 elif self.args['showMean'] and self.args['showRMS'] and (self.args['showMeanError'] or self.args['showRMSError']):
0088 textBox.SetTextSize(self.statBoxTextSize-0.005)
0089 else:
0090 textBox.SetTextSize(self.statBoxTextSize)
0091 else:
0092 if self.args['useFitError']:
0093 textBox.SetTextSize(self.statBoxTextSize-0.008)
0094 else:
0095 textBox.SetTextSize(self.statBoxTextSize-0.005)
0096 textBox.SetTextFont(42)
0097
0098 return textBox
0099
0100 def __createSingleArchitecture__(self):
0101
0102
0103
0104
0105
0106 duplicity_check = False
0107 if len(self.dataDirs) != 0:
0108 if self.args['isDMR']:
0109
0110 if not os.path.isdir(self.outputDir):
0111 self.__log__("i","Creating subdirectory for single DMRs: "+self.outputDir)
0112 os.system("mkdir "+self.outputDir)
0113 else:
0114 self.__log__("i","Results directory "+self.outputDir+" exists.")
0115
0116
0117 dirsToMake = []
0118 for dataDir in self.dataDirs:
0119 for root,dirs,files in os.walk(dataDir):
0120 for dir in dirs:
0121 if dir.startswith("offline"): dirsToMake.append(self.outputDir+"/"+dir)
0122 for dir in dirsToMake:
0123 if not os.path.isdir(dir):
0124 os.system("mkdir "+dir)
0125 else:
0126 duplicity_check = True
0127 else:
0128 self.__log__("e","No input directory found! No DATA or MC present.")
0129 sys.exit(0)
0130
0131 if duplicity_check:
0132 self.__log__("w","Duplicated file names found. Plots will be overwritten.")
0133
0134 def __createArchitecture__(self):
0135
0136
0137
0138
0139
0140 dataControl = True
0141 for datafile in self.dataFiles:
0142 if not os.path.isfile(datafile):
0143 dataControl = False
0144 for mcfile in self.MCobjects:
0145 if not os.path.isfile(mcfile):
0146 dataControl = False
0147
0148 if dataControl and not (len(self.dataFiles) == 0 and len(self.MCobjects) == 0):
0149 if not os.path.isdir(self.outputDir):
0150 self.__log__("i","Final plots will be stored in: "+self.outputDir)
0151 os.system("mkdir "+self.outputDir)
0152 else:
0153 self.__log__("i","Results directory "+self.outputDir+" exists.")
0154 else:
0155 self.__log__("f","Results file NOT found! No DATA or MC present.")
0156 sys.exit(0)
0157
0158 def __defineSingleObjects__(self):
0159
0160
0161
0162
0163 objDicts = {'DATA' : [], 'MC' : []}
0164
0165
0166 for datafile in self.dataFiles:
0167 if not os.path.isfile(datafile): continue
0168 fInput = ROOT.TFile.Open(datafile,'READ')
0169 keyList = ROOT.gDirectory.GetListOfKeys()
0170 _id = [ id for id in datafile.split("/") if "offline_" in id ]
0171 id = "0"
0172 if len(_id) > 0:
0173 id = str(_id[0].split("_")[-1])
0174 objDict = {}
0175 objList = []
0176 objAreIgnored = []
0177 _objNameList = []
0178 for key in keyList:
0179 obj = key.ReadObj()
0180 if "TH1" in obj.ClassName():
0181 objList.append(obj.Clone())
0182 objName = obj.GetName()
0183
0184 skipHist = False
0185 for tag in ["layer","disc","plus","minus"]:
0186 if tag in objName: skipHist = True
0187 if skipHist: continue
0188
0189 if objName[-1] != "y":
0190 generalObjName = self._replaceMulti(objName, [objName.split("_")[0]+"_","_"+objName.split("_")[-1]], "")
0191 if len(self.args['objects']) == 0:
0192 if generalObjName not in _objNameList:
0193 _objNameList.append(generalObjName)
0194 else:
0195 if generalObjName not in self.args['objects']:
0196 self.__log__("w","Object \""+generalObjName+"\" found but ignored for plotting!")
0197 objAreIgnored.append(generalObjName)
0198 else:
0199 if generalObjName not in _objNameList:
0200 _objNameList.append(generalObjName)
0201 self.objNameList = [ genObjName for genObjName in _objNameList ]
0202
0203
0204 for objName in self.objNameList:
0205 objDict[objName] = []
0206 for obj in objList:
0207 if objName in obj.GetName():
0208 segment = ""
0209 var = ""
0210 if obj.GetName()[-1] == "y":
0211 segment = obj.GetName().split("_")[-2]
0212 var = obj.GetName().split("_")[0]+"Y"
0213 else:
0214 segment = obj.GetName().split("_")[-1]
0215 var = obj.GetName().split("_")[0]+"X"
0216 obj.SetDirectory(0)
0217 objDict[objName].append({ 'hist' : obj,
0218 'segment' : segment,
0219 'var' : var,
0220 'id' : id,
0221 'type' : "DATA"
0222 })
0223 fInput.Close()
0224 objDicts['DATA'].append(objDict)
0225
0226
0227 if len(self.args['objects']) != 0:
0228 order = []
0229 for genObjName in self.objNameList:
0230 order.append(self.args['objects'].index(genObjName))
0231 orderedList = [self.objNameList[i] for i in order]
0232 self.objNameList = orderedList
0233
0234 if len(self.objNameList) == 0 and len(self.dataFiles) !=0:
0235 self.__log__("e","Data object names (if specified) must correspond to names in given input file!")
0236 sys.exit(0)
0237 else:
0238 for genObjName in self.objNameList:
0239 self.__log__("i","Object \""+genObjName+"\" found for plotting.")
0240
0241
0242 for mcFile in self.mcFiles:
0243 fInputMC = ROOT.TFile.Open(mcFile,'READ')
0244 keyListMC = ROOT.gDirectory.GetListOfKeys()
0245 objListMC = []
0246 objDictMC = {}
0247 generalObjName = ""
0248 objIsIgnored = False
0249 for key in keyListMC:
0250 obj = key.ReadObj()
0251 if "TH1" in obj.ClassName():
0252 objName = obj.GetName()
0253 objListMC.append(obj.Clone(objName))
0254
0255 skipHist = False
0256 for tag in ["layer","disc","plus","minus"]:
0257 if tag in objName: skipHist = True
0258 if skipHist: continue
0259
0260 if objName[-1] != "y":
0261 generalObjName = self._replaceMulti(objName, [objName.split("_")[0]+"_","_"+objName.split("_")[-1]], "")
0262 if len(self.args['objects']) == 0:
0263 if generalObjName not in self.objNameListMC:
0264 self.objNameListMC.append(generalObjName)
0265 else:
0266 if generalObjName not in self.args['objects']:
0267 self.__log__("w","Object \""+generalObjName+"\" found but ignored for plotting!")
0268 objIsIgnored = True
0269 else:
0270 if generalObjName not in self.objNameListMC:
0271 self.objNameListMC.append(generalObjName)
0272
0273
0274 if not objIsIgnored:
0275 objDictMC[generalObjName] = []
0276 for obj in objListMC:
0277 if generalObjName in obj.GetName():
0278 segment = ""
0279 var = ""
0280 if obj.GetName()[-1] == "y":
0281 segment = obj.GetName().split("_")[-2]
0282 var = obj.GetName().split("_")[0]+"Y"
0283 else:
0284 segment = obj.GetName().split("_")[-1]
0285 var = obj.GetName().split("_")[0]+"X"
0286 obj.SetDirectory(0)
0287 objDictMC[generalObjName].append({ 'hist' : obj,
0288 'segment' : segment,
0289 'var' : var,
0290 'type' : "MC"
0291 })
0292 fInputMC.Close()
0293 objDicts['MC'].append(objDictMC)
0294
0295 if len(self.objNameListMC) == 0 and len(self.mcFiles) != 0:
0296 self.__log__("e","MC object names (if specified) must correspond to names in given input file!")
0297 sys.exit(0)
0298 else:
0299 for genObjName in self.objNameListMC:
0300 self.__log__("i","Object \""+genObjName+"\" found for plotting.")
0301
0302 return objDicts
0303
0304 def __defineObjects__(self):
0305
0306
0307
0308
0309
0310
0311
0312 objDict = {}
0313 for datafile in self.dataFiles:
0314 fInput = ROOT.TFile.Open(datafile,'READ')
0315 keyList = ROOT.gDirectory.GetListOfKeys()
0316 objList = []
0317 objAreIgnored = []
0318 _objNameList = []
0319 for key in keyList:
0320 obj = key.ReadObj()
0321 if "TH1" in obj.ClassName():
0322 objList.append(obj.Clone())
0323 objName = obj.GetName()
0324
0325 skipHist = False
0326 for tag in ["layer","disc","plus","minus"]:
0327 if tag in objName: skipHist = True
0328 if skipHist: continue
0329
0330 if objName[-1] != "y":
0331 generalObjName = self._replaceMulti(objName, [objName.split("_")[0]+"_","_"+objName.split("_")[-1]], "")
0332 if len(self.args['objects']) == 0:
0333 if generalObjName not in _objNameList:
0334 _objNameList.append(generalObjName)
0335 else:
0336 if generalObjName not in self.args['objects']:
0337 self.__log__("w","Object \""+generalObjName+"\" found but ignored for plotting!")
0338 objAreIgnored.append(generalObjName)
0339 else:
0340 if generalObjName not in _objNameList:
0341 _objNameList.append(generalObjName)
0342 duplicates = [ genObjName for genObjName in _objNameList if genObjName in self.objNameList ]
0343 for dup in duplicates:
0344 self.__log__("e","Duplicated object "+str(dup)+" was found! Please rename this object in your input file!")
0345 sys.exit(0)
0346 self.objNameList += [ genObjName for genObjName in _objNameList if genObjName not in self.objNameList ]
0347
0348
0349 for objName in _objNameList:
0350 if objName in objAreIgnored: continue
0351 objDict[objName] = []
0352 for obj in objList:
0353 if objName == self._middleString(obj.GetName()):
0354 segment = ""
0355 var = ""
0356 if obj.GetName()[-1] == "y":
0357 segment = obj.GetName().split("_")[-2]
0358 var = obj.GetName().split("_")[0]+"Y"
0359 else:
0360 segment = obj.GetName().split("_")[-1]
0361 var = obj.GetName().split("_")[0]+"X"
0362 obj.SetDirectory(0)
0363 objDict[objName].append({ 'hist' : obj,
0364 'segment' : segment,
0365 'var' : var,
0366 'type' : "DATA"
0367 })
0368 fInput.Close()
0369
0370
0371 '''
0372 if len(self.args['objects']) != 0:
0373 order = []
0374 for genObjName in self.objNameList:
0375 order.append(self.args['objects'].index(genObjName))
0376 orderedList = [self.objNameList[i] for i in order]
0377 self.objNameList = orderedList
0378 '''
0379
0380 if len(self.objNameList) == 0 and len(self.dataFiles) !=0:
0381 self.__log__("e","Data object names (if specified) must correspond to names in given input file!")
0382 sys.exit(0)
0383 else:
0384 for genObjName in self.objNameList:
0385 self.__log__("i","Object \""+genObjName+"\" found for plotting.")
0386
0387
0388 for MCobject in self.MCobjects:
0389 fInputMC = ROOT.TFile.Open(MCobject,'READ')
0390 keyListMC = ROOT.gDirectory.GetListOfKeys()
0391 objListMC = []
0392
0393
0394 objAreIgnored = []
0395 _objNameList = []
0396 for key in keyListMC:
0397 obj = key.ReadObj()
0398 if "TH1" in obj.ClassName():
0399 objName = obj.GetName()
0400 objListMC.append(obj.Clone(objName))
0401
0402 skipHist = False
0403 for tag in ["layer","disc","plus","minus"]:
0404 if tag in objName: skipHist = True
0405 if skipHist: continue
0406
0407 if objName[-1] != "y":
0408 generalObjName = self._replaceMulti(objName, [objName.split("_")[0]+"_","_"+objName.split("_")[-1]], "")
0409 if len(self.args['objects']) == 0:
0410 if generalObjName not in _objNameList:
0411 _objNameList.append(generalObjName)
0412 else:
0413 if generalObjName not in self.args['objects']:
0414 self.__log__("w","Object \""+generalObjName+"\" found but ignored for plotting!")
0415 objAreIgnored.append(generalObjName)
0416 else:
0417 if generalObjName not in _objNameList:
0418 _objNameList.append(generalObjName)
0419 duplicates = [ genObjName for genObjName in _objNameList if genObjName in self.objNameListMC ]
0420 for dup in duplicates:
0421 self.__log__("e","Duplicated object "+str(dup)+" was found! Please rename this object in your input file!")
0422 sys.exit(0)
0423 self.objNameListMC += [ genObjName for genObjName in _objNameList if genObjName not in self.objNameListMC ]
0424
0425
0426 for objName in _objNameList:
0427 if objName in objAreIgnored: continue
0428 objDict[objName] = []
0429 for obj in objListMC:
0430 if objName in obj.GetName():
0431 segment = ""
0432 var = ""
0433 if obj.GetName()[-1] == "y":
0434 segment = obj.GetName().split("_")[-2]
0435 var = obj.GetName().split("_")[0]+"Y"
0436 else:
0437 segment = obj.GetName().split("_")[-1]
0438 var = obj.GetName().split("_")[0]+"X"
0439 obj.SetDirectory(0)
0440 objDict[objName].append({ 'hist' : obj,
0441 'segment' : segment,
0442 'var' : var,
0443 'type' : "MC"
0444 })
0445 fInputMC.Close()
0446
0447 if len(self.objNameListMC) == 0 and len(self.MCobjects) != 0:
0448 self.__log__("e","MC object names (if specified) must correspond to names in given input file!")
0449 sys.exit(0)
0450 else:
0451 for genObjName in self.objNameListMC:
0452 self.__log__("i","Object \""+genObjName+"\" found for plotting.")
0453
0454
0455 self.objNameList += self.objNameListMC
0456 if len(self.args['objects']) != 0:
0457 order = []
0458 for genObjName in self.objNameList:
0459 order.append(self.args['objects'].index(genObjName))
0460 orderedList = [self.objNameList[i] for i in order]
0461 self.objNameList = orderedList
0462 return objDict
0463
0464 def __fitGauss__(self,hist):
0465
0466
0467
0468
0469
0470
0471 if not hist or hist.GetEntries() < 20: return 0
0472 self.__log__("i","Fitting histogram: "+hist.GetName())
0473
0474 xScale = 10000.
0475 mean = hist.GetMean(1)*xScale
0476 sigma = hist.GetRMS(1)*xScale
0477 funcName = "gaussian_"+hist.GetName()
0478 func = ROOT.TF1(funcName,"gaus",mean - 2.*sigma,mean + 2.*sigma)
0479 func.SetLineColor(ROOT.kMagenta)
0480 func.SetLineStyle(2)
0481
0482
0483 if int(hist.Fit(func,"QNR")) == 0:
0484 mean = func.GetParameter(1)
0485 sigma = func.GetParameter(2)
0486 func.SetRange(mean - 3.*sigma, mean + 3.*sigma)
0487
0488
0489
0490 if int(hist.Fit(func,"Q0ILR")) == 0:
0491 return func
0492 else:
0493 return 0
0494 else:
0495 return 0
0496
0497 def __getStat__(self,hist,var):
0498
0499
0500
0501
0502
0503
0504
0505 statLabel = ""
0506 delimeter = ""
0507 muScale = 1.
0508 muUnit = ""
0509 form = "{:.2g}"
0510 formScie = "{:.1e}"
0511 if "median" in var:
0512 muScale = 10000.
0513 muUnit = " #mum"
0514 if not self.args['useFit'] or "median" not in var:
0515 if self.args['showMean'] and self.args['showRMS']:
0516 delimeter = ", "
0517 if self.args['showMean']:
0518 statLabel += "#mu="
0519 if hist.GetMean(1) >= 0.:
0520 statLabel += (" "+form).format(Decimal(str(hist.GetMean(1)*muScale)))
0521 else:
0522 statLabel += form.format(Decimal(str(hist.GetMean(1)*muScale)))
0523 if self.args['showMeanError']:
0524 statLabel += " #pm "
0525 statLabel += formScie.format(Decimal(str(hist.GetMeanError(1)*muScale)))
0526 statLabel += delimeter
0527 if self.args['showRMS']:
0528 statLabel += "rms="
0529 statLabel += (" "+form).format(Decimal(str(hist.GetRMS(1)*muScale)))
0530 if self.args['showRMSError']:
0531 statLabel += " #pm "
0532 statLabel += form.format(Decimal(str(hist.GetRMSError(1)*muScale)))
0533 statLabel += muUnit
0534 else:
0535 fitResults = self.__fitGauss__(hist)
0536 if not isinstance(fitResults, int):
0537 delimeter = ", "
0538 meanFit = fitResults.GetParameter(1)
0539 meanFitError = fitResults.GetParError(1)
0540 sigmaFit = fitResults.GetParameter(2)
0541 sigmaFitError = fitResults.GetParError(2)
0542 statLabel += "#mu="
0543 if meanFit >= 0.:
0544 statLabel += (" "+formScie).format(Decimal(str(meanFit)))
0545 if self.args['useFitError']:
0546 statLabel += " #pm "
0547 statLabel += form.format(Decimal(str(meanFitError)))
0548 else:
0549 statLabel += formScie.format(Decimal(str(meanFit)))
0550 if self.args['useFitError']:
0551 statLabel += " #pm "
0552 statLabel += form.format(Decimal(str(meanFitError)))
0553 statLabel += delimeter
0554 statLabel += "#sigma="
0555 statLabel += (" "+form).format(Decimal(str(sigmaFit)))
0556 if self.args['useFitError']:
0557 statLabel += " #pm "
0558 statLabel += form.format(Decimal(str(sigmaFitError)))
0559 statLabel += muUnit
0560
0561 return statLabel
0562
0563 def __setTHStyle__(self,objects):
0564
0565
0566
0567
0568
0569 varsX = {'medianX' : "median(x\'_{pred}-x\'_{hit})[#mum]",
0570 'medianY' : "median(y\'_{pred}-y\'_{hit})[#mum]",
0571 'DrmsNRX' : "RMS((x\'_{pred}-x\'_{hit})/#sigma)",
0572 'DrmsNRY' : "RMS((y\'_{pred}-y\'_{hit})/#sigma)"
0573 }
0574 self.varsX = varsX
0575 varsY = {'medianX' : "luminosity-weighted number of modules",
0576 'medianY' : "luminosity-weighted number of modules",
0577 'DrmsNRX' : "luminosity-weighted number of modules",
0578 'DrmsNRY' : "luminosity-weighted number of modules"
0579 }
0580 limitX = {'min' : 10000, 'max' : 10000}
0581
0582
0583 for objName,objList in objects.items():
0584 for obj in objList:
0585
0586 scaleFactor =""
0587 obj['hist'].GetXaxis().SetTitle(varsX[obj['var']])
0588 obj['hist'].GetXaxis().SetTitleFont(obj['hist'].GetYaxis().GetTitleFont())
0589 obj['hist'].GetYaxis().SetTitleSize(0.038)
0590 obj['hist'].GetYaxis().SetTitleOffset(1.7)
0591 if "median" in obj['var']:
0592 scaleFactor ="/"+'{:.2f}'.format((obj['hist'].GetXaxis().GetXmax()*limitX['max']-obj['hist'].GetXaxis().GetXmin()*limitX['min'])/obj['hist'].GetXaxis().GetNbins())+" #mum"
0593 minX = obj['hist'].GetXaxis().GetXmin()
0594 maxX = obj['hist'].GetXaxis().GetXmax()
0595 obj['hist'].GetXaxis().SetLimits(minX*limitX['min'],maxX*limitX['max'])
0596 obj['hist'].GetYaxis().SetTitle(varsY[obj['var']]+scaleFactor)
0597
0598
0599 obj['hist'].SetTitle("")
0600
0601
0602 if len(self.args['objects']) != 0:
0603 if obj['type'] == "MC":
0604 obj['hist'].SetLineColor(self.args['colors'][self.args['objects'].index(objName)])
0605 obj['hist'].SetLineStyle(self.args['styles'][self.args['objects'].index(objName)])
0606 obj['hist'].SetLineWidth(3)
0607 elif obj['type'] == "DATA":
0608 obj['hist'].SetMarkerColor(self.args['colors'][self.args['objects'].index(objName)])
0609 obj['hist'].SetLineColor(self.args['colors'][self.args['objects'].index(objName)])
0610 obj['hist'].SetLineWidth(3)
0611 obj['hist'].SetMarkerStyle(self.args['styles'][self.args['objects'].index(objName)])
0612 obj['hist'].SetMarkerSize(1.5)
0613
0614
0615 tStyle = ROOT.TStyle("StyleCMS","Style CMS")
0616
0617
0618 tStyle.SetErrorX(0)
0619
0620
0621 tStyle.SetCanvasBorderMode(0)
0622 tStyle.SetCanvasColor(ROOT.kWhite)
0623 tStyle.SetCanvasDefH(800)
0624 tStyle.SetCanvasDefW(800)
0625 tStyle.SetCanvasDefX(0)
0626 tStyle.SetCanvasDefY(0)
0627
0628
0629 tStyle.SetFrameBorderMode(0)
0630 tStyle.SetFrameBorderSize(10)
0631 tStyle.SetFrameFillColor(ROOT.kBlack)
0632 tStyle.SetFrameFillStyle(0)
0633 tStyle.SetFrameLineColor(ROOT.kBlack)
0634 tStyle.SetFrameLineStyle(0)
0635 tStyle.SetFrameLineWidth(1)
0636 tStyle.SetLineWidth(2)
0637
0638
0639 tStyle.SetPadBorderMode(0)
0640 tStyle.SetPadColor(ROOT.kWhite)
0641 tStyle.SetPadGridX(False)
0642 tStyle.SetPadGridY(False)
0643 tStyle.SetGridColor(0)
0644 tStyle.SetGridStyle(3)
0645 tStyle.SetGridWidth(1)
0646
0647
0648 tStyle.SetPadTopMargin(0.08)
0649 tStyle.SetPadBottomMargin(0.13)
0650 tStyle.SetPadLeftMargin(0.16)
0651 tStyle.SetPadRightMargin(0.05)
0652
0653
0654 tStyle.SetHistLineStyle(0)
0655 tStyle.SetHistLineWidth(3)
0656 tStyle.SetMarkerSize(0.8)
0657 tStyle.SetEndErrorSize(4)
0658 tStyle.SetHatchesLineWidth(1)
0659
0660
0661 tStyle.SetOptFile(0)
0662
0663
0664 tStyle.SetAxisColor(1,"XYZ")
0665 tStyle.SetTickLength(0.03,"XYZ")
0666 tStyle.SetNdivisions(510,"XYZ")
0667 tStyle.SetPadTickX(1)
0668 tStyle.SetPadTickY(1)
0669 tStyle.SetStripDecimals(ROOT.kFALSE)
0670
0671
0672 tStyle.SetTitleColor(1,"XYZ")
0673 tStyle.SetLabelColor(1,"XYZ")
0674 tStyle.SetLabelFont(42,"XYZ")
0675 tStyle.SetLabelOffset(0.007,"XYZ")
0676 tStyle.SetLabelSize(0.04,"XYZ")
0677 tStyle.SetTitleFont(42,"XYZ")
0678 tStyle.SetTitleSize(0.047,"XYZ")
0679 tStyle.SetTitleXOffset(1.2)
0680 tStyle.SetTitleYOffset(1.7)
0681
0682
0683 tStyle.SetLegendBorderSize(0)
0684 tStyle.SetLegendTextSize(self.legendTextSize)
0685 tStyle.SetLegendFont(42)
0686
0687
0688 tStyle.cd()
0689
0690 return tStyle
0691
0692 def __beautify__(self, canvas, CMSextraLabel, eraLabel):
0693
0694
0695
0696
0697 leftMargin = canvas.GetLeftMargin()
0698 rightMargin = canvas.GetRightMargin()
0699 topMargin = canvas.GetTopMargin()
0700 canvas.cd()
0701
0702
0703 CMSlabel = "CMS"
0704 CMSextraOffset = 0.10
0705 CMStext = ROOT.TLatex()
0706 CMSextra = ROOT.TLatex()
0707
0708 CMStext.SetNDC()
0709 CMSextra.SetNDC()
0710
0711 CMStext.SetTextAngle(0)
0712 CMSextra.SetTextAngle(0)
0713
0714 CMStext.SetTextColor(ROOT.kBlack)
0715 CMSextra.SetTextColor(ROOT.kBlack)
0716
0717 CMStext.SetTextFont(61)
0718 CMSextra.SetTextFont(52)
0719
0720 CMStext.SetTextAlign(11)
0721 CMStext.SetTextSize(0.045)
0722 CMSextra.SetTextSize(0.035)
0723
0724 CMStext.DrawLatex(leftMargin,1.-topMargin+0.01,CMSlabel)
0725 CMSextra.DrawLatex(leftMargin+CMSextraOffset,1-topMargin+0.01,CMSextraLabel)
0726
0727
0728 eraText = ROOT.TLatex()
0729 eraText.SetNDC()
0730 eraText.SetTextAngle(0)
0731 eraText.SetTextColor(ROOT.kBlack)
0732 eraText.SetTextFont(42)
0733 eraText.SetTextAlign(33)
0734 eraText.SetTextSize(0.035)
0735 eraText.DrawLatex(1.-rightMargin,1.-topMargin+0.035,eraLabel)
0736
0737
0738 canvas.RedrawAxis()
0739
0740 def __cleanSingle__(self):
0741
0742
0743
0744
0745
0746 for dirpath,dirs,files in os.walk(self.cwd):
0747 if dirpath != self.cwd: continue
0748 for n_file in files:
0749 if ".png" in n_file or ".pdf" in n_file or ".eps" in n_file:
0750 self.__log__("i","File "+n_file+" was created.")
0751 os.system("mv "+n_file+" "+self.outputDir)
0752 self.__log__("i","Done.")
0753
0754 def __clean__(self):
0755
0756
0757
0758
0759
0760 for datafile in self.dataFiles:
0761 os.system("mv "+datafile+" "+self.outputDir)
0762 for mcfile in self.MCobjects:
0763 os.system("mv "+mcfile+" "+self.outputDir)
0764 for dirpath,dirs,files in os.walk(self.cwd):
0765 if dirpath != self.cwd: continue
0766 for n_file in files:
0767 if ".png" in n_file or ".pdf" in n_file or ".eps" in n_file:
0768 self.__log__("i","File "+n_file+" was created.")
0769 os.system("mv "+n_file+" "+self.outputDir)
0770 self.__log__("i","Done.")
0771
0772 def __finalize__(self):
0773
0774
0775
0776
0777 for dirpath,dirs,files in os.walk(self.outputDir):
0778 for n_file in files:
0779 if ".png" in n_file or ".pdf" in n_file or ".eps" in n_file:
0780 self.__log__("i","File "+n_file+" was created.")
0781 self.__log__("i","Done.")
0782
0783
0784 def addDATA(self,filename):
0785
0786
0787
0788 if os.path.isfile(str(filename)):
0789 self.__log__("i","DATA file: "+str(filename)+" was added for plotting.")
0790 self.dataFiles.append(str(filename))
0791 elif os.path.isfile(os.path.join(str(filename),self.fileBaseName)):
0792 self.__log__("i","DATA file: "+os.path.join(str(filename),self.fileBaseName)+" was added for plotting.")
0793 self.dataFiles.append(os.path.join(str(filename),self.fileBaseName))
0794 else:
0795 self.__log__("w","DATA file: "+os.path.join(str(filename),self.fileBaseName)+" NOT found.")
0796
0797 def addDirDATA(self, dataDir):
0798
0799
0800
0801 if os.path.isdir(dataDir):
0802 self.__log__("i","DATA dir: "+dataDir+" was added for plotting.")
0803 self.dataDirs.append(dataDir)
0804 else:
0805 self.__log__("w","DATA dir: "+dataDir+" NOT found.")
0806
0807
0808 if len(self.dataDirs) != 0:
0809 if self.args['isDMR']:
0810 for dataDir in self.dataDirs:
0811 for root,dirs,files in os.walk(dataDir):
0812 for dir in dirs:
0813 if dir.startswith("offline"):
0814 self.dataFiles.append(dataDir+"/"+dir+"/ExtendedOfflineValidation_Images/OfflineValidationSummary.root")
0815
0816 def addDirMC(self, mcDir):
0817
0818
0819
0820 if os.path.isdir(mcDir):
0821 self.__log__("i","MC dir: "+mcDir+" was added for plotting.")
0822 nFiles = 0
0823 for dirpath,dirs,files in os.walk(mcDir):
0824 for file in files:
0825 if self.fileBaseName.replace(".root","") in file and file.endswith(".root"):
0826 self.__log__("i","MC file: "+str(file)+" was added for plotting.")
0827 self.MCobjects.append(os.path.join(dirpath,file))
0828 nFiles += 1
0829 if nFiles == 0:
0830 self.__log__("w","No MC file found in "+str(mcDir)+".")
0831 else:
0832 self.__log__("w","MC dir: "+mcDir+" NOT found.")
0833
0834 def addMC(self,filename):
0835
0836
0837
0838 if os.path.isfile(str(filename)):
0839 self.__log__("i","MC file: "+str(filename)+" was added for plotting.")
0840 self.MCobjects.append(str(filename))
0841 elif os.path.isfile(os.path.join(str(filename),self.fileBaseName)):
0842 self.__log__("i","MC file: "+os.path.join(str(filename),self.fileBaseName)+" was added for plotting.")
0843 self.MCobjects.append(os.path.join(str(filename),self.fileBaseName))
0844 else:
0845 self.__log__("w","MC file: "+str(os.path.join(str(filename),self.fileBaseName))+" NOT found.")
0846
0847 def plotSingle(self):
0848
0849
0850
0851
0852
0853 self.__createSingleArchitecture__()
0854
0855
0856 objects = self.__defineSingleObjects__()
0857 objectsData = objects['DATA']
0858 objectsMC = objects['MC']
0859
0860
0861 for objDict in objectsData:
0862 self.__setTHStyle__(objDict)
0863 for objDict in objectsMC:
0864 self.__setTHStyle__(objDict)
0865
0866
0867 ROOT.gROOT.SetBatch(True)
0868 ROOT.gROOT.ProcessLine("gErrorIgnoreLevel = 1001;")
0869
0870 for objDict in objectsData:
0871 for segment in self.segments:
0872 for var in self.varsX:
0873 id = "0"
0874 for key in objDict.keys():
0875 for _obj in objDict[key]:
0876 id = _obj['id']
0877 canvas = ROOT.TCanvas(id+"_"+var+"_"+segment)
0878 canvas.cd()
0879
0880
0881 segmentText = {'text' : segment, 'xmin' : 0.0, 'xmax' : 0.0}
0882 statText = {'xmin' : 0.0, 'xmax' : 0.0}
0883 if "median" in var:
0884 segmentText['xmin'] = 2.5
0885 segmentText['xmax'] = 3.5
0886 statText['xmin'] = 0.20
0887 statText['xmax'] = 0.85
0888 else:
0889 segmentText['xmin'] = 1.4
0890 segmentText['xmax'] = 1.6
0891 statText['xmin'] = 0.65
0892 statText['xmax'] = 0.95
0893
0894
0895 isEmpty = True
0896 maxY = 0.0
0897 objGroup = []
0898 for objName in self.objNameList:
0899 for obj in objDict[objName]:
0900 if obj['var'] == var and obj['segment'] == segment:
0901 if obj['hist'].GetBinContent(obj['hist'].GetMaximumBin()) >= maxY:
0902 maxY = obj['hist'].GetBinContent(obj['hist'].GetMaximumBin())
0903 isEmpty = False
0904 legendLabel = objName.replace("_"," ")
0905 if len(self.args['labels']) != 0:
0906 legendLabel = self.args['labels'][self.args['objects'].index(objName)]
0907
0908
0909 histsMC = []
0910 labelsMC = []
0911 statsMC = []
0912 for objDictMC in objectsMC:
0913 for objNameMC in self.objNameListMC:
0914 for objMC in objDictMC[objNameMC]:
0915 if objMC['var'] == var and objMC['segment'] == segment:
0916 if objMC['hist'].GetBinContent(objMC['hist'].GetMaximumBin()) >= maxY:
0917 maxY = objMC['hist'].GetBinContent(objMC['hist'].GetMaximumBin())
0918 legendLabelMC = objNameMC.replace("_"," ")
0919 if len(self.args['labels']) != 0:
0920 legendLabelMC = self.args['labels'][self.args['objects'].index(objNameMC)]
0921 objMC['hist'].SetDirectory(0)
0922 histsMC.append(objMC['hist'])
0923 labelsMC.append(legendLabelMC)
0924 statsMC.append(self.__getStat__(objMC['hist'],var))
0925 objGroup.append({'hist' : obj['hist'],
0926 'histsMC' : histsMC,
0927 'labelsMC': labelsMC,
0928 'statsMC' : statsMC,
0929 'label' : legendLabel,
0930 'stat' : self.__getStat__(obj['hist'],var)
0931 })
0932
0933 if not isEmpty:
0934 datasetType = "singlemuon"
0935 legMinY = (1./self.legendOffset)+(1.-1./self.legendOffset)*(self.maxEntriesPerColumn-len(objGroup))/(self.maxEntriesPerColumn*3)
0936 nColumns = 1
0937 if len(objGroup) > self.maxEntriesPerColumn:
0938 nColumns = 2
0939 legMinY = 1./self.legendOffset
0940 leg = ROOT.TLegend(0.08,legMinY,0.45,0.88)
0941 leg.SetNColumns(nColumns)
0942 seg = ROOT.TLatex()
0943 maxX = objGroup[0]['hist'].GetXaxis().GetXmax()
0944 stat = self._styledTPaveText(maxX*statText['xmin'],(legMinY+0.025)*self.legendOffset*maxY,maxX*statText['xmax'],0.95*self.legendOffset*maxY,var)
0945 for igroup,group in enumerate(objGroup):
0946 group['hist'].GetYaxis().SetRangeUser(0,self.legendOffset*maxY)
0947 leg.AddEntry(group['hist'],group['label'],"l")
0948 stat.AddText(group['stat'])
0949 group['hist'].Draw("HISTSAME")
0950
0951 if igroup == len(objGroup)-1:
0952 for ihist,histmc in enumerate(group['histsMC']):
0953 leg.AddEntry(histmc,group['labelsMC'][ihist],"l")
0954 stat.AddText(group['statsMC'][ihist])
0955 histmc.Draw("HISTSAME")
0956 leg.Draw("SAME")
0957 seg.DrawLatex(segmentText['xmin'],self.segmentTextOffset['ymin']*maxY,segmentText['text'])
0958 stat.Draw("SAME")
0959 self.__beautify__(canvas,self.args['CMSlabel'],self.args['Rlabel'])
0960 canvas.SaveAs(self.outputDir+"/offline_"+datasetType+"_"+str(id)+"/"+var+"_"+segment+".png")
0961 canvas.SaveAs(self.outputDir+"/offline_"+datasetType+"_"+str(id)+"/"+var+"_"+segment+".pdf")
0962 self.__log__("i","Saving "+self.outputDir+"/offline_"+datasetType+"_"+str(id)+"/"+var+"_"+segment)
0963
0964
0965
0966 self.__log__("i","Done.")
0967
0968 def plot(self):
0969
0970
0971
0972
0973
0974 self.__createArchitecture__()
0975
0976
0977 objects = self.__defineObjects__()
0978
0979
0980 currentStyle = self.__setTHStyle__(objects)
0981
0982
0983 ROOT.gROOT.SetBatch(True)
0984 ROOT.gROOT.ProcessLine("gErrorIgnoreLevel = 1001;")
0985
0986 for segment in self.segments:
0987 for var in self.varsX:
0988 canvas = ROOT.TCanvas(var+"_"+segment)
0989 canvas.cd()
0990
0991
0992 segmentText = {'text' : segment, 'xmin' : 0.0, 'xmax' : 0.0}
0993 statText = {'xmin' : 0.0, 'xmax' : 0.0}
0994 if "median" in var:
0995 segmentText['xmin'] = 2.5
0996 segmentText['xmax'] = 3.5
0997 statText['xmin'] = 0.27
0998 statText['xmax'] = 0.92
0999 else:
1000 segmentText['xmin'] = 1.4
1001 segmentText['xmax'] = 1.6
1002 statText['xmin'] = 0.75
1003 statText['xmax'] = 0.95
1004
1005
1006 isEmpty = True
1007 maxY = 0.0
1008 objGroup = []
1009 for objName in self.objNameList:
1010 for obj in objects[objName]:
1011 if obj['var'] == var and obj['segment'] == segment:
1012 if obj['hist'].GetBinContent(obj['hist'].GetMaximumBin()) >= maxY:
1013 maxY = obj['hist'].GetBinContent(obj['hist'].GetMaximumBin())
1014 isEmpty = False
1015 legendLabel = objName.replace("_"," ")
1016 if len(self.args['labels']) != 0:
1017 legendLabel = self.args['labels'][self.args['objects'].index(objName)]
1018 drawStyle = ""
1019 legStyle = ""
1020 if obj['type'] == "MC":
1021 drawStyle = "HIST SAME"
1022 legStyle = "l"
1023 if obj['type'] == "DATA":
1024 drawStyle += "P HIST SAME"
1025 legStyle = "p"
1026 objGroup.append({'hist' : obj['hist'],
1027 'label' : legendLabel,
1028 'stat' : self.__getStat__(obj['hist'],var),
1029 'drawStyle' : drawStyle,
1030 'legStyle' : legStyle
1031 })
1032
1033 if not isEmpty:
1034 legMinY = (1./self.legendOffset)+(1.-1./self.legendOffset)*(self.maxEntriesPerColumn-len(objGroup))/(self.maxEntriesPerColumn*3)
1035 nColumns = 1
1036 if len(objGroup) > self.maxEntriesPerColumn:
1037 nColumns = 2
1038 legMinY = 1./self.legendOffset
1039 leg = ROOT.TLegend(0.20,legMinY,0.50,0.88)
1040 leg.SetNColumns(nColumns)
1041 seg = ROOT.TLatex()
1042 maxX = objGroup[0]['hist'].GetXaxis().GetXmax()
1043 stat = self._styledTPaveText(maxX*statText['xmin'],(legMinY+0.025)*self.legendOffset*maxY,maxX*statText['xmax'],0.95*self.legendOffset*maxY,var)
1044 for group in objGroup:
1045 group['hist'].GetYaxis().SetRangeUser(0,self.legendOffset*maxY)
1046 leg.AddEntry(group['hist'],group['label'],group['legStyle'])
1047 stat.AddText(group['stat'])
1048 group['hist'].Draw(group['drawStyle'])
1049 leg.Draw("SAME")
1050 seg.DrawLatex(segmentText['xmin'],self.segmentTextOffset['ymin']*maxY,segmentText['text'])
1051 stat.Draw("SAME")
1052 self.__beautify__(canvas,self.args['CMSlabel'],self.args['Rlabel'])
1053 canvas.Print(self.outputDir+"/"+var+"_"+segment+".png")
1054 canvas.Print(self.outputDir+"/"+var+"_"+segment+".pdf")
1055
1056
1057 self.__finalize__()