CMS 3D CMS Logo

getPayloadData.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 
4 from __future__ import print_function
5 import shutil
6 import glob
7 import json
8 import sys
9 import sys
10 import os
11 
12 from importlib import import_module
13 from argparse import ArgumentParser, RawTextHelpFormatter
14 
15 
16 import pluginCondDBV2PyInterface
17 pluginCondDBV2PyInterface.CMSSWInit()
18 
19 
20 
21 def supress_output( f ):
22  '''
23  Temporarily disables stdout and stderr so that printouts from the plot
24  plugin does not compromise the purity of our ssh stream if
25  args.suppress_output is true
26  '''
27  def decorated( *fargs, **fkwargs ):
28 
29  suppress = args.suppress_output
30  if suppress:
31 
32  # Get rid of what is already there ( should be nothing for this script )
33  sys.stdout.flush()
34 
35  # Save file descriptors so it can be reactivated later
36  saved_stdout = os.dup( 1 )
37  saved_stderr = os.dup( 2 )
38 
39  # /dev/null is used just to discard what is being printed
40  devnull = os.open( '/dev/null', os.O_WRONLY )
41 
42  # Duplicate the file descriptor for /dev/null
43  # and overwrite the value for stdout (file descriptor 1)
44  os.dup2( devnull, 1 )
45  os.dup2( devnull, 2 )
46 
47  result = f( *fargs, **fkwargs )
48 
49  if suppress:
50 
51  # Close devnull after duplication (no longer needed)
52  os.close( devnull )
53 
54  # Reenable stdout and stderr
55  os.dup2( saved_stdout, 1 )
56  os.dup2( saved_stderr, 2 )
57 
58  return result
59 
60  return decorated
61 
62 
63 @supress_output
64 def deserialize_iovs(db, plugin_name, plot_name, tag, time_type, iovs):
65  ''' Deserializes given iovs data and returns plot coordinates '''
66 
67  output('Starting to deserialize iovs: ', '')
68  output('db: ', db)
69  output('plugin name: ', plugin_name)
70  output('plot name: ', plot_name)
71  output('tag name: ', tag)
72  output('tag time type: ', time_type)
73  output('iovs: ', iovs)
74 
75  plugin_base = import_module('pluginModule_PayloadInspector')
76  output('PI plugin base: ', plugin_base)
77 
78  plugin_obj = import_module(plugin_name)
79  output('PI plugin object: ', plugin_obj)
80 
81  # get plot method and execute it with given iovs
82  plot = getattr(plugin_obj, plot_name)()
83  output('plot object: ', plot)
84 
85  if db == "Prod":
86  db_name = 'frontier://FrontierProd/CMS_CONDITIONS'
87  elif db == 'Prep' :
88  db_name = 'frontier://FrontierPrep/CMS_CONDITIONS'
89  else:
90  db_name = db
91  output('full DB name: ', db_name)
92 
93 
94  success = plot.process(db_name, tag, time_type, int(iovs['start_iov']), int(iovs['end_iov']))
95  output('plot processed data successfully: ', success)
96  if not success:
97  return False
98 
99 
100  result = plot.data()
101  output('deserialized data: ', result)
102  return result
103 
105  ''' Returns a list of Payload Inspector plugin names
106  Example:
107  ['pluginBasicPayload_PayloadInspector', 'pluginBeamSpot_PayloadInspector', 'pluginSiStrip_PayloadInspector']
108  '''
109  architecture = os.environ.get('SCRAM_ARCH', None)
110  output('architecture: ', architecture)
111 
112  plugins = []
113  releases = [
114  os.environ.get('CMSSW_BASE', None),
115  os.environ.get('CMSSW_RELEASE_BASE', None)
116  ]
117 
118  for r in releases:
119  if not r: continue # skip if release base is not specified
120  output('* release: ', r)
121 
122  path = os.path.join(r, 'lib', architecture)
123  output('* full release path: ', path)
124 
125  plugins += glob.glob(path + '/plugin*_PayloadInspector.so' )
126  output('found plugins: ', plugins)
127 
128  if r: break # break loop if CMSSW_BASE is specified
129 
130  # extracts the object name from plugin path:
131  # /afs/cern.ch/cms/slc6_amd64_gcc493/cms/cmssw/CMSSW_8_0_6/lib/slc6_amd64_gcc493/pluginBasicPayload_PayloadInspector.so
132  # becomes pluginBasicPayload_PayloadInspector
133  result = []
134  for p in plugins:
135  result.append(p.split('/')[-1].replace('.so', ''))
136 
137  output('discovered plugins: ', result)
138  return result
139 
140 def discover():
141  ''' Discovers object types and plots for a given cmssw release
142  Example:
143  {
144  "BasicPayload": [
145  {"plot": "plot_BeamSpot_x", "plot_type": "History",
146  "single_iov": false, "plugin_name": "pluginBeamSpot_PayloadInspector",
147  "title": "x vs run number"},
148  ...
149  ],
150  ...
151  }
152  '''
153  plugin_base = import_module('pluginModule_PayloadInspector')
154  result = {}
155  for plugin_name in discover_plugins():
156  output(' - plugin name: ', plugin_name)
157  plugin_obj = import_module(plugin_name)
158  output('*** PI plugin object: ', plugin_obj)
159  for plot in dir(plugin_obj):
160  if 'plot_' not in plot: continue # skip if method doesn't start with 'plot_' prefix
161  output(' - plot name: ', plot)
162  plot_method= getattr(plugin_obj, plot)()
163  output(' - plot object: ', plot_method)
164  payload_type = plot_method.payloadType()
165  output(' - payload type: ', payload_type)
166  plot_title = plot_method.title()
167  output(' - plot title: ', plot_title)
168  plot_type = plot_method.type()
169  output(' - plot type: ', plot_type)
170  single_iov = plot_method.isSingleIov()
171  output(' - is single iov: ', single_iov)
172  result.setdefault(payload_type, []).append({'plot': plot, 'plugin_name': plugin_name, 'title': plot_title, 'plot_type': plot_type, 'single_iov': single_iov})
173  output('currently discovered info: ', result)
174  output('*** final output:', '')
175  return json.dumps(result)
176 
177 def output(description, param):
178  if args.verbose:
179  print('')
180  print(description, param)
181 
182 if __name__ == '__main__':
183 
184  description = '''
185  Payload Inspector - data visualisation tool which is integrated into the cmsDbBrowser.
186  It allows to display plots and monitor the calibration and alignment data.
187 
188  You can access Payload Inspector with a link below:
189  https://cms-conddb.cern.ch/cmsDbBrowser/payload_inspector/Prod
190 
191  This script is a part of the Payload Inspector service and is responsible for:
192  a) discovering PI objects that are available in a given cmssw release
193  b) deserializing payload data which is later used as plot coordinates
194  c) testing new PI objects which are under development
195 
196  To test new PI objects please do the following:
197  a) run ./getPayloadData.py --discover
198  to check if your newly created object is found by the script.
199  Please note that we strongly rely on naming conventions so if you don't
200  see your object listed you probably misnamed it in objectType() method.
201  Also all plot methods should start with "plot_" prefix.
202 
203  b) second step is to test if it returns data correctly:
204  run ./getPayloadData.py --plugin YourPIPluginName --plot YourObjectPlot --tag tagName --time_type Run --iovs '{"start_iov": "201", "end_iov": "801"}' --db Prod --test
205 
206  Here is an example for BasicPayload object:
207  run ./getPayloadData.py --plugin pluginBasicPayload_PayloadInspector --plot plot_BasicPayload_data0 --tag BasicPayload_v2 --time_type Run --iovs '{"start_iov": "201", "end_iov": "801"}' --db Prod --test
208 
209  c) if it works correctly please make a pull request and once it's accepted
210  go to cmsDbBrowser and wait for the next IB to test it.
211  '''
212 
213  parser = ArgumentParser(description=description, formatter_class=RawTextHelpFormatter)
214  parser.add_argument("-d", "--discover", help="discovers object types and plots \nfor a given cmssw release", action="store_true")
215  parser.add_argument("-i", "--iovs", help="deserializes given iovs data encoded in base64 and returns plot coordinates also encoded in base64")
216  parser.add_argument("-o", "--plugin", help="Payload Inspector plugin name needed for iovs deserialization")
217  parser.add_argument("-p", "--plot", help="plot name needed for iovs deserialization")
218  parser.add_argument("-t", "--tag", help="tag name needed for iovs deserialization")
219  parser.add_argument("-tt", "--time_type", help="tag time type name needed for iovs deserialization")
220  parser.add_argument("-b", "--db", help="db (Prod or Prep) needed for iovs deserialization")
221  parser.add_argument("-test", "--test", help="add this flag if you want to test the deserialization function and want to see a readable output", action="store_true")
222  parser.add_argument("-v", "--verbose", help="verbose mode. Shows more information", action="store_true")
223  parser.add_argument("-ip","--image_plot", help="Switch telling the script that this plot type is of type Image", action="store_true")
224  parser.add_argument("-s", "--suppress-output", help="Supresses output from so that stdout and stderr can be kept pure for the ssh transmission", action="store_true")
225 
226  # shows help if no arguments are provided
227  if len(sys.argv) == 1:
228  parser.print_help()
229  sys.exit(1)
230 
231  args = parser.parse_args()
232 
233  # Return discover of plot if requested
234  if args.discover:
235  os.write( 1, discover() )
236 
237  # Return a plot if iovs are provided
238  if args.iovs:
239 
240  # Run plugin with arguments
241  result = deserialize_iovs(args.db, args.plugin, args.plot, args.tag, args.time_type, json.loads(args.iovs))
242 
243  # If test -> output the result as formatted json
244  if args.test:
245  os.write( 1, json.dumps( json.loads( result ), indent=4 ))
246 
247  # If image plot -> get image file from result, open it and output bytes
248  elif args.image_plot:
249 
250  filename = None
251 
252  try:
253  filename = json.loads( result )['file']
254  except ValueError as e:
255  os.write( 2, 'Value error when getting image name: %s\n' % str( e ))
256  except KeyError as e:
257  os.write( 2, 'Key error when getting image name: %s\n' % str( e ))
258 
259  if not filename or not os.path.isfile( filename ):
260  os.write( 2, 'Error: Generated image file (%s) not found\n' % filename )
261 
262  try:
263  with open( filename, 'r' ) as f:
264  shutil.copyfileobj( f, sys.stdout )
265  except IOError as e:
266  os.write( 2, 'IO error when streaming image: %s' % str( e ))
267  finally:
268  os.remove( filename )
269 
270 
271  # Else -> output result json string with base 64 encoding
272  else:
273  os.write( 1, result.encode( 'base64' ))
274 
def supress_output(f)
def output(description, param)
def replace(string, replacements)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
double f[11][100]
def deserialize_iovs(db, plugin_name, plot_name, tag, time_type, iovs)
dbl *** dir
Definition: mlp_gen.cc:35
#define str(s)