13from DQConfMakerBase.DQElements
import DQRegion, DQReference, DQAlgorithm, DQAlgorithmParameter
64def recurse(rdir, dqregion, ignorepath, modelrefs=[], displaystring='Draw=PE', displaystring2D='Draw=COLZ', regex=None, startpath=None, hists=None, manglefunc=None):
65 if manglefunc
is None:
66 manglefunc =
lambda a, b: a
67 for key
in rdir.GetListOfKeys():
68 cl = key.GetClassName(); rcl = ROOT.TClass.GetClass(cl)
69 if ' ' in key.GetName():
70 print(
'WARNING: cannot have spaces in histogram names for han config; not including %s %s' % (cl, key.GetName()))
72 if rcl.InheritsFrom(
'TH1')
or rcl.InheritsFrom(
'TGraph')
or rcl.InheritsFrom(
'TEfficiency'):
73 if '/' in key.GetName():
74 print(
'WARNING: cannot have slashes in histogram names, encountered in directory %s, histogram %s' % (rdir.GetPath(), key.GetName()))
76 if key.GetName() ==
'summary':
77 print(
'WARNING: cannot have histogram named summary, encountered in %s' % rdir.GetPath())
79 fpath = rdir.GetPath().
replace(ignorepath,
'')
80 name = (fpath +
'/' + key.GetName()).lstrip(
'/')
87 if not match:
continue
89 if not regex.match(name):
continue
90 dqpargs = {
'id' : (
'' if fpath
else 'top_level/') + name,
91 'inputdatasource': (startpath +
'/' if startpath
else '') + name,
95 for mref
in modelrefs:
96 newref = DQReference(manglefunc(mref.getReference().
replace(
'same_name', (startpath +
'/' if startpath
else '') + name), mref.id))
97 newref.addAnnotation(
'info', mref.id)
98 lnewrefs.append(newref)
99 dqpargs.update({
'algorithm': repeatalgorithm,
100 'algorithmparameters': algorithmparameters,
101 'thresholds': thresh,
102 'references': lnewrefs
105 dqpargs[
'algorithm'] = norefalgorithm
106 dqpar = dqregion.newDQParameter( **dqpargs)
108 if not options.normalize: drawstrs.append(
'NoNorm')
109 if options.logy
and (cl.startswith(
'TH1')
or cl==
'TProfile'): drawstrs.append(
'LogY')
110 if options.logy
and (cl.startswith(
'TH2')
or cl==
'TProfile2D'): drawstrs.append(
'LogZ')
111 if cl.startswith(
'TH1'): drawstrs.append(displaystring)
112 if cl ==
'TProfile': drawstrs.append(displaystring)
113 if cl.startswith(
'TH2')
or cl==
'TProfile2D': drawstrs.append(displaystring2D)
114 if options.scaleref != 1: drawstrs.append(
'ScaleRef=%f' % options.scaleref)
115 if options.ratio: drawstrs.append(
'RatioPad')
117 if options.ratio2D: drawstrs.append(
'Ref2DRatio')
118 if options.ratiorange
is not None:
119 drawstrs.append(
'delta(%f)' % options.ratiorange)
121 drawstrs.append(
'DataName=%s' % options.title)
122 dqpar.addAnnotation(
'display',
','.join(drawstrs))
124 elif rcl.InheritsFrom(
'TDirectory'):
125 newregion = dqregion.newDQRegion( key.GetName(), algorithm=worst )
126 recurse(key.ReadObj(), newregion, ignorepath, modelrefs, displaystring, displaystring2D, regex, startpath, hists, manglefunc)
130 returns True if we should kill this node
131 False if we should not
133 params = dqregion.getDQParameters()
136 subregions = dqregion.getSubRegions()
137 if subregions
is None:
140 subregions = subregions[:]
142 for sr
in subregions:
146 dqregion.delRelation(
'DQRegions', sr)
147 subregions = dqregion.getSubRegions()
148 if subregions
is None:
150 if len(subregions) + len(params) == 0:
165def process(infname, confname, options, refs=None):
167 f = ROOT.TFile.Open(infname,
'READ')
169 print(
'ERROR: cannot open %s' % infname)
172 top_level = DQRegion(id=
'topRegion',algorithm=worst)
173 print(
'Building tree...')
174 refpairs = refs.split(
',')
if refs
else []
176 refdict = dict(_.split(
':', 1)
for _
in refpairs)
177 except Exception
as e:
180 dqrs = [DQReference(reference=
'%s:same_name' % v, id=k)
181 for k, v
in list(refdict.items())]
182 displaystring = options.drawopt
183 if options.refdrawopt:
184 displaystring +=
',' + (
','.join(
'DrawRef=%s' % _
for _
in options.refdrawopt.split(
',')))
185 displaystring2D = options.drawopt2D
186 if options.drawrefopt2D:
187 displaystring2D +=
',' + (
','.join(
'DrawRef2D=%s' % _
for _
in options.drawrefopt2D.split(
',')))
189 if options.startpath:
190 topindir = f.Get(options.startpath)
192 raise ValueError(
"Path %s doesn't exist in input file" % options.startpath)
193 topindirname = f.GetPath() + options.startpath.strip(
'/')
194 startpath = options.startpath.strip(
'/')
197 topindirname = f.GetPath()
201 refstartpaths = options.refstartpath.split(
',')
if options.refstartpath
else []
203 refstartpathdict = dict(_.split(
':')
for _
in refstartpaths)
204 for k, v
in refstartpathdict.items():
205 refstartpathdict[k] = v.strip(
'/')
206 except Exception
as e:
208 def refpath_manglefunc(path, id):
210 pfx = refstartpathdict[id]
212 return path.replace(
':' + (startpath +
'/' if startpath
else ''),
':' + (pfx +
'/' if pfx
else ''), 1)
217 if options.histlistfile:
218 hists = [re.compile(line.rstrip(
'\n'))
for line
in open(options.histlistfile)]
219 if options.pathregex:
print(
"histlistfile given, pathregex is ignored")
220 if options.refmangle:
222 sys.path.append(os.getcwd())
224 manglefunc = importlib.import_module(options.refmangle).mangle
226 manglefunc = refpath_manglefunc
227 recurse(topindir, top_level, topindirname, dqrs, displaystring, displaystring2D,
228 re.compile(options.pathregex), startpath, hists, manglefunc=manglefunc)
229 print(
'Pruning dead branches...')
233 sublevel = top_level.getSubRegions()[:]
235 top_level.delRelation(
'DQRegions', x)
237 print(
'Writing output')
238 writeHanConfiguration( filename = confname , roots = sublevel)
242 import shutil, os, sys, contextlib
246 han_is_found = (ROOT.gSystem.Load(
'libDataQualityInterfaces') != 1)
248 print(
'ERROR: unable to load offline DQMF; unable to proceed')
250 bname = os.path.basename(fname)
257 prebuilt_hcfg =
False
259 @contextlib.contextmanager
262 td = tempfile.mkdtemp()
266 with tmpdir()
as hantmpdir:
268 print(
'====> Processing file %s' % (fname))
269 print(
'====> Generating han configuration file')
270 hantmpinput = os.path.join(hantmpdir, bname)
271 shutil.copyfile(fname, hantmpinput)
272 haninput = hantmpinput
273 hanconfig = os.path.join(hantmpdir,
'han.config')
274 rv =
process(hantmpinput, hanconfig, options, options.reffile)
279 print(
'No histograms to display; exiting with code 0')
282 print(
'====> Compiling han configuration')
283 hanhcfg = os.path.join(hantmpdir,
'han.hcfg')
284 ROOT.dqi.HanConfig().AssembleAndSave( hanconfig, hanhcfg )
285 print(
'====> Executing han')
287 memlimit = resource.getrlimit(resource.RLIMIT_AS)
288 resource.setrlimit(resource.RLIMIT_AS, (memlimit[1], memlimit[1]))
289 hanoutput = haninput.rpartition(
'.')[0] +
'_han.root'
291 rv = ROOT.dqi.HanApp().Analyze( hanhcfg, haninput, hanoutput )
293 raise Exception(
'failure in han')
295 rf = ROOT.TFile.Open(hanoutput,
'UPDATE')
296 HanMetadata.addMetadata(rf,
'AMI', {
'AMI Tag': options.amitag})
298 if not options.hanonly:
299 print(
'====> Dumping web display output')
300 from DataQualityUtils
import handimod
301 handimod.handiWithComparisons( options.title,
305 'https://atlasdqm.web.cern.ch/atlasdqm/js/',
306 3
if options.jsRoot
else 1)
307 if options.hanoutput:
308 from pathlib
import Path
309 print(
'====> Copying han output to', options.hanoutput)
310 target = Path(options.hanoutput)
312 target.parent.mkdir(parents=
True, exist_ok=
True)
313 except Exception
as e:
314 print(
'Unable to create %s for some reason: %s' % (target.parent, e))
315 raise Exception(
'Error during execute')
from e
316 shutil.copy2(hanoutput, options.hanoutput)
317 print(
'====> Cleaning up')
319 except Exception
as e:
322 traceback.print_exc()
323 if 'canonical format' not in str(e):
327 if not prebuilt_hcfg:
328 os.unlink(hantmpinput)
recurse(rdir, dqregion, ignorepath, modelrefs=[], displaystring='Draw=PE', displaystring2D='Draw=COLZ', regex=None, startpath=None, hists=None, manglefunc=None)