1 |
#!/usr/bin/env python
|
2 |
#
|
3 |
# Run by typing:
|
4 |
# ./tree2hists.py
|
5 |
#
|
6 |
# Creates histograms from TTree in one or more files.
|
7 |
# Different cuts & scales can be set for each file.
|
8 |
#
|
9 |
# Details are specified in a configruation file, and run with:
|
10 |
# ./tree2hists.py config.py
|
11 |
#
|
12 |
# Michael Anderson
|
13 |
# Original: Nov 4, 2009
|
14 |
# Updated: May 20, 2010
|
15 |
|
16 |
import sys # For exiting program
|
17 |
if sys.version_info < (2, 6):
|
18 |
print "Go to a CMSSW dir and type 'cmsenv' first. (this loads a modern version of python)"
|
19 |
sys.exit(0)
|
20 |
from ROOT import TFile, TH1F, TH2F, TH3F, TTree, gROOT # Import any ROOT class you want
|
21 |
from copy import deepcopy # For copying histograms
|
22 |
from math import pi
|
23 |
from array import array # For making Float_t array ROOT wants (for hists)
|
24 |
from datetime import datetime # For output filename
|
25 |
from os import path # For finding file
|
26 |
|
27 |
########################################
|
28 |
# Class for root files to store
|
29 |
# file's name, scale, cuts, etc...
|
30 |
class rootFile:
|
31 |
def __init__(self, fileName, scale=1.0, cuts="", tree=""):
|
32 |
self.name = fileName
|
33 |
self.scale = scale
|
34 |
self.cuts = cuts
|
35 |
self.file = TFile(fileName, "read") # Open TFile
|
36 |
if self.file.IsZombie():
|
37 |
print "Error opening %s, exiting..." % self.name
|
38 |
sys.exit(0)
|
39 |
print "Opened %s, scale=%.2e, cuts='%s'" % (fileName, scale, cuts)
|
40 |
self.ttree = TTree() # Create empty TTree, and
|
41 |
try: # try to get TTree from file.
|
42 |
self.file.GetObject(tree, self.ttree) # ttreeName set in variables below
|
43 |
except:
|
44 |
print "Error: %s not found in %s, exiting..." % (tree, fileName)
|
45 |
sys.exit(0)
|
46 |
print "\t %s contains %.0f entries before cuts, %.0f after." % (tree, self.ttree.GetEntries(), self.ttree.GetEntries(cuts))
|
47 |
|
48 |
# Class to store varibles, histograms to plot them into, and cuts
|
49 |
class Plot:
|
50 |
def __init__(self, treeVariable, histogram, cuts="", drawopt=""):
|
51 |
self.treeVariable = treeVariable
|
52 |
self.histogram = histogram
|
53 |
self.cuts = cuts
|
54 |
self.drawopt = drawopt
|
55 |
self.histogram.Sumw2() # Store errors
|
56 |
|
57 |
# This joins a list of cuts (strings)
|
58 |
# into something ROOT can handle
|
59 |
# example: given several strings, like "1<2","","5>4"
|
60 |
# this returns the sting "1<2&&5>4"
|
61 |
def joinNonEmpty(*listOfCuts):
|
62 |
listOfNonEmptyCuts=[]
|
63 |
for cut in listOfCuts:
|
64 |
if cut:
|
65 |
listOfNonEmptyCuts.append(cut)
|
66 |
return '&&'.join(listOfNonEmptyCuts)
|
67 |
|
68 |
def writeDefaultConfig():
|
69 |
if path.exists('t2h_config.py'):
|
70 |
print "Specify a config file, like:"
|
71 |
print "./tree2hists.py t2h_config.py"
|
72 |
sys.exit(0)
|
73 |
defaultConfig = """# Configuration file for tree2hists
|
74 |
# Created %s.
|
75 |
|
76 |
from tree2hists import *
|
77 |
|
78 |
listOfFiles = [rootFile("MultiPhotonAnalyzer_SDEG_jetsFixed_May18_01PM.root", scale=1.0, tree="Analysis"),
|
79 |
rootFile("MultiPhotonAnalyzer_SD_EG_May7_jetsFixed_May18_01PM.root", scale=1.0, tree="Analysis")]
|
80 |
|
81 |
outputFilename = "Hists_Data_%%s.root" %% datetime.now().strftime("%%b%%d_%%I%%p")
|
82 |
|
83 |
cutForAllFiles = "!vtxIsFake&&et[0]>15.0&&!isEBGap[0]&&!isTransGap[0]&&((isEB[0]&&(seedSeverity[0]!=3&&seedSeverity[0]!=4)&&(seedRecoFlag[0]!=2))||isEE[0])"
|
84 |
|
85 |
# All plots are made for each "cutSet".
|
86 |
# A cut set is 3 things: folder name to store hists in, string to add to hist titles, and actual cuts
|
87 |
cutSets = (
|
88 |
# ("","",""), # all plots with no special cuts
|
89 |
("barrel15to20", "(|#eta|<1.45, 15<E_{T}<20)", "et[0]>15&&et[0]<20&&abs(eta[0])<1.45"),
|
90 |
("barrel20to30", "(|#eta|<1.45, 20<E_{T}<30)", "et[0]>20&&et[0]<30&&abs(eta[0])<1.45"),
|
91 |
("endcap15to20", "(1.7<|#eta|<2.5, 15<E_{T}<20)", "et[0]>15&&et[0]<20&&abs(eta[0])>1.7&&abs(eta[0])<2.5"),
|
92 |
("endcap20to30", "(1.7<|#eta|<2.5, 20<E_{T}<30)", "et[0]>20&&et[0]<30&&abs(eta[0])>1.7&&abs(eta[0])<2.5")
|
93 |
)
|
94 |
|
95 |
# Define histograms to plot
|
96 |
bins_et = array('f', [15.0, 20.0, 30.0, 50.0, 80.0, 120.0])
|
97 |
bins_eta = array('f', [-2.5, -1.7, -1.45, 0.0, 1.45, 1.7, 2.5])
|
98 |
listOfPlots = [
|
99 |
Plot('et[0]' , TH1F("pho_et" , "Lead #gamma: E_{T};E_{T} (GeV);entries/bin", len(bins_et)-1, bins_et)),
|
100 |
Plot('eta[0]' , TH1F("pho_eta" , "Lead #gamma: #eta;#eta;entries/bin" , len(bins_eta)-1, bins_eta)),
|
101 |
Plot('sigmaIetaIeta[0]', TH1F("pho_sigmaIEtaIEta", "Lead #gamma: #sigma_{i#etai#eta};#sigma_{i#etai#eta};entries/bin",20, 0, 0.06)),
|
102 |
Plot('ESRatio[0]' , TH1F("pho_ESRatio" , "Lead #gamma: ESRatio (E3/E21);ESatio;entries/bin", 20, 0, 1.0),"abs(eta[0])>1.65"),
|
103 |
Plot('metEt/et[0]' , TH1F("metEt_over_phoEt" , "MET / E_{T}(#gamma);MET/E_{T}(sc);entries/bin" , 20, 0.0, 3.0)),
|
104 |
]
|
105 |
""" % datetime.now().strftime("%b %d, %Y")
|
106 |
f = open('t2h_config.py', 'w')
|
107 |
f.write(defaultConfig)
|
108 |
f.close()
|
109 |
print "Created default configuration file: t2h_config.py"
|
110 |
print "Edit it, and run with:"
|
111 |
print " tree2hists t2h_config.py"
|
112 |
########################################
|
113 |
|
114 |
|
115 |
########################################
|
116 |
if __name__ == '__main__':
|
117 |
if len(sys.argv) > 1:
|
118 |
if path.isfile(sys.argv[1]):
|
119 |
config_file = sys.argv[1].split('.')[0]
|
120 |
try:
|
121 |
exec("from " + config_file + " import *")
|
122 |
except Exception, e:
|
123 |
print e
|
124 |
sys.exit(1)
|
125 |
else:
|
126 |
print "%s not found." % sys.argv[1]
|
127 |
print "Create default config file by running tree2hists.py with no argument."
|
128 |
sys.exit(1)
|
129 |
else:
|
130 |
writeDefaultConfig()
|
131 |
sys.exit(0)
|
132 |
|
133 |
if path.isfile('rootlogon.C'):
|
134 |
print "Loading rootlogon.C"
|
135 |
gROOT.Macro('rootlogon.C') # Run ROOT logon script
|
136 |
|
137 |
outputFile = TFile(outputFilename, "recreate") # Open output file
|
138 |
if not outputFile.IsZombie():
|
139 |
print "Opened %s for output." % outputFilename
|
140 |
else:
|
141 |
print "Error opening %s for output exiting..." % outputFilename
|
142 |
sys.exit(1)
|
143 |
|
144 |
listOfPlotsToWrite = []
|
145 |
|
146 |
print "\nCuts applied to all plots from all files:\n %s" % cutForAllFiles
|
147 |
numberOfPlots = len(listOfPlots)
|
148 |
print "\nCreating %i plots for each of %i cut sets..." % (numberOfPlots, len(cutSets))
|
149 |
for setOfCuts in cutSets:
|
150 |
histNamePostfix, titlePostfix, currentCutSet = setOfCuts
|
151 |
print '\n Cut set "%s": %s' % (histNamePostfix, currentCutSet)
|
152 |
# Loop over all things to plot
|
153 |
for i, plot in enumerate(listOfPlots):
|
154 |
newTitle = ' '.join((plot.histogram.GetTitle(), titlePostfix))
|
155 |
newPlot = deepcopy(plot)
|
156 |
dir = histNamePostfix
|
157 |
listOfPlotsToWrite.append((dir, newPlot))
|
158 |
newPlot.histogram.SetTitle(newTitle)
|
159 |
# Print plot being made
|
160 |
print " %i %s >> %s/%s" % (i, newPlot.treeVariable, dir, newPlot.histogram.GetName()),
|
161 |
if newPlot.cuts:
|
162 |
print "\textra cuts: %s" % newPlot.cuts, # Plot-specific cuts
|
163 |
# Loop over all TTrees (from the different files)
|
164 |
for aFile in listOfFiles:
|
165 |
tempHist = newPlot.histogram.Clone("temp") # Create temp histogram
|
166 |
cuts = joinNonEmpty(cutForAllFiles, aFile.cuts, currentCutSet, newPlot.cuts)# Set cuts for temp
|
167 |
aFile.ttree.Draw( "%s >> temp" % newPlot.treeVariable, cuts, "goff" ) # Draw into temp with cuts; graphics off
|
168 |
tempHist.Scale(aFile.scale) # Scale temp
|
169 |
newPlot.histogram.Add(tempHist) # Add temp to total histogram
|
170 |
print "%i" % newPlot.histogram.GetEntries()
|
171 |
print "done."
|
172 |
|
173 |
# Store and save/close files
|
174 |
outputFile.cd()
|
175 |
for setOfCuts in cutSets:
|
176 |
outputFile.mkdir(setOfCuts[0])
|
177 |
for dir, plot in listOfPlotsToWrite:
|
178 |
outputFile.cd(dir)
|
179 |
plot.histogram.Write()
|
180 |
|
181 |
print "Closing files...",
|
182 |
outputFile.Close()
|
183 |
for aFile in listOfFiles:
|
184 |
aFile.file.Close()
|
185 |
print "done.\n\nHistograms stored in\n %s" % outputFilename
|
186 |
########################################
|