ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/RootMacros/overlayHists.py
Revision: 1.6
Committed: Fri Nov 20 20:16:30 2009 UTC (15 years, 5 months ago) by klukas
Content type: text/x-python
Branch: MAIN
Changes since 1.5: +6 -3 lines
Log Message:
Now outputs running count of histograms to stdout

File Contents

# User Rev Content
1 klukas 1.1 #!/usr/bin/env python
2    
3     ## Created by Jeff Klukas (klukas@wisc.edu), November 2009
4    
5     ## For more information, use the -h option:
6     ## ./overlayHists.py -h
7    
8     ## Define usage string for help option
9     usage="""usage: %prog [options] file1.root file2.root file3.root ...
10    
11 klukas 1.3 function: overlays corresponding histograms from several files, dumping the
12     images into an identical directory structure in the local directory
13     and also merging all images into a single file (if output is pdf)
14 klukas 1.1
15     naming: histograms whose names contain certain key terms will be handled
16     specially. Use this to your advantage!
17     'Eff' : y-axis will be scaled from 0 to 1
18     'Norm': plot will be area normalized
19     'Logx': x-axis will be on log scale
20     'Logy': y-axis will be on log scale"""
21    
22     ## Define colors
23 klukas 1.4 rgbvals = [[82, 124, 219],
24     [145, 83, 207],
25     [231, 139, 77],
26     [114, 173, 117],
27     [67, 77, 83]]
28 klukas 1.1
29     ## Import python libraries
30     import sys
31     import optparse
32     import os
33     import re
34    
35     ## Import ROOT in batch mode
36     if '-h' not in sys.argv:
37     sys.argv.append('-b')
38     import ROOT
39     if os.path.exists('rootlogon.C'): ROOT.gROOT.Macro('rootlogon.C')
40     sys.argv.remove('-b')
41     ROOT.gErrorIgnoreLevel = ROOT.kWarning
42 klukas 1.4 colors = [ROOT.TColor.GetColor(rgb[0], rgb[1], rgb[2]) for rgb in rgbvals]
43 klukas 1.1 c1 = ROOT.TCanvas()
44    
45     ## Parse options
46     parser = optparse.OptionParser(usage=usage)
47     parser.add_option('-n', '--normalize', action="store_true", default=False,
48     help="area normalize all histograms")
49     parser.add_option('-e', '--ext', default="pdf",
50 klukas 1.3 help="choose an output extension; default is pdf")
51 klukas 1.1 parser.add_option('-o', '--output', default="overlaidHists", metavar="NAME",
52 klukas 1.3 help="name of output directory; default is 'overlaidHists'")
53 klukas 1.1 parser.add_option('-m', '--match', default="", metavar="REGEX",
54 klukas 1.3 help="only make plots for paths containing the specified "
55     "regular expression (use '.*' for wildcard)")
56 klukas 1.1 options, arguments = parser.parse_args()
57     plot_dir = "%s/%s" % (os.path.abspath('.'), options.output)
58     regex = re.compile(options.match)
59    
60    
61 klukas 1.4
62 klukas 1.1 class RootFile:
63     def __init__(self, file_name):
64     self.name = file_name[0:file_name.find(".root")]
65     self.file = ROOT.TFile(file_name, "read")
66     if self.file.IsZombie():
67     print "Error opening %s, exiting..." % file_name
68     sys.exit(1)
69     def Get(self, object_name):
70     return self.file.Get(object_name)
71    
72    
73    
74     def main():
75 klukas 1.4 files = [RootFile(filename) for filename in arguments]
76 klukas 1.2 if len(files) == 0:
77     parser.print_help()
78     sys.exit(0)
79 klukas 1.1 process_directory("", files)
80 klukas 1.6 print
81 klukas 1.1 if options.ext == "pdf":
82 klukas 1.6 print "Writing merged pdf..."
83 klukas 1.1 os.system("gs -q -dBATCH -dNOPAUSE -sDEVICE=pdfwrite "
84     "-dAutoRotatePages=/All "
85     "-sOutputFile=%s.pdf " % options.output +
86     "[0-9][0-9][0-9].pdf")
87     os.system("rm [0-9]*.pdf")
88    
89    
90    
91     def process_directory(path, files):
92     dir_to_make = "%s/%s" % (plot_dir, path)
93     if not os.path.exists(dir_to_make):
94     os.mkdir(dir_to_make)
95     keys = files[0].file.GetDirectory(path).GetListOfKeys()
96     key = keys[0]
97     while key:
98     obj = key.ReadObj()
99     key = keys.After(key)
100     new_path = "%s/%s" % (path, obj.GetName())
101     if obj.IsA().InheritsFrom("TDirectory"):
102     process_directory(new_path, files)
103     if (regex.search(new_path) and
104     obj.IsA().InheritsFrom("TH1") and
105     not obj.IsA().InheritsFrom("TH2") and
106     not obj.IsA().InheritsFrom("TH3")):
107     counter = next_counter()
108     name = obj.GetName()
109     hist = files[0].file.GetDirectory(path).Get(name)
110     title = hist.GetTitle()
111     x_title = hist.GetXaxis().GetTitle()
112     y_title = hist.GetYaxis().GetTitle()
113     if "Norm" in name or options.normalize:
114     y_title = "Fraction of Events in Bin"
115     hist.Draw()
116     stack = ROOT.THStack("st%.3i" % int(counter), title)
117 klukas 1.5 legend_height = 0.04 * len(files) + 0.02
118     legend = ROOT.TLegend(0.65, 0.89 - legend_height, 0.87, 0.89)
119 klukas 1.1 c1.SetLogx("Logx" in name)
120     c1.SetLogy("Logy" in name)
121     for i, file in enumerate(files):
122     hist = file.file.GetDirectory(path).Get(name)
123     if not hist: continue
124     hist.Draw()
125     hist.SetTitle(file.name)
126     color = colors[i % len(colors)]
127     hist.SetLineColor(color)
128 klukas 1.6 ## hist.SetMarkerColor(color)
129     ## hist.SetMarkerStyle(i + 1)
130 klukas 1.1 if "Norm" in name or options.normalize:
131     integral = hist.Integral()
132 klukas 1.4 hist.Scale(1. / integral)
133 klukas 1.1 stack.Add(hist)
134     legend.AddEntry(hist)
135     stack.Draw("nostack p H")
136     stack.SetTitle("%s;%s;%s" % (title, x_title, y_title))
137     if "Eff" in name:
138     stack.Draw("nostack e p")
139     stack.SetMaximum(1.)
140     stack.SetMinimum(0.)
141     legend.Draw()
142     if options.ext == "pdf":
143     c1.SaveAs("%.3i.pdf" % counter)
144     c1.SaveAs("%s/%s/%s.%s" % (plot_dir, path, name, options.ext))
145 klukas 1.6 print "\r%i plots written to %s" % (counter, options.output),
146     sys.stdout.flush()
147 klukas 1.1
148    
149    
150     def counter_generator():
151     k = 0
152     while True:
153     k += 1
154     yield k
155     next_counter = counter_generator().next
156    
157    
158    
159     if __name__ == "__main__":
160     sys.exit(main())
161