ATLAS Offline Software
Loading...
Searching...
No Matches
DeMoUpdate.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# Queries the defect database, computes and displays the data losses.
7# On request update the year stats.
8#
9# Documentation: https://twiki.cern.ch/twiki/bin/viewauth/Atlas/DataQualityDemo
10
11
12import os, sys, socket, pathlib, errno
13
14import time
15
16from ROOT import TFile
17from ROOT import TH1F,TProfile
18from ROOT import TCanvas,TPaveText
19from ROOT import kBlack,kAzure,kBlue,kGreen,kRed
20from ROOT import gStyle
21from ROOT import gROOT
22from ROOT import TLatex,TText
23gROOT.SetBatch(False)
24
25import xmlrpc.client
26
27sys.path.append("/afs/cern.ch/user/l/larmon/public/prod/Misc")
28from LArMonCoolLib import GetLBTimeStamps,GetOnlineLumiFromCOOL,GetOfflineLumiFromCOOL,GetLBDuration,GetReadyFlag,GetNumberOfCollidingBunches
29
30from DeMoLib import strLumi,plotStack,initializeMonitoredDefects,retrieveYearTagProperties,MakeTH1,MakeTProfile,SetXLabel
31import DQDefects
32
33sys.path.append("/afs/cern.ch/user/l/larcalib/LArDBTools/python/")
34import showEventVeto,showEventVetoNoLumi
35
36from DQUtils import fetch_iovs
37
38global startrun
39global endrun
40
41global debug
42debug = False
43#debug = True
44
45passfile = open("/afs/cern.ch/user/l/larmon/public/atlasdqmpass.txt")
46passwd = passfile.read().strip(); passfile.close()
47dqmapi = xmlrpc.client.ServerProxy('https://%s@atlasdqm.cern.ch'%(passwd))
48
49#scriptdir = str(pathlib.Path(__file__).parent.resolve())
50runListDir = "./YearStats-common"
51
52
53
55def sort_period(text):
56 letter = "".join([i for i in text if not i.isdigit()])
57 number = "".join([i for i in text if i.isdigit()])
58 return (letter, int(number))
59
60def printProp(varname):
61 print("**",varname,"**")
62 if hasattr(sys.modules[__name__],varname):
63 print(getattr(sys.modules[__name__],varname))
64
65
66
67def listify(l):
68 if len(l)==0: return ''
69 elif len(l)==1: return str(l[0])
70 l.sort()
71 interval=False
72 a = ''
73 for i in range(len(l)-1):
74 if interval:
75 if l[i+1]-l[i]==1: pass
76 else: a += str(l[i])+' '; interval=False
77 else:
78 a += str(l[i])
79 if l[i+1]-l[i]==1: a += '-'; interval=True
80 else: a += ' '
81 a += str(l[-1])
82 return a
83
84
85def findLB(lbts,startOfVetoPeriod):
86 # Find the lumiblock where a veto period starts
87 for i in list(lbts.keys()):
88 if (startOfVetoPeriod>lbts[i][0] and startOfVetoPeriod<lbts[i][1]):
89 return i
90 return i
91
92
94def printBoth(string0,boolean,f):
95 # Print and, if the boolean is true, also write to the provided file
96 print(string0)
97 if boolean:# Also write on txt file
98 f.write(string0+'\n')
99 return
100
101def singleRunReport(runNumber,dict1,dict2,directory,defects,veto,exactVetoComput):
102 # Print single run report. Only printing, no computation
103 import string
104
105 runDir = directory+"/Run"
106
107 if dict1['signoff'] == "DONE" or dict1['signoff'] == "FINAL OK":
108 repOnDisk = True
109 f = open(runDir+'/%s.txt' % (runNumber), 'w')
110 else:
111 repOnDisk = False
112 f = open(runDir+'/dummy.txt', 'w')
113
114 printBoth('Run start : %s'%dict1['Start'],repOnDisk,f)
115 printBoth('Run stop : %s'%dict1['Stop'],repOnDisk,f)
116 printBoth('LB with ATLAS ready = %9s'%(listify(dict1["readyLB"])),repOnDisk,f)
117 printBoth('LB with ATLAS ready and no global defect = %9s'%(listify(dict1["readyLB_globalFilter"])),repOnDisk,f)
118 printBoth('Nb of bunches = %d'%(dict1['nBunches']),repOnDisk,f)
119 printBoth('Peak lumi = %.1e'%(dict1['peakLumi']*1e30),repOnDisk,f)
120 printBoth('Integrated luminosity used for normalis. = %s'%(strLumi(dict1['Lumi'],"ub",False,True)),repOnDisk,f)
121 printBoth('%s GRL inefficiency : %.2f%% / %s'%(options["system"],dict1["ineffDefect_allIntol"],strLumi(dict1['Lumi']*dict1["ineffDefect_allIntol"]/100.,"ub",False,True)),repOnDisk,f)
122 for idef in (defects["globIntol"]):
123 if (len(dict2[idef])>0):
124 printBoth('Nb of LBs with %24s: %i -> %.2f%% (%s)'%(defectVeto["description"][idef].ljust(24),len(dict2[idef]),dict1["ineffDefect_%s"%(idef)],str(dict2[idef])),repOnDisk,f)
125 for idef in (defects["partIntol"]):
126 if (len(dict2[idef]["AllPartitions"])>0):
127 printBoth('Nb of LBs with %24s: %i -> %.2f%% (%s)'%(defectVeto["description"][idef].ljust(24),len(dict2[idef]["AllPartitions"]),dict1["ineffDefect_%s"%(idef)],str(dict2[idef]["AllPartitions"])),repOnDisk,f)
128 if len(veto["all"])>0:
129 if exactVetoComput:
130 printBoth('LAr veto inefficiency : %.3f%%'%(dict1["ineffVeto_allVeto"]),repOnDisk,f)
131 else:
132 printBoth('LAr veto inefficiency (rough computat.): %.3f%%'%(dict1["ineffVeto_allVeto"]),repOnDisk,f)
133 for iVeto in veto["all"]:
134 printBoth('%s veto inefficiency : %.3f%%'%(defectVeto["description"][iVeto],dict1["ineffVeto_%s"%(iVeto)]),repOnDisk,f)
135 f.close()
136
137 return
138
139
141def extractNamePartition(foundDefect):
142 # Parse the defect name, return name, partition where available
143 defectName = ""
144 defectPart = ""
145 if (foundDefect.startswith("PIXEL")): # [PIXEL]_[PARTITION]_[NAME]
146 defectSplitted = foundDefect.split("_",2)
147 if len(defectSplitted) > 2:
148 defectPart=defectSplitted[1]
149 defectName=defectSplitted[2]
150 elif (foundDefect.startswith("SCT")): # SCT_[NAME]
151 defectSplitted = foundDefect.split("_",1)
152 if len(defectSplitted) > 1:
153 defectName=defectSplitted[1]
154 elif (foundDefect.startswith("TRT")): # TRT_[NAME]
155 defectSplitted = foundDefect.split("_",1)
156 if len(defectSplitted) > 1:
157 defectName=defectSplitted[1]
158 elif (foundDefect.startswith("LAR")): # [LAR]_[PART]_[Name] or [LAR]_[Name] - No "_" in any [NAME]
159 defectSplitted = foundDefect.split("_",2)
160 if len(defectSplitted) == 2: # LAR_[NAME]
161 defectName=defectSplitted[1]
162 elif len(defectSplitted) == 3: # LAR_[PART]_[NAME]
163 defectPart=defectSplitted[1]
164 defectName=defectSplitted[2]
165 elif (foundDefect.startswith("CALO_ONLINEDB")):# CALO_ONLINEDB_[NAME] (only for CALO_ONLINEDB_LOWMU) - Accounted to LAr
166 defectSplitted = foundDefect.split("_",2)
167 if len(defectSplitted) > 2:
168 defectName=defectSplitted[2]
169 elif (foundDefect.startswith("TILE")): # [TILE]_[PART]_[Name]
170 defectSplitted = foundDefect.split("_",2)
171 if len(defectSplitted) > 2:
172 defectPart=defectSplitted[1]
173 defectName=defectSplitted[2]
174 elif (foundDefect.startswith("MS")): # MS_[SUBDETECTOR]_[PARTITION]_[NAME]
175 defectSplitted = foundDefect.split("_",3)
176 if len(defectSplitted) > 3:
177 systemAffected=defectSplitted[1]
178 defectPart=defectSplitted[2]
179 defectName=defectSplitted[3]
180 elif (foundDefect.startswith("MCP")): # MCP_[NAME]
181 defectSplitted = foundDefect.split("_",1)
182 if len(defectSplitted) > 1:
183 defectName=defectSplitted[1]
184 elif (foundDefect.startswith("ID")):# ID_[NAME]
185 defectSplitted = foundDefect.split("_",1)
186 if len(defectSplitted) > 1:
187 defectName=defectSplitted[1]
188 elif (foundDefect.startswith("JET")):# JET_[NAME]
189 defectSplitted = foundDefect.split("_",1)
190 if len(defectSplitted) > 1:
191 defectName=defectSplitted[1]
192 elif (foundDefect.startswith("MET")):# MET_[NAME]
193 defectSplitted = foundDefect.split("_",1)
194 if len(defectSplitted) > 1:
195 defectName=defectSplitted[1]
196 elif (foundDefect.startswith("EGAMMA")):# EGAMMA_[NAME]_[PART] or EGAMMA_[NAME]
197 if ("BARREL" in foundDefect or "ENDCAP" in foundDefect or "FORWARD" in foundDefect): #EGAMMA_[NAME]_[PART]
198 defectSplitted = foundDefect.split("_",2)
199 if len(defectSplitted) > 2:
200 defectName=defectSplitted[1]
201 defectPart=defectSplitted[2]
202 else:
203 defectSplitted = foundDefect.split("_",1)
204 if len(defectSplitted) > 1:
205 defectName=defectSplitted[1]
206 elif (foundDefect.startswith("TAU")): # TAU_[PART]_[NAME]
207 defectSplitted = foundDefect.split("_",2)
208 if len(defectSplitted) > 2:
209 defectPart=defectSplitted[1]
210 defectName=defectSplitted[2]
211 elif (foundDefect.startswith("CALO")): # CALO_[PART]_[NAME]
212 defectSplitted = foundDefect.split("_",2)
213 if len(defectSplitted) > 2:
214 defectPart=defectSplitted[1]
215 defectName=defectSplitted[2]
216 elif (foundDefect.startswith("BTAG")):# BTAG_[NAME]
217 defectSplitted = foundDefect.split("_",1)
218 if len(defectSplitted) > 1:
219 defectName=defectSplitted[1]
220 elif (foundDefect.startswith("TRIG")): # TRIG_L1_[NAME] TRIG_HLT_[NAME]
221 defectSplitted = foundDefect.split("_",2)
222 if len(defectSplitted) > 2:
223 defectName=defectSplitted[2]
224 elif (foundDefect.startswith("LUMI")): # LUMI_[NAME]
225 defectSplitted = foundDefect.split("_",1)
226 if len(defectSplitted) > 1:
227 defectName=defectSplitted[1]
228 elif (foundDefect.startswith("ALFA")): # ALFA_[NAME]
229 defectSplitted = foundDefect.split("_",1)
230 if len(defectSplitted) > 1:
231 defectName=defectSplitted[1]
232 elif (foundDefect.startswith("AFP")): # AFP_[NAME] or AFP_[PART]_[NAME]
233 if ("_A_" in foundDefect or "_C_" in foundDefect): #AFP_[PART]_[NAME]
234 defectSplitted = foundDefect.split("_",2)
235 if len(defectSplitted) > 2:
236 defectName=defectSplitted[2]
237 defectPart=defectSplitted[1]
238 if ("_A_NEAR_" in foundDefect or "_C_NEAR_" in foundDefect or "_A_FAR_" in foundDefect or "_C_FAR_" in foundDefect): #AFP_[PART]_[NEAR/FAR]_[NAME]
239 defectSplitted = foundDefect.split("_",3)
240 if len(defectSplitted) > 3:
241 defectName=defectSplitted[3]
242 defectPart="%s_%s"%(defectSplitted[1],defectSplitted[2])
243 else:
244 defectSplitted = foundDefect.split("_",1)
245 if len(defectSplitted) > 1:
246 defectName=defectSplitted[1]
247 elif (foundDefect.startswith("LCD")): # LCD_[NAME]
248 defectSplitted = foundDefect.split("_",1)
249 if len(defectSplitted) > 1:
250 defectName=defectSplitted[1]
251 elif (foundDefect.startswith("ZDC")): # ZDC_[NAME]
252 defectSplitted = foundDefect.split("_",1)
253 if len(defectSplitted) > 1:
254 defectName=defectSplitted[1]
255 elif (foundDefect.startswith("GLOBAL")): # GLOBAL_[NAME]
256 defectSplitted = foundDefect.split("_",1)
257 if len(defectSplitted) > 1:
258 defectName=defectSplitted[1]
259
260 return defectName, defectPart
261
262def retrieveDefectsFromDB(run, defectTag, grlDef,signOffDefects):
263 # Get the list of defects for this run, parse them
264 defectDatabase = DQDefects.DefectsDB(tag=defectTag)
265 system_defects = []
266 for iPrefix in grlDef["prefix"]:
267 system_defects += [d for d in (defectDatabase.defect_names | defectDatabase.virtual_defect_names) if (d.startswith(iPrefix))]
268 for iSignOff in signOffDefects.keys():
269 if (signOffDefects[iSignOff] != ""):
270 system_defects += signOffDefects[iSignOff]
271 retrievedDefects = defectDatabase.retrieve((run, 1), (run+1, 0), system_defects)
272 parsed_defects = {}
273 for rd in retrievedDefects:
274 defectName, defectPart = extractNamePartition(rd.channel)
275 if not( defectName is None and defectName is None):
276 parsed_defects[rd] = [defectName, defectPart]
277 return parsed_defects
278
279
281def updateRunList(year=time.localtime().tm_year):
282 # Update list of runs. If there is not an up-to-date file, get the latest info from the atlas dqm APIs'''
283 print("Checking run list for year",year)
284
285 latestRun=dqmapi.get_latest_run()
286 recentRuns = dqmapi.get_run_beamluminfo({'low_run':str(latestRun-1000),'high_run':str(latestRun)})
287 def writeRuns(outfile, fileRuns = []):
288 for r in sorted(recentRuns.keys(), key=int):
289 if (recentRuns[r][2]): # ATLAS ready
290 if r not in fileRuns:
291 fileRuns.append(r)
292 print("Adding the ATLAS ready run: %s"%r)
293 outfile.write("%s\n"%r)
294 allRunListDat = "%s/%s/runlist-%s-AtlasReady.dat"%(runListDir,str(year),str(year))
295 if os.path.isfile(allRunListDat):
296 fRunList = open(allRunListDat,'r+')
297 fileRuns = [l.strip() for l in fRunList.readlines() ]
298 if len(fileRuns)>0:
299 latestFileRun = max([int(r) for r in fileRuns])
300 else: latestFileRun = 0
301 if latestFileRun < latestRun:
302 print("Run file",allRunListDat,"is not up-to-date")
303 print("Latest run is ",latestRun, " while latest run in file is",latestFileRun)
304 print("Will check ATLAS ready filters & update if needed")
305 writeRuns(fRunList, fileRuns)
306 fRunList.close()
307 sys.exit()
308 else:
309 print("The run list for year ",year," is not available... please create one by hand")
310 sys.exit()
311
312
314def getRunInfo(runlist, defectTag="HEAD"):
315 # Retrieve run characteristics (period, time...)
316 possSignoffDefects = sum(list(signOff.values()),[])
317 run_signoffDefects = dqmapi.get_defects_lb({'run_list':runlist},possSignoffDefects,defectTag,True,True)
318
319 infokeys = ["Run type", "Project tag", "Partition name", "Number of events passing Event Filter", "Run start", "Run end", "Number of luminosity blocks", "Data source", "Detector mask", "Recording enabled", "Number of events in physics streams" ]
320
321 defectvals = [ "startlb", "endlb", "status", "time"]
322
323 beamkeys = ["Max beam energy during run", "Stable beam flag enabled during run", "ATLAS ready flag enabled during run", "Total integrated luminosity", "ATLAS ready luminosity (/nb)"]
324
325 for rd in run_signoffDefects.keys():
326 for defect in run_signoffDefects[rd].keys():
327 run_signoffDefects[rd][defect] = { ik:li for ik,li in zip(defectvals,run_signoffDefects[rd][defect][0]) }
328
329 run_spec = {'run_list':runlist, 'stream': 'physics_CosmicCalo', 'source': 'tier0'}
330 run_info = dqmapi.get_run_information(run_spec)
331 for ri in run_info.keys():
332 run_info[ri] = { ik:li for ik,li in zip(infokeys,run_info[ri]) }
333
334 beam_info = dqmapi.get_run_beamluminfo(run_spec)
335 for bi in beam_info.keys():
336 beam_info[bi] = { ik:li for ik,li in zip(beamkeys,beam_info[bi]) }
337
338 run_periods = dqmapi.get_data_periods({'run_list':runlist})
339 allinfo = {}
340 def addDetails(inputDict, col=None):
341 for r in inputDict.keys():
342 run = int(r)
343 if run not in allinfo.keys():
344 allinfo[run] = {}
345 if col is not None:
346 allinfo[run][col] = inputDict[r]
347 else:
348 allinfo[run].update(inputDict[r])
349 addDetails(run_info)
350 addDetails(beam_info)
351 addDetails(run_periods, "periods")
352 addDetails(run_signoffDefects, "signoffDefects")
353
354 # only take first period??
355 for r in allinfo.keys():
356 try:
357 allinfo[r]["period"] = allinfo[r]["periods"][0]
358 except IndexError:
359 print("Weird list of periods for",r,":",allinfo[r]["periods"])
360 allinfo[r]["period"]="?"
361
362
363 return allinfo
364
365
366
369from argparse import RawTextHelpFormatter,ArgumentParser
370
371parser = ArgumentParser(description='',formatter_class=RawTextHelpFormatter)
372# General arguments
373parser.add_argument('-y','--year',dest='year',default = str(time.localtime().tm_year),help='Year [Default: '+str(time.localtime().tm_year)+']. May also include special conditions such as 5TeV, hi...',action='store')
374parser.add_argument('-t','--tag',dest='tag',default = "AtlasReady",help='Defect tag [Default: "AtlasReady"]',action='store')
375parser.add_argument('-s','--system',dest='system',default="LAr",help='System: LAr, Pixel, IDGlobal, RPC... [Default: "LAr"]',action='store')
376parser.add_argument('-b','--batch',dest='batchMode',help='Batch mode',action='store_true')
377# Different options.
378parser.add_argument('--runListUpdate',dest='runListUpdate',help='Update of the run list for the AtlasReady tag. No other action allowed. Exit when done.',action='store_true')
379parser.add_argument('--weeklyReport',dest='weekly',help='Weekly report. No run range to specify, no year-stats update.',action='store_true')
380# Selection of runs to be considered
381parser.add_argument('--runRange',type=int,dest='runRange',default=[],help='Run or run range (in addition to RunList)',nargs='*',action='store')
382parser.add_argument('--skipAlreadyUpdated',dest='skipAlreadyUpdated',help='Ignore completely runs that are already included in year stats',action='store_true')
383parser.add_argument('--noGlobalFilter',dest='noGlobalFilter',help='Switch off the primary filter based on GLOBAL defects. So far, the global defects used are: "GLOBAL_LHC_50NS","GLOBAL_LHC_NONSTANDARD_BC","GLOBAL_LHC_LOW_N_BUNCHES","GLOBAL_LHC_NOBUNCHTRAIN","GLOBAL_LHC_COMMISSIONING","GLOBAL_LHC_HIGHBETA","GLOBAL_LOWMUCONFIG_IN_HIGHMU","LUMI_VDM","GLOBAL_NOTCONSIDERED (defined in DeMoLib.py)"',action='store_true')
384# Option related to year stats
385parser.add_argument('--resetYearStats',dest='resetYearStats',help='Reset year stats. To be used only the incremental update can not be used (for example, when runs were removed or when a defect of an already signed off run was changed)',action='store_true')
386parser.add_argument('--updateYearStats',dest='updateYearStats',help='Update year stats with the new runs fully signed off',action='store_true')
387# Veto options (relevant only for LAr)
388parser.add_argument('--noVeto',dest='noVeto',help='Do not consider time-veto information',action='store_true')
389parser.add_argument('--vetoLumiEvol',dest='vetoLumiEvolution',help='Plot the evolution of veto as a function of lumi',action='store_true')
390parser.add_argument('--roughVetoComput',dest='exactVetoComput',help='Rough veto computation (no lumi weighting,no correlation with intol defect.)',action='store_false')
391# Plotting, saving
392parser.add_argument('--noPlot',dest='plotResults',help='Do not plot the results',action='store_false')
393parser.add_argument('--saveHistos',dest='saveHistos',help='Save all histograms (NOT needed for year stats)',action='store_true')
394parser.add_argument('--savePlots',dest='savePlots',help='Save all plots in Weekly dir',action='store_true')
395# Characteristics of luminosity used for nirmalisation
396parser.add_argument('--deliveredLumiNorm',dest='deliveredLumiNorm',help='Normalize by the delivered lumi',action='store_true')
397parser.add_argument('--onlineLumiNorm',dest='onlineLumiNorm',help='Normalize by the online lumi',action='store_true')
398
399
400args = parser.parse_args()
401# parser.print_help()
402
403if args.batchMode:
404 gROOT.SetBatch(True)
405
406print("Current time: %s"%(time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())))
407print("Currently running from",os.getcwd(),"on",socket.gethostname())
408options = {}
409yearTagProperties = {}
410partitions = {}
411grlDef = {}
412defectVeto = {}
413veto = {}
414signOff = {}
415runlist = {'filename':"",'primary':[],'toprocess':[],'weeklyfile':[],'weekly-dqmeeting':"",'roughVeto':[]}
416
417if args.runListUpdate:
418 updateRunList(year=args.year)
419 print("Done.I am exiting...")
420 sys.exit()
421
422options = args.__dict__
423initializeMonitoredDefects(options['system'],partitions,grlDef,defectVeto,veto,signOff,options['year'],options['tag'],runlist)
424yearTagProperties = retrieveYearTagProperties(options['year'],options['tag'])
425
426if debug:
427 printProp("yearTagProperties")
428 printProp("partitions")
429 printProp("grlDef")
430 printProp("defectVeto")
431 printProp("veto")
432 printProp("signOff")
433
434# Choose between recorded and delivered luminosity - By default, use the delivered one
435options['recordedLumiNorm'] = not options['deliveredLumiNorm']
436# tag to access defect database and COOL database (for veto windows) - Defined in DeMoLib.py
437options['defectTag']=yearTagProperties["Defect tag"]
438if len(yearTagProperties["Veto tag"])>0: # The veto tag is not defined for all systems
439 options['vetoTag']=yearTagProperties["Veto tag"]
440else:
441 options['vetoTag']=""
442options['yearStatsDir'] = "YearStats-%s/%s/%s"%(options['system'],options['year'],options['tag'])
443
444# No run range active, no update years stats, no filter... in weekly report
445if (options['weekly']):
446 options['tag'] = "AtlasReady" # Weekly reports are relevant only for the AtlasReady tag
447 options['updateYearStats'] = False
448 options['runRange'] = []
449
450# Token to avoid having multiple yearStats update in the same time
451if options['updateYearStats']:
452 tokenName = "DeMo-%s-%s-%s.token"%(options['system'],options['year'],options['tag'])
453 if os.path.exists(tokenName):
454 print("A different DeMoUpdate is apparently running (or it was not properly ended recently). This may cause trouble when updating yearStats")
455 os.system("ls -ltr %s"%tokenName)
456 print("If you are sure that it is not the case, you can remove the %s..."%tokenName)
457 print("If you are not the owner, contact the DQ coordinator")
458 sys.exit()
459 else:
460 os.system("touch %s"%tokenName)
461
462startrun = 0
463endrun = 1e12
464if len(options['runRange']) == 1: # Single run
465 startrun = options['runRange'][0]
466 endrun = options['runRange'][0]
467if len(options['runRange']) == 2: # Run range
468 startrun = options['runRange'][0]
469 endrun = options['runRange'][1]
470
471# runlist['primary'] contains all runs extracted from the runList convoluted with the run range (if any was defined - not mandatory - Deactivated for weeklyReport)
472# runlist['toprocess'] is derived from the primary list. Some runs may be removed depending on the options (skipAlreadyUpdated) and also for the weekly report (see below)
473# runlist['toprocess'] contains all run that will be processed and that will be displayed in the final table / plots
474runListFilename = "%s/%s/%s"%(runListDir,options['year'],runlist['filename'])
475if os.path.exists(runListFilename):
476 fRunList = open(runListFilename,'r')
477 for iRun in fRunList.readlines():
478 if (int(iRun) >= startrun and int(iRun) <= endrun):
479 runlist['primary'].append(int(iRun))
480 fRunList.close()
481else:
482 print("The %s file does not exist. Create it or choose a different tag."%runListFilename)
483 sys.exit()
484
485if (len(runlist['primary']) == 0):
486 print("No run found -> Exiting")
487 sys.exit()
488
489roughVetoFilename = runListDir+"/%s/%s/roughVeto-%s.dat"%(options['system'],options['year'],options['year'])
490if os.path.exists(roughVetoFilename):
491 fRoughVeto = open(roughVetoFilename,'r')
492 for iRun in fRoughVeto.readlines():
493 runlist['roughVeto'].append(int(iRun))
494 fRoughVeto.close()
495
496if len(veto["all"]) == 0:
497 options['noVeto'] = True
498 print("No veto information provided in DeMoLib.py")
499else:
500 if options['noVeto']:
501 print("WARNING: I do not consider time veto information...")
502
503yearStatsArchiveFilename = '%s/TProfiles.root'%options['yearStatsDir']
504if options['updateYearStats']:
505 if not os.path.exists(yearStatsArchiveFilename):
506 print("No archive file found in %s"%options['yearStatsDir'])
507 print("I am forcing the year stats reset...")
508 options['resetYearStats'] = True
509 elif os.path.getsize("%s/runs-ALL.dat"%options['yearStatsDir']) == 0.:
510 # Test here relevant at the beginning of the year when some runs have been reviewed at EXPR/BULK level (but not FINAL hence no year stats)
511 # In such a case a TProfiles.root file may exist even if no update was made
512 # April 18: I am not sure that this situation is still relevant...
513 print("No run found in %s"%options['yearStatsDir'])
514 print("I am forcing the year stats reset...")
515 options['resetYearStats'] = True
516
517# Reseting the year stats - Allowed even if updateYearStats not requested
518if options['resetYearStats']:
519 print("WARNING: I am going to reset the %s stats..."%options['yearStatsDir'])
520 if (options['batchMode']): # In batch mode, no confirmation requested
521 confirm = "y"
522 else:
523 confirm = input("Please confirm by typing y: ")
524
525 if ("y" in confirm):
526 print("I reset the %s stats"%options['yearStatsDir'])
527 os.system("rm -f %s/lumi*.dat"%options['yearStatsDir'])
528 os.system("rm -f %s/runs*.dat"%options['yearStatsDir'])
529 os.system("rm -f %s/errors.log"%options['yearStatsDir'])
530 os.system("rm -f %s/loss*.dat"%options['yearStatsDir'])
531 os.system("rm -f %s/Run/*.txt"%options['yearStatsDir'])
532 os.system("rm -f %s"%(yearStatsArchiveFilename))
533 fLastReset = open("%s/lastResetYS.dat"%options['yearStatsDir'],"w")
534 fLastReset.write("%s\n"%(time.strftime("%a, %d %b %H:%M",time.localtime())))
535 fLastReset.close()
536
537# Open log file : errors and not yet signed off runs
538errorLogFile = open("%s/errors.log"%options['yearStatsDir'],'a')
539notYetSignedOffRuns = open('%s/runs-notYetSignedOff.dat'%options['yearStatsDir'],'w')
540
541# Retrieve all characteristics of the runs of the primary list (start, end, nb of LB, ATLAS ready LB...)x
542runinfo = getRunInfo(runlist['primary'],options['defectTag'])
543
544# If the run is too recent (< 2 hours) or still ongoing, remove it from the runlist['primary']
545for run in runlist['primary']:
546 if runinfo[run]["Run end"] == 0:
547 print("Run",run,"is still ongoing")
548 runinfo.pop(run)
549 runlist['primary'].pop(runlist['primary'].index(run))
550 if (time.time() - runinfo[run]["Run end"])/3600 < 2:
551 print("Run",run,"ended very recently. It is best to wait for the defects DBs to properly populate")
552 runinfo.pop(run)
553 runlist['primary'].pop(runlist['primary'].index(run))
554
555# Fill the list of runs to be considered
556oldRunsNotYetignedOff = []
557if options['weekly']: # Weekly report - Look for the last 7-days runs + the signed off runs in the last 7 days
558 print("===== Weekly =====")
559 print("I am looking for all runs taken or signed off in the past week...")
560 options['savePlots'] = True
561 options['updateYearStats'] = False
562 oneWeek = 7*24*3600 # Nb of seconds in one week
563 for run in sorted(runlist['primary'], key=int, reverse=True):
564 if "signoffDefects" not in runinfo[run].keys():
565 print("Run",run, "has no defects... perhaps it is still ongoing?")
566 continue
567 defects = runinfo[run]["signoffDefects"].keys()
568 statuses = [ runinfo[run]["signoffDefects"][d]["status"] for d in defects ]
569
570 fullySignedOff = True
571 if any('Red' in s for s in statuses):
572 fullySignedOff = False
573 if (time.time()-runinfo[run]["Run start"] > oneWeek):
574 oldRunsNotYetignedOff.append(run)
575
576 signOffTime = 0
577 if any('Green' in s for s in statuses):
578 signOffTime = max([ runinfo[run]["signoffDefects"][d]["time"] for d in defects if runinfo[run]["signoffDefects"][d]["status"] == "Green" ] )
579 if (fullySignedOff and time.time()-signOffTime < oneWeek):
580 print("Old run",run,"was fully signed off during the last seven days")
581 runlist['toprocess'].append(run)
582 elif (time.time()-runinfo[run]["Run start"] < oneWeek):
583 print("Run",run,"was acquired during the last seven days")
584 runlist['toprocess'].append(run)
585 if (os.path.exists("%s/%s/runlist-weekly.dat"%(runListDir,options['year']))):
586 weeklyFile = open("%s/%s/runlist-weekly.dat"%(runListDir,options['year']),'r')
587 print("I found a runlist-weekly.dat file and will add some runs...")
588 for iRun in weeklyFile.readlines():
589 if runlist['weekly-dqmeeting'] == "": # The first line of the weekly file contains the date of the DQ meeting
590 runlist['weekly-dqmeeting'] = iRun
591 continue
592 runlist['weeklyfile'].append(int(iRun))
593 if (int(iRun) not in runlist['toprocess'] and int(iRun) in runlist['primary']):
594 print(iRun)
595 runlist['toprocess'].append(int(iRun))
596 weeklyFile.close()
597
598 runlist['toprocess'].sort(reverse=False)
599 print("I will process these runs :",runlist['toprocess'])
600else: # Default option (i.e. not a weekly report). The possible run range was already filtered in the runlist['primary'] list
601 runlist['toprocess'] = runlist['primary']
602
603if len(runlist['toprocess']) == 0:
604 print("No run to process")
605 print("Please double check your run range (if any) or update the runlist file...")
606 if options['updateYearStats']:
607 os.system("rm -f %s"%tokenName)
608 sys.exit()
609
610periodListCurrent = {} # Dictionary of all runs referenced by period name
611newPeriodInYearStats = [] # List of periods not yet considered
612bool_newRunsInYearStats = False
613
614allperiods_full = list(set([ p for irun in runlist['toprocess'] for p in runinfo[irun]["periods"] ])) # should we just take the first period listed??
615allperiods = list(set([runinfo[irun]["period"] for irun in runlist['toprocess'] if runinfo[irun]["period"] != "?"])) # should we just take the first period listed??
616print("Periods (full)", allperiods_full)
617print("Periods",allperiods)
618for p in allperiods:
619 for run in runlist['toprocess']:
620 if run in runinfo.keys() and p in runinfo[run]["periods"]:
621 if p not in periodListCurrent:
622 periodListCurrent[p] = [run]
623 else:
624 periodListCurrent[p].append(run)
625
626if (len(allperiods) == 0 and options['updateYearStats']):
627 print("No period available yet for the runs to process")
628 print("I am exiting...")
629 if options['updateYearStats']:
630 os.system("rm -f %s"%tokenName)
631 sys.exit()
632
633for irun in runinfo.keys():
634 runinfo[irun]['newInYearStats'] = False
635
636for iper in allperiods:
637 periodFileName = "%s/runs-%s.dat"%(options['yearStatsDir'],iper)
638 if os.path.exists(periodFileName): # This period is already treated in year stats. Look for new runs
639 f = open(periodFileName,'r')
640 existingRuns = f.readlines()
641 for irun in periodListCurrent[iper]:
642 if (options['updateYearStats'] and "%d\n"%(irun) not in existingRuns):
643 runinfo[irun]['newInYearStats'] = True
644 else:
645 runinfo[irun]['newInYearStats'] = False
646 f.close()
647 else: # This is a period not yet treated in year stats.
648 periodToBeAdded = False
649 for irun in periodListCurrent[iper]:
650 if options['updateYearStats']:
651 runinfo[irun]['newInYearStats'] = True
652 periodToBeAdded = True
653 else:
654 runinfo[irun]['newInYearStats'] = False
655 if options['updateYearStats'] and periodToBeAdded:
656 print("I am going to add period %s in year stats!"%(iper))
657 newPeriodInYearStats.append(iper)
658
659for iper in list(periodListCurrent.keys()): # Loop on all periods found and print the runs to be updated
660 for irun in periodListCurrent[iper]:
661 if runinfo[irun]['newInYearStats']:
662 print("I am going to add run %d (period %s) in %s stats (provided that it is fully signed off - Not yet known...)!"%(irun,runinfo[irun]['period'],options['year']))
663 else:
664 if (options['skipAlreadyUpdated']):
665 runinfo.pop(irun)
666 runlist['toprocess'].pop(runlist['toprocess'].index(irun))
667 print("%d was already processed in yearStats - I am complety skipping it..."%(irun))
668
669if (len(runlist['toprocess']) == 0):
670 print("No run to process :-). Exiting...")
671 if options['updateYearStats']:
672 os.system("rm -f %s"%tokenName)
673 sys.exit()
674
675
676
677runinfo['AllRuns'] = {}
678runinfo['AllRuns']['Start'] = "-"
679runinfo['AllRuns']['Stop'] = "-"
680runinfo['AllRuns']['readyLB'] = "-"
681runinfo['AllRuns']['readyLB_globalFilter'] = "-"
682runinfo['AllRuns']['peakLumi'] = 0.
683runinfo['AllRuns']['period'] = "-"
684runinfo['AllRuns']['signoff'] = "-"
685
686
689hProfRun_IntolDefect = {}
690hProfRun_Veto = {}
691
692if (options['updateYearStats']):
693 hProfPeriod_IntolDefect = {}
694 hProfPeriod_Veto = {}
695
696allIntolDef = ["allIntol","allIntol_recov"] # New histograms defined to avoid double counting
697
698for idef in grlDef["intol"]+grlDef["intol_recov"]+allIntolDef: #Intolerable defects only
699 idefName = idef.split("__")[0] # Trick needed to get the defect name for the recoverable defect histogram
700 # Histogram of defect ineffiency per run
701 hProfRun_IntolDefect[idef] = MakeTProfile("hProfRun_Defect_%s"%(idef),"%s"%(defectVeto["description"][idefName]),"Lost luminosity (%)", -0.5,+0.5+len(runlist['toprocess']),len(runlist['toprocess'])+1,defectVeto["color"][idefName])
702 SetXLabel(hProfRun_IntolDefect[idef],runlist['toprocess'])
703 hProfRun_IntolDefect[idef].GetXaxis().SetBinLabel(len(runlist['toprocess'])+1,"All")
704 # If an update of year stats is requested, define empty histograms, retrieve the already known periods and fill the new histos
705 if (options['updateYearStats']):
706 periodListYear = [] # This is the period list used for the TProfile
707 profPeriodName = "hProfPeriod_IntolDefect_%s"%(idef)
708 if (not options['resetYearStats']): # Retrieve the already known period
709 file = TFile(yearStatsArchiveFilename)
710 hProfPeriod_archive = file.Get("%s_archive"%(profPeriodName))
711 for iBin in range(1,hProfPeriod_archive.GetNbinsX()): # Retrieve name of past periods
712 periodListYear.append(hProfPeriod_archive.GetXaxis().GetBinLabel(iBin))
713 file.Close()
714
715 if len(periodListYear) != 0 or len(periodListCurrent) != 0: # At least one period found in current or past runs, otherwise no way to plot year stats
716 # Collect all periods (archived ones + new ones)
717 periodListYear = periodListYear + newPeriodInYearStats
718 periodListYear = sorted(periodListYear, key=sort_period) # The list of periods is now sorted
719 periodNbYear = len(periodListYear) # Number of periods
720 # Create the empty year stats TProfile histograms for the updated period list
721 hProfPeriod_IntolDefect[idef] = MakeTProfile(profPeriodName,"%s"%(defectVeto["description"][idefName]),"Lost luminosity (%)", -0.5,+0.5+periodNbYear,periodNbYear+1,defectVeto["color"][idefName])
722 SetXLabel(hProfPeriod_IntolDefect[idef],periodListYear)
723 hProfPeriod_IntolDefect[idef].GetXaxis().SetBinLabel(periodNbYear+1,"All") # In all bins, all runs
724 # Fill them with the previous period data
725 if (not options['resetYearStats']):
726 file = TFile(yearStatsArchiveFilename)
727 hProfPeriod_archive = file.Get("%s_archive"%(profPeriodName))
728 for iBin in range(1,periodNbYear+1): # Loop on all extended periods and check if already considered in past runs - Mandatory as periodListYear was sorted
729 for iBin2 in range(1,hProfPeriod_archive.GetNbinsX()):
730 if (hProfPeriod_IntolDefect[idef].GetXaxis().GetBinLabel(iBin) == hProfPeriod_archive.GetXaxis().GetBinLabel(iBin2)):
731 hProfPeriod_IntolDefect[idef].Fill(iBin-1,hProfPeriod_archive.GetBinContent(iBin2),hProfPeriod_archive.GetBinEntries(iBin2))
732 # And the last bin for all periods
733 hProfPeriod_IntolDefect[idef].Fill(len(periodListYear),hProfPeriod_archive.GetBinContent(hProfPeriod_archive.GetNbinsX()),hProfPeriod_archive.GetBinEntries(hProfPeriod_archive.GetNbinsX()))
734 file.Close()
735
736# Book histograms for time window veto
737if (not options['noVeto']):
738 for iVeto in veto["all"]+["allVeto"]: # New "allVeto" histograms defined similarly as for defect - Not sure how to deal with double counting in veto but not problematic at first order.
739 hProfRun_Veto[iVeto] = MakeTProfile("hProfRun_Veto_%s"%(iVeto),"","Inefficiency - Time veto (%)",-0.5,+0.5+len(runlist['toprocess']),len(runlist['toprocess'])+1,defectVeto["color"][iVeto])
740 hProfRun_Veto[iVeto].SetMarkerColor(defectVeto["color"][iVeto])
741 SetXLabel(hProfRun_Veto[iVeto],runlist['toprocess'])
742 hProfRun_Veto[iVeto].GetXaxis().SetBinLabel(len(runlist['toprocess'])+1,"All")
743
744 if (options['updateYearStats']):
745 profPeriodName = "hProfPeriod_Veto_%s"%(iVeto)
746 # Create the period TProfile - The extended period list is the same as for the defects
747 hProfPeriod_Veto[iVeto] = MakeTProfile(profPeriodName,"","Inefficiency - Time veto (%%) %s"%(defectVeto["description"][iVeto]), -0.5,+0.5+len(periodListYear),len(periodListYear)+1,defectVeto["color"][iVeto])
748 hProfPeriod_Veto[iVeto].SetMarkerColor(defectVeto["color"][iVeto])
749 SetXLabel(hProfPeriod_Veto[iVeto],periodListYear)
750 hProfPeriod_Veto[iVeto].GetXaxis().SetBinLabel(len(periodListYear)+1,"All")
751
752 if (not options['resetYearStats']): # Fill with the previous period data
753 file = TFile(yearStatsArchiveFilename)
754 hProfPeriod_archive = file.Get("%s_archive"%(profPeriodName))
755 for iBin in range(1,periodNbYear+1): # Loop on all extended periods and check if already considered in past runs - Mandatory as periodListYear was sorted
756 for iBin2 in range(1,hProfPeriod_archive.GetNbinsX()):
757 if (hProfPeriod_Veto[iVeto].GetXaxis().GetBinLabel(iBin) == hProfPeriod_archive.GetXaxis().GetBinLabel(iBin2)):
758 hProfPeriod_Veto[iVeto].Fill(iBin-1,hProfPeriod_archive.GetBinContent(iBin2),hProfPeriod_archive.GetBinEntries(iBin2))
759 # And the last bin for all periods
760 hProfPeriod_Veto[iVeto].Fill(len(periodListYear),hProfPeriod_archive.GetBinContent(hProfPeriod_archive.GetNbinsX()),hProfPeriod_archive.GetBinEntries(hProfPeriod_archive.GetNbinsX()))
761 file.Close()
762
763h1Run_IntLuminosity = MakeTH1("h1_IntLumi","Run","Integrated luminosity", -0.5,+0.5+len(runlist['toprocess']),len(runlist['toprocess'])+1,kBlack)
764SetXLabel(h1Run_IntLuminosity,runlist['toprocess'])
765h1Run_IntLuminosity.GetXaxis().SetBinLabel(len(runlist['toprocess'])+1,"All")
766
767
768if (options['updateYearStats'] and periodNbYear>0): # If update is required, it is now sure that some periods exist. Create a TH1 to store the integrated luminosity
769 h1Per_IntLumi = MakeTH1("periodLuminosity","Period","Luminosity(pb-1)",-0.5,+0.5+periodNbYear,periodNbYear+1,1)
770 h1Per_IntLumi.SetTitle("")
771 SetXLabel(h1Per_IntLumi,periodListYear)
772 h1Per_IntLumi.GetXaxis().SetBinLabel(periodNbYear+1,"All")
773
774 for iBin in range(1,hProfPeriod_IntolDefect[idef].GetNbinsX()+1): # No matter what is idef, we just need the number of entries per bin to get the luminosity of past periods
775 h1Per_IntLumi.Fill(iBin-1,hProfPeriod_IntolDefect[idef].GetBinEntries(iBin)/1e6)
776
777
778
780if options['vetoLumiEvolution']:
781 h1_vetoInstLumiEvol = {}
782 h1_vetoInstLumiEvol['NoVeto'] = MakeTH1("LuminosityProfile","Instantaneous luminosity (10^{33} cm^{-2}s^{-1})","Time length (s)",4,19,60,1)
783 for iVeto in veto["all"]:
784 h1_vetoInstLumiEvol[iVeto] = MakeTH1("LuminosityVeto_%s"%(iVeto),"Instantaneous luminosity (10^{33} cm^{-2}s^{-1}) - Runs %d-%d"%(runlist['toprocess'][0],runlist['toprocess'][-1]),"#splitline{Inefficiency Time Veto}{(%s) [percent]}"%(defectVeto["description"][iVeto]),4,19,60,1)
785
786
787
789runinfo['AllRuns']['Lumi'] = 0. # Total luminosity
790for idef in (grlDef["tol"]+grlDef["intol"]+grlDef["intol_recov"]+allIntolDef):
791 runinfo['AllRuns']['lumiDefect_%s'%(idef)] = 0.
792 runinfo['AllRuns']['ineffDefect_%s'%(idef)] = 0.
793
794for iVeto in veto["all"]+["allVeto"]:
795 runinfo['AllRuns']['lumiVeto_%s'%iVeto] = 0. # Total luminosity rejected by each time veto
796 runinfo['AllRuns']['ineffVeto_%s'%iVeto] = 0. # Overall inefficiency due to each time veto
797
798if (len(list(runinfo.keys())) == 1):
799 print("I did not find any run in runList.")
800 print("Please check the run range/options")
801
802print("I will use the following defect/veto tags:%s %s"%(options['defectTag'],options['vetoTag']))
803
804
806for irun,runNb in enumerate(runlist['toprocess']):
807 print("=================================================================")
808 print("=============================Run %d (%d/%d)======================"%(runNb,irun+1,len(runlist['toprocess'])))
809
810 # Init variables - List (indexed by partition) of tables of lumi blocks affected by defects
811 lbAffected = {}
812 for idef in grlDef["part"]+grlDef["partIntol_recov"]: # All partition defects
813 lbAffected[idef] = {}
814 lbAffected[idef]["AllPartitions"] = []
815 for idef in grlDef["glob"]+grlDef["globIntol_recov"]: # All global defects
816 lbAffected[idef] = [] # Global defect - Simple list and not dictionnary
817
818 lbAffected['allIntol'] = [] # List of LBs affected with intolerable defect independant of the defect/partition
819 lbAffected['allIntol_recov'] = [] # List of LBs affected with intolerable recoverable defect independant of the defect/partition
820 lbAffected['allIntol_irrecov'] = [] # List of LBs affected with intolerable irrecoverable defect independant of the defect/partition
821
822
823 boolExactVetoComput_run = (options['exactVetoComput']) and (runNb not in runlist['roughVeto'])
824
825 # Start retrieving the general characteristics of the run
826 # Get run infos
827 # Luminosity blocks UTC timestamps
828 v_lbTimeSt = GetLBTimeStamps(runNb)
829 runinfo[runNb]['Start'] = time.strftime("%a, %d %b %H:%M",time.localtime(v_lbTimeSt[1][0]))
830 runinfo[runNb]['Stop'] = time.strftime("%a, %d %b %H:%M",time.localtime(v_lbTimeSt[len(v_lbTimeSt)][1]))
831 runinfo[runNb]['nBunches'] = GetNumberOfCollidingBunches(runNb)
832 # Number of luminosity blocks
833 runinfo[runNb]['nLB'] = len(v_lbTimeSt)
834
835 defectDatabase = DQDefects.DefectsDB(tag=options['defectTag'])
836 # Treatement of global filter
837 globalFilterLB = []
838 runinfo[runNb]['globalFilter'] = False
839 runinfo["AllRuns"]['globalFilter'] = False
840 if not options['noGlobalFilter']:
841 retrievedDefects = defectDatabase.retrieve((runNb, 1), (runNb, runinfo[runNb]['nLB']), grlDef["globalFilterDefects"])
842 for iRetrievedDefects in retrievedDefects:
843 if (iRetrievedDefects.until.lumi > 4000000000):
844 # The GLOBAL_NOTCONSIDERED defect is apparently set by default with a huge end of IOV.
845 # A priori, it should not survive the 48 hours calibration loop but anyway, In such a case, no filter is applied.
846 # BT October 2022 : this protection should be obsolete with the change of run 2 lines above. To be confirmed
847# if (time.time()-v_lbTimeSt[len(v_lbTimeSt)][1]) > 48*3600: # During 48 hours after the end of run, the global filter is deactived to display all recent runs
848# for lb in range(iRetrievedDefects.since.lumi,runinfo[runNb]['nLB']+1):
849# globalFilterLB.append(lb)
850 continue
851 else:
852 for lb in range(iRetrievedDefects.since.lumi,iRetrievedDefects.until.lumi):
853 globalFilterLB.append(lb)
854
855 # Atlas Ready
856 atlasready=GetReadyFlag(runNb)
857 runinfo[runNb]['readyLB']=[]
858 runinfo[runNb]['readyLB_globalFilter']=[]
859 for lb in list(atlasready.keys()):
860 if (atlasready[lb]>0): runinfo[runNb]['readyLB']+=[lb]
861 if (atlasready[lb]>0) and (lb not in globalFilterLB): runinfo[runNb]['readyLB_globalFilter']+=[lb]
862 if (lb in globalFilterLB):
863 runinfo[runNb]['globalFilter'] = True
864 runinfo["AllRuns"]['globalFilter'] = True
865 runinfo[runNb]['nLBready'] = float(len(runinfo[runNb]['readyLB_globalFilter']))
866
867 thisRunPerLB = dict() # Contains various per LB run characteristics retrieved from COOL
868 # COOL delivered luminosity
869 if options['onlineLumiNorm']:
870 thisRunPerLB["deliveredLumi"] = GetOnlineLumiFromCOOL(runNb,0)
871 else:
872 thisRunPerLB["deliveredLumi"] = GetOfflineLumiFromCOOL(runNb,0,yearTagProperties["OflLumi tag"])
873
874 # Look for peak lumi
875 runinfo[runNb]['peakLumi'] = 0.
876 for lb in list(thisRunPerLB['deliveredLumi'].keys()):
877 if thisRunPerLB['deliveredLumi'][lb] > runinfo[runNb]['peakLumi']: runinfo[runNb]['peakLumi']=thisRunPerLB['deliveredLumi'][lb]
878 if thisRunPerLB['deliveredLumi'][lb] > runinfo['AllRuns']['peakLumi']: runinfo['AllRuns']['peakLumi']=thisRunPerLB['deliveredLumi'][lb]
879
880 # Store the duration
881 thisRunPerLB['duration'] = GetLBDuration(runNb)
882
883 # Back up method. Retrieve the precise LB duration (more precise than GetLBDuration(runNb)) and liveFraction (relevant if recorded lumi normalisation).
884 lumiacct=fetch_iovs('COOLOFL_TRIGGER::/TRIGGER/OFLLUMI/LumiAccounting', tag=yearTagProperties["OflLumiAcct tag"], since=v_lbTimeSt[1][0]*1000000000, until=v_lbTimeSt[len(v_lbTimeSt)][1]*1000000000)
885 thisRunPerLB['duration'] = dict()
886 for iLumiAcct in range(len(lumiacct)):
887 if options['recordedLumiNorm']: # The LB duration is corrected by the live fraction
888 thisRunPerLB['duration'][lumiacct[iLumiAcct].LumiBlock] = lumiacct[iLumiAcct].LBTime*lumiacct[iLumiAcct].LiveFraction
889 else:
890 thisRunPerLB['duration'][lumiacct[iLumiAcct].LumiBlock] = lumiacct[iLumiAcct].LBTime
891
892 # Store the luminosity used for the efficiency normalisations
893 for lb in range(1,runinfo[runNb]['nLB']+2): # Loop on all LB - Protection to set a zero luminosity if not available
894 if lb in runinfo[runNb]['readyLB_globalFilter']:
895 if lb not in list(thisRunPerLB["deliveredLumi"].keys()):
896 thisRunPerLB["deliveredLumi"][lb] = 0.
897 errorMsg = "Missing lumi for Run %d - LB %d\n"%(runNb,lb)
898 print(errorMsg)
899 errorLogFile.write(errorMsg)
900 if lb not in list(thisRunPerLB["duration"].keys()):
901 thisRunPerLB["duration"][lb] = 0.
902 errorMsg = "Missing duration/LiveFraction for Run %d - LB %d\n"%(runNb,lb)
903 print(errorMsg)
904 errorLogFile.write(errorMsg)
905 else:
906 if lb not in list(thisRunPerLB["deliveredLumi"].keys()):
907 thisRunPerLB["deliveredLumi"][lb] = 0.
908 if lb not in list(thisRunPerLB["deliveredLumi"].keys()):
909 thisRunPerLB["duration"][lb] = 0.
910
911 if options['vetoLumiEvolution']:
912 for lb in runinfo[runNb]['readyLB_globalFilter']: # Fill the luminosity profile
913 if thisRunPerLB["deliveredLumi"][lb] != 0.:
914 h1_vetoInstLumiEvol['NoVeto'].Fill(thisRunPerLB["deliveredLumi"][lb]/1e3,v_lbTimeSt[lb][1]-v_lbTimeSt[lb][0])
915
916 # Finished retrieving the general characteristics of the run
917
918 # Get defects
919
920 parsedDefects = retrieveDefectsFromDB(runNb, options['defectTag'], grlDef,signOff)
921 retrievedDefects = list(parsedDefects.keys())
922
923 runinfo[runNb]['exprSignedOff'] = True
924 runinfo[runNb]['bulkSignedOff'] = True
925 runinfo[runNb]['signoff'] = 'FINAL OK'
926 # Loop over all defects and store in list (1 per partition and type) the affected LB
927 # Consider only LB in runinfo[runNb]["readyLB_globalFilter"]
928 for iRetrievedDefects in retrievedDefects:
929 # keep track of runs with missing sign-off - Store the earliest stage of the sign off procedure
930 for iSignOff in signOff["EXPR."]:
931 if iRetrievedDefects.channel == iSignOff:
932 runinfo[runNb]['signoff'] = "EXPR."
933 if "EXPR." not in runinfo[runNb]['signoff']:
934 for iSignOff in signOff["BULK"]:
935 if iRetrievedDefects.channel == iSignOff:
936 runinfo[runNb]['signoff'] = "BULK"
937 if "BULK" not in runinfo[runNb]['signoff']:
938 for iSignOff in signOff["FINAL"]:
939 if iRetrievedDefects.channel == iSignOff:
940 runinfo[runNb]['signoff'] = "DONE"
941
942 if runinfo[runNb]['signoff'] != 'FINAL OK': # Update year stats only after final signoff
943 runinfo[runNb]['newInYearStats'] = False
944
945 # Checks if the defect corresponds to a defect in the system list
946 defectFound, partAffected = parsedDefects[iRetrievedDefects]
947
948 # Now stored the affected
949 if defectFound in grlDef["part"]:
950 for lb in range(iRetrievedDefects.since.lumi,iRetrievedDefects.until.lumi):
951 if(lb in runinfo[runNb]['readyLB_globalFilter']):# The LB is with ATLAS ready
952
953 if partAffected not in lbAffected[defectFound]: # Store the affected partitions - A priori no longer used
954 lbAffected[defectFound][partAffected]=[]
955 lbAffected[defectFound][partAffected].append(lb)
956
957 lbAffected[defectFound]["AllPartitions"].append(lb)
958 if (defectFound in grlDef["partIntol"]):# Update the LBs affected by an intolerable defect whatever is the partition
959 if (lb not in lbAffected['allIntol']):
960 lbAffected['allIntol'].append(lb)
961 if (not iRetrievedDefects.recoverable and lb not in lbAffected['allIntol_irrecov']): # Update the LBs affected by an intolerable irrecoverable defect
962 lbAffected['allIntol_irrecov'].append(lb)
963
964 if defectFound in grlDef["glob"]:
965 # The min is a protection for a single 2017 run with Trig_HLT (326468) that lead to a crash...
966 for lb in range(iRetrievedDefects.since.lumi,min(iRetrievedDefects.until.lumi,runinfo[runNb]['nLB']+1)):
967 if(lb in runinfo[runNb]["readyLB_globalFilter"]):
968 lbAffected[defectFound].append(lb)
969 if (defectFound in grlDef["globIntol"]):# Update the LBs affected by an intolerable irrecoverable defect
970 if (lb not in lbAffected['allIntol']):
971 lbAffected['allIntol'].append(lb)
972 if (not iRetrievedDefects.recoverable and lb not in lbAffected['allIntol_irrecov']):
973 lbAffected['allIntol_irrecov'].append(lb)
974
975 # Now treat recoverability - Storing all irrecoverable lb per defect (not partition wise as useless)
976 for idef in grlDef["partIntol"]:
977 lbAffected['%s__recov'%idef]["AllPartitions"]=[]
978 for ilb in lbAffected[idef]["AllPartitions"]:
979 if ilb not in lbAffected['allIntol_irrecov']:
980 lbAffected['%s__recov'%idef]["AllPartitions"].append(ilb)
981 for idef in grlDef["globIntol"]:
982 for ilb in lbAffected[idef]:
983 if ilb not in lbAffected['allIntol_irrecov']:
984 lbAffected['%s__recov'%idef].append(ilb)
985 lbAffected['allIntol_recov'].append(ilb)
986
987 # Prepare the computation of inefficiencies - Initialization
988 for idef in (grlDef["tol"]+grlDef["intol"]+grlDef["intol_recov"]+allIntolDef):
989 runinfo[runNb]["lumiDefect_%s"%(idef)] = 0.
990 runinfo[runNb]["ineffDefect_%s"%(idef)] = 0.
991 runinfo[runNb]['Lumi'] = 0.
992
993 # Loop on all LB of the run
994 for lb in runinfo[runNb]["readyLB_globalFilter"]:
995 # Compute integrated luminosities
996 runinfo[runNb]['Lumi'] = runinfo[runNb]['Lumi'] +thisRunPerLB["deliveredLumi"][lb]*thisRunPerLB['duration'][lb]
997 runinfo['AllRuns']['Lumi'] = runinfo['AllRuns']['Lumi'] +thisRunPerLB["deliveredLumi"][lb]*thisRunPerLB['duration'][lb]
998 # Loop on defects already stored - Partition defect (Tolerable + intolerable)
999 for idef in grlDef["part"]+grlDef["partIntol_recov"]:
1000 if lb in lbAffected[idef]["AllPartitions"]:
1001 runinfo[runNb]["lumiDefect_%s"%(idef)] = runinfo[runNb]["lumiDefect_%s"%(idef)] + thisRunPerLB["deliveredLumi"][lb]*thisRunPerLB['duration'][lb]
1002 runinfo["AllRuns"]["lumiDefect_%s"%(idef)] = runinfo["AllRuns"]["lumiDefect_%s"%(idef)] + thisRunPerLB["deliveredLumi"][lb]*thisRunPerLB['duration'][lb]
1003 if (runinfo[runNb]["Lumi"] != 0.):
1004 runinfo[runNb]["ineffDefect_%s"%(idef)] = runinfo[runNb]["lumiDefect_%s"%(idef)]/runinfo[runNb]["Lumi"]*100.
1005
1006 # Loop on defects already stored - Global defect (Tolerable + intolerable) + all intolerable (used to avoid double counting)
1007 for idef in grlDef["glob"]+grlDef["globIntol_recov"]+allIntolDef:
1008 if lb in lbAffected[idef]:
1009 runinfo[runNb]["lumiDefect_%s"%(idef)] = runinfo[runNb]["lumiDefect_%s"%(idef)] + thisRunPerLB["deliveredLumi"][lb]*thisRunPerLB['duration'][lb]
1010 runinfo["AllRuns"]["lumiDefect_%s"%(idef)] = runinfo["AllRuns"]["lumiDefect_%s"%(idef)] + thisRunPerLB["deliveredLumi"][lb]*thisRunPerLB['duration'][lb]
1011 if (runinfo[runNb]["Lumi"] != 0.):
1012 runinfo[runNb]["ineffDefect_%s"%(idef)] = runinfo[runNb]["lumiDefect_%s"%(idef)]/runinfo[runNb]["Lumi"]*100.
1013
1014 if runinfo[runNb]['Lumi']==0: runinfo[runNb]['Lumi']=1e-50
1015
1016 for idef in grlDef["intol"]+grlDef["intol_recov"]+allIntolDef:
1017 hProfRun_IntolDefect[idef].Fill(irun,runinfo[runNb]["ineffDefect_%s"%(idef)])
1018 hProfRun_IntolDefect[idef].Fill(len(runlist['toprocess']),runinfo[runNb]["ineffDefect_%s"%(idef)],runinfo[runNb]['Lumi']) # Fill last bins (all runs) - Reminder : this is a profile !
1019 if (options['updateYearStats'] and runinfo[runNb]['newInYearStats']):
1020 hProfPeriod_IntolDefect[idef].Fill(periodListYear.index(runinfo[runNb]["period"]),runinfo[runNb]["ineffDefect_%s"%(idef)],runinfo[runNb]['Lumi'])
1021 hProfPeriod_IntolDefect[idef].Fill(len(periodListYear),runinfo[runNb]["ineffDefect_%s"%(idef)],runinfo[runNb]['Lumi'])
1022
1023 h1Run_IntLuminosity.Fill(irun,runinfo[runNb]['Lumi']/1e6)
1024 h1Run_IntLuminosity.Fill(len(runlist['toprocess']),runinfo[runNb]['Lumi']/1e6)
1025
1026 if (options['updateYearStats'] and runinfo[runNb]['newInYearStats']):
1027 h1Per_IntLumi.Fill(periodListYear.index(runinfo[runNb]["period"]),runinfo[runNb]['Lumi']/1e6)
1028 h1Per_IntLumi.Fill(h1Per_IntLumi.GetNbinsX()-1,runinfo[runNb]['Lumi']/1e6) # Cumulated for the year
1029
1030 # Now starts veto inefficiency
1031 # Retrieve the length of time period vetoed
1032 db2="COOLOFL_LAR/CONDBR2"
1033 folderName="/LAR/BadChannelsOfl/EventVeto"
1034 if (not options['noVeto']):
1035 if (boolExactVetoComput_run):
1036 totalVeto = showEventVeto.showEventVetoFolder(db2,folderName,options['vetoTag'],runNb,runNb,0)
1037 else:
1038 print("WARNING: you use the rough event veto loss. To be used only if default is too slow...")
1039 totalVeto = showEventVetoNoLumi.showEventVetoFolder(db2,folderName,options['vetoTag'],runNb,runNb,0)
1040 else:
1041 totalVeto = None
1042
1043 for iVeto in veto["all"]+["allVeto"]:
1044 runinfo[runNb]["lumiVeto_%s"%(iVeto)] = 0.
1045 runinfo[runNb]["ineffVeto_%s"%(iVeto)] = 0.
1046
1047 if (totalVeto is not None):
1048 if (boolExactVetoComput_run):# Computation of veto rejection weighting by inst. lumi and ignoring LB already in intolerable defect list
1049 for iVeto in veto["all"]:
1050 for iVetoedLB in range(len(totalVeto[veto["COOL"][iVeto]])): # Loop on all veto periods
1051 lb0 = findLB(v_lbTimeSt,totalVeto[veto["COOL"][iVeto]][iVetoedLB][0]/1e9) # Start of veto period
1052 lb1 = findLB(v_lbTimeSt,totalVeto[veto["COOL"][iVeto]][iVetoedLB][0]/1e9) # End of veto period
1053 if options['vetoLumiEvolution']:
1054 h1_vetoInstLumiEvol[iVeto].Fill(thisRunPerLB["deliveredLumi"][lb0]/1e3,(totalVeto[veto["COOL"][iVeto]][iVetoedLB][1]-totalVeto[veto["COOL"][iVeto]][iVetoedLB][0])/1e9)
1055 if (lb0 not in lbAffected['allIntol'] and lb1 not in lbAffected['allIntol'] and (lb0 in runinfo[runNb]["readyLB_globalFilter"] or lb1 in runinfo[runNb]["readyLB_globalFilter"])): # If end/start not in lb with intol defect, add rejection period - Incorrect if > 1 LBs
1056 runinfo[runNb]["lumiVeto_%s"%iVeto] = runinfo[runNb]["lumiVeto_%s"%iVeto] + thisRunPerLB["deliveredLumi"][lb0]*((totalVeto[veto["COOL"][iVeto]][iVetoedLB][1]-totalVeto[veto["COOL"][iVeto]][iVetoedLB][0])/1e9)
1057 # Assumption that there is no overlap between the different tipes of time veto. To be fixed ideally...
1058 runinfo[runNb]["lumiVeto_allVeto"] = runinfo[runNb]["lumiVeto_allVeto"] + runinfo[runNb]["lumiVeto_%s"%iVeto]
1059 else:
1060 for iVeto in veto["all"]:
1061 if len(runinfo[runNb]["readyLB_globalFilter"]) != 0.:
1062 runinfo[runNb]["lumiVeto_%s"%(iVeto)] = totalVeto[iVeto][1] # WARNING : the veto inefficiency is computed from time (and not lumi). To be normalized by time
1063 # Assumption that there is no overlap between the different tipes of time veto. To be fixed ideally...
1064 runinfo[runNb]["lumiVeto_allVeto"] = runinfo[runNb]["lumiVeto_allVeto"] + runinfo[runNb]["lumiVeto_%s"%iVeto]
1065
1066 if (not options['noVeto']):
1067 for iVeto in veto["all"]+["allVeto"]:
1068 if boolExactVetoComput_run:
1069 runinfo[runNb]["ineffVeto_%s"%(iVeto)] = runinfo[runNb]["lumiVeto_%s"%(iVeto)]/runinfo[runNb]['Lumi']*100.
1070 else:# The veto inefficiency is computed from time (and not lumi). The ineff is normalized by time
1071 if len(runinfo[runNb]["readyLB_globalFilter"]) != 0.:
1072 runinfo[runNb]["ineffVeto_%s"%(iVeto)] = runinfo[runNb]["lumiVeto_%s"%(iVeto)]/(len(runinfo[runNb]["readyLB_globalFilter"])*60*1e9)*100.
1073 else:
1074 runinfo[runNb]["ineffVeto_%s"%(iVeto)] = 0.
1075
1076 hProfRun_Veto[iVeto].Fill(irun,runinfo[runNb]["ineffVeto_%s"%(iVeto)])
1077 hProfRun_Veto[iVeto].Fill(len(runlist['toprocess']),runinfo[runNb]["ineffVeto_%s"%(iVeto)],runinfo[runNb]['Lumi']) # Fill last bins (all runs) - Reminder : this is a profile !
1078
1079 if (options['updateYearStats'] and runinfo[runNb]['newInYearStats']):
1080 hProfPeriod_Veto[iVeto].Fill(periodListYear.index(runinfo[runNb]["period"]),runinfo[runNb]["ineffVeto_%s"%(iVeto)],runinfo[runNb]['Lumi'])
1081 hProfPeriod_Veto[iVeto].Fill(len(periodListYear),runinfo[runNb]["ineffVeto_%s"%(iVeto)],runinfo[runNb]['Lumi']) # Fill last bins (all periods)
1082
1083 runinfo['AllRuns']['lumiVeto_%s'%iVeto] = runinfo['AllRuns']['lumiVeto_%s'%iVeto] + runinfo[runNb]["lumiVeto_%s"%iVeto]
1084
1085 singleRunReport(runNb,runinfo[runNb],lbAffected,options['yearStatsDir'],grlDef,veto,boolExactVetoComput_run)
1086
1087
1088# End of loop on runs
1089
1090
1091
1092if options['vetoLumiEvolution']:
1093 for iVeto in veto["all"]:
1094 h1_vetoInstLumiEvol[iVeto].Divide(h1_vetoInstLumiEvol[iVeto],h1_vetoInstLumiEvol['NoVeto'],100.,1.)
1095
1096
1097if (runinfo['AllRuns']['Lumi']!=0):
1098 # Compute inefficiencies for the whole period
1099
1100 # Defect inefficencies first
1101 for iDef in grlDef["intol"]+grlDef["intol_recov"]+allIntolDef:
1102 runinfo['AllRuns']['ineffDefect_%s'%iDef] = hProfRun_IntolDefect[iDef].GetBinContent(hProfRun_IntolDefect[iDef].GetNbinsX())
1103
1104 if (not options['noVeto']):
1105 for iVeto in veto["all"]+["allVeto"]:
1106 runinfo['AllRuns']['ineffVeto_%s'%iVeto] = hProfRun_Veto[iVeto].GetBinContent(hProfRun_IntolDefect[iDef].GetNbinsX())
1107
1108 # Prepare the summary tables
1109 lineNb = {}
1110 column = {}
1111 lineNb = {}
1112 c1 = {}
1113
1114 canvasIndex = 0
1115 newCanvas = True
1116 for runNb in runlist['toprocess']+["AllRuns"]:
1117 if runNb not in list(runinfo.keys()):
1118 continue # Protection in case of the runs was not yet signed off and removed (with Unsignedoff option) from the list
1119
1120 if newCanvas:
1121 # NewCanvas facility almost removed (70 runs cut) Size of the last TCanvas not properly computed
1122 c1[canvasIndex] = TCanvas("runSummary_%s"%canvasIndex,"Run collection - %s"%canvasIndex,10,10,1000,(len(runlist['toprocess'])+6)*22)
1123 column[canvasIndex] = []
1124 lineNb[canvasIndex] = 0
1125 labels_col = ["Run","Run start / stop","LB ready","Peak lumi","Filt. lumi","GRL ineff.","Veto ineff.","Period","Status"]
1126 xlow_col = [0.01,0.075,0.405,0.485,0.57,0.65,0.735,0.83,0.89,0.99]
1127 ylowTable = 0.99 - 0.98/(len(runlist['toprocess'])+6)*(len(runlist['toprocess'])+2)
1128
1129 for i in range(len(labels_col)):
1130 column[canvasIndex].append(TPaveText(xlow_col[i],ylowTable,xlow_col[i+1],0.99))
1131 column[canvasIndex][i].AddText(labels_col[i])
1132 if (i%2 == 0):
1133 column[canvasIndex][i].SetFillColor(kAzure+2)
1134 else:
1135 column[canvasIndex][i].SetFillColor(kBlue-10)
1136 notYetSignedOff_TPave = TPaveText(xlow_col[0],0.01,xlow_col[len(labels_col)],ylowTable)
1137 if runlist['weekly-dqmeeting'] != "":
1138 notYetSignedOff_TPave.AddText("#club: runs to be signed off at %s"%runlist['weekly-dqmeeting'])
1139 if runinfo['AllRuns']['globalFilter'] != "":
1140 notYetSignedOff_TPave.AddText("#diamond: runs for which a global filter has been applied (for more information, look at the Global system)")
1141 notYetSignedOff_TPave.AddText("Completed at %s"%(time.strftime("%H:%M (%d %b)", time.localtime())))
1142 notYetSignedOff_TPave.SetFillColor(kAzure+2)
1143
1144 newCanvas = False
1145 if runNb == "AllRuns":
1146 column[canvasIndex][0].AddText("ALL")
1147 else:
1148 column[canvasIndex][0].AddText("%d"%(runNb))
1149 column[canvasIndex][1].AddText("%s / %s"%(runinfo[runNb]['Start'],runinfo[runNb]['Stop']))
1150 column[canvasIndex][2].AddText("%s"%(listify(runinfo[runNb]["readyLB"])))
1151 column[canvasIndex][3].AddText("%.1e"%(runinfo[runNb]['peakLumi']*1e30))
1152 if (runinfo[runNb]['globalFilter']):
1153 column[canvasIndex][4].AddText("%s #diamond"%(strLumi(runinfo[runNb]['Lumi'])))
1154 else:
1155 column[canvasIndex][4].AddText("%s"%(strLumi(runinfo[runNb]['Lumi'])))
1156 column[canvasIndex][5].AddText("%.2f %%"%(runinfo[runNb]['ineffDefect_allIntol']))
1157 column[canvasIndex][6].AddText("%.2f %%"%(runinfo[runNb]['ineffVeto_allVeto']))
1158 column[canvasIndex][7].AddText("%s"%(runinfo[runNb]["period"]))
1159 if (runNb in runlist['weeklyfile']):
1160 column[canvasIndex][8].AddText("%8s #club"%(runinfo[runNb]["signoff"]))
1161 else:
1162 column[canvasIndex][8].AddText("%10s"%(runinfo[runNb]["signoff"]))
1163 lineNb[canvasIndex] += 1
1164 if (lineNb[canvasIndex]==70 or runNb == "AllRuns"):
1165 for i in range(len(column[canvasIndex])):
1166 column[canvasIndex][i].Draw()
1167 tmp = "Old runs (> 7 days) not yet signed off: "
1168 tmp2 = ""
1169 if len(oldRunsNotYetignedOff):
1170 for iRun in range(len(oldRunsNotYetignedOff)):
1171 if (iRun < 10):
1172 tmp = tmp + "%d "%oldRunsNotYetignedOff[iRun]
1173 else:
1174 tmp2 = tmp2 + "%d "%oldRunsNotYetignedOff[iRun]
1175 else:
1176 tmp = tmp + "None :-)"
1177 notYetSignedOff_TPave.AddText(tmp)
1178 notYetSignedOff_TPave.AddText(tmp2)
1179 notYetSignedOff_TPave.Draw()
1180
1181 c1[canvasIndex].SetWindowSize(1000,lineNb[canvasIndex]*40)
1182 c1[canvasIndex].Update()
1183
1184 newCanvas = True
1185 canvasIndex += 1
1186
1187 if options['updateYearStats'] and (runinfo[runNb]["signoff"] != "FINAL OK" or runinfo[runNb]['Lumi'] < 1e-40) and runNb != "AllRuns":
1188 if (runinfo[runNb]['Lumi'] < 1e-40 ):
1189 print("Run %d has zero luminosity (wrong faulty db tag?) -> no year stats update. Current status: %s"%(runNb,runinfo[runNb]["signoff"]))
1190 if (runinfo[runNb]["signoff"] != "FINAL OK"):
1191 print("Run %d not fully signed off -> no year stats update. Current status: %s"%(runNb,runinfo[runNb]["signoff"]))
1192 notYetSignedOffRuns.write("%d (period %s) -> Current status : %s \n"%(runNb,runinfo[runNb]['period'],runinfo[runNb]["signoff"]))
1193 if options['updateYearStats'] and runinfo[runNb]["signoff"] == "FINAL OK" and runinfo[runNb]['newInYearStats']:
1194 bool_newRunsInYearStats = True
1195
1196 if options['savePlots']:
1197 for iCanvas in range(len(c1)):
1198 c1[iCanvas].SaveAs("%s/Weekly/summary-%d.png"%(options['yearStatsDir'],iCanvas))
1199
1200
1201canvasResults = {}
1202legendResults = {}
1203stackResults = {}
1204
1205
1206gStyle.SetOptStat(0)
1207if options['plotResults']:
1208 gStyle.SetHistMinimumZero()
1209
1210 plotStack("defects--Run--%s"%(options['tag']),hProfRun_IntolDefect,grlDef["intol"],defectVeto["description"],h1Run_IntLuminosity,False,stackResults,canvasResults,legendResults)
1211 if (len(veto["all"])):
1212 plotStack("veto--Run--%s"%(options['tag']),hProfRun_Veto,veto["all"],defectVeto["description"],h1Run_IntLuminosity,False,stackResults,canvasResults,legendResults)
1213
1214 if options['vetoLumiEvolution']:
1215 for iVeto in veto["all"]:
1216 canvasResults["%s_veto_evol"%(iVeto)] = TCanvas("%s_veto_evol"%(iVeto),"%s inefficiency (%s time veto) vs Inst.Lumi."%(options["system"],defectVeto["description"][iVeto]), 200, 10, 1000, 500)
1217 canvasResults["%s_veto_evol"%(iVeto)].SetGridy(1)
1218 h1_vetoInstLumiEvol[iVeto].Draw()
1219
1220 if options['savePlots']:
1221 for iCanvas in list(canvasResults.keys()):
1222 canvasResults[iCanvas].SaveAs("%s/Weekly/%s.png"%(options['yearStatsDir'],iCanvas))
1223
1224# End of plots
1225# Save the histograms when requested. NB:This is different from yearStats update
1226if (options['saveHistos']):
1227 filename = 'Files/weeklyHisto-%s-%s.root'%(startrun, endrun)
1228 f = TFile(filename,"recreate")
1229 for idef in grlDef["intol"]:
1230 hProfRun_IntolDefect[idef].Write()
1231 if options['vetoLumiEvolution']:
1232 h1_vetoInstLumiEvol["NoVeto"].Write()
1233 for iVeto in veto["all"]:
1234 hProfRun_Veto[iVeto].Write()
1235 if options['vetoLumiEvolution']:
1236 h1_vetoInstLumiEvol[iVeto].Write()
1237 f.Close()
1238 print("Histos saved in %s"%(filename))
1239
1240# yearStats update
1241# If new runs were added to period plots, save them
1242if (options['updateYearStats'] and bool_newRunsInYearStats):
1243 print("WARNING: I am going to update the %s stats with the following runs:"%(options['year']))
1244 print("NB: only runs fully signed off are considered")
1245 for irun in list(runinfo.keys()):
1246 if (irun != "AllRuns"):
1247 if runinfo[irun]['newInYearStats']:
1248 print(irun)
1249
1250 if (options['batchMode']): # In batch mode, no confirmation requested
1251 confirm = "y"
1252 else:
1253 confirm = input("Are you sure ([y]/n)?: ")
1254
1255 if ("n" not in confirm):
1256 f = TFile(yearStatsArchiveFilename,"recreate") #this file summarize all year stats with proper periods assigned
1257 for idef in grlDef["intol"] + grlDef["intol_recov"]+allIntolDef:#Intolerable defects only
1258 hProfPeriod_IntolDefect[idef].SetName("%s_archive"%(hProfPeriod_IntolDefect[idef].GetName()))
1259 hProfPeriod_IntolDefect[idef].Write()
1260 if (len(veto["all"])):
1261 for iVeto in (veto["all"]+["allVeto"]):
1262 hProfPeriod_Veto[iVeto].SetName("%s_archive"%(hProfPeriod_Veto[iVeto].GetName()))
1263 hProfPeriod_Veto[iVeto].Write()
1264
1265 h1Per_IntLumi.SetName("h1Period_IntLuminosity_archive")
1266 h1Per_IntLumi.Write()
1267 f.Close()
1268
1269 # Creating empty files for new period
1270 for iper in newPeriodInYearStats:
1271 periodFileName = "%s/runs-%s.dat"%(options['yearStatsDir'],iper)
1272 f = open(periodFileName,'w')
1273 f.close()
1274
1275 # Adding all runs not treated in year stats
1276 fAll = open("%s/runs-ALL.dat"%options['yearStatsDir'],'a')
1277 for iper in list(periodListCurrent.keys()): # Loop on all periods found
1278 periodFileName = "%s/runs-%s.dat"%(options['yearStatsDir'],iper)
1279 f = open(periodFileName,'a')
1280 for irun in periodListCurrent[iper]:
1281 if (irun in list(runinfo.keys()) and runinfo[irun]['newInYearStats']): # Runs not yet considered in yearStats
1282 f.write("%d\n"%(irun))
1283 fAll.write("%d (%s)\n"%(irun,iper))
1284 f.close()
1285 fAll.close()
1286 print("I have updated year stats")
1287
1288# The update of the defect dat files is now decoupled from the yearStatsUpdate to allows to also monitor runs (special runs notably)
1289# that are not in the GRL.
1290# for irun in list(runinfo.keys()): # should just be processed runs, or we don't have signoff
1291for irun in runlist['toprocess']:
1292 if runinfo[irun]['signoff'] == 'FINAL OK' and irun != "AllRuns" and options['updateYearStats']:
1293 # NB : GRL information no longer stored here
1294 # Backwards compatibility with DeMoScan to be checked
1295 irun_string = "%d (%.0f ub-1)"%(irun,runinfo[irun]['Lumi'])
1296
1297 for idef in grlDef["intol"]+grlDef["tol"]:
1298 if (runinfo[irun]["lumiDefect_%s"%(idef)]>0.):
1299 defectFileName = "%s/loss-%s.dat"%(options['yearStatsDir'],idef)
1300 if idef in grlDef["intol"]:
1301 defString = "%s -> %.6f pb-1 (recov: %.6f pb-1)\n"%(irun_string,runinfo[irun]["lumiDefect_%s"%(idef)]/1e6,runinfo[irun]["lumiDefect_%s__recov"%(idef)]/1e6)
1302 else:
1303 defString = "%s -> %.6f pb-1\n"%(irun_string,runinfo[irun]["lumiDefect_%s"%(idef)]/1e6)
1304 toAdd = True
1305 if (os.path.exists(defectFileName)):# Check that the same defect was not already stored
1306 f2 = open(defectFileName,'r')
1307 if defString in f2.readlines():
1308 toAdd = False
1309 f2.close()
1310 if toAdd:
1311 f2 = open(defectFileName,'a')
1312 f2.write(defString)
1313 f2.close()
1314
1315 if runinfo[irun]["ineffVeto_allVeto"]>0. : # Loss due to veto. Update the veto dat files
1316 for iVeto in veto["all"]:
1317 if (runinfo[irun]["lumiVeto_%s"%(iVeto)]>0.):
1318 vetoFileName = "%s/loss-%sVETO.dat"%(options['yearStatsDir'],iVeto)
1319 vetoString = "%s -> %.6f pb-1 \n"%(irun_string,runinfo[irun]["lumiVeto_%s"%(iVeto)]/1e6)
1320 toAdd = True
1321 if (os.path.exists(vetoFileName)):# Check that the same veto was not already stored
1322 f2 = open(vetoFileName,'r')
1323 if vetoString in f2.readlines():
1324 toAdd = False
1325 f2.close()
1326 if toAdd:
1327 f2 = open(vetoFileName,'a')
1328 f2.write(vetoString)
1329 f2.close()
1330
1331errorLogFile.close()
1332notYetSignedOffRuns.close()
1333
1334if options['updateYearStats']:
1335 os.system("rm -f %s"%tokenName)
1336if not options['batchMode']:
1337 input("I am done. Type <return> to exit...")
if(febId1==febId2)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void print(char *figname, TCanvas *c1)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
STL class.
getRunInfo(runlist, defectTag="HEAD")
Retrieval of run characteristics.
findLB(lbts, startOfVetoPeriod)
Definition DeMoUpdate.py:85
singleRunReport(runNumber, dict1, dict2, directory, defects, veto, exactVetoComput)
printBoth(string0, boolean, f)
Functions dedicated to output printing.
Definition DeMoUpdate.py:94
updateRunList(year=time.localtime().tm_year)
Retrieval of new runs not yet in YearStats-common/runlist-[year]-AtlasReady.dat.
sort_period(text)
Ancillary functions.
Definition DeMoUpdate.py:55
retrieveDefectsFromDB(run, defectTag, grlDef, signOffDefects)
printProp(varname)
Definition DeMoUpdate.py:60
extractNamePartition(foundDefect)
Functions dedicated to defect retrieval and basic string manipulations.
Definition index.py:1