Back to home page

Project CMSSW displayed by LXR



File indexing completed on 2023-03-17 10:44:28

0001 #! /usr/bin/env python
0002 #G.Benelli Aug 26 2010
0003 #Process the DEBUG output log files to prepare them as inputs to tkmapcreator...
0004 #Incorporating also the next step: cloning the files (1 per log file, i.e. 1 per IOV) and execute cmsRun
0005 #producing the wanted tkMaps.
0007 #TODO:
0008 #Could use this same script to do other processing as input to the for other type of plots etc...
0010 #Script assumes that it is run in the same dir as the output of
0011 #TODO:
0012 #In the future can put it in scripts/ and take dir to run from and write to as options.
0014 from __future__ import print_function
0015 import os, subprocess
0017 def ProduceTkMapVoltageInputFiles(workdir=os.getcwd()): #Setting the dir by default to the current working directory...
0018     """
0019     Function that processes the indicated workdir directory (defaults to current working directory) looking for
0020     DetVOffReaderDebug*.log files.
0021     For each log file (that correspond to 1 IOV) 2 input files (one for LV one for HV status) are created for the TkVoltageMapCreator plugin.
0022     The function returns the 2 lists of HV and LV files.
0023     """
0024     #Get all the files in the directory workdir (1 file per IOV):
0025     print("Analysing %s directory"%workdir)
0026     logfilenames=[x for x in os.listdir(workdir) if x.startswith("DetVOffReaderDebug")]
0027     if logfilenames:
0028         print("Processing %s logfiles..."%len(logfilenames))
0029     else:
0030         print("No DetVIfReaderDebug files found!\nPlease run this script in the same dir you have run, or in the dir where you store the output logfiles.")
0032     #Let's dump for each IOV a TkVoltageMapCreator ready input file, i.e. with 1 entry per detID...
0033     #Need to read in our usual pkl to get all the strip detids
0034     #Get it from the release
0035     import pickle
0036     #FIX:
0037     #Until the tag is in the release, CMSSW_RELEASE_BASE should be replaced by CMSSW_BASE...
0038     StripDetIDAliasPickle=os.path.join(os.getenv("CMSSW_RELEASE_BASE"),"src/CalibTracker/SiStripDCS/data","StripDetIDAlias.pkl")
0039     #TODO:
0040     #Could use try/except to make this robust... but from next CVS commit should be fine...
0041     #Otherwise can use the file in ~gbenelli/O2O/StripDetIDAlias.pkl, use full AFS path!
0042     DetIDdict=open(StripDetIDAliasPickle,"r")
0043     StripDetIDAlias=pickle.load(DetIDdict)
0045     #Process the logfiles!
0046     #Lists to keep the LV/HV input files, that will be returned by the function:
0047     LVFilenames=[]
0048     HVFilenames=[]
0049     for logfilename in logfilenames:
0050         print(logfilename)
0051         #Create LV/HV filenames for the input files we will write
0052         #TODO:
0053         #Could add here the possibility of writing in a different dir, by adding an extra outdir argument to the function
0054         #and use that instead of workdir...
0055         LVfilename=os.path.join(workdir,logfilename.replace("DetVOffReaderDebug_","LV"))
0056         HVfilename=os.path.join(workdir,logfilename.replace("DetVOffReaderDebug_","HV"))
0058         #Adding the filenames to the respective lists that will be returned by the function:
0059         LVFilenames.append(LVfilename)
0060         HVFilenames.append(HVfilename)
0062         #Open input/output files:
0063         logfile=open(logfilename,"r")
0064         LVfile=open(LVfilename,"w")
0065         HVfile=open(HVfilename,"w")
0067         #File parsing and creation of 2 separate LV and HV status files:
0068         #Need dicts to handle the filling of files with all detIDs:
0069         LVDict={}
0070         HVDict={}
0071         for line in logfile:
0072             if "OFF" in line: #All the interesting lines contain "OFF" by definition 
0073                 (detid,HV,LV)=line.split()
0074             LVDict.update({detid:LV})
0075             HVDict.update({detid:HV})
0077         #Handle the LV/HV files:
0078         for detid in StripDetIDAlias.keys():
0079             detid=str(detid)
0080             if detid in LVDict.keys(): #Set the detids to whatever status they were reported (can be ON or OFF, since the detid would be reported in the case of HV OFF and LV ON of course...)
0081                 LVfile.write(detid+"\t"+LVDict[detid]+"\n")
0082             else: #Set the remaining detids as ON (they would be reported otherwise in the LVDict)
0083                 LVfile.write(detid+"\tON\n")
0084             if detid in HVDict.keys(): #Set the detids to whatever status they were reported (should only reported when OFF..., HV ON while LV OFF should be impossible)
0085                 HVfile.write(detid+"\t"+HVDict[detid]+"\n")
0086             else: #Set the remaining detids as ON (they would be reported otherwise in the HVDict)
0087                 HVfile.write(detid+"\tON\n")
0090         #Close files:
0091         logfile.close()
0092         LVfile.close()
0093         HVfile.close()
0095     #Now finally return the 2 lists of LV and HV TkVoltageMapCreator input files:
0096     return LVFilenames,HVFilenames
0098 #Function to run a (for us cmsRun) command:
0099 def runcmd(command):
0100     """
0101     Function that uses subprocess.Popen to run commands, it returns the exit code of the command. 
0102     """
0103     try:
0104         process  = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
0106         exitstat= process.wait()
0107         cmdout   =
0108         exitstat = process.returncode
0109     except OSError as detail:
0110         print("Race condition in subprocess.Popen has robbed us of the exit code of the %s process (PID %s).Assume it failed!\n %s\n"%(command,pid,detail))
0111         exitstat=999
0112     if exitstat == None:
0113         print("Something strange is going on! Exit code was None for command %s: check if it really ran!"%command)
0114         exitstat=0
0115     return exitstat
0117 def CreateTkVoltageMapsCfgs(workdir=os.getcwd()): #Default to current working directory (could pass HV/LV list)
0118     """
0119     Function that looks for TkVoltageMapCreator input files, creates 1 for each IOV.
0120     It returns the list of cfgs ready to be cmsRun to produce the maps 
0121     """
0122     #Use HV log files to loop... could use also LV logs...
0123     HVLogs=[x for x in os.listdir(workdir) if x.startswith("HV") and "FROM" in x and x.endswith(".log")]
0125     #Open the file to use as template
0126     TkMapCreatorTemplateFile=open(os.path.join(os.getenv("CMSSW_BASE"),"src/CalibTracker/SiStripDCS/test",""),"r")
0127     TkMapCreatorTemplateContent=TkMapCreatorTemplateFile.readlines()
0128     #Let's do it!
0129     TkMapCfgFilenames=[]
0130     for HVlog in HVLogs:
0131         #Use full path since workdir could be different than current working dir:
0132         HVlog=os.path.join(workdir,HVlog)
0133             #Check if the corresponding LV log is there!
0134         LVlog=os.path.join(workdir,HVlog.replace("HV","LV"))
0135         if not os.path.exists(LVlog):
0136             print("ARGH! Missing LV file for file %s"%HVlog)
0137             print("Will not process the HV file either!")
0138         TkMapCfgFilename=os.path.join(workdir,HVlog.replace("HV","TkVoltageMap").replace(".log",""))
0139         TkMapCfgFilenames.append(TkMapCfgFilename)
0140         TkMapCfg=open(TkMapCfgFilename,"w")
0141         for line in TkMapCreatorTemplateContent:
0142             if "LVStatusFile" in line and "#" not in line:
0143                 line='\tLVStatusFile = cms.string("%s"),\n'%LVlog
0144             if "LVTkMapName" in line and "#" not in line:
0145                 line='\tLVTkMapName = cms.string("%s"),\n'%LVlog.replace(".log",".png")
0146             if "HVStatusFile" in line and "#" not in line:
0147                 line='\tHVStatusFile = cms.string("%s"),\n'%HVlog
0148             if "HVTkMapName" in line and "#" not in line:
0149                 line='\tHVTkMapName = cms.string("%s")\n'%HVlog.replace(".log",".png")
0150             TkMapCfg.write(line)
0151         TkMapCfg.close()
0153     TkMapCreatorTemplateFile.close()
0154     return TkMapCfgFilenames
0156 def CreateTkVoltageMaps(workdir=os.getcwd()): #Default to current working directory for now...
0157     """
0158     Function that looks for TkVoltageMap* in the workdir directory and launches each of them
0159     creating 2 TkVoltageMaps per IOV, one for LV and one of HV status (each as a png file). 
0160     """
0161     TkMapCfgs=[x for x in os.listdir(workdir) if x.startswith("TkVoltageMap") and "FROM" in x and x.endswith("")]
0162     for TkMapCfg in TkMapCfgs:
0163         #Make sure we run the cfg in the workdir and also the logfile is saved there...
0164         TkMapCfg=os.path.join(workdir,TkMapCfg)
0165         cmsRunCmd="cmsRun %s >& %s"%(TkMapCfg,TkMapCfg.replace(".py",".log"))
0166         print(cmsRunCmd)
0167         exitstat=runcmd(cmsRunCmd)
0168         if exitstat != 0:
0169             print("Uh-Oh!")
0170             print("Command %s FAILED!"%cmsRunCmd)
0172 #Could put in a def main...
0174 #Create the TkVoltageMapCreator input files in the test dir below:
0175 (LVfiles,HVfiles)=ProduceTkMapVoltageInputFiles()
0176 #print LVfiles
0177 #print HVfiles
0179 #Create the actual TkVoltageMaps!
0180 TkMapCfgFilenames=CreateTkVoltageMapsCfgs()
0181 print(TkMapCfgFilenames)
0182 CreateTkVoltageMaps()
0184 #Finish this up, so that it can be committed, but above all use it!
0185 #Check how to use to access the Offline DB directly! Maybe can fold this in?