CMS 3D CMS Logo

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