ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/RootMacros/tree2hists.py
(Generate patch)

Comparing UserCode/RootMacros/tree2hists.py (file contents):
Revision 1.3 by anderson, Thu May 20 19:44:30 2010 UTC vs.
Revision 1.4 by anderson, Sun May 23 20:56:57 2010 UTC

# Line 1 | Line 1
1   #!/usr/bin/env python
2 + """
3 + Create ROOT Histograms from one or more ROOT TTrees or TNtuples.
4 +
5 + Options are specified in the given configuration file.
6 + """
7 + ## Created by Michael Anderson (mbanderson@wisc.edu), May 2010
8   #
9 < # Run by typing:
10 < #   ./tree2hists.py
11 < #
12 < # Creates histograms from TTree in one or more files.
13 < # Different cuts & scales can be set for each file.
14 < #
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
9 > # Create configuration file:
10 > #   tree2hists.py
11 > # Edit, then run with config file:
12 > #   tree2hists.py config.py
13 >
14 > ######## Import python libraries #############################################
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
20 > from ROOT import TFile, TTree, TH1F, TH2F, TH3F, gROOT # Import any ROOT class you want
21 > from copy import deepcopy      # For copying histograms
22 > from math import pi            # For use in histogram bounds
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 > ######## Define classes and generators #######################################
28  
27 ########################################
28 # Class for root files to store
29 # file's name, scale, cuts, etc...
29   class rootFile:
30 +    """Wrapper for TTrees and TNtuples, allowing association with
31 +    a scale and cuts."""
32      def __init__(self, fileName, scale=1.0, cuts="", tree=""):
33          self.name  = fileName
34          self.scale = scale
# Line 45 | Line 46 | class rootFile:
46              sys.exit(0)
47          print "\t %s contains %.0f entries before cuts, %.0f after." % (tree, self.ttree.GetEntries(), self.ttree.GetEntries(cuts))
48  
48 # Class to store varibles, histograms to plot them into, and cuts
49   class Plot:
50 <    def __init__(self, treeVariable, histogram, cuts=""):
50 >    """Wrapper for TH1 objects, associating TTree variables with a histogram"""
51 >    def __init__(self, treeVariable, histogram, cuts="", storeErrors=True):
52          self.treeVariable = treeVariable
53          self.histogram = histogram
54          self.cuts = cuts
55 <        self.histogram.Sumw2()  # Store errors
55 >        if storeErrors: self.histogram.Sumw2()
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"
59 < #  this returns the sting "1<2&&5>4"
60 < def joinNonEmpty(*listOfCuts):
57 > def joinCuts(*listOfCuts):
58 >    """Joines list of cuts (strings) into something ROOT can handle.
59 >    Example:  given ("1<2","","5>4") returns '1<2&&5>4'"""
60      listOfNonEmptyCuts=[]
61      for cut in listOfCuts:
62          if cut:
63              listOfNonEmptyCuts.append(cut)
64      return '&&'.join(listOfNonEmptyCuts)
65  
66 < def writeDefaultConfig():
67 <    if path.exists('t2h_config.py'):
69 <        print "Specify a config file, like:"
70 <        print "./tree2hists.py t2h_config.py"
71 <        sys.exit(0)
66 > def writeDefaultT2HConfig():
67 >    """Writes configuration file for tree2hists"""
68      defaultConfig = '''# Configuration file for tree2hists.py
69   # Created %s.
70   from tree2hists import *
71  
72 < listOfFiles = [rootFile("MultiPhotonAnalyzer_SDEG.root", scale=1.0, tree="NTuples/Analysis"),
73 <               rootFile("MultiPhotonAnalyzer_SD_EG_May7.root", scale=1.0, tree="NTuples/Analysis")]
72 > listOfFiles = [rootFile("MultiPhotonAnalyzer_SDEG.root", tree="NTuples/Analysis", scale=1.0, cuts=""),
73 >               rootFile("MultiPhotonAnalyzer_SD_EG_May7.root", tree="NTuples/Analysis", scale=1.0 cuts="")]
74  
75   outputFilename = "Hists_Data_%%s.root" %% datetime.now().strftime("%%b%%d_%%I%%p")
76  
# Line 82 | Line 78 | cutForAllFiles = "(!TTBit[36] && !TTBit[
78                   "&&((isEB[0] && (seedSeverity[0]!=3 && seedSeverity[0]!=4 ) && (seedRecoFlag[0] != 2) ) || isEE[0])"
79  
80   # All plots are made for each "cutSet".
81 < # A cut set is 3 things: folder name to store hists in, string to add to hist titles, and actual cuts
82 < cutSets = (
81 > # A "cutSet" is 3 things: folder name to store hists in, string to add to hist titles, and cuts for these hists.
82 > # Set cutSet = [] to make all plots.
83 > cutSets = [
84      ("barrel15to20", "(|#eta|<1.45, 15<E_{T}<20)", "et[0]>15&&et[0]<20&&abs(eta[0])<1.45"),
85      ("barrel20to30", "(|#eta|<1.45, 20<E_{T}<30)", "et[0]>20&&et[0]<30&&abs(eta[0])<1.45"),
86      ("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"),
87      ("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")
88 < #    ("","",""),  # all plots with no special cuts
92 <    )
88 >    ]
89  
90   # Define histograms to plot
91   bins_et     = array("f", [15.0, 20.0, 30.0, 50.0, 80.0, 120.0])
# Line 108 | Line 104 | listOfPlots = [
104      f.close()
105      print "Created default configuration file: t2h_config.py"
106      print "Edit it, and run with:"
107 <    print "  tree2hists t2h_config.py"
107 >    print "  tree2hists.py t2h_config.py"
108   ########################################
109  
110  
111 < ########################################
112 < if __name__ == '__main__':
113 <    if len(sys.argv) > 1:
114 <        if path.isfile(sys.argv[1]):
115 <            config_file = sys.argv[1].split('.')[0]
116 <            try:
117 <                exec("from " + config_file + " import *")
118 <            except Exception, e:
119 <                print e
120 <                sys.exit(1)
121 <        else:
122 <            print "%s not found." % sys.argv[1]
123 <            print "Create default config file by running tree2hists.py with no argument."
124 <            sys.exit(1)
129 <    else:
130 <        writeDefaultConfig()
131 <        sys.exit(0)
111 > ######## Define the main program #############################################
112 > def tree2hists_main(config_file):
113 >    try:
114 >        # Import only certain variables
115 >        _temp = __import__(config_file, globals(), locals(), ['listOfFiles','outputFilename','cutForAllFiles','cutSets','listOfPlots'], -1)
116 >        listOfFiles    = _temp.listOfFiles
117 >        outputFilename = _temp.outputFilename
118 >        cutForAllFiles = _temp.cutForAllFiles
119 >        cutSets        = _temp.cutSets
120 >        listOfPlots    = _temp.listOfPlots
121 >        if not cutSets: cutSets = [("","","")] # Make all plots, no extra cuts
122 >    except Exception, e:
123 >        print e
124 >        sys.exit(1)
125  
126      if path.isfile('rootlogon.C'):
127          print "Loading rootlogon.C"
128 <        gROOT.Macro('rootlogon.C')          # Run ROOT logon script
128 >        gROOT.Macro('rootlogon.C')             # Run ROOT logon script (for loading of functions)
129  
130 <    outputFile = TFile(outputFilename, "recreate")      # Open output file
130 >    outputFile = TFile(outputFilename, "recreate")
131      if not outputFile.IsZombie():
132          print "Opened %s for output." % outputFilename
133      else:
# Line 146 | Line 139 | if __name__ == '__main__':
139      print "\nCuts applied to all plots from all files:\n  %s" % cutForAllFiles
140      numberOfPlots = len(listOfPlots)
141      print "\nCreating %i plots for each of %i cut sets..." % (numberOfPlots, len(cutSets))
142 <    for setOfCuts in cutSets:
142 >    for setOfCuts in cutSets:                                                   # Make all plots for each cutSet
143          histNamePostfix, titlePostfix, currentCutSet = setOfCuts
144          print '\n Cut set "%s":  %s' % (histNamePostfix, currentCutSet)
145 <        # Loop over all things to plot
153 <        for i, plot in enumerate(listOfPlots):
145 >        for i, plot in enumerate(listOfPlots):                                  # Loop over plots
146              newTitle = ' '.join((plot.histogram.GetTitle(), titlePostfix))
147              newPlot  = deepcopy(plot)
148              dir = histNamePostfix
149              listOfPlotsToWrite.append((dir, newPlot))
150              newPlot.histogram.SetTitle(newTitle)
151 <            # Print plot being made
152 <            print "  %i %s >> %s/%s" % (i, newPlot.treeVariable, dir, newPlot.histogram.GetName()),
151 >            for aFile in listOfFiles:                                                   # Loop over all TTrees
152 >                tempHist = newPlot.histogram.Clone("temp")                               # Create temp histogram
153 >                cuts = joinCuts(cutForAllFiles, aFile.cuts, currentCutSet, newPlot.cuts) # Set cuts for temp
154 >                aFile.ttree.Draw( "%s >> temp" % newPlot.treeVariable, cuts, "goff")     # Draw into temp; graphics off
155 >                tempHist.Scale(aFile.scale)                                              # Scale temp
156 >                newPlot.histogram.Add(tempHist)                                          # Add temp to total histogram
157 >            print "  %3i %7i %s >> %s/%s" % (i, newPlot.histogram.GetEntries(), newPlot.treeVariable, dir, newPlot.histogram.GetName()),
158              if newPlot.cuts:
159 <                print "\textra cuts: %s" % newPlot.cuts, # Plot-specific cuts
160 <            # 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; 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()
159 >                print "\textra cuts: %s" % newPlot.cuts,    # plot-specific cuts
160 >            print
161      print "done."
162      
163      #   Store and save/close files
# Line 178 | Line 168 | if __name__ == '__main__':
168          outputFile.cd(dir)
169          plot.histogram.Write()
170  
181    print "Closing files...",
171      outputFile.Close()
172      for aFile in listOfFiles:
173          aFile.file.Close()
174 <    print "done.\n\nHistograms stored in\n  %s" % outputFilename
174 >    print "\n\nHistograms stored in\n  %s" % outputFilename
175   ########################################
176 +
177 + if __name__ == "__main__":
178 +    if len(sys.argv) > 1:
179 +        if path.isfile(sys.argv[1]):
180 +            config_file = sys.argv[1].split('.')[0]
181 +            tree2hists_main(config_file)
182 +        else:
183 +            print "%s not found." % sys.argv[1]
184 +            print "Create default config file by running tree2hists.py with no argument."
185 +            sys.exit(1)
186 +    else:
187 +        if path.exists('t2h_config.py'):
188 +            print "Specify a config file, like:"
189 +            print "tree2hists.py t2h_config.py"
190 +            sys.exit(1)
191 +        writeDefaultT2HConfig()
192 +        sys.exit(0)
193 +    #import cProfile
194 +    #cProfile.run('main()', 'fooprof')
195 +    #import pstats
196 +    #p = pstats.Stats('fooprof')
197 +    #p.sort_stats('cumulative').print_stats(15)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines