CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Validation/RecoParticleFlow/Benchmarks/Tools/valtools.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # set of tools to create and submit validation webpages 
00003 # author: Colin
00004 
00005 import shutil, sys, os, re, glob, string 
00006 
00007 from optparse import OptionParser
00008 
00009 
00010 class webpage:
00011 
00012     # sets variables related to the creation of the local webpage. 
00013     def __init__(self):
00014         self.parser_ = OptionParser()
00015         self.parser_.add_option("-c", "--comments", dest="comments",
00016                                help="name of another release",
00017                                default=None)
00018         self.parser_.add_option("-f", "--force", dest="force",
00019                                 action="store_true",
00020                                 help="overwrites the local benchmark page.",
00021                                 default=False)
00022         self.rootFile_ = 'benchmark.root'
00023         self.dirPlots_ = './'
00024         self.templates_ = '../Tools/templates'
00025         self.date_ =  os.popen( 'date' ).read()
00026         self.benchmarkName_ = os.path.basename( os.getcwd() ) 
00027 
00028     def parseArgs(self):
00029         (self.options_, self.args_) = self.parser_.parse_args()
00030 
00031     #create output dir, if it does not exist
00032     def setOutputDir(self, outputDir ):
00033 
00034         self.outputDir_ = outputDir
00035         if os.path.isdir( outputDir ):
00036             print outputDir, "already exists"
00037             if self.options_.force == False:
00038                 print 'sorry... run the script with the -h option for more information' 
00039                 sys.exit(3)
00040             else:
00041                 print 'overwriting local output directory...'
00042         else:
00043             os.makedirs( outputDir )
00044 
00045     # read the caption file and produce the html
00046     # code for the Plots section
00047     def readCaptions(self, captions):
00048         imgTemplate = '<IMG src="%s" width="500" align="left" border="0"><br clear="ALL">'
00049         images = ''
00050         captionsContents = open( captions )
00051         for line in captionsContents:
00052             try:
00053                 (picfile, caption) = self.readCaption( line )
00054                 img = imgTemplate % os.path.basename(picfile)
00055                 images = "%s<h3>%s:</h3>\n%s\n" % (images, caption, img)
00056                 # what to do if the file's not there? 
00057                 # : print a warning
00058                 shutil.copy(picfile, self.outputDir_) 
00059             except Exception:
00060                 print 'File %s does not exist. Did you generate the comparison plots?' % picfile
00061                 print 'Aborting the script.\n'
00062                 print 'Solution 1: run without the -m "" option, to run the compare.C macro'
00063                 print 'Solution 2: run with the -m "myMacro.C" option, to run another macro'
00064                 sys.exit(1)
00065                 raise
00066         return images
00067 
00068     # decode a caption line, and return
00069     # the caption, and the filename
00070     # COULD HANDLE SEVERAL FILES
00071     def readCaption( self, line ):
00072         
00073         if( re.compile('^\s*$').match(line) ):
00074             raise Exception
00075         
00076         p = re.compile('^\s*(\S+)\s*\"(.*)\"');
00077         m = p.match(line)
00078         if m:
00079             pic = m.group(1)
00080             caption = m.group(2)
00081             return (pic, caption)
00082         else:
00083             print 'bad caption format: "%s"' % line
00084             raise Exception
00085 
00086 class website:
00087     def __init__(self):
00088         self.website_ = '/afs/cern.ch/cms/Physics/particleflow/Validation/cms-project-pfvalidation/Releases'
00089         self.url_ = 'http://cern.ch/pfvalidation/Releases'
00090     
00091     def __str__(self):
00092         return self.website_
00093 
00094 
00095     def writeAccess(self):
00096         if( os.access(self.website_, os.W_OK)==False ):
00097             print 'cannot write to the website. Please ask Colin to give you access.'
00098             sys.exit(1)
00099 
00100     def listBenchmarks(self, pattern, afs=False, url=False):
00101         for bench in glob.glob(self.website_ + '/' + pattern):
00102             # strip off the root path of the website
00103             p = re.compile('^%s/(\S+)$' % self.website_);
00104             m = p.match( bench )
00105             if m:
00106                 (release, benchName, extension) = decodePath( m.group(1) )
00107                 if release == None:
00108                     # this is a comparison
00109                     continue
00110                 print
00111                 bench = benchmark(m.group(1))
00112                 print bcolors.OKGREEN + m.group(1) + bcolors.ENDC
00113                 if afs or url:                        
00114                     if afs: print '  ',bench.benchmarkOnWebSite( self )
00115                     if url: print '  ',bench.benchmarkUrl( self )
00116         
00117     def listComparisons(self, benchmark):
00118 
00119         comparisons = []
00120         find = 'find %s -type d' % self.website_
00121         for dir in os.popen( find ):
00122             dir = dir.rstrip()
00123             #print dir 
00124             comp = '%s/\S+/\S+/%s' % (self.website_,
00125                                       benchmark.fullName() )
00126             #print "** ", comp
00127             p = re.compile(comp)
00128             m = p.match(dir)
00129             if m:
00130                 comparisons.append(dir)
00131                 #print ' ',dir
00132         return comparisons
00133 
00134 class benchmark:
00135  
00136     # arg can be either the full name of a benchmark, or 
00137     # an extension, in which case, the release and benchmark name are guessed 
00138     # from the environment variables. 
00139     def __init__(self, arg=None):
00140 
00141         release = None
00142         benchName = None
00143         extension = None
00144         self.indexHtml_ = 'index.html'
00145         
00146         if arg != None:
00147             (release, benchName, extension) = decodePath( arg )
00148 
00149         if release == None:
00150             # we get there if:
00151             # - arg == None
00152             # - the decoding of arg as a full benchmark name has failed. 
00153             self.release_ = os.environ['CMSSW_VERSION']
00154         
00155             # benchmark directory, as the current working directory
00156             self.benchmark_ = os.path.basename( os.getcwd() )
00157 
00158             # underscore are not allowed in extension names 
00159             if arg!=None and arg.count('_'):
00160                 print 'sorry, as said many times, underscores are not allowed in the extension ;P'
00161                 sys.exit(5)
00162             
00163             extension = arg
00164         else:
00165             self.release_ = release
00166             self.benchmark_ = benchName
00167 
00168         self.benchmarkWithExt_ = self.benchmark_
00169         if( extension != None ):
00170             self.benchmarkWithExt_ = '%s_%s' % (self.benchmark_, extension)
00171 
00172         
00173     def __str__(self):
00174         return self.release_ + '/' + self.benchmarkWithExt_
00175 
00176     def fullName(self):
00177         return self.release_ + '/' + self.benchmarkWithExt_
00178   
00179     def releaseOnWebSite( self, website ):
00180         return '%s/%s'  % ( website, self.release_ )
00181 
00182     def benchmarkOnWebSite( self, website ):
00183         return  '%s/%s' % ( website, self.fullName() )
00184 #        return '%s/%s'  % ( self.releaseOnWebSite(website), 
00185 #                            self.benchmarkWithExt_ )
00186 
00187     def rootFileOnWebSite( self, website ):
00188         return '%s/%s'  % ( self.benchmarkOnWebSite(website), 
00189                             'benchmark.root' )
00190     
00191     def releaseUrl( self, website ):
00192         return '%s/%s'  % ( website.url_, self.release_ )
00193 
00194     
00195     def benchmarkUrl( self, website ):
00196         return '%s/%s'  % ( self.releaseUrl( website ), 
00197                             self.benchmarkWithExt_ )
00198     
00199     def makeRelease( self, website):
00200         rel = self.releaseOnWebSite(website)
00201         if( os.path.isdir( rel )==False):
00202             print 'creating release %s' % self.release_
00203             print rel
00204             os.mkdir( rel )
00205 
00206     def exists( self, website): 
00207         if( os.path.isdir( self.benchmarkOnWebSite(website) )):
00208             print 'benchmark %s exists for release %s' % (self.benchmarkWithExt_, self.release_)
00209             return True
00210         else:
00211             print 'benchmark %s does not exist for release %s' % (self.benchmarkWithExt_, self.release_)
00212             return False
00213 
00214     def addLinkToComparison( self, website, comparison ):
00215         url = comparison.comparisonUrl( website )
00216         index = self.benchmarkOnWebSite(website) + '/' + self.indexHtml_
00217         indexTmp = self.benchmarkOnWebSite(website) + '/index.tmp.html' 
00218         indexFile = open( index)
00219         indexFileTmp = open( indexTmp, 'w')
00220         for line in indexFile:
00221             p = re.compile('<h2>Comparisons:</h2>')
00222             m = p.match(line)
00223             indexFileTmp.write(line)
00224             if m:
00225                 link = '<A href="%s">%s</A><BR>\n' % (url, url)
00226                 indexFileTmp.write(link)
00227         shutil.move( indexTmp, index)
00228 
00229 class comparison:
00230 
00231     def __init__(self, benchmark, comparisonPath):
00232         self.benchmark_ = benchmark
00233         self.path_ = comparisonPath
00234 
00235     def comparisonOnWebSite(self, website):
00236         return  '%s/%s' % ( self.benchmark_.benchmarkOnWebSite(website),
00237                             self.path_ )
00238 
00239     def comparisonUrl(self, website):
00240         return '%s/%s'  % ( self.benchmark_.benchmarkUrl(website),
00241                             self.path_ )
00242 
00243     def submit(self, website, force=False):
00244         print 'Submitting comparison:'
00245         print '  from: ',self.path_
00246         print '  to  : ',self.comparisonOnWebSite(website)
00247 
00248         if( os.path.isdir(self.comparisonOnWebSite(website) ) ):
00249             print 'comparison already exists'
00250             if force:
00251                 print 'overwriting comparison on the website...'
00252             else:
00253                 print 'submission cancelled. run with -h for a solution.'
00254                 return False
00255         else:
00256             print 'comparison directory does not yet exist. creating it.'
00257             mkdir = 'mkdir -p ' + self.comparisonOnWebSite(website)
00258             print mkdir    
00259             if os.system( mkdir ):
00260                 print 'problem creating the output directory on the website. Aborting.'
00261                 return False
00262         cp = 'cp %s %s' % (self.path_ + '/*',
00263                            self.comparisonOnWebSite(website))
00264         if os.system(cp):
00265             print 'problem copying the files to the website aborting'
00266             return False
00267 
00268         print 'access your comparison here:'
00269         print '  ', self.comparisonUrl(website)
00270 
00271 
00272 
00273 # pathname in the form: CMSSW_3_1_0_pre7/TauBenchmarkGeneric_Extension
00274 def decodePath( path ):
00275     p = re.compile('^(\S+)/([^\s_]+)_(\S+)');
00276     m = p.match(path)
00277     if m:
00278         release = m.group(1)
00279         benchmarkname = m.group(2)
00280         extension = m.group(3)
00281         return (release, benchmarkname, extension )
00282     else:
00283         return (None, None, None)
00284 
00285 #test that a given file is a file with the correct extenstion, e.g. .root
00286 def testFileType( file, ext ):
00287 
00288      if file == "None":
00289           return
00290      
00291      if os.path.isfile( file ) == False:
00292           print '%s is not a file' % file
00293           sys.exit(2)
00294      
00295      (fileroot, fileext) = os.path.splitext( file )
00296      if fileext != ext:
00297           print '%s does not end with %s' % (file, ext) 
00298           sys.exit(3)
00299 
00300 
00301 # copy a file to a destination directory, and return the basename
00302 # that is the filename without the path. that name is used
00303 # to set a relative link in the html code
00304 def processFile( file, outputDir ):
00305  
00306      if file == "None":
00307           return 'infoNotFound.html'
00308      else:
00309           if os.path.isfile(file):
00310                shutil.copy(file, outputDir)
00311                return os.path.basename(file)
00312           else:
00313                return file
00314 
00315 class bcolors:
00316     HEADER = '\033[95m'
00317     OKBLUE = '\033[94m'
00318     OKGREEN = '\033[92m'
00319     WARNING = '\033[93m'
00320     FAIL = '\033[91m'
00321     ENDC = '\033[0m'
00322 
00323     def disable(self):
00324         self.HEADER = ''
00325         self.OKBLUE = ''
00326         self.OKGREEN = ''
00327         self.WARNING = ''
00328         self.FAIL = ''
00329         self.ENDC = ''
00330