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