CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
valtools.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # set of tools to create and submit validation webpages
3 # author: Colin
4 
5 import shutil, sys, os, re, glob, string
6 
7 from optparse import OptionParser
8 
9 
10 class webpage:
11 
12  # sets variables related to the creation of the local webpage.
13  def __init__(self):
14  self.parser_ = OptionParser()
15  self.parser_.add_option("-c", "--comments", dest="comments",
16  help="name of another release",
17  default=None)
18  self.parser_.add_option("-f", "--force", dest="force",
19  action="store_true",
20  help="overwrites the local benchmark page.",
21  default=False)
22  self.rootFile_ = 'benchmark.root'
23  self.dirPlots_ = './'
24  self.templates_ = '../Tools/templates'
25  self.date_ = os.popen( 'date' ).read()
26  self.benchmarkName_ = os.path.basename( os.getcwd() )
27 
28  def parseArgs(self):
29  (self.options_, self.args_) = self.parser_.parse_args()
30 
31  #create output dir, if it does not exist
32  def setOutputDir(self, outputDir ):
33 
34  self.outputDir_ = outputDir
35  if os.path.isdir( outputDir ):
36  print outputDir, "already exists"
37  if self.options_.force == False:
38  print 'sorry... run the script with the -h option for more information'
39  sys.exit(3)
40  else:
41  print 'overwriting local output directory...'
42  else:
43  os.makedirs( outputDir )
44 
45  # read the caption file and produce the html
46  # code for the Plots section
47  def readCaptions(self, captions):
48  imgTemplate = '<IMG src="%s" width="500" align="left" border="0"><br clear="ALL">'
49  images = ''
50  captionsContents = open( captions )
51  for line in captionsContents:
52  try:
53  (picfile, caption) = self.readCaption( line )
54  img = imgTemplate % os.path.basename(picfile)
55  images = "%s<h3>%s:</h3>\n%s\n" % (images, caption, img)
56  # what to do if the file's not there?
57  # : print a warning
58  shutil.copy(picfile, self.outputDir_)
59  except Exception:
60  print 'File %s does not exist. Did you generate the comparison plots?' % picfile
61  print 'Aborting the script.\n'
62  print 'Solution 1: run without the -m "" option, to run the compare.C macro'
63  print 'Solution 2: run with the -m "myMacro.C" option, to run another macro'
64  sys.exit(1)
65  raise
66  return images
67 
68  # decode a caption line, and return
69  # the caption, and the filename
70  # COULD HANDLE SEVERAL FILES
71  def readCaption( self, line ):
72 
73  if( re.compile('^\s*$').match(line) ):
74  raise Exception
75 
76  p = re.compile('^\s*(\S+)\s*\"(.*)\"');
77  m = p.match(line)
78  if m:
79  pic = m.group(1)
80  caption = m.group(2)
81  return (pic, caption)
82  else:
83  print 'bad caption format: "%s"' % line
84  raise Exception
85 
86 class website:
87  def __init__(self):
88  self.website_ = '/afs/cern.ch/cms/Physics/particleflow/Validation/cms-project-pfvalidation/Releases'
89  self.url_ = 'http://cern.ch/pfvalidation/Releases'
90 
91  def __str__(self):
92  return self.website_
93 
94 
95  def writeAccess(self):
96  if( os.access(self.website_, os.W_OK)==False ):
97  print 'cannot write to the website. Please ask Colin to give you access.'
98  sys.exit(1)
99 
100  def listBenchmarks(self, pattern, afs=False, url=False):
101  for bench in glob.glob(self.website_ + '/' + pattern):
102  # strip off the root path of the website
103  p = re.compile('^%s/(\S+)$' % self.website_);
104  m = p.match( bench )
105  if m:
106  (release, benchName, extension) = decodePath( m.group(1) )
107  if release == None:
108  # this is a comparison
109  continue
110  print
111  bench = benchmark(m.group(1))
112  print bcolors.OKGREEN + m.group(1) + bcolors.ENDC
113  if afs or url:
114  if afs: print ' ',bench.benchmarkOnWebSite( self )
115  if url: print ' ',bench.benchmarkUrl( self )
116 
117  def listComparisons(self, benchmark):
118 
119  comparisons = []
120  find = 'find %s -type d' % self.website_
121  for dir in os.popen( find ):
122  dir = dir.rstrip()
123  #print dir
124  comp = '%s/\S+/\S+/%s' % (self.website_,
125  benchmark.fullName() )
126  #print "** ", comp
127  p = re.compile(comp)
128  m = p.match(dir)
129  if m:
130  comparisons.append(dir)
131  #print ' ',dir
132  return comparisons
133 
134 class benchmark:
135 
136  # arg can be either the full name of a benchmark, or
137  # an extension, in which case, the release and benchmark name are guessed
138  # from the environment variables.
139  def __init__(self, arg=None):
140 
141  release = None
142  benchName = None
143  extension = None
144  self.indexHtml_ = 'index.html'
145 
146  if arg != None:
147  (release, benchName, extension) = decodePath( arg )
148 
149  if release == None:
150  # we get there if:
151  # - arg == None
152  # - the decoding of arg as a full benchmark name has failed.
153  self.release_ = os.environ['CMSSW_VERSION']
154 
155  # benchmark directory, as the current working directory
156  self.benchmark_ = os.path.basename( os.getcwd() )
157 
158  # underscore are not allowed in extension names
159  if arg!=None and arg.count('_'):
160  print 'sorry, as said many times, underscores are not allowed in the extension ;P'
161  sys.exit(5)
162 
163  extension = arg
164  else:
165  self.release_ = release
166  self.benchmark_ = benchName
167 
169  if( extension != None ):
170  self.benchmarkWithExt_ = '%s_%s' % (self.benchmark_, extension)
171 
172 
173  def __str__(self):
174  return self.release_ + '/' + self.benchmarkWithExt_
175 
176  def fullName(self):
177  return self.release_ + '/' + self.benchmarkWithExt_
178 
179  def releaseOnWebSite( self, website ):
180  return '%s/%s' % ( website, self.release_ )
181 
182  def benchmarkOnWebSite( self, website ):
183  return '%s/%s' % ( website, self.fullName() )
184 # return '%s/%s' % ( self.releaseOnWebSite(website),
185 # self.benchmarkWithExt_ )
186 
187  def rootFileOnWebSite( self, website ):
188  return '%s/%s' % ( self.benchmarkOnWebSite(website),
189  'benchmark.root' )
190 
191  def releaseUrl( self, website ):
192  return '%s/%s' % ( website.url_, self.release_ )
193 
194 
195  def benchmarkUrl( self, website ):
196  return '%s/%s' % ( self.releaseUrl( website ),
197  self.benchmarkWithExt_ )
198 
199  def makeRelease( self, website):
200  rel = self.releaseOnWebSite(website)
201  if( os.path.isdir( rel )==False):
202  print 'creating release %s' % self.release_
203  print rel
204  os.mkdir( rel )
205 
206  def exists( self, website):
207  if( os.path.isdir( self.benchmarkOnWebSite(website) )):
208  print 'benchmark %s exists for release %s' % (self.benchmarkWithExt_, self.release_)
209  return True
210  else:
211  print 'benchmark %s does not exist for release %s' % (self.benchmarkWithExt_, self.release_)
212  return False
213 
214  def addLinkToComparison( self, website, comparison ):
215  url = comparison.comparisonUrl( website )
216  index = self.benchmarkOnWebSite(website) + '/' + self.indexHtml_
217  indexTmp = self.benchmarkOnWebSite(website) + '/index.tmp.html'
218  indexFile = open( index)
219  indexFileTmp = open( indexTmp, 'w')
220  for line in indexFile:
221  p = re.compile('<h2>Comparisons:</h2>')
222  m = p.match(line)
223  indexFileTmp.write(line)
224  if m:
225  link = '<A href="%s">%s</A><BR>\n' % (url, url)
226  indexFileTmp.write(link)
227  shutil.move( indexTmp, index)
228 
230 
231  def __init__(self, benchmark, comparisonPath):
232  self.benchmark_ = benchmark
233  self.path_ = comparisonPath
234 
235  def comparisonOnWebSite(self, website):
236  return '%s/%s' % ( self.benchmark_.benchmarkOnWebSite(website),
237  self.path_ )
238 
239  def comparisonUrl(self, website):
240  return '%s/%s' % ( self.benchmark_.benchmarkUrl(website),
241  self.path_ )
242 
243  def submit(self, website, force=False):
244  print 'Submitting comparison:'
245  print ' from: ',self.path_
246  print ' to : ',self.comparisonOnWebSite(website)
247 
248  if( os.path.isdir(self.comparisonOnWebSite(website) ) ):
249  print 'comparison already exists'
250  if force:
251  print 'overwriting comparison on the website...'
252  else:
253  print 'submission cancelled. run with -h for a solution.'
254  return False
255  else:
256  print 'comparison directory does not yet exist. creating it.'
257  mkdir = 'mkdir -p ' + self.comparisonOnWebSite(website)
258  print mkdir
259  if os.system( mkdir ):
260  print 'problem creating the output directory on the website. Aborting.'
261  return False
262  cp = 'cp %s %s' % (self.path_ + '/*',
263  self.comparisonOnWebSite(website))
264  if os.system(cp):
265  print 'problem copying the files to the website aborting'
266  return False
267 
268  print 'access your comparison here:'
269  print ' ', self.comparisonUrl(website)
270 
271 
272 
273 # pathname in the form: CMSSW_3_1_0_pre7/TauBenchmarkGeneric_Extension
274 def decodePath( path ):
275  p = re.compile('^(\S+)/([^\s_]+)_(\S+)');
276  m = p.match(path)
277  if m:
278  release = m.group(1)
279  benchmarkname = m.group(2)
280  extension = m.group(3)
281  return (release, benchmarkname, extension )
282  else:
283  return (None, None, None)
284 
285 #test that a given file is a file with the correct extenstion, e.g. .root
286 def testFileType( file, ext ):
287 
288  if file == "None":
289  return
290 
291  if os.path.isfile( file ) == False:
292  print '%s is not a file' % file
293  sys.exit(2)
294 
295  (fileroot, fileext) = os.path.splitext( file )
296  if fileext != ext:
297  print '%s does not end with %s' % (file, ext)
298  sys.exit(3)
299 
300 
301 # copy a file to a destination directory, and return the basename
302 # that is the filename without the path. that name is used
303 # to set a relative link in the html code
304 def processFile( file, outputDir ):
305 
306  if file == "None":
307  return 'infoNotFound.html'
308  else:
309  if os.path.isfile(file):
310  shutil.copy(file, outputDir)
311  return os.path.basename(file)
312  else:
313  return file
314 
315 class bcolors:
316  HEADER = '\033[95m'
317  OKBLUE = '\033[94m'
318  OKGREEN = '\033[92m'
319  WARNING = '\033[93m'
320  FAIL = '\033[91m'
321  ENDC = '\033[0m'
322 
323  def disable(self):
324  self.HEADER = ''
325  self.OKBLUE = ''
326  self.OKGREEN = ''
327  self.WARNING = ''
328  self.FAIL = ''
329  self.ENDC = ''
330 
def decodePath
Definition: valtools.py:274
def processFile
Definition: valtools.py:304
def testFileType
Definition: valtools.py:286
string WARNING
Definition: valtools.py:319
string OKGREEN
Definition: valtools.py:318
perl if(1 lt scalar(@::datatypes))
Definition: edlooper.cc:31
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:6