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