ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/SampleClass.C
Revision: 1.22
Committed: Thu Jan 17 16:24:52 2013 UTC (12 years, 3 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.21: +9 -3 lines
Log Message:
Fixed memory corruption bug due to JSON-based sample collection

File Contents

# Content
1 #include <iostream>
2 #include <sstream>
3 #include <vector>
4 #include <utility>
5
6 #include <TFile.h>
7 #include <TTree.h>
8 #include <TH1.h>
9 #include <TH2.h>
10 #include <TCut.h>
11 #include <THStack.h>
12 #include <TColor.h>
13 #include <TCanvas.h>
14 #include <TError.h>
15 #include <TText.h>
16 #include <TLegend.h>
17 #include <TError.h>
18 #include <TTreeFormula.h>
19
20 #define SampleClassLoaded
21
22 #ifndef Verbosity
23 #define Verbosity 0
24 #endif
25 #ifndef HUSH
26 #define HUSH 1
27 #endif
28 #ifndef GeneralToolBoxLoaded
29 #include "GeneralToolBox.C"
30 #endif
31 using namespace std;
32
33 bool doesROOTFileExist(string filename);
34 bool addoverunderflowbins=false;
35 string treename="PFevents";
36
37 class sample
38 {
39 public:
40 string filename;
41 string samplename;
42 long Nentries;
43 float xs;//cross section
44 float weight;
45 bool is_data;
46 bool is_signal;
47 bool is_active;
48 float weightrenormalization;
49 int groupindex;
50 Color_t samplecolor;
51
52 TFile *tfile;
53 TTree *events;
54
55 sample(string m_filename,string m_samplename,long m_Nentries, float m_xs,bool is_data, bool m_is_signal, int m_groupindex, Color_t color);
56 string ExtractVersion(string FullVersionString);
57 void closeFile();
58 };
59
60 string write_mc_or_data(bool is_data)
61 {
62 if(is_data) return "data";
63 return "MC";
64 }
65
66 string sample::ExtractVersion(string FullVersionString) {
67 string Result=FullVersionString.substr(FullVersionString.find(" ")+1,FullVersionString.length());
68 Result=Result.substr(0,Result.find(" "));
69 return Result;
70 }
71
72 sample::sample(string m_filename, string m_samplename, long m_Nentries, float m_xs,bool m_is_data, bool m_is_signal, int m_groupindex, Color_t mycolor)
73 {
74 this->filename=m_filename;
75 this->samplename=m_samplename;
76 this->Nentries=m_Nentries;
77 this->xs=m_xs;
78 this->is_data=m_is_data;
79 this->is_signal=m_is_signal;
80 this->groupindex=m_groupindex;
81 this->is_active=true;
82 this->samplecolor=mycolor;
83 this->weightrenormalization=1.0;
84 if(!doesROOTFileExist(this->filename)) {
85 stringstream message;
86 message << "The " << write_mc_or_data(is_data) << " sample " << this->samplename << " is invalid because the associated file path, " << this->filename << " is incorrect.";
87 write_error("Sample::Sample",message.str());
88 this->is_active=false;
89 }
90
91 if(doesROOTFileExist(this->filename)) {
92 //suppressing stupid 64/32 errors here (Warning in <TFile::ReadStreamerInfo>: /scratch/buchmann/MC_Spring11_PU_PF/TToBLNu_TuneZ2_t-channel_7TeV-madgraph.root: not a TStreamerInfo object)
93 // Int_t currlevel=gErrorIgnoreLevel;
94 // gErrorIgnoreLevel=5000;
95 this->tfile = new TFile(m_filename.c_str());
96 // gErrorIgnoreLevel=currlevel;
97 this->events=(TTree*)(this->tfile)->Get(treename.c_str());
98 if(Verbosity>0) dout << "The " << write_mc_or_data(is_data) << " file " << this->filename << " has been added successfully to the list of samples. " << endl;
99 long long measured_nevents=(long)1;
100 TH1F *weight_histo = (TH1F*)(this->tfile)->Get("weight_histo");
101 float average_weight = 1.0;
102 if(weight_histo) {
103 //average_weight = weight_histo->Integral()/weight_histo->GetEntries();
104 measured_nevents = (long)weight_histo->GetEntries();
105 } else {
106 measured_nevents=(this->events)->GetEntries();
107 }
108
109 if(((this->Nentries>1)||(this->Nentries==0))&&measured_nevents!=this->Nentries) {
110 //special cases: m_Nentries=1 : we want to give each event the full weight (->scans!)
111 // m_Nentries=0: detect the number of events and set the nevents automatically
112 // m_Nentries<0: set manually (see below)
113
114 stringstream warning;
115 warning << "Detected incorrect number of events in sample initialization of sample " << m_filename << " (detected Nevents: " << measured_nevents << " , definition claims: " << this->Nentries << "; will use measured number of events. If you want to use this algorithm to set the number of events anyway, set the number of events to 0.";
116 if(m_Nentries>1) write_warning(__FUNCTION__,warning.str());
117 this->Nentries=measured_nevents;
118 } else if ( this->Nentries<0 ) {
119 this->Nentries = -this->Nentries;
120 }
121 if ( average_weight>0 ) {
122 this->weight=(xs/(float)Nentries)/average_weight;
123 this->weightrenormalization=(1.0/average_weight);
124 } else {
125 if(average_weight>0) {
126 this->weight=(xs/(float)Nentries)/average_weight;
127 this->weightrenormalization=(1.0/average_weight);
128 } else {
129 this->weight = (xs/(float)Nentries);
130 this->weightrenormalization=1;
131 }
132 }
133
134 }
135 else {
136 this->is_active=false;
137 }
138
139 }
140
141 void sample::closeFile()
142 {
143 if(doesROOTFileExist(this->filename)) {
144 (this->tfile)->Close();
145 }
146 else {
147 dout << "SAMPLE " << this->samplename << " cannot be closed as the underlying file (" << this->filename << ") does not exist!" << endl;
148 this->is_active=false;
149 }
150 }
151
152 bool doesROOTFileExist(string filename)
153 {
154 //suppressing stupid 64/32 errors here (Warning in <TFile::ReadStreamerInfo>: /scratch/buchmann/MC_Spring11_PU_PF/TToBLNu_TuneZ2_t-channel_7TeV-madgraph.root: not a TStreamerInfo object)
155 // Int_t currlevel=gErrorIgnoreLevel;
156 // gErrorIgnoreLevel=5000;
157 TFile *f = new TFile(filename.c_str());
158
159 if (f->IsZombie()) {
160 dout << "Error opening file" << filename << endl;
161 return 0;
162 }
163 f->Close();
164 // gErrorIgnoreLevel=currlevel;
165 return 1;
166 }
167 //********************************************************
168
169 TCut essentialcut("mll>0");
170 // The following cut (cutWeight) will reweight all the events: use "weight" to correct MC for pileUP, "1.0" otherwise
171 TCut cutWeight("weight");
172 //TCut cutWeight("(weight*(((id1==id2&&id1==0)*1.2)+((id1==id2&&id1==1)/1.2)+(id1!=id2)))");
173
174 void setessentialcut(TCut ess) {
175 essentialcut=ess;
176 }
177
178 class samplecollection
179 {
180 public:
181 string name;
182 vector<sample> collection;
183 int nsamples;
184 int ndatasamples;
185 int nmcsamples;
186 int ngroups;
187
188 samplecollection(string m_name);
189 void AddSample(string m_filename,string m_samplename,long m_Nentries, float m_xs,bool is_data, bool m_is_signal, int groupindex, Color_t color);
190
191 //vector quantities
192 TH1F* Draw(string m_histoname,string m_var, vector<float> binning, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, vector<int> onlyindex, bool drawsignal);
193 TH1F* Draw(string m_histoname,string m_var, vector<float> binning, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, bool drawsignal);
194
195 //minx,maxs quantities
196 TH1F* Draw(string m_histoname,string m_var, int m_nbins, float m_minx, float m_maxx, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, bool drawsignal);
197 TH1F* Draw(string m_histoname,string m_var, int m_nbins, float m_minx, float m_maxx, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, vector<int> onlyindex, bool drawsignal);
198
199 TH2F* Draw(string m_histoname,string m_var, vector<float> binningx, vector<float> binningy, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, vector<int> onlyindex, bool drawsignal);
200
201 vector<float> get_optimal_binsize(string variable, TCut cut,int nbins, float low, float high);
202
203 THStack DrawStack(string m_histoname,string m_var, int m_nbins, float m_minx, float m_maxx, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, bool drawsignal);
204 THStack DrawStack(string m_histoname,string m_var, vector<float> binning, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, bool drawsignal);
205 vector<int> FindSample(string what);
206 vector<int> FindSampleBySampleName(string what);
207 void ListSamples();
208 bool do_sample(int thissample, vector<int> &selected_samples);
209 Color_t GetColor(string filename);
210 Color_t GetColor(int sampleindex);
211
212 TLegend* allbglegend(string title,float x, float y);
213 TLegend* allbglegend(string title, TH1F *data, float x, float y);
214
215 void PickUpFromThisFile(int isamp, string cut, vector<string> &output, vector<string> &pickupfile);
216 void PickUpEvents(string cut);
217 string find_units(string&);
218
219 void RemoveLastSample();
220 };
221
222 samplecollection::samplecollection(string m_name)
223 {
224 this->name=m_name;
225 if(Verbosity>0) dout << "Initiated sample collection " << this->name << " " << endl;
226 }
227
228 void samplecollection::ListSamples()
229 {
230 dout << "---------------------------------------------------------------------------------------------------" << endl;
231 dout << "Listing all " << this->nsamples << " sample(s) of the sample collection called " << this->name << " : " << endl;
232 if(this->ndatasamples>0) {
233 dout << "Data sample(s): " << endl;
234 for (int isamp=0;isamp<(int)this->collection.size();isamp++)
235 {
236 if((this->collection)[isamp].is_data) dout << " - " << (this->collection)[isamp].samplename << " from " << (this->collection)[isamp].filename << endl;
237 }
238 }
239 if(this->nmcsamples>0) {
240 dout << "MC sample(s): " << endl;
241 for (int isamp=0;isamp<(int)this->collection.size();isamp++)
242 {
243 if(!(this->collection)[isamp].is_data) dout << " - " << (this->collection)[isamp].samplename << " (" << (this->collection)[isamp].filename << ") xs=" << (this->collection)[isamp].xs << " pb, N(events)=" << (this->collection)[isamp].Nentries << endl;
244 }
245 }
246 dout << "---------------------------------------------------------------------------------------------------" << endl;
247 }
248
249 void samplecollection::AddSample(string m_filename,string m_samplename,long m_Nentries, float m_xs,bool is_data, bool m_is_signal, int groupindex, Color_t newcolor)
250 {
251 sample NewSample(m_filename,m_samplename,m_Nentries,m_xs,is_data,m_is_signal,groupindex,newcolor);
252 if (!NewSample.is_active) {
253 write_warning(__FUNCTION__,"Not adding this sample ("+m_filename+") as it has been declared inactive");
254 return;
255 }
256 (this->collection).push_back(NewSample);
257 if((this->collection).size()==1) {
258 this->nmcsamples=0;
259 this->ndatasamples=0;
260 this->nsamples=0;
261 this->ngroups=0;
262 }
263 if(groupindex>this->ngroups) this->ngroups=groupindex;
264 if(is_data) this->ndatasamples++;
265 else this->nmcsamples++;
266 this->nsamples=this->collection.size();
267 }
268
269 bool samplecollection::do_sample(int thissample, vector<int> &selected_samples)
270 {
271 bool drawit=false;
272 for(int isel=0;isel<(int)selected_samples.size();isel++)
273 {
274 if(selected_samples[isel]==thissample) {
275 drawit=true;
276 break;
277 }
278 }
279 return drawit;
280 }
281
282 TH1F* samplecollection::Draw(string m_histoname,string m_var, int m_nbins, float m_minx, float m_maxx, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, bool drawsignal=false)
283 {
284 vector<int> emptyvector;
285 TH1F *histo = this->Draw(m_histoname,m_var, m_nbins, m_minx, m_maxx, m_xlabel, m_ylabel, Cut, m_is_data, luminosity,emptyvector,drawsignal);
286 return histo;
287 }
288
289 TH1F* samplecollection::Draw(string m_histoname,string m_var, vector<float> binning, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, bool drawsignal=false)
290 {
291 vector<int> emptyvector;
292 TH1F *histo = this->Draw(m_histoname,m_var, binning, m_xlabel, m_ylabel, Cut, m_is_data, luminosity,emptyvector,drawsignal);
293 return histo;
294 }
295
296 TH1F* samplecollection::Draw(string m_histoname,string m_var, vector<float> binning, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, vector<int> onlyindex, bool drawsignal=false) {
297 if(Verbosity>0) dout << endl << endl;
298 if(Verbosity>0) dout << "-------------------------------------------------------------------------------------" << endl;
299 if(Verbosity>0) dout << "histoname : " << m_histoname << " , m_var = " << m_var << ", m_xlabel=" << m_xlabel << " m_ylabel=" << m_ylabel << " m_is_data = " << m_is_data << " lumi = " << luminosity << " onlyindex size: " << onlyindex.size() << endl;
300
301 if(HUSH==0) dout << "Drawing histo called " << m_histoname << "... " << endl;
302 bool do_only_selected_samples=false;
303 if(onlyindex.size()>0&&onlyindex[0]!=-1) {
304 if(Verbosity>0) {dout << "Requested to only draw sample corresponding to the following sample(s) : " << endl;}
305 for(int is=0;is<(int)onlyindex.size();is++) {
306 if(Verbosity>0) dout << " - " << (this->collection)[onlyindex[is]].filename << " (sample index: " << onlyindex[is] << ")" << endl;
307 }
308 do_only_selected_samples=true;
309 }
310 if(onlyindex.size()==1&&onlyindex[0]==-1) {
311 do_only_selected_samples=true; // this is the special case when we request a non-existing sample - we shouldn't draw anything then.
312 onlyindex.clear();
313 }
314 stringstream h_histoname;
315 h_histoname<<"h_"<<m_histoname;
316 float binningarray[binning.size()+1];
317 for(int i=0;i<(int)binning.size();i++) {binningarray[i]=binning[i];}
318 TH1F *histo = new TH1F(m_histoname.c_str(),"",binning.size()-1,binningarray);
319 histo->Sumw2();
320
321 stringstream drawthis;
322 drawthis<<m_var<<">>tempdrawhisto";
323
324 for (unsigned int isample=0;isample<(this->collection).size();isample++) {
325 bool use_this_sample=false;
326 if(!(this->collection)[isample].is_active) continue; // skip inactive samples right away
327 if(((this->collection)[isample].is_data==m_is_data)&&(!do_only_selected_samples)) {
328 if(drawsignal==false&&(this->collection)[isample].is_signal==true) continue;
329 use_this_sample=true;
330 }
331 if(do_only_selected_samples&&this->do_sample(isample,onlyindex)) {
332 use_this_sample=true;
333 }
334 TH1F *tempdrawhisto = new TH1F("tempdrawhisto","tempdrawhisto",binning.size()-1,binningarray);
335 tempdrawhisto->Sumw2();
336 if(use_this_sample) {
337 (this->collection)[isample].events->Draw(drawthis.str().c_str(),(essentialcut&&Cut)*cutWeight);//this weight is based on PU etc. not XS
338 // cout << "\033[1;33m Drawing " << drawthis.str() << " with cut " << (const char*) (essentialcut&&Cut)*cutWeight << " for sample " << (this->collection)[isample].filename << "\033[0m (overflow: " << addoverunderflowbins << ")" << endl;
339 if(addoverunderflowbins) {
340 //now also adding the overflow & underflow bins:
341 tempdrawhisto->SetBinContent(tempdrawhisto->GetNbinsX(),tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()+1)+tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()));
342 tempdrawhisto->SetBinError(tempdrawhisto->GetNbinsX(),TMath::Sqrt(tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX())));
343 // tempdrawhisto->SetBinContent(1,tempdrawhisto->GetBinContent(0)+tempdrawhisto->GetBinContent(1));
344 // tempdrawhisto->SetBinError(1,TMath::Sqrt(tempdrawhisto->GetBinContent(1)));
345 // Delete over- and under-flow bins
346 tempdrawhisto->SetBinContent(tempdrawhisto->GetNbinsX()+1,0);
347 // tempdrawhisto->SetBinContent(0,0);
348 }
349
350 if(!(this->collection)[isample].is_data) tempdrawhisto->Scale(luminosity*((this->collection)[isample].weight));//weight applied here is XS & N(entries)
351 if(Verbosity>0) dout << "[samplecollection::Draw] : Added contribution from sample " << (this->collection)[isample].samplename << ": " <<tempdrawhisto->Integral() << endl;
352 histo->Add(tempdrawhisto);
353 }
354 tempdrawhisto->Delete();
355 }//end of loop over isample
356 if(Verbosity>0) dout << "Histo has been filled and now contains " << histo->Integral() << " points (integral)" << endl;
357 histo->GetXaxis()->SetTitle(m_xlabel.c_str());
358 // Try to add bin width information: look for units in m_xlabel
359 string units = find_units(m_xlabel);
360 if ( units.length()>0 ) {
361 stringstream ylabel;
362 ylabel << m_ylabel << " / " << histo->GetBinWidth(1) << " " << units;
363 histo->GetYaxis()->SetTitle( ylabel.str().c_str() );
364 } else {
365 histo->GetYaxis()->SetTitle(m_ylabel.c_str());
366 }
367 histo->GetXaxis()->CenterTitle();
368 histo->GetYaxis()->CenterTitle();
369 if(do_only_selected_samples) histo->SetLineColor(this->GetColor(onlyindex[0]));
370 return histo;
371 }
372
373 TH2F* samplecollection::Draw(string m_histoname,string m_var, vector<float> binningx, vector<float> binningy, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, vector<int> onlyindex, bool drawsignal=false) {
374 if(Verbosity>0) dout << endl << endl;
375 if(Verbosity>0) dout << "-------------------------------------------------------------------------------------" << endl;
376 if(Verbosity>0) dout << "histoname : " << m_histoname << " , m_var = " << m_var << ", m_xlabel=" << m_xlabel << " m_ylabel=" << m_ylabel << " m_is_data = " << m_is_data << " lumi = " << luminosity << " onlyindex size: " << onlyindex.size() << endl;
377 if(HUSH==0) dout << "Drawing histo called " << m_histoname << "... " << endl;
378 bool do_only_selected_samples=false;
379 if(onlyindex.size()>0&&onlyindex[0]!=-1) {
380 if(Verbosity>0) {dout << "Requested to only draw sample corresponding to the following sample(s) : " << endl;}
381 for(int is=0;is<(int)onlyindex.size();is++) {
382 if(Verbosity>0) dout << " - " << (this->collection)[onlyindex[is]].filename << " (sample index: " << onlyindex[is] << ")" << endl;
383 }
384 do_only_selected_samples=true;
385 }
386 if(onlyindex.size()==1&&onlyindex[0]==-1) {
387 do_only_selected_samples=true; // this is the special case when we request a non-existing sample - we shouldn't draw anything then.
388 onlyindex.clear();
389 }
390 stringstream h_histoname;
391 h_histoname<<"h_"<<m_histoname;
392 float binningarray[binningx.size()+1];
393 float binningyarray[binningy.size()+1];
394 for(int i=0;i<(int)binningx.size();i++) {binningarray[i]=binningx[i];binningyarray[i]=binningy[i];}
395 TH2F *histo = new TH2F(m_histoname.c_str(),"",binningx.size()-1,binningarray,binningy.size()-1,binningyarray);
396 histo->Sumw2();
397
398 stringstream drawthis;
399 drawthis<<m_var<<">>tempdrawhisto";
400
401 for (unsigned int isample=0;isample<(this->collection).size();isample++) {
402 bool use_this_sample=false;
403 if(!(this->collection)[isample].is_active) continue; // skip inactive samples right away
404 if(((this->collection)[isample].is_data==m_is_data)&&(!do_only_selected_samples)) {
405 if(drawsignal==false&&(this->collection)[isample].is_signal==true) continue;
406 use_this_sample=true;
407 }
408 if(do_only_selected_samples&&this->do_sample(isample,onlyindex)) {
409 use_this_sample=true;
410 }
411 TH2F *tempdrawhisto = new TH2F("tempdrawhisto","tempdrawhisto",binningx.size()-1,binningarray,binningy.size()-1,binningyarray);
412 tempdrawhisto->Sumw2();
413 if(use_this_sample) {
414 if(Verbosity>0) dout << "[samplecollection::Draw] : Added contribution from sample " << (this->collection)[isample].samplename << endl;
415 (this->collection)[isample].events->Draw(drawthis.str().c_str(),(essentialcut&&Cut)*cutWeight);//this weight is based on PU etc. not XS
416 // cout << "About to draw : " << drawthis.str() << " with cut " << (const char*) (essentialcut&&Cut)*cutWeight << endl;
417 if(addoverunderflowbins) {
418 //now also adding the overflow & underflow bins:
419 tempdrawhisto->SetBinContent(tempdrawhisto->GetNbinsX(),tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()+1)+tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()));
420 tempdrawhisto->SetBinError(tempdrawhisto->GetNbinsX(),TMath::Sqrt(tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX())));
421 tempdrawhisto->SetBinContent(1,tempdrawhisto->GetBinContent(0)+tempdrawhisto->GetBinContent(1));
422 tempdrawhisto->SetBinError(1,TMath::Sqrt(tempdrawhisto->GetBinContent(1)));
423 }
424
425 if(!(this->collection)[isample].is_data) tempdrawhisto->Scale(luminosity*((this->collection)[isample].weight));//weight applied here is XS & N(entries)
426 histo->Add(tempdrawhisto);
427 }
428 tempdrawhisto->Delete();
429 }//end of loop over isample
430 if(Verbosity>0) dout << "Histo has been filled and now contains " << histo->Integral() << " points (integral)" << endl;
431 histo->GetXaxis()->SetTitle(m_xlabel.c_str());
432 histo->GetYaxis()->SetTitle(m_ylabel.c_str());
433 histo->GetXaxis()->CenterTitle();
434 histo->GetYaxis()->CenterTitle();
435 if(do_only_selected_samples) histo->SetLineColor(this->GetColor(onlyindex[0]));
436 return histo;
437 }
438
439
440 TH1F* samplecollection::Draw(string m_histoname,string m_var, int m_nbins, float m_minx, float m_maxx, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, vector<int> onlyindex, bool drawsignal=false)
441 {
442 vector<float> binning;
443 for(int i=0;i<=m_nbins;i++)
444 {
445 binning.push_back(((float)(m_maxx-m_minx)/((float)m_nbins))*i+m_minx);
446 }
447
448 TH1F *histo = this->Draw(m_histoname,m_var, binning, m_xlabel, m_ylabel, Cut, m_is_data, luminosity, onlyindex,drawsignal);
449 return histo;
450 }
451
452 THStack samplecollection::DrawStack(string m_histoname,string m_var, vector<float> binning, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, bool drawsignal=false) {
453 stringstream h_histoname;
454 h_histoname<<"h_"<<m_histoname;
455 THStack thestack("thestack",m_histoname.c_str());
456
457 stringstream drawthis;
458 drawthis<<m_var<<">>tempdrawhisto";
459
460 TH1F *histogroups[this->ngroups+1];
461 int bookedhistos[this->ngroups+1];
462 for(int ih=0;ih<=this->ngroups;ih++) bookedhistos[ih]=0;
463
464 float binningarray[binning.size()+1];
465 for(int i=0;i<(int)binning.size();i++) {binningarray[i]=binning[i];}
466
467 for (unsigned int isample=0;isample<(this->collection).size();isample++) {
468 if(!drawsignal&&(this->collection)[isample].is_signal) continue;
469 if((this->collection)[isample].is_active&&(this->collection)[isample].is_data==m_is_data) {//fills mc if we want mc, else fills data.
470 TH1F *tempdrawhisto = new TH1F("tempdrawhisto","",binning.size()-1,binningarray);
471 tempdrawhisto->Sumw2();
472 (this->collection)[isample].events->Draw(drawthis.str().c_str(),(essentialcut&&Cut)*cutWeight);
473
474 if(addoverunderflowbins) {
475 //now also adding the overflow & underflow bins:
476 tempdrawhisto->SetBinContent(tempdrawhisto->GetNbinsX(),tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()+1)+tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()));
477 // tempdrawhisto->SetBinError(tempdrawhisto->GetNbinsX(),TMath::Sqrt(tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()))); // errors not necessary for stack!
478 tempdrawhisto->SetBinContent(1,tempdrawhisto->GetBinContent(0)+tempdrawhisto->GetBinContent(1));
479 // tempdrawhisto->SetBinError(1,TMath::Sqrt(tempdrawhisto->GetBinContent(1))); // errors not necessary for stack!
480 }
481
482 if(!(this->collection)[isample].is_data) tempdrawhisto->Scale(luminosity*((this->collection)[isample].weight));
483 tempdrawhisto->SetFillColor(this->GetColor(isample));
484 if(bookedhistos[(this->collection)[isample].groupindex]==0) {
485 tempdrawhisto->SetName((removefunnystring((this->collection)[isample].samplename)+"__"+GetNumericHistoName()).c_str());
486 histogroups[(this->collection)[isample].groupindex]=(TH1F*)tempdrawhisto->Clone();
487 bookedhistos[(this->collection)[isample].groupindex]=1;
488 }
489 else
490 {
491 histogroups[(this->collection)[isample].groupindex]->Add(tempdrawhisto);
492 bookedhistos[(this->collection)[isample].groupindex]++;
493 }
494 tempdrawhisto->Delete();
495 }
496 }
497 vector<int> ordered_indices;
498 vector<float> ordered_integrals;
499
500 for(int ig=0;ig<=this->ngroups;ig++) {
501 if(bookedhistos[ig]>0) {
502 ordered_indices.push_back(ig);
503 ordered_integrals.push_back(histogroups[ig]->Integral());
504 }
505 }
506
507 /*
508 bubbleSort(ordered_integrals,ordered_indices);
509 // for(int index=ordered_indices.size()-1;index>=0;index--) {
510 for(int index=0;index<ordered_indices.size();index++) {
511 thestack.Add(histogroups[ordered_indices[index]]);
512 }
513 */
514 for(int index=0;index<(int)ordered_indices.size();index++) {
515 thestack.Add(histogroups[ordered_indices[index]]);
516 }
517 return thestack;
518 }
519
520 THStack samplecollection::DrawStack(string m_histoname,string m_var, int m_nbins, float m_minx, float m_maxx, string m_xlabel, string m_ylabel, TCut Cut, bool m_is_data, float luminosity, bool
521 drawsignal=false)
522 {
523 vector<float> binning;
524 for(int i=0;i<=m_nbins;i++)
525 {
526 binning.push_back(((float)(m_maxx-m_minx)/((float)m_nbins))*i+m_minx);
527 }
528 return this->DrawStack(m_histoname,m_var, binning, m_xlabel, m_ylabel, Cut, m_is_data, luminosity, drawsignal);
529 }
530
531
532 vector<int> samplecollection::FindSample(string what)
533 {
534 vector<int> hitcollection;
535 for(unsigned int isam=0;isam<(this->collection).size();isam++)
536 {
537 if(((this->collection)[isam].filename).find(what)!=string::npos) {
538 hitcollection.push_back(isam);
539 } else {
540 }
541 }
542 if(hitcollection.size()==0) {
543 hitcollection.push_back(-1);
544 write_warning(__FUNCTION__,"Couldn't find sample "+string(what)+" using sample collection \""+string(this->name)+"\"");
545 }
546 return hitcollection;
547 }
548
549 vector<int> samplecollection::FindSampleBySampleName(string what)
550 {
551 vector<int> hitcollection;
552 for(unsigned int isam=0;isam<(this->collection).size();isam++)
553 {
554 if(((this->collection)[isam].samplename).find(what)!=string::npos) {
555 hitcollection.push_back(isam);
556 } else {
557 }
558 }
559 if(hitcollection.size()==0) {
560 hitcollection.push_back(-1);
561 write_warning(__FUNCTION__,"Couldn't find sample "+string(what)+" using sample collection \""+string(this->name)+"\"");
562 }
563 return hitcollection;
564 }
565
566 Color_t samplecollection::GetColor(string filename) {
567 vector<int> corresponding_samples = this->FindSample(filename);
568 if(corresponding_samples.size()>0) return this->GetColor(corresponding_samples[0]);
569 return kBlack;
570 }
571
572 Color_t samplecollection::GetColor(int sampleindex) {
573 return this->collection[sampleindex].samplecolor;
574 }
575
576 TLegend* samplecollection::allbglegend(string title, TH1F *data,float posx=0.65, float posy=0.60) {
577 // TLegend *leg = new TLegend(0.65,0.60,0.89,0.77);
578 TLegend *leg = new TLegend(posx,posy,0.89,0.89);
579 if(title!="") leg->SetHeader(title.c_str());
580 if(data->GetName()!="nothing") leg->AddEntry(data,"Data","lp");
581 leg->SetFillColor(kWhite);
582 leg->SetBorderSize(0);
583 leg->SetLineColor(kWhite);
584
585 int maxIgroup=0;
586 for(int isample=0;isample<(int)(this->collection).size();isample++) {
587 if((this->collection)[isample].groupindex>maxIgroup) maxIgroup=(this->collection)[isample].groupindex;
588 }
589
590 TH1F *fakehistos[maxIgroup];
591 bool donealready[maxIgroup];
592
593 for(int i=0;i<maxIgroup;i++) donealready[i]=false;
594 for(int isample=0;isample<(int)(this->collection).size();isample++) {
595 if((this->collection)[isample].is_data||(this->collection)[isample].is_signal) continue;
596
597 if(!donealready[(this->collection)[isample].groupindex]) {
598 fakehistos[(this->collection)[isample].groupindex] = new TH1F(GetNumericHistoName().c_str(),"",1,0,1);
599 fakehistos[(this->collection)[isample].groupindex]->Fill(1);
600 fakehistos[(this->collection)[isample].groupindex]->SetFillColor(this->GetColor(isample));
601 leg->AddEntry(fakehistos[(this->collection)[isample].groupindex],((this->collection)[isample].samplename).c_str(),"f");
602 donealready[(this->collection)[isample].groupindex]=true;
603 PlottingSetup::FakeHistoHeap.push_back(fakehistos[(this->collection)[isample].groupindex]);
604 }
605 }
606 DrawPrelim();
607 leg->SetTextFont(42);
608 return leg;
609 }
610
611 TLegend* samplecollection::allbglegend(string title="",float posx=0.65, float posy=0.60) {
612 // Int_t currlevel=gErrorIgnoreLevel;
613 // gErrorIgnoreLevel=5000;
614 TH1F *blub = new TH1F("nothing","nothing",1,0,1);
615 // gErrorIgnoreLevel=currlevel;//we know this possibly replaces a previous histo, but we don't care since it's fake anyway.
616 TLegend *leg = this->allbglegend(title,blub,posx,posy);
617 delete blub;
618 return leg;
619 }
620
621
622 void set_treename(string treen="events") {
623 dout << "Treename has been set to " << treen << endl;
624 if(treen=="PFevents"||treen=="events") treename=treen;
625 else write_error("sample::set_treename","Setting the treename failed as you provided an invalid tree name.");
626 }
627
628 vector<float> samplecollection::get_optimal_binsize(string variable, TCut cut,int nbins, float low, float high) {
629 TH1F *histo = this->Draw("histo",variable,5000,low,high, "finding_optimal_binsize", "events", cut,0,1000);
630 float eventsperbin=histo->Integral()/nbins;
631 vector<float> binning;
632 binning.push_back(high);
633 float runningsum=0;
634 for(int i=histo->GetNbinsX();i>0;i--) {
635 runningsum+=histo->GetBinContent(i);
636 if(TMath::Abs(runningsum-eventsperbin)<0.05*eventsperbin||runningsum>eventsperbin) {
637 binning.push_back(histo->GetBinLowEdge(i));
638 runningsum=0;
639 }
640 }
641 if(runningsum>0) binning.push_back(low);
642 for(int i=0;i<int(binning.size()/2);i++) {
643 float temp=binning[i];
644 binning[i]=binning[binning.size()-1-i];
645 binning[binning.size()-1-i]=temp;
646 }
647
648 return binning;
649
650 }
651
652 void samplecollection::PickUpFromThisFile(int isamp, string cut, vector<string> &output, vector<string> &pickupfile) {
653 int lumi,eventNum,runNum;
654 float jzb[30];
655 (this->collection)[isamp].events->SetBranchAddress("jzb",&jzb);
656 (this->collection)[isamp].events->SetBranchAddress("lumi",&runNum);
657 (this->collection)[isamp].events->SetBranchAddress("eventNum",&eventNum);
658 (this->collection)[isamp].events->SetBranchAddress("lumi",&lumi);
659 (this->collection)[isamp].events->SetBranchAddress("runNum",&runNum);
660
661
662 TTreeFormula *select = new TTreeFormula("select", cut.c_str()&&essentialcut, (this->collection)[isamp].events);
663 int npickedup=0;
664 for (Int_t entry = 0 ; entry < (this->collection)[isamp].events->GetEntries() ; entry++) {
665 (this->collection)[isamp].events->LoadTree(entry);
666 if (select->EvalInstance()) {
667 (this->collection)[isamp].events->GetEntry(entry);
668 dout << runNum << ":" << lumi << ":" << eventNum << endl;
669 npickedup++;
670 }
671 }
672 dout << "Printed out a total of " << npickedup << " events" << endl;
673 }
674
675
676
677 void samplecollection::PickUpEvents(string cut) {
678 vector<string> output;
679 vector<string> pickupfile;
680 for (int isamp=0;isamp<(int)this->collection.size();isamp++)
681 {
682 if((this->collection)[isamp].is_data) {
683 //we have a data sample !
684 this->PickUpFromThisFile(isamp,cut,output,pickupfile);
685 }
686 }
687 //do something with output and of course the pickup file!
688 }
689
690 //________________________________________________________________________________________
691 // Find units from histogram x-label (looks for '[...]')
692 string samplecollection::find_units(string& xlabel) {
693
694 string units;
695 size_t pos1 = xlabel.find("[");
696 if ( pos1 != string::npos ) {
697 size_t pos2 = xlabel.find("]");
698 units = xlabel.substr(pos1+1,pos2-pos1-1);
699 }// else {
700 // size_t pos1 = xlabel.find("(");
701 // if ( pos1 != string::npos ) {
702 // size_t pos2 = xlabel.find(")");
703 // units = xlabel.substr(pos1+1,pos2-pos1-1);
704 // }
705 // }
706 return units;
707
708 }
709
710 void samplecollection::RemoveLastSample() {
711 dout << "Removing last sample: " << ((this->collection)[(this->collection).size()-1]).filename << std::endl;
712 if(((this->collection)[(this->collection).size()-1]).is_data) this->ndatasamples--;
713 else this->nmcsamples--;
714 this->nsamples--;
715 ((this->collection)[(this->collection).size()-1]).closeFile();
716 (this->collection).pop_back();
717 }
718
719 void switch_overunderflow(bool newpos=false) {
720 addoverunderflowbins=newpos;
721 }
722
723