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