ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/SampleClass.C
Revision: 1.6
Committed: Tue May 22 10:21:36 2012 UTC (12 years, 11 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.5: +8 -1 lines
Log Message:
checking weights for each sample and correcting for the average weight

File Contents

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