Fork me on GitHub

source: git/python/DelphesAnalysis/BaseControlPlots.py@ 952bbbc

Last change on this file since 952bbbc was ae1d49f, checked in by pavel <pavel@…>, 12 years ago

add DelphesAnalysis

  • Property mode set to 100644
File size: 5.7 KB
Line 
1#! /usr/bin/env python
2import ROOT
3from CPconfig import configuration
4
5def getArgSet(controlplots):
6 assert isinstance(controlplots,list)
7 merged = ROOT.RooArgSet()
8 for ctrlplot in controlplots:
9 merged.add(ctrlplot._obsSet)
10 return merged
11
12def runTest(path='../testfiles/', controlPlots=None):
13 # these modules are only needed in that function, used for debugging.
14 # so we only import them here.
15 import Delphes
16 import os
17 import AnalysisEvent
18 import EventSelection
19 assert isinstance(controlPlots, BaseControlPlots)
20 if os.path.isdir(path):
21 dirList=os.listdir(path)
22 files=[]
23 for fname in dirList:
24 files.append(path+fname)
25 elif os.path.isfile(path):
26 files=[path]
27 else:
28 files=[]
29 events = AnalysisEvent.AnalysisEvent(files)
30 EventSelection.prepareAnalysisEvent(events)
31 controlPlots.beginJob()
32 i = 0
33 for event in events:
34 if i%100==0 : print "Processing... event ", i
35 controlPlots.processEvent(event)
36 i += 1
37 controlPlots.endJob()
38
39class BaseControlPlots:
40 """A class to create control plots"""
41
42 def __init__(self, dir=None, purpose="generic", dataset=None, mode="plots"):
43 """Initialize the ControlPlots, creating output file if needed. If no file is given, it means it is delegated."""
44 self._mode = mode
45 self._purpose = purpose
46 # for plots
47 if self._mode=="plots":
48 # create output file if needed. If no file is given, it means it is delegated
49 if dir is None:
50 self._f = ROOT.TFile(configuration.defaultFilename+".root", "RECREATE")
51 self._dir = self._f.mkdir(purpose)
52 else :
53 self._f = None
54 self._dir = dir
55 self._h_vector = { }
56 # for ntuples
57 if self._mode=="dataset":
58 self._obsSet = ROOT.RooArgSet()
59 if dataset is None:
60 self._rds = ROOT.RooDataSet(configuration.RDSname, configuration.RDSname, self._obsSet)
61 self._ownedRDS = True
62 else:
63 self._rds = dataset
64 self._ownedRDS = False
65 self._rrv_vector = { }
66 self._rooCategories = { }
67
68 def beginJob(self):
69 """Declare histograms, and for derived classes instantiate handles. Must be overloaded."""
70 raise NotImplementedError
71
72 def defineCategories(self, categories):
73 """Define the categories, given a list of names. Only works for datasets"""
74 if self._mode!="dataset": return
75 for i, name in enumerate(categories):
76 rc = ROOT.RooCategory("rc_"+self._purpose+"_"+str(i),name.split('/')[-1])
77 rc.defineType("not_acc",0)
78 rc.defineType("acc",1)
79 self._rooCategories[i] = rc
80 self._rds.addColumn(rc)
81 self._obsSet.add(rc)
82
83 def addHisto(self,*args):
84 """Add one histograms to the list of products. Arguments are as for TH1F."""
85 # this fills a distionnary name <-> histogram
86 self._dir.cd()
87 self._h_vector[args[0]] = ROOT.TH1F(*args)
88
89 def addVariable(self,*args):
90 """Add one variable to the list of products. Arguments are as for RooRealVar."""
91 # this fills a distionnary name <-> RooRealVar
92 self._rrv_vector[args[0]] = ROOT.RooRealVar(self._purpose+args[0],*(args[1:]))
93 self._obsSet.add(self._rrv_vector[args[0]])
94 self._rds.addColumn(self._rrv_vector[args[0]])
95
96 def add(self, *args):
97 """Add one item to the list of products. Arguments are as for TH1F."""
98 if self._mode=="plots":
99 self.addHisto(*args)
100 else:
101 self.addVariable(*[args[i] for i in [0,1,3,4]])
102
103 def processEvent(self, event, weight = 1.):
104 """process event and fill histograms"""
105 self.fill(self.process(event),weight)
106
107 def process(self, event):
108 """Process event data to extract histogrammables. Must be overloaded."""
109 raise NotImplementedError
110 # this is just an example, we never get there
111 # that method must return a dictionnary name <-> value that matches self._h_vector
112 result = { }
113 result["var1"] = 1.
114 result["var2"] = 2.3
115 result["var3"] = 5.711
116 return result
117
118 def setCategories(self, categories):
119 """Set the categories, given a list of booleans. Only works for datasets"""
120 if self._mode!="dataset": return
121 for c, flag in enumerate(categories):
122 if flag: self._rooCategories[c].setIndex(1)
123 else: self._rooCategories[c].setIndex(0)
124
125 def fillPlots(self, data, weight = 1.):
126 """Fills histograms with the data provided as input."""
127 for name,value in data.items():
128 if isinstance(value,list):
129 for val in value: self._h_vector[name].Fill(val,weight)
130 else:
131 self._h_vector[name].Fill(value,weight)
132
133 def fillRDS(self, data):
134 """Fills roodataset with the data provided as input."""
135 for rrv in self._rrv_vector:
136 # data is not guaranteed to contain all variables,
137 # so if we don't do this, these variables will keep the old value
138 self._rrv_vector[rrv].setVal(-1000)
139 for name,value in data.items():
140 if isinstance(value,list):
141 #for now, we only store scalars, not vectors
142 pass
143 else:
144 self._rrv_vector[name].setVal(value)
145 if self._ownedRDS:
146 self._rds.add(self._obsSet)
147
148 def fill(self, data, weight = 1.):
149 """Fills whatever must be filled in"""
150 if self._mode=="plots":
151 self.fillPlots(data, weight)
152 else:
153 self.fillRDS(data)
154
155 def endJob(self):
156 """Save and close."""
157 if self._mode=="plots":
158 self._dir.cd()
159 self._dir.Write()
160 if not self._f is None:
161 self._f.Close()
162 else:
163 if self._ownedRDS:
164 ws = ROOT.RooWorkspace(self._purpose,self._purpose)
165 getattr(ws,'import')(self._rds)
166 ws.writeToFile(configuration.defaultFilename+"_"+self._purpose+".root")
Note: See TracBrowser for help on using the repository browser.