1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
#! /usr/bin/env python
#G.Benelli Aug 26 2010
#Process the CheckAllIOVs.py DEBUG output log files to prepare them as inputs to tkmapcreator...
#Incorporating also the next step: cloning the cfg.py files (1 per log file, i.e. 1 per IOV) and execute cmsRun
#producing the wanted tkMaps.
#TODO:
#Could use this same script to do other processing as input to the ValidateO2O.py for other type of plots etc...
#Script assumes that it is run in the same dir as the output of CheckAllIOVs.py
#TODO:
#In the future can put it in scripts/ and take dir to run from and write to as options.
import os, subprocess
def ProduceTkMapVoltageInputFiles(workdir=os.getcwd()): #Setting the dir by default to the current working directory...
"""
Function that processes the indicated workdir directory (defaults to current working directory) looking for CheckAllIOVs.py
DetVOffReaderDebug*.log files.
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.
The function returns the 2 lists of HV and LV files.
"""
#Get all the files in the directory workdir (1 file per IOV):
print("Analysing %s directory"%workdir)
logfilenames=[x for x in os.listdir(workdir) if x.startswith("DetVOffReaderDebug")]
if logfilenames:
print("Processing %s logfiles..."%len(logfilenames))
else:
print("No DetVIfReaderDebug files found!\nPlease run this script in the same dir you have run CheckAllIOVS.py, or in the dir where you store the output logfiles.")
#Let's dump for each IOV a TkVoltageMapCreator ready input file, i.e. with 1 entry per detID...
#Need to read in our usual pkl to get all the strip detids
#Get it from the release
import pickle
#FIX:
#Until the tag is in the release, CMSSW_RELEASE_BASE should be replaced by CMSSW_BASE...
StripDetIDAliasPickle=os.path.join(os.getenv("CMSSW_RELEASE_BASE"),"src/CalibTracker/SiStripDCS/data","StripDetIDAlias.pkl")
#TODO:
#Could use try/except to make this robust... but from next CVS commit should be fine...
#Otherwise can use the file in ~gbenelli/O2O/StripDetIDAlias.pkl, use full AFS path!
DetIDdict=open(StripDetIDAliasPickle,"r")
StripDetIDAlias=pickle.load(DetIDdict)
#Process the logfiles!
#Lists to keep the LV/HV input files, that will be returned by the function:
LVFilenames=[]
HVFilenames=[]
for logfilename in logfilenames:
print(logfilename)
#Create LV/HV filenames for the input files we will write
#TODO:
#Could add here the possibility of writing in a different dir, by adding an extra outdir argument to the function
#and use that instead of workdir...
LVfilename=os.path.join(workdir,logfilename.replace("DetVOffReaderDebug_","LV"))
HVfilename=os.path.join(workdir,logfilename.replace("DetVOffReaderDebug_","HV"))
#Adding the filenames to the respective lists that will be returned by the function:
LVFilenames.append(LVfilename)
HVFilenames.append(HVfilename)
#Open input/output files:
logfile=open(logfilename,"r")
LVfile=open(LVfilename,"w")
HVfile=open(HVfilename,"w")
#File parsing and creation of 2 separate LV and HV status files:
#Need dicts to handle the filling of files with all detIDs:
LVDict={}
HVDict={}
for line in logfile:
if "OFF" in line: #All the interesting lines contain "OFF" by definition
(detid,HV,LV)=line.split()
LVDict.update({detid:LV})
HVDict.update({detid:HV})
#Handle the LV/HV files:
for detid in StripDetIDAlias.keys():
detid=str(detid)
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...)
LVfile.write(detid+"\t"+LVDict[detid]+"\n")
else: #Set the remaining detids as ON (they would be reported otherwise in the LVDict)
LVfile.write(detid+"\tON\n")
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)
HVfile.write(detid+"\t"+HVDict[detid]+"\n")
else: #Set the remaining detids as ON (they would be reported otherwise in the HVDict)
HVfile.write(detid+"\tON\n")
#Close files:
logfile.close()
LVfile.close()
HVfile.close()
#Now finally return the 2 lists of LV and HV TkVoltageMapCreator input files:
return LVFilenames,HVFilenames
#Function to run a (for us cmsRun) command:
def runcmd(command):
"""
Function that uses subprocess.Popen to run commands, it returns the exit code of the command.
"""
try:
process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
pid=process.pid
exitstat= process.wait()
cmdout = process.stdout.read()
exitstat = process.returncode
except OSError as detail:
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))
exitstat=999
if exitstat == None:
print("Something strange is going on! Exit code was None for command %s: check if it really ran!"%command)
exitstat=0
return exitstat
def CreateTkVoltageMapsCfgs(workdir=os.getcwd()): #Default to current working directory (could pass HV/LV list)
"""
Function that looks for TkVoltageMapCreator input files, creates 1 cfg.py for each IOV.
It returns the list of cfgs ready to be cmsRun to produce the maps
"""
#Use HV log files to loop... could use also LV logs...
HVLogs=[x for x in os.listdir(workdir) if x.startswith("HV") and "FROM" in x and x.endswith(".log")]
#Open the file to use as template
TkMapCreatorTemplateFile=open(os.path.join(os.getenv("CMSSW_BASE"),"src/CalibTracker/SiStripDCS/test","TkVoltageMapCreator_cfg.py"),"r")
TkMapCreatorTemplateContent=TkMapCreatorTemplateFile.readlines()
#Let's do it!
TkMapCfgFilenames=[]
for HVlog in HVLogs:
#Use full path since workdir could be different than current working dir:
HVlog=os.path.join(workdir,HVlog)
#Check if the corresponding LV log is there!
LVlog=os.path.join(workdir,HVlog.replace("HV","LV"))
if not os.path.exists(LVlog):
print("ARGH! Missing LV file for file %s"%HVlog)
print("Will not process the HV file either!")
TkMapCfgFilename=os.path.join(workdir,HVlog.replace("HV","TkVoltageMap").replace(".log","_cfg.py"))
TkMapCfgFilenames.append(TkMapCfgFilename)
TkMapCfg=open(TkMapCfgFilename,"w")
for line in TkMapCreatorTemplateContent:
if "LVStatusFile" in line and "#" not in line:
line='\tLVStatusFile = cms.string("%s"),\n'%LVlog
if "LVTkMapName" in line and "#" not in line:
line='\tLVTkMapName = cms.string("%s"),\n'%LVlog.replace(".log",".png")
if "HVStatusFile" in line and "#" not in line:
line='\tHVStatusFile = cms.string("%s"),\n'%HVlog
if "HVTkMapName" in line and "#" not in line:
line='\tHVTkMapName = cms.string("%s")\n'%HVlog.replace(".log",".png")
TkMapCfg.write(line)
TkMapCfg.close()
TkMapCreatorTemplateFile.close()
return TkMapCfgFilenames
def CreateTkVoltageMaps(workdir=os.getcwd()): #Default to current working directory for now...
"""
Function that looks for TkVoltageMap*cfg.py in the workdir directory and launches each of them
creating 2 TkVoltageMaps per IOV, one for LV and one of HV status (each as a png file).
"""
TkMapCfgs=[x for x in os.listdir(workdir) if x.startswith("TkVoltageMap") and "FROM" in x and x.endswith("cfg.py")]
for TkMapCfg in TkMapCfgs:
#Make sure we run the cfg in the workdir and also the logfile is saved there...
TkMapCfg=os.path.join(workdir,TkMapCfg)
cmsRunCmd="cmsRun %s >& %s"%(TkMapCfg,TkMapCfg.replace(".py",".log"))
print(cmsRunCmd)
exitstat=runcmd(cmsRunCmd)
if exitstat != 0:
print("Uh-Oh!")
print("Command %s FAILED!"%cmsRunCmd)
#Could put in a def main...
#Create the TkVoltageMapCreator input files in the test dir below:
(LVfiles,HVfiles)=ProduceTkMapVoltageInputFiles()
#print LVfiles
#print HVfiles
#Create the actual TkVoltageMaps!
TkMapCfgFilenames=CreateTkVoltageMapsCfgs()
print(TkMapCfgFilenames)
CreateTkVoltageMaps()
#Finish this up, so that it can be committed, but above all use it!
#Check how to use CheckAllIOVs.py to access the Offline DB directly! Maybe can fold this in?
|