ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/SampleClass.C
Revision: 1.20
Committed: Wed Dec 5 09:46:45 2012 UTC (12 years, 5 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.19: +1 -1 lines
Log Message:
Removed weight renormalization for PURW (was needed for 3D PURW)

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