1 |
#!/usr/bin/env python
|
2 |
import sys
|
3 |
import os
|
4 |
import fileinput
|
5 |
from array import *
|
6 |
from optparse import OptionParser
|
7 |
from OSUT3Analysis.Configuration.configurationOptions import *
|
8 |
from OSUT3Analysis.Configuration.processingUtilities import *
|
9 |
|
10 |
parser = OptionParser()
|
11 |
|
12 |
#input/output options
|
13 |
parser.add_option("-l", "--localConfig", dest="localConfig",
|
14 |
help="local configuration file")
|
15 |
parser.add_option("-c", "--condorDir", dest="condorDir",
|
16 |
help="condor output directory")
|
17 |
parser.add_option("-o", "--output-file", dest="outputFileName",
|
18 |
help="specify an output file name for the histogram file, default is 'bgMCTable.tex'")
|
19 |
|
20 |
#columns to include
|
21 |
parser.add_option("-b", "--box", action="store_true", dest="showDatasetColors", default=False,
|
22 |
help="include a column of dataset colors NOTE: the colors must be predefined in your latex file!")
|
23 |
parser.add_option("-s", "--shortName", action="store_true", dest="showShortNames", default=False,
|
24 |
help="include a column of component dataset nicknames (using the legend entry text)")
|
25 |
parser.add_option("-a", "--summedName", action="store_true", dest="showSummedNames", default=False,
|
26 |
help="include a column of composite dataset nicknames (using the legend entry text)")
|
27 |
parser.add_option("-f", "--fullNames", action="store_true", dest="showFullNames", default=False,
|
28 |
help="include a column of full dataset names")
|
29 |
|
30 |
parser.add_option("-x", "--xsection", action="store_true", dest="showXsections", default=False,
|
31 |
help="include a column of process cross sections")
|
32 |
parser.add_option("-e", "--efflumi", action="store_true", dest="showEffLumi", default=False,
|
33 |
help="include a column of effective luminosities")
|
34 |
parser.add_option("-n", "--numEvents", action="store_true", dest="showNumEvents", default=False,
|
35 |
help="include a column of number of generated events")
|
36 |
parser.add_option("-w", "--weight", action="store_true", dest="showWeight", default=False,
|
37 |
help="include a column of luminosity weighting factors")
|
38 |
|
39 |
#other options
|
40 |
parser.add_option("-r", "--replace", action="append", dest="replacements",
|
41 |
help="specify strings to be replaced by askterisks and moved into the caption ")
|
42 |
|
43 |
#initialize parser
|
44 |
(arguments, args) = parser.parse_args()
|
45 |
|
46 |
#import from local config
|
47 |
if arguments.localConfig:
|
48 |
sys.path.append(os.getcwd())
|
49 |
exec("from " + arguments.localConfig.rstrip('.py') + " import *")
|
50 |
|
51 |
#set condor directory
|
52 |
condor_dir = set_condor_output_dir(arguments)
|
53 |
|
54 |
#set output file name
|
55 |
outputFileName = "bgMCTable.tex"
|
56 |
if arguments.outputFileName:
|
57 |
outputFileName = arguments.outputFileName
|
58 |
|
59 |
outputFile = condor_dir + "/" + outputFileName
|
60 |
|
61 |
from ROOT import TFile
|
62 |
|
63 |
hLine = "\\hline\n"
|
64 |
endLine = " \\\\ "
|
65 |
newLine = " \n"
|
66 |
|
67 |
#function to make the replacements in the dataset names requested by the user
|
68 |
def formatString(inputString):
|
69 |
filler = "*"
|
70 |
if not arguments.replacements:
|
71 |
return inputString
|
72 |
for replacement in arguments.replacements:
|
73 |
inputString = inputString.replace(replacement,filler)
|
74 |
filler = filler + "*"
|
75 |
|
76 |
return inputString
|
77 |
|
78 |
#function to put spaces between every 3 digits in a number
|
79 |
def formatNumber(inputNumber):
|
80 |
inputList = list(inputNumber)
|
81 |
decimalIndex = inputNumber.find(".")
|
82 |
if decimalIndex is not -1:# found decimal point
|
83 |
numDigitsAboveOne = decimalIndex
|
84 |
numDigitsBelowOne = len(inputList) - numDigitsAboveOne - 1
|
85 |
else: # didn't find a decimal point
|
86 |
numDigitsAboveOne = len(inputList)
|
87 |
numDigitsBelowOne = 0
|
88 |
|
89 |
outputString = "$"
|
90 |
|
91 |
for index in range(numDigitsAboveOne): #print digits > 1
|
92 |
outputString = outputString + inputList[index]
|
93 |
if (numDigitsAboveOne - index - 1) % 3 is 0 and (numDigitsAboveOne - index - 1) is not 0:
|
94 |
outputString = outputString + "\;"
|
95 |
if decimalIndex is not -1: #print "." if needed
|
96 |
outputString = outputString + "."
|
97 |
for index in range(numDigitsBelowOne):#print digits < 1
|
98 |
outputString = outputString + inputList[index+numDigitsAboveOne+1]
|
99 |
if (index+1) % 3 is 0 and (numDigitsBelowOne - index -1) is not 0:
|
100 |
outputString = outputString + "\;"
|
101 |
|
102 |
outputString = outputString + "$"
|
103 |
|
104 |
return outputString
|
105 |
|
106 |
#function to round to a certain number of significant digits
|
107 |
def round_sigfigs(num, sig_figs):
|
108 |
if num != 0:
|
109 |
return round(num, -int(math.floor(math.log10(abs(num))) - (sig_figs - 1)))
|
110 |
else:
|
111 |
return 0 # Can't take the log of 0
|
112 |
|
113 |
#### check which bgMC input datasets have valid output files
|
114 |
processed_datasets = []
|
115 |
for dataset in datasets:
|
116 |
if types[dataset] is not "bgMC":
|
117 |
continue
|
118 |
fileName = condor_dir + "/" + dataset + ".root"
|
119 |
if not os.path.exists(fileName):
|
120 |
continue
|
121 |
testFile = TFile(fileName)
|
122 |
if not (testFile.IsZombie()):
|
123 |
processed_datasets.append(dataset)
|
124 |
|
125 |
if len(processed_datasets) is 0:
|
126 |
sys.exit("Can't find any output root files for the given list of datasets")
|
127 |
|
128 |
|
129 |
#set the text for the luminosity label
|
130 |
if(intLumi < 1000.):
|
131 |
LumiText = str.format('{0:.1f}', LumiInPb) + " \\pbinv"
|
132 |
else:
|
133 |
LumiInFb = intLumi/1000.
|
134 |
LumiText = str.format('{0:.1f}', LumiInFb) + " \\fbinv"
|
135 |
|
136 |
#setting up the column alignments for the table
|
137 |
numColumns = 0 #always show the full datatset name column
|
138 |
columnStructure = "{"
|
139 |
if arguments.showDatasetColors:
|
140 |
numColumns = numColumns + 1
|
141 |
columnStructure = columnStructure + "c"
|
142 |
if arguments.showShortNames:
|
143 |
numColumns = numColumns + 1
|
144 |
columnStructure = columnStructure + "c"
|
145 |
if arguments.showSummedNames:
|
146 |
numColumns = numColumns + 1
|
147 |
columnStructure = columnStructure + "c"
|
148 |
if arguments.showFullNames:
|
149 |
numColumns = numColumns + 1
|
150 |
columnStructure = columnStructure + "l"
|
151 |
if arguments.showNumEvents:
|
152 |
numColumns = numColumns + 1
|
153 |
columnStructure = columnStructure + "c"
|
154 |
if arguments.showXsections:
|
155 |
numColumns = numColumns + 1
|
156 |
columnStructure = columnStructure + "c"
|
157 |
if arguments.showEffLumi:
|
158 |
numColumns = numColumns + 1
|
159 |
columnStructure = columnStructure + "c"
|
160 |
if arguments.showWeight:
|
161 |
numColumns = numColumns + 1
|
162 |
columnStructure = columnStructure + "c"
|
163 |
columnStructure = columnStructure + "}"
|
164 |
|
165 |
|
166 |
|
167 |
fout = open (outputFile, "w")
|
168 |
fout.write ("\\makebox[0pt]{\\renewcommand{\\arraystretch}{1.2}\\begin{tabular}"+columnStructure+newLine+hLine)
|
169 |
|
170 |
#write the column headers to the output file
|
171 |
headerLine = ""
|
172 |
if arguments.showDatasetColors:
|
173 |
headerLine = headerLine + "\\shortstack{Composite \\\\ Dataset \\\\ Color} & "
|
174 |
if arguments.showSummedNames:
|
175 |
headerLine = headerLine + "\\shortstack{Composite \\\\ Dataset \\\\ Nickname} & "
|
176 |
if arguments.showShortNames:
|
177 |
headerLine = headerLine + "\\shortstack{Individual \\\\ Dataset \\\\ Nickname} & "
|
178 |
if arguments.showFullNames:
|
179 |
headerLine = headerLine + "\\multicolumn{1}{c}{Individual Dataset Source Name} & "
|
180 |
if arguments.showNumEvents:
|
181 |
headerLine = headerLine + "\\shortstack{Generated \\\\ Events} & "
|
182 |
if arguments.showXsections:
|
183 |
headerLine = headerLine + "\\shortstack{Cross \\\\ Section \\\\ (pb)} & "
|
184 |
if arguments.showEffLumi:
|
185 |
headerLine = headerLine + "\\shortstack{Effective \\\\ Luminosity \\\\ (\\fbinv)} & "
|
186 |
if arguments.showWeight:
|
187 |
headerLine = headerLine + "\\shortstack{Weighting \\\\ Factor \\\\ for " + LumiText + "} & "
|
188 |
|
189 |
|
190 |
fout.write (headerLine.rstrip(" & ")+endLine+newLine+hLine)
|
191 |
|
192 |
|
193 |
for dataset in processed_datasets:
|
194 |
datasetLines = ""
|
195 |
numComponents = 1
|
196 |
component_datasets = []
|
197 |
|
198 |
#if there are component datasets, we'll need all of them
|
199 |
if dataset in composite_dataset_definitions:
|
200 |
numComponents = len(composite_dataset_definitions[dataset])
|
201 |
for component in composite_dataset_definitions[dataset]:
|
202 |
component_datasets.append(component)
|
203 |
else:
|
204 |
component_datasets.append(dataset)
|
205 |
|
206 |
|
207 |
#include the fancy multirow business for dataset nicknames
|
208 |
if arguments.showDatasetColors:
|
209 |
datasetLines = datasetLines + "\\multirow{"+str(numComponents)+"}{*}{\\color{"+str(colors[dataset])+"}{\\LARGE $\\blacksquare$}} & "
|
210 |
if arguments.showSummedNames:
|
211 |
rawlabel = "$" + labels[dataset] + "$"
|
212 |
label = rawlabel.replace("#","\\").replace("\\rightarrow","{\\rightarrow}").replace(" ","\\ ")
|
213 |
datasetLines = datasetLines + "\\multirow{"+str(numComponents)+"}{*}{"+label+"} & "
|
214 |
|
215 |
|
216 |
#loop over each component (even if there's just one) and add the appropriate content to the table
|
217 |
counter = 0
|
218 |
for component in component_datasets:
|
219 |
counter = counter + 1
|
220 |
if arguments.showDatasetColors and counter > 1:
|
221 |
datasetLines = datasetLines + " & "
|
222 |
if arguments.showSummedNames and counter > 1:
|
223 |
datasetLines = datasetLines + " & "
|
224 |
if arguments.showShortNames:
|
225 |
datasetLines = datasetLines + "$" + labels[component].replace("#","\\").replace("\\rightarrow","{\\rightarrow}").replace(" ","\\ ").replace("Pt","\\pt") + "$" + " & "
|
226 |
if arguments.showFullNames:
|
227 |
datasetLines = datasetLines + "\\texttt{" + formatString(dataset_names[component]).lstrip("/").replace("/","_").replace("_","\_") + "}" + " & "
|
228 |
if arguments.showNumEvents:
|
229 |
fileName = condor_dir + "/" + component + "/numberOfEvents.txt"
|
230 |
with open(fileName) as numEventsFile:
|
231 |
content = numEventsFile.readlines()
|
232 |
numEvents = content[0].strip("\n")
|
233 |
datasetLines = datasetLines + formatNumber(numEvents) + " & "
|
234 |
if arguments.showXsections:
|
235 |
fileName = condor_dir + "/" + component + "/crossSectionInPicobarn.txt"
|
236 |
with open(fileName) as crossSectionFile:
|
237 |
content = crossSectionFile.readlines()
|
238 |
crossSection = content[0].strip("\n")
|
239 |
datasetLines = datasetLines + formatNumber(crossSection) + " & "
|
240 |
if arguments.showEffLumi:
|
241 |
fileName = condor_dir + "/" + component + "/numberOfEvents.txt"
|
242 |
with open(fileName) as numEventsFile:
|
243 |
content = numEventsFile.readlines()
|
244 |
numEvents = content[0].strip("\n")
|
245 |
fileName = condor_dir + "/" + component + "/crossSectionInPicobarn.txt"
|
246 |
with open(fileName) as crossSectionFile:
|
247 |
content = crossSectionFile.readlines()
|
248 |
crossSection = content[0].strip("\n")
|
249 |
datasetLines = datasetLines + formatNumber(str(round_sigfigs(float(numEvents)/float(crossSection)/1000.,3)).rstrip("0").rstrip(".")) + " & "
|
250 |
if arguments.showWeight:
|
251 |
fileName = condor_dir + "/" + component + "/numberOfEvents.txt"
|
252 |
with open(fileName) as numEventsFile:
|
253 |
content = numEventsFile.readlines()
|
254 |
numEvents = content[0].strip("\n")
|
255 |
fileName = condor_dir + "/" + component + "/crossSectionInPicobarn.txt"
|
256 |
with open(fileName) as crossSectionFile:
|
257 |
content = crossSectionFile.readlines()
|
258 |
crossSection = content[0].strip("\n")
|
259 |
datasetLines = datasetLines + formatNumber(str(round_sigfigs(intLumi*float(crossSection)/float(numEvents),3)).rstrip("0").rstrip(".")) + " & "
|
260 |
|
261 |
|
262 |
datasetLines = datasetLines.rstrip(" & ")
|
263 |
datasetLines = datasetLines + endLine + newLine
|
264 |
|
265 |
fout.write(datasetLines)
|
266 |
fout.write(hLine)
|
267 |
|
268 |
|
269 |
|
270 |
if arguments.replacements:
|
271 |
replacementsText = ""
|
272 |
filler = "*"
|
273 |
for replacement in arguments.replacements:
|
274 |
line = "\\multicolumn{"+str(numColumns)+"}{l}{" + " \\texttt{" + filler + " " + replacement.replace("/","_").replace("_","\_") + "}}" + endLine + newLine
|
275 |
filler = filler + "*"
|
276 |
replacementsText = replacementsText + line
|
277 |
fout.write(replacementsText)
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
fout.write("\\end{tabular}}")
|
283 |
fout.close()
|
284 |
|
285 |
|
286 |
|