ATLAS Offline Software
Loading...
Searching...
No Matches
DeMoStatus.py
Go to the documentation of this file.
1#! /usr/bin/env python
2# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3# Author : Benjamin Trocme (CNRS/IN2P3 - LPSC Grenoble) - 2017 - 2023
4# Python 3 migration by Miaoran Lu (University of Iowa)- 2022
5#
6# Display the year stats
7#
8# Documentation: https://twiki.cern.ch/twiki/bin/viewauth/Atlas/DataQualityDemo
9
10
11import os,sys
12
13import time
14
15from ROOT import TFile
16from ROOT import TProfile,TH1F
17from ROOT import TCanvas
18from ROOT import gStyle,gPad,gROOT
19from ROOT import kBlack,kOrange,kGreen
20gROOT.SetBatch(False)
21
22sys.path.append("/afs/cern.ch/user/l/larmon/public/prod/Misc")
23
24from DeMoLib import strLumi,plotStack,initializeMonitoredDefects,retrieveYearTagProperties,MakeTH1,SetXLabel,MakeTProfile
25
26global debug
27debug = False
28#debug = True
29
30
31def mergeSubPeriod(tprof_subperiod,tprof_letter):
32 index_letter = {}
33 nb_letter = tprof_letter.GetNbinsX()
34 nb_subperiod = tprof_subperiod.GetNbinsX()
35 for iBin in range(1,nb_letter): # Loop on all subperiods of letter TProfile
36 index_letter[tprof_letter.GetXaxis().GetBinLabel(iBin)] = iBin
37
38 for iBin in range(1,nb_subperiod): # Loop on all subperiods
39 letter = tprof_subperiod.GetXaxis().GetBinLabel(iBin)[0]
40 if (tprof_letter.IsA().InheritsFrom("TProfile")):
41 tprof_letter.Fill(index_letter[letter]-1,tprof_subperiod.GetBinContent(iBin),tprof_subperiod.GetBinEntries(iBin))
42 tprof_letter.Fill(nb_letter-1,tprof_subperiod.GetBinContent(iBin),tprof_subperiod.GetBinEntries(iBin))
43 elif (tprof_letter.IsA().InheritsFrom("TH1")):
44 tprof_letter.Fill(index_letter[letter]-1,tprof_subperiod.GetBinContent(iBin))
45 tprof_letter.Fill(nb_letter-1,tprof_subperiod.GetBinContent(iBin))
46
47 return
48
49
51def ATLASLabel(x,y,text=""):
52 from ROOT import TLatex
53 from ROOT import gPad
54 l = TLatex()
55 l.SetNDC();
56 l.SetTextFont(72);
57 l.DrawLatex(x,y,"ATLAS")
58 delx = 0.115*696*gPad.GetWh()/(472*gPad.GetWw())
59 if (text != ""):
60 p = TLatex()
61 p.SetNDC()
62 p.SetTextFont(42)
63 p.DrawLatex(x+delx,y,text);
64
65 return
66
67
68
71from argparse import RawTextHelpFormatter,ArgumentParser
72from ROOT import gROOT
73
74parser = ArgumentParser(description='',formatter_class=RawTextHelpFormatter)
75parser.add_argument('-y','--year',dest='parser_year',default = ["2022"],nargs='*',help='Year [Default: 2022]',action='store')
76parser.add_argument('-t','--tag',dest='parser_tag',default = ["AtlasReady"],nargs='*',help='Defect tag [Default: "AtlasReady"]',action='store')
77parser.add_argument('-s','--system',dest='parser_system',default="LAr",help='System: LAr, CaloCP [Default: "LAr"]',action='store')
78parser.add_argument('-d','--directory',dest='parser_directory',default="./",help='Directory to display',action='store')
79parser.add_argument('-b','--batch',dest='parser_batchMode',help='Batch mode',action='store_true')
80parser.add_argument('--yearStats',dest='parser_plotYS',help='Plot the year stats per period',action='store_true')
81parser.add_argument('--yearStatsLarge',dest='parser_letterYS',help='Plot the year stats as a function of the letter (large) periods',action='store_true')
82parser.add_argument('--lumiNotPercent',dest='parser_lumiNotPercent',help='Display results in term of lumi and not percent',action='store_true')
83parser.add_argument('--noRecovPlot',dest='parser_noRecovPlot',help='Do not plot the recoverable histograms',action='store_false')
84parser.add_argument('--savePlots',dest='parser_savePlots',help='Save yearStats results in ~larmon/public/prod/LADIeS/DeMoPlots',action='store_true')
85parser.add_argument('--approvedPlots',dest='parser_approvedPlots',help='Cosmetics to get the approved plots',action='store_true')
86parser.add_argument('--noSingleTagPlot',dest='parser_noSingleTagPlot',help='When > 1 tag, display only comparison plots',action='store_true')
87
88args = parser.parse_args()
89
90parser.print_help()
91
92if args.parser_batchMode:
93 gROOT.SetBatch(True)
94
95ytp = {}
96partitions = {}
97defects = {}
98defectVeto = {}
99veto = {}
100signOff = {}
101initializeMonitoredDefects(args.parser_system,partitions,defects,defectVeto,veto,signOff,args.parser_year[0],args.parser_tag[0])
102
103yearTagList = []
104yearTagDir = {}
105for iYear in args.parser_year:
106 for iTag in args.parser_tag:
107 directory = "%s/YearStats-%s/%s/%s"%(args.parser_directory,args.parser_system,iYear,iTag)
108 if os.path.exists(directory):
109 ytp = retrieveYearTagProperties(iYear,iTag)
110 yearTag = "%s/%s"%(iYear,ytp["Description"])
111 yearTagList.append(yearTag)
112 yearTagDir[yearTag] = directory
113
114yearTagList.sort()
115
116if len(yearTagList) == 0:
117 print("No year / tag matching - Please check YearStats directory")
118 sys.exit()
119
120options = {}
121options['plotYearStats'] = args.parser_plotYS
122options['plotYearStatsLarge'] = args.parser_letterYS # Plot results as a function of letter period (A,B,C...) and not only as a function of subperiod (A1,A2,B1,B2,B3...)
123options['lumiNotPercent'] = args.parser_lumiNotPercent
124options['recovPlot'] = args.parser_noRecovPlot
125options['savePlots'] = args.parser_savePlots
126options['approvedPlots'] = args.parser_approvedPlots
127options['noSingleTagPlot'] = args.parser_noSingleTagPlot
128
129if options['savePlots']:
130 options['plotYearStats'] = True
131 options['plotYearStatsLarge'] = False
132 options['lumiNotPercent'] = False
133
134if options['approvedPlots']:
135 options['plotYearStats'] = False
136 options['plotYearStatsLarge'] = True
137 options['lumiNotPercent'] = False
138 options['recovPlot'] = False
139
140if not (options['plotYearStats'] or options['plotYearStatsLarge'] or options['savePlots']):
141 options['plotYearStats'] = True
142
143yearTagNb = len(yearTagList)
144yearTagLabels = yearTagNb*[""]
145for iYT in range(yearTagNb):
146 if options['approvedPlots']: yearTagLabels[iYT] = yearTagList[iYT].split("/")[0]
147 else: yearTagLabels[iYT] = yearTagList[iYT]
148
149gStyle.SetOptStat(0)
150
151canvasResults = {}
152legendResults = {}
153stackResults = {}
154file = {}
155
156hProfPeriod_IntolDefect = {}
157hProfPeriod_Veto = {}
158hProfPeriodLett_IntolDefect = {}
159hProfPeriodLett_Veto = {}
160h1Period_IntLuminosity = {}
161h1PeriodLett_IntLuminosity = {}
162subperiodNb = {}
163runsCharact = {}
164
165for iYT in yearTagList:
166 print(("I am treating the following year/tag:%s"%iYT))
167
168 canvasResults[iYT] = {}
169 legendResults[iYT] = {}
170 stackResults[iYT] = {}
171
172 yearStatsArchiveFilename = '%s/TProfiles.root'%(yearTagDir[iYT])
173 file[iYT] = TFile(yearStatsArchiveFilename)
174 h1Period_IntLuminosity[iYT] = file[iYT].Get("h1Period_IntLuminosity_archive")
175 subperiodNb[iYT] = h1Period_IntLuminosity[iYT].GetNbinsX()
176
177 # Retrieve the nb of runs updated by reading dat files
178 runsCharact[iYT] = {'Low':1e10,'High':0,'Number':0}
179
180 fTemp = open("%s/runs-ALL.dat"%yearTagDir[iYT])
181 for iline in fTemp.readlines():
182 runNb = int(iline.split(" (")[0]) # Removing the period
183 if runNb<runsCharact[iYT]['Low']:runsCharact[iYT]['Low']=int(runNb)
184 if runNb>runsCharact[iYT]['High']:runsCharact[iYT]['High']=int(runNb)
185 runsCharact[iYT]['Number'] += 1
186
187 runsCharact[iYT]['Range']="%d->%d"%(runsCharact[iYT]['Low'],runsCharact[iYT]['High'])
188 print(("I found %d runs in this year/tag (%s)"%(runsCharact[iYT]['Number'],runsCharact[iYT]['Range'])))
189
190 if (options['plotYearStats'] or options['plotYearStatsLarge']):
191 if options['approvedPlots']:
192 xAxisTitle = "Period"
193 legendHead = "%s - %s"%(args.parser_system,iYT.split("/")[0])
194 else:
195 xAxisTitle = "Period (%s)"%runsCharact[iYT]['Range']
196 legendHead = "%s - %s"%(args.parser_system,iYT)
197
198 # Retrieve the defect, veto histograms from the YearStats root file
199 hProfPeriod_IntolDefect[iYT] = {}
200 allIntolDef = ["allIntol","allIntol_recov"] # Summed inefficiencies without double counting
201 for iDef in defects["intol"]+defects["intol_recov"]+allIntolDef:
202 iDefName = iDef.rsplit("__",1)[0] # Trick needed to get the defect name for the recoverable defect histogram
203 hProfPeriod_IntolDefect[iYT][iDef] = file[iYT].Get("hProfPeriod_IntolDefect_%s_archive"%(iDef))
204 hProfPeriod_IntolDefect[iYT][iDef].SetFillColor(defectVeto["color"][iDefName])
205
206 hProfPeriod_Veto[iYT] = {}
207 for iVeto in veto["all"]:
208 hProfPeriod_Veto[iYT][iVeto] = file[iYT].Get("hProfPeriod_Veto_%s_archive"%(iVeto))
209 hProfPeriod_Veto[iYT][iVeto].SetFillColor(defectVeto["color"][iVeto])
210 if len(veto["all"]): # Summed inefficiencies
211 hProfPeriod_Veto[iYT]["allVeto"] = file[iYT].Get("hProfPeriod_Veto_allVeto_archive")
212 hProfPeriod_Veto[iYT]["allVeto"].SetFillColor(kBlack)
213
214
215 # Plot the stack for subperiod
216 if (options['plotYearStats'] and not options['noSingleTagPlot']):
217 totalIneffDef = plotStack("defects--%s--%s - %s"%(xAxisTitle,args.parser_system,iYT),hProfPeriod_IntolDefect[iYT],defects["intol"],defectVeto["description"],h1Period_IntLuminosity[iYT],options['lumiNotPercent'],stackResults[iYT],canvasResults[iYT],legendResults[iYT],options['recovPlot'],False,options['approvedPlots'])
218 if options['approvedPlots']:
219 ATLASLabel(0.4,0.8,"Internal")
220# ATLASLabel(0.1,0.81,"Preliminary")
221 if len(veto["all"]):
222 totalIneffVeto = plotStack("veto--%s--%s"%(xAxisTitle,iYT),hProfPeriod_Veto[iYT],veto["all"],defectVeto["description"],h1Period_IntLuminosity[iYT],options['lumiNotPercent'],stackResults[iYT],canvasResults[iYT],legendResults[iYT],False,False,options['approvedPlots'])
223 if options['approvedPlots']:
224 ATLASLabel(0.1,0.81,"Internal")
225# ATLASLabel(0.1,0.81,"Preliminary")
226
227 # Plot the stack for letter period
228 if (options['plotYearStatsLarge']):
229 # Scan all subperiods and extract letter periods -
230 letperiodList = []
231 for iBin in range(1,subperiodNb[iYT]):
232 subperiod = h1Period_IntLuminosity[iYT].GetXaxis().GetBinLabel(iBin)
233 if (subperiod[0] not in letperiodList):
234 letperiodList.append(subperiod[0])
235 letperiodNb = len(letperiodList)
236
237 # Merge the subperiod histograms into letter period histograms
238 hProfPeriodLett_IntolDefect[iYT] = {}
239 hProfPeriodLett_Veto[iYT] = {}
240 for iDef in defects["intol"]+defects["intol_recov"]+allIntolDef: # Loop on defect (including recoverable histos and summed inefficiencies)
241 iDefName = iDef.rsplit("__",1)[0] # Trick needed to get the defect name for the recoverable defect histogram
242 hProfPeriodLett_IntolDefect[iYT][iDef] = MakeTProfile("hProfPeriodLett_IntolDefect_%s_%s"%(iYT,iDef),"%s"%(defectVeto["description"][iDefName]),"Lost luminosity [%]", -0.5,+0.5+letperiodNb,letperiodNb+1,defectVeto["color"][iDefName])
243 SetXLabel(hProfPeriodLett_IntolDefect[iYT][iDef],letperiodList)
244 hProfPeriodLett_IntolDefect[iYT][iDef].GetXaxis().SetBinLabel(letperiodNb+1,"All") # In all bins, all runs
245 mergeSubPeriod(hProfPeriod_IntolDefect[iYT][iDef],hProfPeriodLett_IntolDefect[iYT][iDef])
246
247 for iVeto in veto["all"]: # Loop on veto
248 hProfPeriodLett_Veto[iYT][iVeto] = MakeTProfile("hProfPeriodLett_Veto_%s_%s"%(iYT,iVeto),"%s"%(defectVeto["description"][iVeto]),"Lost luminosity [%]", -0.5,+0.5+letperiodNb,letperiodNb+1,defectVeto["color"][iVeto])
249 SetXLabel(hProfPeriodLett_Veto[iYT][iVeto],letperiodList)
250 hProfPeriodLett_Veto[iYT][iVeto].GetXaxis().SetBinLabel(letperiodNb+1,"All") # In all bins, all runs
251 mergeSubPeriod(hProfPeriod_Veto[iYT][iVeto],hProfPeriodLett_Veto[iYT][iVeto])
252 if len(veto["all"]): # Summed inefficiencies
253 hProfPeriodLett_Veto[iYT]["allVeto"] = MakeTProfile("hProfPeriodLett_Veto_%s_allVeto"%iYT,"allVeto","Lost luminosity [%]", -0.5,+0.5+letperiodNb,letperiodNb+1,kBlack)
254 SetXLabel(hProfPeriodLett_Veto[iYT]["allVeto"],letperiodList)
255 hProfPeriodLett_Veto[iYT]["allVeto"].GetXaxis().SetBinLabel(letperiodNb+1,"All") # In all bins, all runs
256 mergeSubPeriod(hProfPeriod_Veto[iYT]["allVeto"],hProfPeriodLett_Veto[iYT]["allVeto"])
257
258 # Merge the subperiod luminosity histograms
259 h1PeriodLett_IntLuminosity[iYT] = MakeTH1("hProfPeriodLett_IntLuminosity_%s"%(iYT),"Period","Luminosity[pb^{-1}]", -0.5,+0.5+letperiodNb,letperiodNb+1,kBlack)
260 SetXLabel(h1PeriodLett_IntLuminosity[iYT],letperiodList)
261 h1PeriodLett_IntLuminosity[iYT].GetXaxis().SetBinLabel(letperiodNb+1,"All") # In all bins, all runs
262 h1PeriodLett_IntLuminosity[iYT].SetTitle("")
263 mergeSubPeriod(h1Period_IntLuminosity[iYT],h1PeriodLett_IntLuminosity[iYT])
264
265 if (not options['noSingleTagPlot']):
266 # Plot the stack for letter periods
267 totalIneffDef = plotStack("defects--%s--%s"%(xAxisTitle,legendHead),hProfPeriodLett_IntolDefect[iYT],defects["intol"],defectVeto["description"],h1PeriodLett_IntLuminosity[iYT],options['lumiNotPercent'],stackResults[iYT],canvasResults[iYT],legendResults[iYT],options['recovPlot'],False,options['approvedPlots'])
268 if options['approvedPlots']:
269 ATLASLabel(0.4,0.8,"Internal")
270 if len(veto["all"]):
271 totalIneffVeto = plotStack("veto--%s--%s"%(xAxisTitle,legendHead),hProfPeriodLett_Veto[iYT],veto["all"],defectVeto["description"],h1PeriodLett_IntLuminosity[iYT],options['lumiNotPercent'],stackResults[iYT],canvasResults[iYT],legendResults[iYT],False,False,options['approvedPlots'])
272 if options['approvedPlots']:
273 ATLASLabel(0.4,0.85,"Internal")
274
275 # And finally the integrated luminosities
276 canvasResults[iYT]['intLumi']= TCanvas( "c_intLumi_%s"%(iYT),"Integrated luminosity per period", 100, 10, 1350, 500)
277 # Same margin as for the stacked results
278 canvasResults[iYT]['intLumi'].SetLeftMargin(0.08)
279 canvasResults[iYT]['intLumi'].SetRightMargin(0.35)
280
281 if (options['plotYearStatsLarge']):
282 h1PeriodLett_IntLuminosity[iYT].Draw("P HIST")
283 h1PeriodLett_IntLuminosity[iYT].LabelsOption("v")
284 h1PeriodLett_IntLuminosity[iYT].GetXaxis().SetTitleOffset(1.45)
285 h1PeriodLett_IntLuminosity[iYT].GetXaxis().SetLabelSize(0.04)
286 for iBin in range(1,h1PeriodLett_IntLuminosity[iYT].GetNbinsX()+1):
287 print(("Period %s: %.3f pb-1"%(h1PeriodLett_IntLuminosity[iYT].GetXaxis().GetBinLabel(iBin),h1PeriodLett_IntLuminosity[iYT].GetBinContent(iBin))))
288 else:
289 h1Period_IntLuminosity[iYT].Draw("P HIST")
290 h1Period_IntLuminosity[iYT].LabelsOption("v")
291 h1Period_IntLuminosity[iYT].GetXaxis().SetTitleOffset(1.45)
292 h1Period_IntLuminosity[iYT].GetXaxis().SetLabelSize(0.04)
293 for iBin in range(1,h1Period_IntLuminosity[iYT].GetNbinsX()+1):
294 print(("Period %s: %.3f pb-1"%(h1Period_IntLuminosity[iYT].GetXaxis().GetBinLabel(iBin),h1Period_IntLuminosity[iYT].GetBinContent(iBin))))
295
296 canvasResults[iYT]['intLumi'].SetGridy(1)
297
298 # On request, save the plots
299 if options["savePlots"]:
300 for iCanvas in list(canvasResults[iYT].keys()):
301 canvasResults[iYT][iCanvas].Update()
302 if ("defects" in iCanvas):
303 canvasResults[iYT][iCanvas].Print("%s/grl-defects.png"%yearTagDir[iYT])
304 if ("veto" in iCanvas):
305 canvasResults[iYT][iCanvas].Print("%s/grl-veto.png"%yearTagDir[iYT])
306 if ("intLumi" in iCanvas):
307 canvasResults[iYT][iCanvas].Print("%s/grl-lumi.png"%yearTagDir[iYT])
308
309# Produce a unique comparison plot between the different year tags (if more than 2)
310if (yearTagNb >= 2 and (options['plotYearStats'] or options['plotYearStatsLarge'])):
311 h1YearTag_IntLuminosity = MakeTH1("h1YearTag_IntLuminosity","Year/Tag","Luminosity[pb^{-1}]", -0.5,-0.5+yearTagNb,yearTagNb,kBlack)
312 SetXLabel(h1YearTag_IntLuminosity,yearTagLabels)
313 for iYT in range(yearTagNb):
314 h1YearTag_IntLuminosity.Fill(iYT,h1Period_IntLuminosity[yearTagList[iYT]].GetBinContent(subperiodNb[yearTagList[iYT]]))
315
316 h1YearTag_IntolDefect = {}
317 for iDef in defects["intol"]+defects["intol_recov"]+allIntolDef:
318 iDefName = iDef.rsplit("__",1)[0] # Trick needed to get the defect name for the recoverable defect histogram
319 h1YearTag_IntolDefect[iDef] = MakeTH1("h1YearTag_IntolDefect_%s"%(iDef),"%s"%(defectVeto["description"][iDefName]),"Lost luminosity [%]", -0.5,-0.5+yearTagNb,yearTagNb,defectVeto["color"][iDefName])
320 SetXLabel(h1YearTag_IntolDefect[iDef],yearTagLabels)
321 for iYT in range(yearTagNb):
322 h1YearTag_IntolDefect[iDef].Fill(iYT,hProfPeriod_IntolDefect[yearTagList[iYT]][iDef].GetBinContent(subperiodNb[yearTagList[iYT]]))
323
324# legendHeader = ""
325 legendHeader = "#splitline{ %s "%(yearTagLabels[0].split("/")[0])
326 for iTag in range(1,yearTagNb):
327 legendHeader += " / %s "%(yearTagLabels[iTag].split("/")[0])
328 legendHeader += "}{Luminos. : %3.1f fb^{-1} "%(h1Period_IntLuminosity[yearTagList[0]].GetBinContent(subperiodNb[yearTagList[0]])/1000.)
329 for iTag in range(1,yearTagNb):
330 legendHeader += "/ %3.1f fb^{-1}"%(h1Period_IntLuminosity[yearTagList[iTag]].GetBinContent(subperiodNb[yearTagList[iTag]])/1000.)
331 legendHeader += "}"
332
333 plotStack("defects--Year--%s"%legendHeader,h1YearTag_IntolDefect,defects["intol"],defectVeto["description"],h1YearTag_IntLuminosity,options['lumiNotPercent'],stackResults,canvasResults,legendResults,False,True,options['approvedPlots'])
334 if options['approvedPlots']:
335 ATLASLabel(0.1,0.85,"Internal")
336 if options["savePlots"]:
337 canvasResults["defects--Year--%s"%legendHeader].Print("%s/YearStats-%s/run2-defects-DQPaper_.png"%(args.parser_directory,args.parser_system))
338 canvasResults["defects--Year--%s"%legendHeader].Print("%s/YearStats-%s/run2-defects-DQPaper_.pdf"%(args.parser_directory,args.parser_system))
339 canvasResults["defects--Year--%s"%legendHeader].Print("%s/YearStats-%s/run2-defects-DQPaper_.eps"%(args.parser_directory,args.parser_system))
340
341 h1YearTag_Veto = {}
342 if (len(veto["all"])):
343 for iVeto in (veto["all"]+["allVeto"]):
344 h1YearTag_Veto[iVeto] = MakeTH1("h1YearTag_Veto_%s"%(iVeto),"%s"%(defectVeto["description"][iVeto]),"Lost luminosity [%]", -0.5,-0.5+yearTagNb,yearTagNb,defectVeto["color"][iVeto])
345 SetXLabel(h1YearTag_Veto[iVeto],yearTagLabels)
346 for iYT in range(yearTagNb):
347 h1YearTag_Veto[iVeto].Fill(iYT,hProfPeriod_Veto[yearTagList[iYT]][iVeto].GetBinContent(subperiodNb[yearTagList[iYT]]))
348
349 if len(veto["all"]):
350 plotStack("veto--Year--%s"%legendHeader,h1YearTag_Veto,veto["all"],defectVeto["description"],h1YearTag_IntLuminosity,options['lumiNotPercent'],stackResults,canvasResults,legendResults,False,True,options['approvedPlots'])
351 if options['approvedPlots']:
352 ATLASLabel(0.1,0.81,"Internal")
353 if options["savePlots"]:
354 canvasResults["veto--Year--%s"%legendHeader].Print("%s/YearStats-%s/run2-veto-DQPaper_.png"%(args.parser_directory,args.parser_system))
355 canvasResults["veto--Year--%s"%legendHeader].Print("%s/YearStats-%s/run2-veto-DQPaper_.pdf"%(args.parser_directory,args.parser_system))
356 canvasResults["veto--Year--%s"%legendHeader].Print("%s/YearStats-%s/run2-veto-DQPaper_.eps"%(args.parser_directory,args.parser_system))
357
358if not args.parser_batchMode:
359 input("I am done. Type <return> to exit...")
void print(char *figname, TCanvas *c1)
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
mergeSubPeriod(tprof_subperiod, tprof_letter)
Definition DeMoStatus.py:31
ATLASLabel(x, y, text="")
ATLASLabel copied from atlastyle package, as import does not work for unknown reasons.
Definition DeMoStatus.py:51