ATLAS Offline Software
MyPlots.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 from __future__ import print_function
4 
5 """
6 ATLAS beam spot web page for letting users create their customized beam spot plots.
7 """
8 
9 __author__ = 'Juerg Beringer'
10 __version__ = 'MyPlots.py atlas/athena'
11 
12 from WebPage import *
13 from BeamSpotWebPage import BeamSpotWebPage
15 
16 import os
17 import time
18 import glob
19 from math import floor
20 from cgi import escape
21 
22 from future import standard_library
23 standard_library.install_aliases()
24 import subprocess
25 
26 cmdoutput = """\
27 <div class="boldtext">
28 Command:
29 </div>
30 <pre class="text">
31 %s
32 </pre>
33 <div class="boldtext">
34 Output (status %s):
35 </div>
36 <div class="text">
37 <pre>
38 %s
39 </pre>
40 </div>
41 """
42 
43 image = """\
44 <p class="text">
45 <a href="%s">Link to generated plot</a>
46 (<a href="%s">eps</a>,
47 <a href="%s">pdf</a>) (valid for 3 days)
48 <p>
49 <img id="plot" src="%s" />
50 """
51 
52 def error(msg):
53  """Utility to render an error message."""
54  return htmlText(msg,'class="errormsg"',escapeText=True)
55 
56 
58 
59  def __init__(self):
60  BeamSpotWebPage.__init__(self)
61  self.pageConfig['pageTitle'] = 'ATLAS Beam Spot Plots'
62 
63  def content(self,**args):
64 
65  # Configuration and defaults
66  ntDir = self.globalConfig['ntDir']
67  periodDir = ntDir+'/DataPeriods'
68  cmd = self.globalConfig['wwwDir']+'/run-beamspotnt.sh'
69  if not os.path.exists(cmd):
70  return error('Configuration error: %s does not exist or unreadable' % cmd)
71  if not 'plotType' in args:
72  args['plotType'] = 'plot'
73 
74  # Start form
75  form = htmlPara('Select data and what to plot:', attr = 'class ="example"')
76 
77  # Project tag selection
78  projectList = sorted([ os.path.basename(p) for p in glob.glob(periodDir+'/data*')])
79  form += htmlSelect('Project tag','project', args, projectList, 'all data',
80  attr = 'onchange = "this.form.submit()"')
81 
82  # Period selection (only if project selected)
83  if 'project' in args and args['project']:
84  periodList = glob.glob(periodDir+'/'+args['project']+'/*')
85  periodList = sorted([ os.path.basename(p)[:-10] for p in periodList ])
86  if 'AllYear' in periodList:
87  periodList.remove('AllYear')
88  periodList.insert(0,'AllYear')
89  if not 'period' in args and periodList:
90  args['period'] = periodList[0]
91  form += htmlSelect('Period','period', args, periodList, attr='multiple size=5')
92 
93  # Fill and run number selection (only if no project selected)
94  if not args.get('project'):
95  form += htmlTextInput('or select fill', 'fillnr', args,6,6)
96  form += htmlTextInput('or run', 'runnr', args,6,6)
97 
98  # Ntuple selection
99  form += htmlPara()
100  form += htmlSelect('Ntuple', 'nt', args,
101  ['initial T0 processing::t0/beamspotnt-IndetBeampos-ES1-UPD2.root',
102  'latest data from COOL::cool/beamspotnt-COOL-Current.root'])
103 
104  # Plot type selection
105  form += htmlPara()
106  form += htmlSelect('Type of plot','plotType', args,
107  ['time evolution::plot', 'summary (slow)::summary', 'histogram::hist'],
108  attr = 'onchange = "this.form.submit()"')
109 
110  # Plot variable selection (except for summary plot)
111  if args['plotType']!='summary':
112  form += htmlSelect('for','varName', args,
113  ['posX','posY','posZ','sigmaX','sigmaY','sigmaZ','tiltX','tiltY','rhoXY','k'])
114 
115  # Plot options
116  form += htmlPara('Options:', attr='class ="example"')
117  if args['plotType']!='hist':
118  form += htmlCheckbox('Use LB instead of time on x axis','lbaxis',args)
119  form += htmlCheckbox('Predefined axis range','ydef', args)
120  form += htmlPara()
121  form += htmlTextInput('y axis scale expansion factor','yscale',args,6,6)
122  if args['plotType']=='plot':
123  form += htmlPara()
124  form += htmlTextInput('y axis minimum','ymin',args,6,6)
125  form += htmlTextInput('y axis maximum','ymax',args,6,6)
126  else:
127  form += htmlTextInput('x axis minimum','xmin',args,6,6)
128  form += htmlTextInput('x axis maximum','xmax',args,6,6)
129  form += htmlPara()
130  form += htmlCheckbox('Log y axis', 'logy', args)
131 
132  # Command line output option and submit button
133  form += htmlPara('Generate plot (depending on what parameters you choose, this may take a while.. please be patient):', attr='class ="example"')
134  form += htmlCheckbox('Show command line output','verbose',args)
135  form += htmlSubmit('Plot', 'doplot', attr = 'class="submit"')
136 
137  # Render selection form
138  page = htmlForm(form, attr='class="params"')
139 
140  # Output parameters for debugging
141  if 'debug' in args:
142  page += escape(str(args))
143 
144  # Plotting
145  if 'doplot' in args:
146 
147  # Unique file name
148  t = time.time()
149  ms = 1000.*(t-floor(t))
150  varName = args.get('varName', 'all')
151  baseName = 'beamspot-%s-%s' % (args['plotType'], varName)
152  baseName = time.strftime(baseName+'-%Y%m%d-%H%M%S',time.localtime())
153  baseName += '%03i' % ms
154 
155  # Assemble command and execute
156  cmd += ' -b'
157  cmd += ' -f %s/%s' % (ntDir,args['nt'])
158  cmd += ' -o %s/tmp/%s.gif,%s/tmp/%s.eps,%s/tmp/%s.pdf' % (self.globalConfig['wwwDir'],baseName,
159  self.globalConfig['wwwDir'],baseName,
160  self.globalConfig['wwwDir'],baseName)
161  if args.get('project'):
162  # NOTE: due to the defaults above, period will always be in args
163  selPeriodList = args['period'] if isinstance(args['period'],list) else [args['period']]
164  selPeriodString = ','.join([args['project']+'.'+p for p in selPeriodList])
165  cmd += ' --perioddef %s --period %s' % (periodDir,selPeriodString)
166  if args.get('fillnr'):
167  try:
168  cmd += ' --fill %i' % int(args['fillnr'])
169  except:
170  return page+error('Fill number must be an integer')
171  if args.get('runnr'):
172  try:
173  cmd += ' --run %i' % int(args['runnr'])
174  except:
175  return page+error('Run number must be an integer')
176  if not 'lbaxis' in args:
177  cmd += ' --timeaxis'
178  if 'logy' in args:
179  cmd += ' --logy'
180  if 'ydef' in args:
181  cmd += ' --ydef'
182  if args.get('yscale','')!='':
183  try:
184  dummy = float(args['yscale'])
185  cmd += ' --yscale %s' % args['yscale']
186  except:
187  return page+error('y axis scale expansion factor must be a number')
188  if args.get('ymin','')!='':
189  try:
190  dummy = float(args['ymin'])
191  cmd += ' --ymin %s' % args['ymin']
192  except:
193  return page+error('y axis minimum must be a number')
194  if args.get('ymax','')!='':
195  try:
196  dummy = float(args['ymax'])
197  cmd += ' --ymax %s' % args['ymax']
198  except:
199  return page+error('y axis maximum must be a number')
200  if args.get('xmin','')!='':
201  try:
202  dummy = float(args['xmin'])
203  cmd += ' --xmin %s' % args['xmin']
204  except:
205  return page+error('x axis minimum must be a number')
206  if args.get('xmax','')!='':
207  try:
208  dummy = float(args['xmax'])
209  cmd += ' --xmax %s' % args['xmax']
210  except:
211  return page+error('x axis maximum must be a number')
212  if args['plotType']=='summary':
213  cmd += ' summary'
214  else:
215  cmd += ' %s %s' % (args['plotType'], args['varName'])
216  (status,output) = subprocess.getstatusoutput(cmd)
217 
218  # Plot
219  if not status:
220  imageUrl = '%s/tmp/%s.gif' % (self.globalConfig.baseUrl,baseName)
221  epsUrl = '%s/tmp/%s.eps' % (self.globalConfig.baseUrl,baseName)
222  pdfUrl = '%s/tmp/%s.pdf' % (self.globalConfig.baseUrl,baseName)
223  page += image % (imageUrl,epsUrl,pdfUrl,imageUrl)
224 
225  # Command line output
226  if status or ('verbose' in args):
227  page += cmdoutput % (escape(cmd),status,escape(output))
228 
229  return page
230 
231 
232 # Code to test or run locally
233 if __name__ == '__main__':
234  page = MyPlots()
235  print (p.index())
WebPage.WebPage.globalConfig
globalConfig
Definition: WebPage.py:290
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
WebPage.htmlForm
def htmlForm(contents, action='', method='post', attr='')
Definition: WebPage.py:168
MyPlots.MyPlots
Definition: MyPlots.py:57
WebPage.htmlPara
def htmlPara(text='', attr='', escapeText=False)
Definition: WebPage.py:70
TaskManager
MyPlots.MyPlots.content
def content(self, **args)
Definition: MyPlots.py:63
WebPage.htmlTextInput
def htmlTextInput(labelText, parName, args, size=None, maxLength=None, labelAttr='', attr='')
Definition: WebPage.py:213
WebPage.htmlCheckbox
def htmlCheckbox(labelText, parName, args, labelAttr='', attr='')
Definition: WebPage.py:206
MyPlots.MyPlots.__init__
def __init__(self)
Definition: MyPlots.py:59
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
WebPage.htmlText
def htmlText(text, attr='', escapeText=False)
Definition: WebPage.py:58
WebPage.htmlSelect
def htmlSelect(labelText, parName, args, choiceList, hint=None, descriptionSeparator='::', labelAttr='', attr='')
Definition: WebPage.py:183
MyPlots.error
def error(msg)
Definition: MyPlots.py:52
str
Definition: BTagTrackIpAccessor.cxx:11
error
Definition: IImpactPoint3dEstimator.h:70
readCCLHist.float
float
Definition: readCCLHist.py:83
WebPage.htmlSubmit
def htmlSubmit(text, parName, attr='', onlyOnce=False)
Definition: WebPage.py:227
WebPage.WebPage.pageConfig
pageConfig
Definition: WebPage.py:273
BeamSpotWebPage.BeamSpotWebPage
Definition: BeamSpotWebPage.py:47