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