File indexing completed on 2024-11-26 02:34:10
0001
0002
0003 import sys
0004 import os
0005 from ROOT import gROOT, gStyle, gPad, TCanvas, TClass, TGraph, TFile, TArrow, TLatex, TH2Poly, kBlack
0006 from copy import deepcopy
0007 from array import array
0008
0009 gROOT.SetBatch()
0010
0011
0012
0013 def getFileInPath(rfile):
0014 import os
0015 for dir in os.environ['CMSSW_SEARCH_PATH'].split(":"):
0016 if os.path.exists(os.path.join(dir,rfile)): return os.path.join(dir,rfile)
0017 return None
0018
0019
0020
0021 inputFileName = "DQM_V0013_R000292154__StreamExpressCosmics__Commissioning2017-Express-v1__DQMIO.root"
0022 limitsFileName = "limits.dat"
0023 outputDirectoryName = "OUT/"
0024 minMaxFileName = "minmax.out"
0025
0026 detIDsFileName = getFileInPath('DQM/SiStripMonitorClient/data/detids.dat')
0027
0028 baseRootDirs = ["DQMData/Run 292154/PixelPhase1/Run summary/Phase1_MechanicalView"
0029 ,"DQMData/Run 292154/PixelPhase1/Run summary/Tracks"
0030 ]
0031
0032
0033 maxPxBarrel = 4
0034 maxPxForward = 3
0035 barrelLadderShift = [0, 14, 44, 90]
0036
0037 forwardDiskXShift = [25, 75, 125]
0038 forwardDiskYShift = 45;
0039
0040 plotWidth, plotHeight = 3000, 2000
0041 extremeBinsNum = 20
0042
0043 limits = ["num_digis 0.01 90 1 0",
0044 "num_clusters 0.01 25 1 0",
0045 "Trechitsize_y 0.01 10 0 0",
0046 "Trechitsize_x 0.01 10 0 0",
0047 "Tresidual_y 0.0000001 0.004 0 1",
0048 "Tresidual_x 0.0000001 0.004 0 1",
0049 "Tcharge 2000 80000 0 0",
0050 "Thitefficiency 0.95 1 0 0",
0051
0052 "Tnum_clusters_ontrack 0.01 15 1 0",
0053 "Tsize 0.01 15 0 0",
0054
0055 "adc 0.01 256 0 0",
0056 "charge 2000 80000 0 0",
0057 "size 0.01 15 0 0",]
0058
0059 class TH2PolyOfflineMaps:
0060
0061
0062
0063
0064
0065
0066
0067 def __TraverseDirTree(self, dir):
0068
0069 try:
0070 currPath = (dir.GetPath().split(":/"))[1]
0071 except:
0072 print("Exception raised: Path not found in the input file")
0073 return
0074
0075 for obj in dir.GetListOfKeys():
0076 if not obj.IsFolder():
0077 if obj.ReadObjectAny(TClass.GetClass("TH2")):
0078 th2 = deepcopy(obj.ReadObj())
0079 name = th2.GetName()
0080 if 6 < th2.GetNbinsX() < 10 and name.find("per") != -1 and name.find("Lumisection") == -1:
0081 print(''.join([dir.GetPath(), '/', name]))
0082
0083
0084 prefix = ""
0085 for i in self.dirs:
0086 if currPath.startswith(i):
0087 prefix = self.dirsAliases[i]
0088 break
0089
0090 th2.SetName(prefix + th2.GetName())
0091 self.listOfNumHistograms.append(th2)
0092 else:
0093 self.__TraverseDirTree(obj.ReadObj())
0094
0095 def __GetPartStr(self, isXlowerThanZero, isYlowerThanZero):
0096 if isXlowerThanZero and isYlowerThanZero:
0097 return "mO"
0098 if isXlowerThanZero and isYlowerThanZero == False:
0099 return "mI"
0100 if isXlowerThanZero == False and isYlowerThanZero:
0101 return "pO"
0102 if isXlowerThanZero == False and isYlowerThanZero == False:
0103 return "pI"
0104
0105 def __GetBarrelSector(self, layer, signedLadder, signedModule):
0106 theLadder = abs(signedLadder)
0107 theModule = abs(signedModule)
0108
0109 sector = 0
0110
0111 if layer == 1:
0112
0113 if theLadder == 1:
0114 if theModule >= 2:
0115 return 1
0116 else:
0117 return 2
0118 if theLadder == 2:
0119 if theModule >= 3:
0120 return 2
0121 else:
0122 return 3
0123 if theLadder == 3:
0124 if theModule >= 4:
0125 return 3
0126 else:
0127 return 4
0128 if theLadder == 4:
0129 if theModule >= 2:
0130 return 5
0131 else:
0132 return 6
0133 if theLadder == 5:
0134 if theModule >= 3:
0135 return 6
0136 else:
0137 return 7
0138 if theLadder == 6:
0139 if theModule >= 4:
0140 return 7
0141 else:
0142 return 8
0143
0144 elif layer == 2:
0145 i = theLadder // 5
0146 sector = i * 3
0147 shortLadder = theLadder - 5 * i
0148 for i in range(0, shortLadder, 2):
0149 sector = sector + 1
0150 return sector
0151 elif layer == 3:
0152 sector = 1
0153 for i in range(2, theLadder, 3):
0154 if (i + 1) % 3 == 0:
0155 sector = sector + 1
0156 return sector
0157 elif layer == 4:
0158 sector = (theLadder + 3) // 4
0159 return sector
0160
0161 def __BuildOnlineBarrelName(self, signedModule, signedLadder, layer):
0162 thePart = self.__GetPartStr(signedModule < 0, signedLadder < 0)
0163 theSector = str(self.__GetBarrelSector(layer, signedLadder, signedModule))
0164 return "BPix_B" + thePart + "_SEC" + theSector + "_LYR" + str(layer) + "_LDR" + str(abs(signedLadder)) + "F_MOD" + str(abs(signedModule))
0165
0166 def __BuildOnlineDiskName(self, signedDisk, signedBlade, panel, ring):
0167 thePart = self.__GetPartStr(signedDisk < 0, signedBlade < 0)
0168 return "FPix_B" + thePart + "_D" + str(abs(signedDisk)) + "_BLD" + str(abs(signedBlade)) + "_PNL" + str(panel) + "_RNG" + str(ring)
0169
0170 def __GroupHistograms(self):
0171 currentGroupName = ""
0172 groupOfHists = []
0173 self.groupedHistograms = []
0174
0175
0176 for obj in self.listOfNumHistograms:
0177 objName = obj.GetName()
0178 objNameSplit = objName.split("_")
0179 objNameCollected = ''.join(objNameSplit[0:-1])
0180 if objNameCollected != currentGroupName:
0181 if len(groupOfHists):
0182 self.groupedHistograms.append(groupOfHists)
0183 groupOfHists = []
0184
0185 currentGroupName = objNameCollected
0186 groupOfHists.append(obj)
0187 self.groupedHistograms.append(groupOfHists)
0188
0189 def __AddNamedBins(self, geoFile, tX, tY, sX, sY, applyModuleRotation = False):
0190
0191 for line in geoFile:
0192 lineSpl = line.strip().split("\"")
0193
0194 detId = str(lineSpl[0].split(" ")[1])+"_("+str(lineSpl[0].split(" ")[0])+")"
0195 vertices = lineSpl[1]
0196 xy = vertices.split(" ")
0197 x, y = array('d'), array('d')
0198 verNum = 1
0199 for coord in xy:
0200 coordSpl = coord.split(",")
0201 if applyModuleRotation:
0202 x.append(-(float(coordSpl[0]) * sX + tX))
0203 y.append((float(coordSpl[1]) * sY + tY))
0204 else:
0205 x.append(float(coordSpl[0]) * sX + tX)
0206 y.append(float(coordSpl[1]) * sY + tY)
0207 verNum = verNum + 1
0208
0209 x.append(x[0])
0210 y.append(y[0])
0211
0212 if applyModuleRotation:
0213 bin = TGraph(verNum, y, x)
0214 else:
0215 bin = TGraph(verNum, x, y)
0216
0217 bin.SetName(detId)
0218
0219 self.__BaseTrackerMap.AddBin(bin)
0220
0221 def __CreateTrackerBaseMap(self):
0222
0223 self.__BaseTrackerMap = TH2Poly("Summary", "", -10, 160, -70, 70)
0224
0225 self.__BaseTrackerMap.SetFloat(1)
0226 self.__BaseTrackerMap.GetXaxis().SetTitle("")
0227 self.__BaseTrackerMap.GetYaxis().SetTitle("")
0228 self.__BaseTrackerMap.SetOption("COLZ L")
0229 self.__BaseTrackerMap.SetStats(0)
0230
0231
0232 for i in range(maxPxBarrel):
0233 with open(self.geometryFilenames[i], "r") as geoFile:
0234 currBarrelTranslateX = 0
0235 currBarrelTranslateY = barrelLadderShift[i]
0236
0237 self.__AddNamedBins(geoFile, currBarrelTranslateX, currBarrelTranslateY, 1, 1, True)
0238
0239
0240
0241
0242 for i in range(-maxPxForward, 0):
0243 with open(self.geometryFilenames[maxPxBarrel + maxPxForward + i], "r") as geoFile:
0244 currForwardTranslateX = forwardDiskXShift[-i - 1]
0245 currForwardTranslateY = -forwardDiskYShift
0246
0247 self.__AddNamedBins(geoFile, currForwardTranslateX, currForwardTranslateY, 1, 1)
0248
0249
0250 for i in range(maxPxForward):
0251 with open(self.geometryFilenames[maxPxBarrel + maxPxForward + i], "r") as geoFile:
0252 currForwardTranslateX = forwardDiskXShift[i]
0253 currForwardTranslateY = forwardDiskYShift
0254
0255 self.__AddNamedBins(geoFile, currForwardTranslateX, currForwardTranslateY, 1, 1)
0256
0257
0258
0259 print("Base Tracker Map: constructed")
0260
0261
0262 def __init__(self, inputDQMName, outputDirName, minMaxFileName, limits, modDicName, runNumber, dirs, dirsAliases):
0263
0264 self.inputFileName = inputDQMName
0265 self.outputDirName = outputDirName
0266 self.minMaxFileName = minMaxFileName
0267
0268 self.detIDsFileName = modDicName
0269 self.limits = limits
0270
0271 self.runNumber = runNumber
0272 self.dirs = dirs
0273 self.dirsAliases = dirsAliases
0274
0275 self.inputFile = TFile(self.inputFileName)
0276 self.listOfNumHistograms = []
0277 self.availableNames = []
0278
0279 self.maxLadderToLayer = {6:1, 14:2, 22:3, 32:4}
0280 self.maxBladeToRing = {11:1, 17:2}
0281
0282 self.geometryFilenames = []
0283 for i in range(maxPxBarrel):
0284 self.geometryFilenames.append(getFileInPath("DQM/SiStripMonitorClient/data/Geometry/vertices_barrel_" + str(i + 1)))
0285
0286 for i in range(-maxPxForward, maxPxForward + 1):
0287 if i == 0:
0288 continue
0289 self.geometryFilenames.append(getFileInPath("DQM/SiStripMonitorClient/data/Geometry/vertices_forward_" + str(i)))
0290
0291
0292 self.internalData = {}
0293
0294 if self.inputFile.IsOpen():
0295 print("%s opened successfully!" % (self.inputFileName))
0296
0297 for dir in self.dirs:
0298 self.__TraverseDirTree(self.inputFile.Get(dir))
0299
0300
0301 self.detDict = {}
0302
0303 with open(self.detIDsFileName, "r") as detIDs:
0304 for entry in detIDs:
0305 items = entry.replace("\n", " ").split(" ")
0306 self.detDict.update({items[1] : int(items[0])})
0307
0308 self.internalData.update({int(items[0]) : {}})
0309
0310 self.rawToOnlineDict = dict((v,k) for k,v in self.detDict.items())
0311
0312 self.__GroupHistograms()
0313
0314 self.__CreateTrackerBaseMap()
0315
0316 else:
0317 print("Unable to open file %s" % (self.inputFileName))
0318
0319
0320
0321 self.limitsDic = {}
0322 for y in limits:
0323
0324 lineSpl = y.strip().split(" ")
0325
0326 if len(lineSpl) < 5:
0327 continue
0328
0329 currName = lineSpl[0]
0330 zMin = float(lineSpl[1])
0331 zMax = float(lineSpl[2])
0332 isLog = False if lineSpl[3] == "0" else True
0333 isAbs = False if lineSpl[4] == "0" else True
0334
0335 self.limitsDic.update({currName : {"zMin" : zMin, "zMax" : zMax, "isLog" : isLog, "isAbs" : isAbs}})
0336
0337
0338 def ReadHistograms(self):
0339 if self.inputFile.IsOpen():
0340 for group in self.groupedHistograms:
0341
0342 if len(group) == 0:
0343 return
0344 print(group[0].GetName())
0345 name = ''.join(group[0].GetName().split("_per_")[0])
0346 self.availableNames.append(name)
0347
0348 for obj in group:
0349 nbinsX = obj.GetNbinsX()
0350 nbinsY = obj.GetNbinsY()
0351
0352 if nbinsX == 9:
0353 maxX = nbinsX // 2
0354 maxY = nbinsY // 2
0355
0356 for x in range(-maxX, maxX + 1):
0357 if x == 0:
0358 continue
0359 for y in range(-maxY, maxY + 1, 1):
0360 if y == 0:
0361 continue
0362 onlineName = self.__BuildOnlineBarrelName(x, y, self.maxLadderToLayer[maxY])
0363 self.internalData[self.detDict[onlineName]].update({name : obj.GetBinContent(x + maxX + 1, y + maxY + 1)})
0364
0365 elif nbinsX == 7:
0366 maxX = nbinsX // 2
0367 maxY = nbinsY // 4
0368
0369 for x in range(-maxX, maxX + 1):
0370 if x == 0:
0371 continue
0372 for y in range(-maxY, maxY + 1):
0373 if int(y) == 0:
0374 continue
0375 for panel in range(1, 3):
0376 onlineName = self.__BuildOnlineDiskName(x, y, panel, self.maxBladeToRing[maxY])
0377 self.internalData[self.detDict[onlineName]].update({name : obj.GetBinContent(x + maxX + 1, (y + maxY) * 2 + (3-panel))})
0378 else:
0379 print("Unrecognized plot")
0380 else:
0381 print("Histograms saved to internal data structure")
0382
0383 def DumpData(self):
0384 for key in self.internalData:
0385 print("#"*20)
0386 print(key)
0387 module = self.internalData[key]
0388 for d in module:
0389 print((d, module[d]))
0390
0391 print(len(self.internalData))
0392
0393 for i in self.availableNames:
0394 print(i)
0395 print(len(self.availableNames))
0396
0397 def PrintTrackerMaps(self):
0398 monitoredValues = []
0399 gStyle.SetPalette(1)
0400 for key in self.internalData:
0401 monitoredValues = self.internalData[key].keys()
0402
0403 break
0404
0405 if os.path.exists(self.outputDirName) == False:
0406 os.system("mkdir " + self.outputDirName)
0407
0408 with open(self.outputDirName + self.minMaxFileName, "w") as minMaxFile:
0409
0410 for mv in monitoredValues:
0411 currentHist = deepcopy(self.__BaseTrackerMap)
0412
0413 histoTitle = "Run " + self.runNumber + ": Tracker Map for " + mv
0414
0415 applyLogScale = False
0416 applyAbsValue = False
0417 if mv in self.limitsDic:
0418 limitsElem = self.limitsDic[mv]
0419
0420 print(mv + " found in limits dictionary - applying custom limits...")
0421
0422 currentHist.SetMinimum(limitsElem["zMin"])
0423 currentHist.SetMaximum(limitsElem["zMax"])
0424 applyLogScale = limitsElem["isLog"]
0425 applyAbsValue = limitsElem["isAbs"]
0426
0427 listOfVals = []
0428 onlineName = ""
0429 nameId = ""
0430
0431 for detId in self.internalData:
0432 val = (self.internalData[detId])[mv]
0433 onlineName = self.rawToOnlineDict[detId]
0434 listOfVals.append([val, detId, onlineName])
0435
0436 nameId = str(onlineName)+"_("+str(detId)+")"
0437
0438 if applyAbsValue:
0439 currentHist.Fill(str(nameId), abs(val))
0440 else:
0441 currentHist.Fill(str(nameId), val)
0442
0443 listOfVals = sorted(listOfVals, key = lambda item: item[0])
0444
0445 minMaxFile.write("\n" + mv + "\n\n")
0446
0447 minMaxFile.write("MIN:\n")
0448 for i in range(extremeBinsNum):
0449 minMaxFile.write("\t" + str(listOfVals[i][1]) + " " + str(listOfVals[i][2]) + " " + str(listOfVals[i][0]) + "\n")
0450
0451 minMaxFile.write("MAX:\n")
0452 for i in range(extremeBinsNum):
0453 minMaxFile.write("\t" + str(listOfVals[-i - 1][1]) + " " + str(listOfVals[-i - 1][2]) + " " + str(listOfVals[-i - 1][0]) + "\n")
0454
0455
0456 c1 = TCanvas("MyT", "MyT", plotWidth , plotHeight)
0457
0458 if applyLogScale:
0459 c1.SetLogz()
0460
0461 currentHist.Draw("AC COLZ L")
0462
0463 gPad.Update()
0464 palette = currentHist.FindObject("palette");
0465 palette.SetX1NDC(0.89);
0466 palette.SetX2NDC(0.91);
0467 palette.SetLabelSize(0.05);
0468 gPad.Update()
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478 arrow = TArrow(0.05, 27.0, 0.05, -30.0, 0.02, "|>")
0479 arrow.SetLineWidth(4)
0480 arrow.Draw()
0481
0482 phiArrow = TArrow(0.0, 27.0, 30.0, 27.0, 0.02, "|>")
0483 phiArrow.SetLineWidth(4)
0484 phiArrow.Draw()
0485
0486 xArrow = TArrow(25.0, 44.5, 50.0, 44.5, 0.02, "|>")
0487 xArrow.SetLineWidth(4)
0488 xArrow.Draw()
0489
0490 yArrow = TArrow(25.0, 44.5, 25.0, 69.5, 0.02, "|>")
0491 yArrow.SetLineWidth(4)
0492 yArrow.Draw()
0493
0494
0495
0496
0497 txt = TLatex()
0498 txt.SetNDC()
0499 txt.SetTextFont(1)
0500 txt.SetTextColor(1)
0501 txt.SetTextAlign(22)
0502 txt.SetTextAngle(0)
0503
0504
0505 txt.SetTextSize(0.05)
0506 txt.DrawLatex(0.5, 0.95, histoTitle)
0507
0508 txt.SetTextSize(0.03)
0509
0510 txt.DrawLatex(0.5, 0.125, "-DISK")
0511 txt.DrawLatex(0.5, 0.075, "NUMBER ->")
0512 txt.DrawLatex(0.5, 0.875, "+DISK")
0513
0514 txt.DrawLatex(0.17, 0.35, "+z")
0515 txt.DrawLatexNDC(0.36, 0.685, "+phi")
0516 txt.DrawLatex(0.38, 0.73, "+x")
0517 txt.DrawLatex(0.26, 0.875, "+y")
0518
0519 txt.SetTextAngle(90)
0520 txt.DrawLatex(0.17, 0.5, "BARREL")
0521
0522
0523 c1.Print(self.outputDirName + mv + ".png")
0524
0525
0526 c1.Clear()
0527 c1.SetLogz(False)
0528 currentHist.GetZaxis().UnZoom()
0529 currentHist.SetLineColor(kBlack)
0530 currentHist.Draw("AL COLZ")
0531 currentHist.GetXaxis().SetRangeUser(-10,155)
0532
0533 palette.SetX1NDC(0.92);
0534 palette.SetX2NDC(0.94);
0535 palette.SetY1NDC(0.02);
0536 palette.SetY2NDC(0.91);
0537 gPad.SetRightMargin(0.08);
0538 gPad.SetLeftMargin(0.01);
0539 gPad.SetTopMargin(0.09);
0540 gPad.SetBottomMargin(0.02);
0541 gPad.Update()
0542
0543 zarrow = TArrow(0, 27, 0, -30, 0.02, "|>")
0544 zarrow.SetLineWidth(3)
0545 zarrow.Draw()
0546 phiArrow.SetLineWidth(3)
0547 phiArrow.Draw()
0548 xArrow.SetLineWidth(3)
0549 xArrow.Draw()
0550 yArrow.SetLineWidth(3)
0551 yArrow.Draw()
0552
0553 txt.Clear()
0554 txt.SetTextAngle(0)
0555 txt.SetTextSize(0.05)
0556 PixelTitle = "Run " + self.runNumber + ": Pixel " + mv
0557 txt.DrawLatex(0.5, 0.95, PixelTitle)
0558
0559 txt.SetTextSize(0.04)
0560 txt.SetNDC(False)
0561 txt.DrawLatex(75, -65, "-DISK")
0562 txt.DrawLatex(75, 65, "+DISK")
0563 txt.DrawLatex(50, -60, "NUMBER ->")
0564
0565 txt.DrawLatex(-5, -20, "+z")
0566 txt.DrawLatex(35, 30, "+phi")
0567 txt.DrawLatex(55, 45, "+x")
0568 txt.DrawLatex(30, 65, "+y")
0569
0570 txt.SetTextAngle(90)
0571 txt.DrawLatex(-5, 0, "BARREL")
0572
0573 c1.SaveAs(self.outputDirName + mv + ".root")
0574 c1.Close()
0575
0576 def __del__(self):
0577 if self.inputFile :
0578 if self.inputFile.IsOpen():
0579 self.inputFile.Close()
0580
0581
0582 for i in range(1, len(sys.argv), 1):
0583 if i == 1:
0584 inputFileName = sys.argv[i]
0585 elif i == 2:
0586 plotWidth = int(sys.argv[i])
0587 elif i == 3:
0588 plotHeight = int(sys.argv[i])
0589
0590
0591
0592 elif i == 4:
0593 detIDsFileName = sys.argv[i]
0594
0595 deductedRunNumber = inputFileName.split("_R000")[1][0:6]
0596 print(deductedRunNumber)
0597
0598 baseRootDirs = ["DQMData/Run " + deductedRunNumber + "/PixelPhase1/Run summary/Phase1_MechanicalView"
0599 ,"DQMData/Run " + deductedRunNumber + "/PixelPhase1/Run summary/Tracks"
0600 ]
0601
0602 baseRootDirsAliases = {baseRootDirs[0]:""
0603 , baseRootDirs[1]:"T"
0604 }
0605
0606 readerObj = TH2PolyOfflineMaps(inputFileName, outputDirectoryName, minMaxFileName, limits, detIDsFileName, deductedRunNumber, baseRootDirs, baseRootDirsAliases)
0607
0608 readerObj.ReadHistograms()
0609
0610 readerObj.PrintTrackerMaps()