ATLAS Offline Software
Loading...
Searching...
No Matches
dq_make_web_display.py
Go to the documentation of this file.
1#!/usr/bin/env python
2
3# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4
5"""
6Transate arbitrary root file into a han config file with the "GatherData" algorithm
7@author: ponyisi@hep.uchicago.edu
89 Oct 2008
9Adapted for fast physics monitoring 14 April 2011
10"""
11
12#HANDIR='/afs/cern.ch/user/a/atlasdqm/dqmdisk/han_results/fastphysmon/1'
13
14from DQConfMakerBase.DQElements import DQReference, DQRegion, DQAlgorithm
15from DQHanConfMaker.hanwriter import writeHanConfiguration
16import ROOT
17
18gatherdata = DQAlgorithm(id='GatherData',
19 libname='libdqm_algorithms.so')
20worst = DQAlgorithm(id='WorstCaseSummary',libname='libdqm_summaries.so')
21
22def recurse(rdir, dqregion, ignorepath, reffile=None):
23
24 for key in rdir.GetListOfKeys():
25 cl = key.GetClassName(); rcl = ROOT.TClass.GetClass(cl)
26 #print key.GetName(), cl
27 if ' ' in key.GetName():
28 print('WARNING: cannot have spaces in histogram names for han config; not including %s %s' % (cl, key.GetName()))
29 continue
30 if rcl.InheritsFrom('TH1'):
31 if '/' in key.GetName():
32 print('WARNING: cannot have slashes in histogram names, encountered in directory %s, histogram %s' % (rdir.GetPath(), key.GetName()))
33 continue
34 if key.GetName() == 'summary':
35 print('WARNING: cannot have histogram named summary, encountered in %s' % rdir.GetPath())
36 continue
37 name = rdir.GetPath().replace(ignorepath, '') + '/' + key.GetName()
38 dqpargs = { 'id' :name,
39 'algorithm': gatherdata,
40 'inputdatasource': name,
41 }
42 if reffile:
43 dqpargs['references'] = DQReference(reference='%s:same_name' % reffile)
44 dqpar = dqregion.newDQParameter( **dqpargs)
45 dqpar.addAnnotation('display', 'NoNorm')
46
47 elif rcl.InheritsFrom('TDirectory'):
48 #print key.GetName()
49 newregion = dqregion.newDQRegion( key.GetName(), algorithm=worst )
50 recurse(key.ReadObj(), newregion, ignorepath, reffile)
51
52def prune(dqregion):
53 """
54 returns True if we should kill this node
55 False if we should not
56 """
57 params = dqregion.getDQParameters()
58 if params is None:
59 params = []
60 subregions = dqregion.getSubRegions()
61 if subregions is None:
62 subregions = []
63 else:
64 subregions = subregions[:]
65 # kill subregions
66 for sr in subregions:
67 if sr is None:
68 continue
69 if prune(sr):
70 dqregion.delRelation('DQRegions', sr)
71 subregions = dqregion.getSubRegions()
72 if subregions is None:
73 subregions = []
74 if len(subregions) + len(params) == 0:
75 return True
76 else:
77 return False
78
79def paramcount(dqregion):
80 params = dqregion.getDQParameters()
81 if params is None:
82 params = []
83 subregions = dqregion.getSubRegions()
84 if subregions is None:
85 subregions = []
86
87 return len(params) + sum([paramcount(region) for region in subregions])
88
89def process(infname, confname, reffile=None):
90 f = ROOT.TFile(infname, 'READ')
91 if not f.IsOpen():
92 print('ERROR: cannot open %s' % infname)
93 return
94
95 top_level = DQRegion(id='topRegion',algorithm=worst)
96 print('Building tree...')
97 recurse(f, top_level, f.GetPath(), reffile)
98 print('Pruning dead branches...')
99 prune(top_level)
100 pc = paramcount(top_level)
101
102 sublevel = top_level.getSubRegions()[:]
103 for x in sublevel:
104 top_level.delRelation('DQRegions', x)
105
106 print('Writing output')
107 writeHanConfiguration( filename = confname , roots = sublevel)
108 return pc
109
110def super_process(fname, options):
111 import shutil, os, sys, contextlib
112 import ROOT
113 han_is_found = (ROOT.gSystem.Load('libDataQualityInterfaces') == 0)
114 if not han_is_found:
115 print('ERROR: unable to load offline DQMF; unable to proceed')
116 sys.exit(1)
117 bname = os.path.basename(fname)
118
119 run = options.run
120 hanconfig = None
121 hanhcfg = None
122 hanoutput = None
123
124 failed = False
125 prebuilt_hcfg = False
126
127 @contextlib.contextmanager
128 def tmpdir():
129 import tempfile
130 td = tempfile.mkdtemp()
131 yield td
132 shutil.rmtree(td)
133
134 with tmpdir() as hantmpdir:
135 try:
136 print('====> Processing file %s' % (fname))
137 print('====> Generating han configuration file')
138 hantmpinput = os.path.join(hantmpdir, bname)
139 shutil.copyfile(fname, hantmpinput)
140 haninput = hantmpinput
141 hanconfig = os.path.join(hantmpdir, 'han.config')
142 rv = process(hantmpinput, hanconfig, options.reffile)
143 # bad hack. rv = number of histogram nodes
144 if rv == 0:
145 print('No histograms to display; exiting with code 0')
146 sys.exit(0)
147
148 print('====> Compiling han configuration')
149 hanhcfg = os.path.join(hantmpdir, 'han.hcfg')
150
151 ROOT.dqi.HanConfig().AssembleAndSave( hanconfig, hanhcfg )
152
153 print('====> Executing han')
154 import resource
155 memlimit = resource.getrlimit(resource.RLIMIT_AS)
156 resource.setrlimit(resource.RLIMIT_AS, (memlimit[1], memlimit[1]))
157 hanoutput = haninput.rpartition('.')[0] + '_han.root'
158
159 rv = ROOT.dqi.HanApp().Analyze( hanhcfg, haninput, hanoutput, '' )
160
161 if rv != 0:
162 raise Exception('failure in han')
163 hantargetdir = os.path.join(options.webdir, str(options.iteration),
164 options.dispname, 'run_%s' % run)
165 print('====> Copying to', hantargetdir)
166 hantargetfile = os.path.join(hantargetdir, 'run_%s_han.root' % run)
167 if not os.access(hantargetdir, os.W_OK):
168 try:
169 os.makedirs(hantargetdir)
170 except Exception as e:
171 print('Unable to create %s for some reason: %s' % (hantargetdir, e))
172 raise Exception('Error during execute')
173 shutil.copy2(hanoutput, hantargetfile)
174 print('====> Cleaning up')
175 except Exception as e:
176 print(e)
177 if 'canonical format' not in str(e):
178 failed = True
179 finally:
180 try:
181 if not prebuilt_hcfg:
182 os.unlink(hantmpinput)
183 os.unlink(hanconfig)
184 os.unlink(hanhcfg)
185 os.unlink(hanoutput)
186 except Exception:
187 pass
188
189 return not failed
190
191
192if __name__=="__main__":
193 import sys, optparse
194 parser = optparse.OptionParser(usage='usage: %prog [options] inputfile run')
195 parser.add_option('--webdir', default='/afs/cern.ch/user/a/atlasdqm/dqmdisk/han_results/fastphysmon',
196 help='Change directory to store web display files')
197 parser.add_option('--dispname', default='Summary',
198 help='Set "stream" name on web display')
199 parser.add_option('--iteration', default=1, type='int',
200 help='Set iteration number for web display')
201 parser.add_option('--reffile', default=None,
202 help='Reference file to use. Must have same structure as inputfile')
203
204 options, args = parser.parse_args()
205
206 if not 2 == len(args):
207 parser.print_help()
208 sys.exit(1)
209 fname = args[0]
210 try:
211 run = int(args[1])
212 options.run = run
213 except ValueError:
214 parser.print_help()
215 print('Specified run', args[1], 'doesn\'t seem to be an integer')
216 sys.exit(1)
217
218 rv = super_process(fname, options)
219 if rv:
220 sys.exit(0)
221 else:
222 sys.exit(1)
void print(char *figname, TCanvas *c1)
const std::string process
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
recurse(rdir, dqregion, ignorepath, reffile=None)
super_process(fname, options)