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 
12 #HANDIR='/afs/cern.ch/user/a/atlasdqm/dqmdisk/han_results/fastphysmon/1'
13 
14 from DQConfMakerBase.DQElements import DQReference, DQRegion, DQAlgorithm
15 from DQHanConfMaker.hanwriter import writeHanConfiguration
16 import ROOT
17 
18 gatherdata = DQAlgorithm(id='GatherData',
19  libname='libdqm_algorithms.so')
20 worst = DQAlgorithm(id='WorstCaseSummary',libname='libdqm_summaries.so')
21 
22 def 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 
52 def 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 
79 def 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 
89 def 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 
110 def 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 
192 if __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)
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:79
dq_make_web_display.super_process
def super_process(fname, options)
Definition: dq_make_web_display.py:110
dq_make_web_display.recurse
def recurse(rdir, dqregion, ignorepath, reffile=None)
Definition: dq_make_web_display.py:22
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
dq_make_web_display.prune
def prune(dqregion)
Definition: dq_make_web_display.py:52
dq_make_web_display.process
def process(infname, confname, reffile=None)
Definition: dq_make_web_display.py:89
beamspotman.tmpdir
string tmpdir
Definition: beamspotman.py:410
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
str
Definition: BTagTrackIpAccessor.cxx:11
python.hanwriter.writeHanConfiguration
def writeHanConfiguration(filename='dq.han.config', roots=[])
Definition: hanwriter.py:723