CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Utilities/RelMon/python/dqm_interfaces.py

Go to the documentation of this file.
00001 ################################################################################
00002 # RelMon: a tool for automatic Release Comparison                              
00003 # https://twiki.cern.ch/twiki/bin/view/CMSPublic/RelMon
00004 #
00005 # $Author: anorkus $
00006 # $Date: 2013/07/10 14:37:45 $
00007 # $Revision: 1.9 $
00008 #
00009 #                                                                              
00010 # Danilo Piparo CERN - danilo.piparo@cern.ch                                   
00011 #                                                                              
00012 ################################################################################
00013 
00014 from copy import deepcopy
00015 from os import chdir,getcwd,makedirs
00016 from os.path import abspath,exists,join, basename
00017 from re import sub,search
00018 from re import compile as recompile
00019 from sys import exit,stderr,version_info
00020 from threading import Thread,activeCount
00021 from time import sleep
00022 from urllib2  import Request,build_opener,urlopen
00023 
00024 import sys
00025 argv=sys.argv
00026 from ROOT import *
00027 import ROOT
00028 sys.argv=argv
00029 
00030 gROOT.SetBatch(True)
00031 
00032 from authentication import X509CertOpen
00033 from dirstructure import Comparison,Directory,tcanvas_print_processes
00034 from utils import Chi2,KS,BinToBin,Statistical_Tests,literal2root
00035 
00036 #-------------------------------------------------------------------------------  
00037 
00038 class Error(Exception):
00039     """Base class for exceptions in this module."""
00040     pass
00041 
00042 class DQM_DB_Communication(Error):
00043     """Exception occurs in case of problems of communication with the server.
00044     """
00045     def __init__(self,msg):
00046         self.msg = msg
00047 
00048 class InvalidNumberOfArguments(Error):
00049 
00050     def __init__(self,msg):
00051         self.msg = msg
00052    
00053 #-----------------------------------------------------------------------------    
00054 
00055 class DQMcommunicator(object):
00056   
00057   """Communicate with the DQM Document server"""
00058   
00059   #-----------------------------------------------------------------------------
00060   
00061   base_dir='/data/json/archive/'
00062   
00063   def __init__(self,
00064                server,
00065                is_private=False,
00066                ident="DQMToJson/1.0 python/%d.%d.%d" % version_info[:3]):
00067     self.ident = ident
00068     self.server = server
00069     self.is_private = is_private
00070     self.DQMpwd=DQMcommunicator.base_dir
00071     self.prevDQMpwd=self.DQMpwd
00072     self.opener=None
00073     if not self.is_private:
00074       self.opener=build_opener(X509CertOpen())
00075   #-----------------------------------------------------------------------------
00076   
00077   def open_url(self,url):
00078     url=url.replace(' ','%20')
00079     datareq = Request(url)
00080     datareq.add_header('User-agent', self.ident)    
00081     url_obj=0
00082     if not self.is_private:
00083       url_obj=self.opener.open(datareq)   
00084       #url_obj=build_opener(X509CertOpen()).open(datareq) 
00085     else:
00086       url_obj=urlopen(datareq)
00087       
00088     return url_obj
00089   
00090   #-----------------------------------------------------------------------------
00091   
00092   def get_data(self, full_url):
00093     #print "getting data from %s" %full_url
00094     data = self.open_url(full_url).read()
00095     
00096     data = sub("-inf", '0', data)
00097     data = sub("\s+inf", '0', data)
00098     data = sub("\s+nan", '0', data)
00099     data = sub('""(CMSSW.*?)""', '"\\1"', data)
00100    
00101     return data
00102   
00103   #-----------------------------------------------------------------------------
00104 
00105   def ls_url(self, url):
00106     url=url.replace(" ","%20")
00107     url=self.server+url
00108     #print "listing "+url
00109     form_folder={}
00110     raw_folder=None
00111     try:
00112       raw_folder=eval(self.get_data(url))
00113     except:
00114       print "Retrying.."
00115       for ntrials in xrange(5):
00116         try:
00117           if ntrials!=0:
00118             sleep(2)
00119           #raw_folder=loads(self.get_data(url))
00120           raw_folder=eval(self.get_data(url))
00121           break
00122         except:
00123           print "Could not fetch %s. Retrying" %url
00124         
00125     #raw_folder=loads(self.get_data(url))
00126     for content_dict in raw_folder["contents"]:      
00127       if content_dict.has_key("subdir"):
00128         form_folder[content_dict["subdir"]]={"type":'dir'}
00129       elif content_dict.has_key("obj"):
00130         properties=content_dict["properties"]
00131         obj_name=content_dict["obj"]
00132         obj_type=properties["type"]
00133         obj_kind=properties["kind"]
00134         obj_as_string=''
00135         if content_dict.has_key("rootobj"):
00136           obj_as_string=content_dict["rootobj"]
00137         form_folder[obj_name]={'type':obj_type,'obj_as_string':obj_as_string,"kind":obj_kind}
00138     #for k,v in form_folder.items():
00139       #print "* %s --> %s" %(k,v["type"])
00140     
00141     return form_folder        
00142   
00143   #-----------------------------------------------------------------------------
00144  
00145   def ls(self, url='', fetch_root=False):
00146     if len(url)==0:
00147       url=join(self.DQMpwd,url)
00148     
00149     form_folder={}   
00150     
00151     if fetch_root:
00152       url='%s?rootcontent=1'%url
00153     form_folder=self.ls_url(url)
00154 
00155     return form_folder
00156     
00157   #-----------------------------------------------------------------------------
00158 
00159   def cd(self, *args):
00160     len_args=len(args)
00161     full_url=""
00162     if len_args!=1 and len_args!=3:
00163       raise(InvalidNumberOfArguments("3 or 1 args expected!"))
00164     if len_args==3:
00165       dataset, run, folder = args    
00166       full_url='%s/data/json/archive/%s/%s/%s' % (self.server, dataset, run, folder)
00167     if len_args==1:
00168       folder=args[0]
00169       if folder==self.DQMpwd:
00170         full_url=self.DQMpwd
00171       elif folder=="..":
00172         full_url=self.DQMpwd[:self.DQMpwd.rfind("/")]
00173       elif folder=="-":
00174         full_url=self.oldDQMpwd
00175       elif folder=="":
00176         full_url=DQMcommunicator.base_dir
00177       else:
00178         full_url=self.DQMpwd+"/"+folder
00179         
00180     full_url=full_url.replace(' ','%20')
00181     #print "cd: "+full_url
00182     
00183     self.oldDQMpwd=self.DQMpwd
00184     self.DQMpwd=full_url   
00185     #print "In %s" %self.DQMpwd
00186   
00187   #-----------------------------------------------------------------------------
00188   
00189   def get_samples(self, samples_string="*"):
00190     """
00191     A sample contains, among the other things, a data type, a dataset name 
00192     and a run.
00193     """
00194     full_url='%s/data/json/samples?match=%s' % (self.server, samples_string)
00195     samples_dict=eval(self.get_data(full_url))
00196     return samples_dict["samples"]
00197 
00198   #-----------------------------------------------------------------------------
00199   
00200   def get_datasets_list(self, dataset_string=""):
00201     samples_list=self.get_samples(dataset_string)    
00202     datasets_list=[]
00203     for sample in samples_list:
00204       temp_datasets_list =  map(lambda item:item["dataset"] ,sample['items'])
00205       for temp_dataset in temp_datasets_list:
00206         if not temp_dataset in datasets_list:
00207           datasets_list.append(temp_dataset)
00208     return datasets_list
00209     
00210   #-----------------------------------------------------------------------------
00211     
00212   def get_RelVal_CMSSW_versions(self,query):
00213     """Get the available cmssw versions for the relvals.
00214     """
00215     relvals_list=self.get_datasets_list(query)
00216     # The samples are of the form /RelValTHISISMYFAVOURITECHANNEL/CMSSW_VERSION/GEN-SIM-WHATEVER-RECO
00217     cmssw_versions_with_duplicates=map (lambda x: x.split("/")[2],relvals_list)
00218     return list(set(cmssw_versions_with_duplicates))
00219     
00220   #-----------------------------------------------------------------------------    
00221     
00222   def get_runs_list(self, dataset_string):
00223     slash="/"
00224     while(dataset_string.endswith(slash) or dataset_string.beginswith(slash)):
00225       dataset_string=dataset_string.strip("/")
00226     samples_list=self.get_samples(dataset_string)
00227     runlist=[]
00228     # Get all the runs in all the items which are in every sample
00229     map( lambda sample: map (lambda item: runlist.append(item['run']), sample['items']), samples_list)
00230     return runlist
00231   
00232   #-----------------------------------------------------------------------------  
00233   
00234   def get_dataset_runs(self,dataset_string):
00235     dataset_runs={}
00236     for dataset in self.get_datasets_list(dataset_string):
00237       dataset_runs[dataset]=self.get_runs_list(dataset)
00238     return dataset_runs
00239 
00240   #-----------------------------------------------------------------------------  
00241   
00242   def get_common_runs(self,dataset_string1,dataset_string2):
00243     set1=set(self.get_runs_list(dataset_string1))
00244     set2=set(self.get_runs_list(dataset_string2))
00245     set1.intersection_update(set2)
00246     return list (set2)
00247 
00248   #-----------------------------------------------------------------------------  
00249   
00250   def get_root_objects_list(self, url=""):
00251     if len(url)==0:
00252       url=self.DQMpwd
00253     else:
00254       url="/"+url    
00255     url = url.replace(" ","%20")
00256     objects=[]
00257     for name,description in self.ls(url,True).items():     
00258       if "dir" not in description["type"]  and "ROOT" in description["kind"]:
00259         objects.append(literal2root(description["obj_as_string"],description["type"]))
00260     return objects
00261 
00262   #-----------------------------------------------------------------------------  
00263   
00264   def get_root_objects(self, url=""):
00265     if len(url)==0:
00266       url=self.DQMpwd
00267     else:
00268       url=self.server+"/"+url    
00269     url = url.replace(" ","%20")
00270     objects={}
00271     for name,description in self.ls(url,True).items():     
00272       if "dir" not in description["type"] and "ROOT" in description["kind"]:
00273         objects[name]=literal2root(description["obj_as_string"],description["type"])
00274     return objects
00275 
00276  #-------------------------------------------------------------------------------
00277   
00278   def get_root_objects_list_recursive(self, url=""):
00279     null_url = (len(url)==0)    
00280     if len(url)==0:
00281       url=self.DQMpwd
00282     else:
00283       url="/"+url    
00284     url = url.replace(" ","%20")      
00285     if not null_url: 
00286       self.cd(url)
00287     objects=[]
00288     for name,description in self.ls("",True).items():     
00289       if "dir" in description["type"]:
00290         objects+=self.get_root_objects_list_recursive(name)
00291         self.cd("..")
00292       elif  "ROOT" in description["kind"]:
00293         objects.append(literal2root(description["obj_as_string"],description["type"]))
00294     if not null_url: 
00295       self.cd("..")
00296     return objects
00297     
00298  #-------------------------------------------------------------------------------
00299   
00300   def get_root_objects_names_list_recursive(self, url="",present_url=""):
00301     null_url = (len(url)==0)
00302     if (not null_url):
00303       if len(present_url)==0:
00304         present_url=url
00305       else:
00306         present_url+="_%s"%url
00307     if len(url)==0:
00308       url=self.DQMpwd
00309     else:
00310       url="/"+url    
00311     url = url.replace(" ","%20")
00312     if not null_url:
00313       self.cd(url)
00314     objects_names=[]
00315     for name,description in self.ls("",False).items():     
00316       if "dir" in description["type"]:        
00317         objects_names+=self.get_root_objects_names_list_recursive(name,present_url)
00318         self.cd("..")
00319       elif  "ROOT" in description["kind"]:
00320         objects_names.append("%s_%s"%(present_url,name))
00321     if not null_url: 
00322       self.cd("..")
00323     return objects_names
00324     
00325  #-------------------------------------------------------------------------------
00326   
00327   def get_root_objects_recursive(self, url="",present_url=""):
00328     null_url = (len(url)==0)
00329     if (not null_url):
00330       if len(present_url)==0:
00331         present_url=url
00332       else:
00333         present_url+="_%s"%url
00334     if len(url)==0:
00335       url=self.DQMpwd
00336     else:
00337       url="/"+url    
00338     url = url.replace(" ","%20")
00339     #if not null_url:
00340     self.cd(url)
00341     objects={}
00342     for name,description in self.ls("",True).items():     
00343       if "dir" in description["type"]:
00344         objects.update(self.get_root_objects_recursive(name,present_url))
00345         self.cd("..")
00346       elif  "ROOT" in description["kind"]:
00347         objects["%s_%s"%(present_url,name)]=literal2root(description["obj_as_string"],description["type"])
00348     #if not null_url:
00349     self.cd("..")
00350     return objects
00351 
00352 #-------------------------------------------------------------------------------
00353 
00354 class DirID(object):
00355   """Structure used to identify a directory in the walked tree,
00356   It carries the name and depth information.
00357   """
00358   def __init__(self,name,depth,mother=""):
00359     self.name=name
00360     self.compname=recompile(name)
00361     self.mother=mother
00362     self.depth=depth
00363   def __eq__(self,dirid):
00364     depth2=dirid.depth
00365     compname2=dirid.compname
00366     name2=dirid.name
00367     is_equal = False
00368     #if self.name in name2 or name2 in self.name:
00369     if search(self.compname,name2)!=None or search(compname2,self.name)!=None:
00370       is_equal = self.depth*depth2 <0 or self.depth==depth2
00371     if len(self.mother)*(dirid.mother)>0:
00372       is_equal = is_equal and self.mother==dirid.mother
00373     return is_equal
00374     
00375   def __repr__(self):
00376     return "Directory %s at level %s" %(self.name,self.depth)
00377     
00378 #-------------------------------------------------------------------------------
00379 class DirFetcher(Thread):
00380   """ Fetch the content of the single "directory" in the dqm.
00381   """
00382   def __init__ (self,comm,directory):
00383       Thread.__init__(self)
00384       self.comm = comm
00385       self.directory = directory
00386       self.contents=None    
00387   def run(self):
00388     self.contents = self.comm.ls(self.directory,True)
00389 
00390 #-------------------------------------------------------------------------------
00391 
00392 class DirWalkerDB(Thread):
00393   """An interface to the DQM document db. It is threaded to compensate the 
00394   latency introduced by the finite response time of the server.
00395   """
00396   def __init__ (self,comm1,comm2,base1,base2,directory,depth=0,do_pngs=True,stat_test="KS",test_threshold=.5,black_list=[]):
00397     Thread.__init__(self)
00398     self.comm1 = deepcopy(comm1)
00399     self.comm2 = deepcopy(comm2)
00400     self.base1,self.base2 = base1,base2
00401     self.directory = directory
00402     self.depth=depth
00403     self.do_pngs=do_pngs
00404     self.test_threshold=test_threshold
00405     self.stat_test=stat_test
00406     self.black_list=black_list
00407     # name of the thread
00408     self.name+="_%s" %directory.name
00409   
00410   def run(self):
00411     
00412     this_dir=DirID(self.directory.name,self.depth)
00413     if this_dir in self.black_list: 
00414       print "Skipping %s since blacklisted!" %this_dir
00415       return 0 
00416     
00417     self.depth+=1
00418     
00419     the_test=Statistical_Tests[self.stat_test](self.test_threshold)
00420     #print "Test %s with threshold %s" %(self.stat_test,self.test_threshold)
00421     
00422     directory1=self.base1+"/"+self.directory.mother_dir+"/"+self.directory.name
00423     directory2=self.base2+"/"+self.directory.mother_dir+"/"+self.directory.name
00424     
00425     fetchers =(DirFetcher(self.comm1,directory1),DirFetcher(self.comm2,directory2))
00426     for fetcher in fetchers:
00427       fetcher.start()
00428     for fetcher in fetchers:  
00429       fetcher.join()
00430     
00431     contents1 = fetchers[0].contents
00432     contents2 = fetchers[1].contents
00433     set1= set(contents1.keys())
00434     set2= set(contents2.keys())  
00435     
00436     walkers=[]
00437     self_directory_directories=self.directory.subdirs
00438     self_directory_comparisons=self.directory.comparisons
00439     contents_names=list(set1.intersection(set2))
00440 
00441     for name in contents_names:
00442       content = contents1[name]
00443       if "dir" in content["type"]:
00444         #if this_dir not in DirWalker.white_list:continue              
00445         subdir=Directory(name,join(self.directory.mother_dir,self.directory.name))        
00446         dirwalker=DirWalkerDB(self.comm1,self.comm2,self.base1,self.base2,subdir,self.depth,
00447                               self.do_pngs,self.stat_test,self.test_threshold,self.black_list)
00448         dirwalker.start()
00449         walkers.append(dirwalker)
00450         n_threads=activeCount()
00451         if n_threads>5:
00452           #print >> stderr, "Threads that are running: %s. Joining them." %(n_threads)    
00453           dirwalker.join()
00454       elif content["kind"]=="ROOT":
00455 #       print directory1,name
00456         comparison=Comparison(name,
00457                               join(self.directory.mother_dir,self.directory.name),
00458                               literal2root(content["obj_as_string"],content["type"]),
00459                               literal2root(contents2[name]["obj_as_string"],content["type"]),
00460                               deepcopy(the_test),
00461                               do_pngs=self.do_pngs)
00462         self_directory_comparisons.append(comparison)
00463     
00464     
00465     for walker in walkers:
00466       walker.join()
00467       walker_directory=walker.directory
00468       if not walker_directory.is_empty():
00469         self_directory_directories.append(walker_directory)
00470         
00471 #-------------------------------------------------------------------------------
00472 
00473 class DQMRootFile(object):
00474   """ Class acting as interface between the user and the harvested DQMRootFile.  
00475   It skips the directories created by the DQM infrastructure so to provide an
00476   interface as similar as possible to a real direcory structure and to the 
00477   directory structure provided by the db interface.
00478   """
00479   def __init__(self,rootfilename):
00480     dqmdatadir="DQMData"
00481     self.rootfile=TFile(rootfilename)  
00482     self.rootfilepwd=self.rootfile.GetDirectory(dqmdatadir)
00483     self.rootfileprevpwd=self.rootfile.GetDirectory(dqmdatadir)
00484     if self.rootfilepwd == None:
00485       print "Directory %s does not exist: skipping. Is this a custom rootfile?" %dqmdatadir
00486       self.rootfilepwd=self.rootfile
00487       self.rootfileprevpwd=self.rootfile
00488   
00489   def __is_null(self,directory,name):
00490     is_null = not directory
00491     if is_null:
00492         print >> stderr, "Directory %s does not exist!" %name
00493     return is_null
00494 
00495   def ls(self,directory_name=""):
00496     contents={}
00497     directory=None
00498     if len(directory_name)==0:
00499       directory=self.rootfilepwd      
00500     
00501     directory=self.rootfilepwd.GetDirectory(directory_name)    
00502     if self.__is_null(directory,directory_name):
00503       return contents
00504     
00505     for key in directory.GetListOfKeys():
00506       contents[key.GetName()]=key.GetClassName()
00507     return contents
00508   
00509   def cd(self,directory_name):
00510     """Change the current TDirectoryFile. The familiar "-" and ".." directories 
00511     can be accessed as well.
00512     """
00513     if directory_name=="-":
00514       tmp=self.rootfilepwd
00515       self.rootfilepwd=self.rootfileprevpwd
00516       self.rootfileprevpwd=tmp
00517     if directory_name=="..":
00518       #print "Setting prevpwd"
00519       self.rootfileprevpwd=self.rootfilepwd
00520       #print "The mom"
00521       mom=self.rootfilepwd.GetMotherDir()
00522       #print "In directory +%s+" %self.rootfilepwd
00523       #print "Deleting the TFileDir"
00524       if "Run " not in self.rootfilepwd.GetName():
00525         self.rootfilepwd.Delete()
00526       #print "Setting pwd to mom"
00527       self.rootfilepwd=mom
00528     else:
00529       new_directory=self.rootfilepwd.GetDirectory(directory_name)
00530       if not self.__is_null(new_directory,directory_name):
00531           self.rootfileprevpwd=self.rootfilepwd
00532           self.rootfilepwd=new_directory
00533     
00534   def getObj(self,objname):
00535     """Get a TObject from the rootfile.
00536     """
00537     obj=self.rootfilepwd.Get(objname)
00538     if not self.__is_null(obj,objname):
00539       return obj
00540 
00541 #-------------------------------------------------------------------------------
00542 
00543 class DirWalkerFile(object):
00544   def __init__(self, name, topdirname,rootfilename1, rootfilename2, run=-1, black_list=[], stat_test="KS", test_threshold=.5,draw_success=True,do_pngs=False, black_list_histos=[]):
00545     self.name=name
00546     self.dqmrootfile1=DQMRootFile(abspath(rootfilename1))
00547     self.dqmrootfile2=DQMRootFile(abspath(rootfilename2))
00548     self.run=run
00549     self.stat_test=Statistical_Tests[stat_test](test_threshold)
00550     self.workdir=getcwd()
00551     self.black_list=black_list
00552     self.directory=Directory(topdirname)
00553     #print "DIRWALKERFILE %s %s" %(draw_success,do_pngs)
00554     self.directory.draw_success=draw_success
00555     self.directory.do_pngs=do_pngs
00556     self.black_list_histos = black_list_histos
00557     self.different_histograms = {}
00558     self.filename1 = basename(rootfilename2)
00559     self.filename2 = basename(rootfilename1)
00560 
00561   def __del__(self):
00562     chdir(self.workdir)
00563      
00564   def cd(self,directory_name, on_disk=False, regexp=False,):
00565     if regexp == True:
00566         if len(directory_name)!=0:
00567             if on_disk:
00568                 if not exists(directory_name):
00569                     makedirs(directory_name)
00570                     chdir(directory_name)  
00571             tmp = self.dqmrootfile2.ls().keys()
00572             for elem in tmp:
00573                 if "Run" in elem:
00574                     next_dir = elem
00575             self.dqmrootfile2.cd(next_dir)
00576             tmp = self.dqmrootfile1.ls().keys()
00577             for elem in tmp:
00578                 if "Run" in elem:
00579                     next_dir = elem
00580             self.dqmrootfile1.cd(next_dir)
00581     else:
00582         if len(directory_name)!=0:
00583             if on_disk:
00584                 if not exists(directory_name):
00585                     makedirs(directory_name)
00586                     chdir(directory_name)
00587             self.dqmrootfile2.cd(directory_name)
00588             self.dqmrootfile1.cd(directory_name)
00589     
00590   def ls(self,directory_name=""):
00591     """Return common objects to the 2 files.
00592     """
00593     contents1=self.dqmrootfile1.ls(directory_name)
00594     contents2=self.dqmrootfile2.ls(directory_name)
00595     #print "cont1: %s"%(contents1)
00596     #print "cont2: %s"%(contents2)
00597     contents={}
00598     self.different_histograms['file1']= {}
00599     self.different_histograms['file2']= {}
00600     keys = filter(lambda key: contents1.has_key(key),contents2.keys()) #set of all possible contents from both files
00601     #print " ## keys: %s" %(keys)
00602     for key in keys:  #iterate on all unique keys
00603       if contents1[key]!=contents2[key]:
00604         diff_file1 = set(contents1.keys()) - set(contents2.keys()) #set of contents that file1 is missing
00605         diff_file2 = set(contents2.keys()) - set(contents1.keys()) #--'-- that file2 is missing
00606         for key1 in diff_file1:
00607             obj_type = contents1[key1]
00608             if obj_type == "TDirectoryFile":
00609               self.different_histograms['file1'][key1] = contents1[key1] #if direcory
00610               #print "\n Missing inside a dir: ", self.ls(key1)
00611               #contents[key] = contents1[key1]
00612             if obj_type[:2]!="TH" and obj_type[:3]!="TPr" : #if histogram
00613               continue
00614             self.different_histograms['file1'][key1] = contents1[key1]
00615         for key1 in diff_file2:
00616             obj_type = contents2[key1]
00617             if obj_type == "TDirectoryFile":
00618               self.different_histograms['file2'][key1] = contents2[key1] #if direcory
00619               #print "\n Missing inside a dir: ", self.ls(key1)
00620               #contents[key] = contents2[key1]
00621             if obj_type[:2]!="TH" and obj_type[:3]!="TPr" : #if histogram
00622               continue
00623             self.different_histograms['file2'][key1] = contents2[key1]
00624       contents[key]=contents1[key]
00625     return contents
00626   
00627   def getObjs(self,name):
00628     h1=self.dqmrootfile1.getObj(name)
00629     h2=self.dqmrootfile2.getObj(name)
00630     return h1,h2
00631   
00632   def __fill_single_dir(self,dir_name,directory,mother_name="",depth=0):
00633     #print "MOTHER NAME  = +%s+" %mother_name
00634    #print "About to study %s (in dir %s)" %(dir_name,getcwd())
00635         
00636     # see if in black_list
00637     this_dir=DirID(dir_name,depth)
00638     #print "  ## this_dir: %s"%(this_dir)
00639     if this_dir in self.black_list: 
00640       #print "Directory %s skipped because black-listed" %dir_name
00641       return 0        
00642         
00643     depth+=1
00644     
00645     self.cd(dir_name)
00646     #if dir_name == 'HLTJETMET':
00647     #    print self.ls()
00648     
00649     #print "Test %s with thre %s" %(self.stat_test.name, self.stat_test.threshold)
00650     
00651     contents=self.ls()
00652     if depth==1:
00653       n_top_contents=len(contents)
00654     
00655     #print contents
00656     cont_counter=1
00657     comparisons=[]
00658     for name,obj_type in contents.items():
00659       if obj_type=="TDirectoryFile":        
00660         #We have a dir, launch recursion!
00661         #Some feedback on the progress
00662         if depth==1:
00663           print "Studying directory %s, %s/%s" %(name,cont_counter,n_top_contents)
00664           cont_counter+=1          
00665  
00666         #print "Studying directory",name
00667         # ok recursion on!
00668         subdir=Directory(name)
00669         subdir.draw_success=directory.draw_success
00670         subdir.do_pngs=directory.do_pngs
00671         self.__fill_single_dir(name,subdir,join(mother_name,dir_name),depth)
00672         if not subdir.is_empty():
00673           if depth==1:
00674             print " ->Appending %s..." %name,
00675           directory.subdirs.append(subdir)
00676           if depth==1:
00677             print "Appended."
00678       else:
00679         # We have probably an histo. Let's make the plot and the png.        
00680         if obj_type[:2]!="TH" and obj_type[:3]!="TPr" :
00681           continue
00682         h1,h2=self.getObjs(name)
00683         #print "COMPARISON : +%s+%s+" %(mother_name,dir_name)
00684         path = join(mother_name,dir_name,name)
00685         if path in self.black_list_histos:
00686           print "  Skipping %s" %(path)
00687           directory.comparisons.append(Comparison(name,
00688                               join(mother_name,dir_name),
00689                               h1,h2,
00690                               deepcopy(self.stat_test),
00691                               draw_success=directory.draw_success,
00692                               do_pngs=directory.do_pngs, skip=True))
00693         else:
00694           directory.comparisons.append(Comparison(name,
00695                                 join(mother_name,dir_name),
00696                                 h1,h2,
00697                                 deepcopy(self.stat_test),
00698                                 draw_success=directory.draw_success,
00699                                 do_pngs=directory.do_pngs, skip=False))
00700           directory.filename1 = self.filename1
00701           directory.filename2 = self.filename2
00702           directory.different_histograms['file1'] = self.different_histograms['file1']
00703           directory.different_histograms['file2'] = self.different_histograms['file2']
00704 
00705     self.cd("..")
00706    
00707   def walk(self):
00708     # Build the top dir in the rootfile first
00709     rundir=""
00710     if self.run<0:
00711       # change dir in the first one...
00712       #print  self.ls().keys()
00713       first_run_dir = ""
00714       try:
00715         first_run_dir = filter(lambda k: "Run " in k, self.ls().keys())[0]
00716       except:
00717          print "\nRundir not there: Is this a generic rootfile?\n"
00718       rundir=first_run_dir
00719       try:
00720         self.run= int(rundir.split(" ")[1])
00721       except:
00722         print "Setting run number to 0"
00723         self.run= 0
00724     else:
00725       rundir="Run %s"%self.run
00726     
00727     try:
00728       self.cd(rundir, False, True) #True -> for checking the Rundir in case of different runs
00729     except:
00730       print "\nRundir not there: Is this a generic rootfile?\n"
00731     
00732     # Let's rock!
00733     self.__fill_single_dir(self.directory.name,self.directory)
00734     print "Finished"
00735     n_left_threads=len(tcanvas_print_processes)
00736     if n_left_threads>0:
00737       print "Waiting for %s threads to finish..." %n_left_threads
00738       for p in tcanvas_print_processes:
00739         p.join()  
00740 
00741 #-------------------------------------------------------------------------------
00742 
00743 class DirWalkerFile_thread_wrapper(Thread):
00744   def __init__(self, walker):
00745     Thread.__init__(self)
00746     self.walker=walker
00747   def run(self):
00748     self.walker.walk()
00749     
00750 #-------------------------------------------------------------------------------
00751 
00752 def string2blacklist(black_list_str):
00753   black_list=[]
00754   # replace the + with " ":
00755   black_list_str=black_list_str.replace("__"," ")
00756   if len(black_list_str)>0:
00757     for ele in black_list_str.split(","):
00758       dirname,level=ele.split("@")
00759       level=int(level)
00760       dirid=None
00761       if "/" not in dirname:
00762         dirid=DirID(dirname,level)
00763       else:
00764         mother,daughter=dirname.split("/")
00765         dirid=DirID(daughter,level,mother)
00766       if not dirid in black_list:
00767         black_list.append(dirid)
00768         
00769   return black_list
00770     
00771 #-------------------------------------------------------------------------------
00772