|
[Rivet-svn] r2393 - in trunk: . binblackhole at projects.hepforge.org blackhole at projects.hepforge.orgThu Apr 8 00:17:34 BST 2010
Author: buckley Date: Thu Apr 8 00:17:33 2010 New Revision: 2393 Log: Adding ~Holger's root2flat script... improve if required :) Added: trunk/bin/root2flat (contents, props changed) Modified: trunk/ChangeLog trunk/bin/Makefile.am Modified: trunk/ChangeLog ============================================================================== --- trunk/ChangeLog Wed Apr 7 18:12:54 2010 (r2392) +++ trunk/ChangeLog Thu Apr 8 00:17:33 2010 (r2393) @@ -1,3 +1,9 @@ +2010-04-08 Andy Buckley <andy at insectnation.org> + + * bin/root2flat: Adding this little helper script, minimally + modified from one which Holger Schulz made for internal use in + ATLAS. + 2010-04-05 Andy Buckley <andy at insectnation.org> * Using spiresbib in rivet-mkanalysis: analysis templates made @@ -23,7 +29,8 @@ compare-histos. * Frank Siegert: LWH output in precision-8 scientific notation, to - solve a binning precision problem... the first one! + solve a binning precision problem... the first time weve noticed a + problem! * Improved treatment of data/reference datasets and labels in compare-histos. Modified: trunk/bin/Makefile.am ============================================================================== --- trunk/bin/Makefile.am Wed Apr 7 18:12:54 2010 (r2392) +++ trunk/bin/Makefile.am Thu Apr 8 00:17:33 2010 (r2393) @@ -1,7 +1,7 @@ bin_SCRIPTS = rivet-config dist_bin_SCRIPTS = \ - aida2flat aida2root flat2aida \ + aida2flat aida2root flat2aida root2flat \ compare-histos make-plots EXTRA_DIST = Added: trunk/bin/root2flat ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/bin/root2flat Thu Apr 8 00:17:33 2010 (r2393) @@ -0,0 +1,195 @@ +#!/usr/bin/env python +"""%prog + +Read in .root files and write out the histograms in FLAT +format suitable for make-plots. + +Use e.g. 'root2flat file1.root -o flathistos' to produce the flat histogram +files which need to be converted to AIDA files using Rivet's flat2aida tool + +Usage: + %prog [options] file1.root + +Use --help to get information for all options. + +""" + +import os, optparse, logging, ROOT +# try: +# from IPython.Shell import IPShellEmbed +# ipshell = IPShellEmbed([]) +# except: +# print "Ipython shell not available." + + +## Parse options +parser = optparse.OptionParser(usage = __doc__) +parser.add_option("-o", dest="OUTDIR", default=".", + help = "specify directory in which to write out converted files") +(opts, args) = parser.parse_args() + + +def readROOT(rootfile): + """ This is the main function that opens a ROOT file, browses its contents + for histograms and tries to write the converted histos to files. + """ + # Open the ROOT file + f=ROOT.TFile(rootfile) + + # Initial browse to see the structure + subdirs, histonames, tgraphnames = browse(f) + + # Keep browding if there are subdirectories TODO: Make this work for + # arbitrarily deep directory structures + if len(subdirs) > 0: + for sd in subdirs: + t_s, t_h = browse(f, sd) + histonames.extend(t_h) + + #primary_keys = f.GetListOfKeys() + #iter_primaries = ROOT.TListIter(primary_keys) + + # This will convert and write the histos + for histoname in histonames: + writeHisto(histoname, f.Get(histoname)) + for tgraphname in tgraphnames: + writeHisto(tgraphname, f.Get(tgraphname), True) + + + +def browse(f, branch=None): + """ This function browses a file/branch, trying to find objects that + either inherit from TH1 or from TProfile. + """ + # Prepare return values + histos = [] + tgraphs = [] + subdirs = [] + + # Get Iterator + if branch: + f.Cd(branch) + + primary_keys = ROOT.gDirectory.GetListOfKeys() + iter_primaries = ROOT.TListIter(primary_keys) + + if branch: + f.Cd('..') + + # Iterate over iterator + for i in xrange(len(primary_keys)): + if branch: + t_n = branch + '/' + iter_primaries.Next().GetName() + else: + t_n = iter_primaries.Next().GetName() + # Make sure we don't have a NoneType object here + if f.Get(t_n): + # Check if the curent hing is a directory + if type(f.Get(t_n)) == ROOT.TDirectoryFile: + subdirs.append(t_n) + # Check if the curent hing is a histogram + elif f.Get(t_n).InheritsFrom("TH1") or f.Get(t_n).InheritsFrom("TProfile"): + histos.append(t_n) + elif f.Get(t_n).InheritsFrom("TGraphAsymmErrors"): + tgraphs.append(t_n) + + return subdirs, histos, tgraphs + + +def convertHisto(R_histo): + """ This sunction read a single ROOT histo and converts it into the + FLAT format suitable for plotting with make-plots. + """ + title = R_histo.GetTitle().replace("#","\\") + xtitle= R_histo.GetXaxis().GetTitle().replace("#","\\") + ytitle= R_histo.GetYaxis().GetTitle().replace("#","\\") + bins = getBinsFromTH1F(R_histo) + for bin in bins: + try: + binstr = "" + for key in ["xlow", "xhigh", "y", "y_err_low", "y_err_high"]: + binstr += "%s: %f "%(key, bin[key]) + logging.info(binstr) + except: + pass + return title, xtitle, ytitle, bins + + +def convertTGraph(TGraph): + title = TGraph.GetTitle().replace("#","\\") + xtitle= TGraph.GetXaxis().GetTitle().replace("#","\\") + ytitle= TGraph.GetYaxis().GetTitle().replace("#","\\") + bins = getBinsFromTGraph(TGraph) + return title, xtitle, ytitle, bins + + +def getBinsFromTH1F(R_histo): + """ A little helper function that returns a list of bin-dictionaries). + """ + allbins=[] + for i in xrange(R_histo.GetNbinsX()): + xlow = R_histo.GetBinLowEdge(i) + xhigh = xlow + R_histo.GetBinWidth(i) + y = R_histo.GetBinContent(i) + y_err = R_histo.GetBinError(i) + bin = {"xlow":xlow, "xhigh":xhigh, "y":y, "y_err_low":y_err, "y_err_high":y_err} + allbins.append(bin) + return allbins + + +def getBinsFromTGraph(TGraph): + allbins=[] + X = TGraph.GetX() + Y = TGraph.GetY() + for i in xrange(TGraph.GetN()): + xlow = X[i] - TGraph.GetErrorXlow(i) + xhigh = X[i] + TGraph.GetErrorXhigh(i) + y = Y[i] + y_err_low = TGraph.GetErrorYlow(i) + y_err_high = TGraph.GetErrorYhigh(i) + bin = {"xlow":xlow, "xhigh":xhigh, "y":y, "y_err_low":y_err_low, "y_err_high":y_err_high} + allbins.append(bin) + return allbins + + +def writeHisto(name, R_histo, tgraph=False): + """ This writes the histogram into a single file, ready to plot with + make-plots. + """ + if tgraph: + title, xlabel, ylabel, bins = convertTGraph(R_histo) + else: + title, xlabel, ylabel, bins = convertHisto(R_histo) + head = "# BEGIN PLOT\nTitle=%s\nLegend=1\nLogY=1\nDrawOnly=%s\n"%(title, name) + head += "XLabel=%s\nYLabel=%s\n# END PLOT\n"%(xlabel, ylabel) + + histo = getFlatHisto(bins, name) + + flatname = name.replace("/","_") + ".dat" + flatfile = os.path.join(opts.OUTDIR, flatname) + f = open(flatfile, "w") + f.write(head) + f.write(histo) + f.close() + + +def getFlatHisto(bins, name): + """ This returns a histo in the FLAT format. """ + histo= "# BEGIN HISTOGRAM %s\n"%name + histo += "LineColor=black\n" + histo += "ErrorBars=1\n" + histo += "PolyMarker=*\n" + histo += "Title=%s\n"%name + for bin in bins: + histo += "%.8e\t%.8e\t%.8e\t%.8e\t%.8e\n"%(bin["xlow"], bin["xhigh"], bin["y"], + bin["y_err_low"], bin["y_err_high"]) + histo += "# END HISTOGRAM\n" + return histo + + +if __name__ == "__main__": + for infile in args: + if not os.path.exists(opts.OUTDIR): + os.mkdir(opts.OUTDIR) + readROOT(infile) + print "Done. Written all plot files to %s" % opts.OUTDIR
More information about the Rivet-svn mailing list |