32 |
|
|
33 |
|
bool doesROOTFileExist(string filename); |
34 |
|
bool addoverunderflowbins=false; |
35 |
< |
string treename="PFevents"; |
35 |
> |
string treename="events"; |
36 |
|
|
37 |
|
class sample |
38 |
|
{ |
45 |
|
bool is_data; |
46 |
|
bool is_signal; |
47 |
|
bool is_active; |
48 |
+ |
float weightrenormalization; |
49 |
|
int groupindex; |
50 |
|
Color_t samplecolor; |
51 |
|
|
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 |
|
|
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; |
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."; |
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; |
93 |
> |
// Int_t currlevel=gErrorIgnoreLevel; |
94 |
> |
// gErrorIgnoreLevel=5000; |
95 |
|
this->tfile = new TFile(m_filename.c_str()); |
96 |
< |
gErrorIgnoreLevel=currlevel; |
96 |
> |
// gErrorIgnoreLevel=currlevel; |
97 |
|
this->events=(TTree*)(this->tfile)->Get(treename.c_str()); |
98 |
+ |
// this->events->SetCacheSize(5000000);//only a 5 MB cache! |
99 |
|
if(Verbosity>0) dout << "The " << write_mc_or_data(is_data) << " file " << this->filename << " has been added successfully to the list of samples. " << endl; |
100 |
|
long long measured_nevents=(long)1; |
101 |
|
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(); |
104 |
> |
//average_weight = weight_histo->Integral()/weight_histo->GetEntries(); |
105 |
|
measured_nevents = (long)weight_histo->GetEntries(); |
106 |
|
} else { |
107 |
|
measured_nevents=(this->events)->GetEntries(); |
108 |
|
} |
109 |
|
|
110 |
< |
if(((this->Nentries>1)||(this->Nentries==0))&measured_nevents!=this->Nentries) { |
110 |
> |
if(((this->Nentries>1)||(this->Nentries==0))&&measured_nevents!=this->Nentries) { |
111 |
|
//special cases: m_Nentries=1 : we want to give each event the full weight (->scans!) |
112 |
|
// m_Nentries=0: detect the number of events and set the nevents automatically |
113 |
+ |
// m_Nentries<0: set manually (see below) |
114 |
|
|
115 |
|
stringstream warning; |
116 |
|
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."; |
117 |
|
if(m_Nentries>1) write_warning(__FUNCTION__,warning.str()); |
118 |
|
this->Nentries=measured_nevents; |
119 |
+ |
} else if ( this->Nentries<0 ) { |
120 |
+ |
this->Nentries = -this->Nentries; |
121 |
|
} |
122 |
< |
this->weight=(xs/(float)Nentries); |
123 |
< |
this->weight/=average_weight; |
122 |
> |
if ( average_weight>0 ) { |
123 |
> |
this->weight=(xs/(float)Nentries)/average_weight; |
124 |
> |
this->weightrenormalization=(1.0/average_weight); |
125 |
> |
} else { |
126 |
> |
if(average_weight>0) { |
127 |
> |
this->weight=(xs/(float)Nentries)/average_weight; |
128 |
> |
this->weightrenormalization=(1.0/average_weight); |
129 |
> |
} else { |
130 |
> |
this->weight = (xs/(float)Nentries); |
131 |
> |
this->weightrenormalization=1; |
132 |
> |
} |
133 |
> |
} |
134 |
> |
|
135 |
|
} |
136 |
|
else { |
137 |
|
this->is_active=false; |
153 |
|
bool doesROOTFileExist(string filename) |
154 |
|
{ |
155 |
|
//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) |
156 |
< |
Int_t currlevel=gErrorIgnoreLevel; |
157 |
< |
gErrorIgnoreLevel=5000; |
156 |
> |
// Int_t currlevel=gErrorIgnoreLevel; |
157 |
> |
// gErrorIgnoreLevel=5000; |
158 |
|
TFile *f = new TFile(filename.c_str()); |
159 |
|
|
160 |
|
if (f->IsZombie()) { |
162 |
|
return 0; |
163 |
|
} |
164 |
|
f->Close(); |
165 |
< |
gErrorIgnoreLevel=currlevel; |
165 |
> |
// gErrorIgnoreLevel=currlevel; |
166 |
|
return 1; |
167 |
|
} |
168 |
|
//******************************************************** |
170 |
|
TCut essentialcut("mll>0"); |
171 |
|
// The following cut (cutWeight) will reweight all the events: use "weight" to correct MC for pileUP, "1.0" otherwise |
172 |
|
TCut cutWeight("weight"); |
173 |
+ |
//TCut cutWeight("(weight*(((id1==id2&&id1==0)*1.2)+((id1==id2&&id1==1)/1.2)+(id1!=id2)))"); |
174 |
|
|
175 |
|
void setessentialcut(TCut ess) { |
176 |
|
essentialcut=ess; |
213 |
|
TLegend* allbglegend(string title,float x, float y); |
214 |
|
TLegend* allbglegend(string title, TH1F *data, float x, float y); |
215 |
|
|
216 |
< |
void PickUpFromThisFile(int isamp, string cut, vector<string> &output, vector<string> &pickupfile); |
217 |
< |
void PickUpEvents(string cut); |
216 |
> |
void PickUpFromThisFile(int isamp, string cut, vector<string> &output, vector<string> &pickupfile, bool QuietMode); |
217 |
> |
void PickUpEvents(string cut,string filename,bool QuietMode); |
218 |
|
string find_units(string&); |
219 |
|
|
220 |
|
void RemoveLastSample(); |
250 |
|
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) |
251 |
|
{ |
252 |
|
sample NewSample(m_filename,m_samplename,m_Nentries,m_xs,is_data,m_is_signal,groupindex,newcolor); |
253 |
+ |
if (!NewSample.is_active) { |
254 |
+ |
write_warning(__FUNCTION__,"Not adding this sample ("+m_filename+") as it has been declared inactive"); |
255 |
+ |
return; |
256 |
+ |
} |
257 |
|
(this->collection).push_back(NewSample); |
258 |
|
if((this->collection).size()==1) { |
259 |
|
this->nmcsamples=0; |
294 |
|
return histo; |
295 |
|
} |
296 |
|
|
297 |
+ |
|
298 |
|
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) { |
299 |
|
if(Verbosity>0) dout << endl << endl; |
300 |
|
if(Verbosity>0) dout << "-------------------------------------------------------------------------------------" << endl; |
301 |
|
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; |
302 |
+ |
|
303 |
|
if(HUSH==0) dout << "Drawing histo called " << m_histoname << "... " << endl; |
304 |
|
bool do_only_selected_samples=false; |
305 |
|
if(onlyindex.size()>0&&onlyindex[0]!=-1) { |
336 |
|
TH1F *tempdrawhisto = new TH1F("tempdrawhisto","tempdrawhisto",binning.size()-1,binningarray); |
337 |
|
tempdrawhisto->Sumw2(); |
338 |
|
if(use_this_sample) { |
308 |
– |
if(Verbosity>0) dout << "[samplecollection::Draw] : Added contribution from sample " << (this->collection)[isample].samplename << endl; |
339 |
|
(this->collection)[isample].events->Draw(drawthis.str().c_str(),(essentialcut&&Cut)*cutWeight);//this weight is based on PU etc. not XS |
340 |
+ |
// 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; |
341 |
+ |
// cout << "Drawing for : " << (this->collection)[isample].filename << endl; |
342 |
+ |
// for(int i=1;i<=tempdrawhisto->GetNbinsX();i++) cout << " Bin " << i << " [" << tempdrawhisto->GetBinLowEdge(i) << "," << tempdrawhisto->GetBinLowEdge(i)+tempdrawhisto->GetBinWidth(i) << "] : " << tempdrawhisto->GetBinContent(i) << " +/- " << tempdrawhisto->GetBinError(i) << endl; |
343 |
|
if(addoverunderflowbins) { |
344 |
|
//now also adding the overflow & underflow bins: |
345 |
|
tempdrawhisto->SetBinContent(tempdrawhisto->GetNbinsX(),tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()+1)+tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX())); |
346 |
|
tempdrawhisto->SetBinError(tempdrawhisto->GetNbinsX(),TMath::Sqrt(tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()))); |
347 |
< |
tempdrawhisto->SetBinContent(1,tempdrawhisto->GetBinContent(0)+tempdrawhisto->GetBinContent(1)); |
348 |
< |
tempdrawhisto->SetBinError(1,TMath::Sqrt(tempdrawhisto->GetBinContent(1))); |
347 |
> |
// tempdrawhisto->SetBinContent(1,tempdrawhisto->GetBinContent(0)+tempdrawhisto->GetBinContent(1)); |
348 |
> |
// tempdrawhisto->SetBinError(1,TMath::Sqrt(tempdrawhisto->GetBinContent(1))); |
349 |
> |
// Delete over- and under-flow bins |
350 |
> |
tempdrawhisto->SetBinContent(tempdrawhisto->GetNbinsX()+1,0); |
351 |
> |
// tempdrawhisto->SetBinContent(0,0); |
352 |
|
} |
353 |
|
|
354 |
|
if(!(this->collection)[isample].is_data) tempdrawhisto->Scale(luminosity*((this->collection)[isample].weight));//weight applied here is XS & N(entries) |
355 |
+ |
if(Verbosity>0) dout << "[samplecollection::Draw] : Added contribution from sample " << (this->collection)[isample].samplename << ": " <<tempdrawhisto->Integral() << endl; |
356 |
|
histo->Add(tempdrawhisto); |
357 |
|
} |
358 |
|
tempdrawhisto->Delete(); |
393 |
|
} |
394 |
|
stringstream h_histoname; |
395 |
|
h_histoname<<"h_"<<m_histoname; |
396 |
< |
float binningarray[binningx.size()+1]; |
360 |
< |
float binningyarray[binningy.size()+1]; |
361 |
< |
for(int i=0;i<(int)binningx.size();i++) {binningarray[i]=binningx[i];binningyarray[i]=binningy[i];} |
362 |
< |
TH2F *histo = new TH2F(m_histoname.c_str(),"",binningx.size()-1,binningarray,binningy.size(),binningyarray); |
396 |
> |
TH2F *histo = new TH2F(m_histoname.c_str(),"",binningx.size()-1,&binningx[0],binningy.size()-1,&binningy[0]); |
397 |
|
histo->Sumw2(); |
398 |
|
|
399 |
|
stringstream drawthis; |
409 |
|
if(do_only_selected_samples&&this->do_sample(isample,onlyindex)) { |
410 |
|
use_this_sample=true; |
411 |
|
} |
412 |
< |
TH2F *tempdrawhisto = new TH2F("tempdrawhisto","tempdrawhisto",binningx.size()-1,binningarray,binningy.size()-1,binningyarray); |
412 |
> |
TH2F *tempdrawhisto = new TH2F("tempdrawhisto","tempdrawhisto",binningx.size()-1,&binningx[0],binningy.size()-1,&binningy[0]); |
413 |
|
tempdrawhisto->Sumw2(); |
414 |
|
if(use_this_sample) { |
415 |
|
if(Verbosity>0) dout << "[samplecollection::Draw] : Added contribution from sample " << (this->collection)[isample].samplename << endl; |
416 |
|
(this->collection)[isample].events->Draw(drawthis.str().c_str(),(essentialcut&&Cut)*cutWeight);//this weight is based on PU etc. not XS |
417 |
+ |
// cout << "About to draw : " << drawthis.str() << " with cut " << (const char*) (essentialcut&&Cut)*cutWeight << endl; |
418 |
|
if(addoverunderflowbins) { |
419 |
|
//now also adding the overflow & underflow bins: |
420 |
|
tempdrawhisto->SetBinContent(tempdrawhisto->GetNbinsX(),tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()+1)+tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX())); |
445 |
|
{ |
446 |
|
binning.push_back(((float)(m_maxx-m_minx)/((float)m_nbins))*i+m_minx); |
447 |
|
} |
448 |
< |
|
448 |
> |
|
449 |
|
TH1F *histo = this->Draw(m_histoname,m_var, binning, m_xlabel, m_ylabel, Cut, m_is_data, luminosity, onlyindex,drawsignal); |
450 |
|
return histo; |
451 |
|
} |
469 |
|
if(!drawsignal&&(this->collection)[isample].is_signal) continue; |
470 |
|
if((this->collection)[isample].is_active&&(this->collection)[isample].is_data==m_is_data) {//fills mc if we want mc, else fills data. |
471 |
|
TH1F *tempdrawhisto = new TH1F("tempdrawhisto","",binning.size()-1,binningarray); |
472 |
+ |
tempdrawhisto->Sumw2(); |
473 |
|
(this->collection)[isample].events->Draw(drawthis.str().c_str(),(essentialcut&&Cut)*cutWeight); |
474 |
< |
|
474 |
> |
// 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; |
475 |
|
if(addoverunderflowbins) { |
476 |
|
//now also adding the overflow & underflow bins: |
477 |
|
tempdrawhisto->SetBinContent(tempdrawhisto->GetNbinsX(),tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX()+1)+tempdrawhisto->GetBinContent(tempdrawhisto->GetNbinsX())); |
515 |
|
for(int index=0;index<(int)ordered_indices.size();index++) { |
516 |
|
thestack.Add(histogroups[ordered_indices[index]]); |
517 |
|
} |
518 |
+ |
|
519 |
|
return thestack; |
520 |
|
} |
521 |
|
|
579 |
|
// TLegend *leg = new TLegend(0.65,0.60,0.89,0.77); |
580 |
|
TLegend *leg = new TLegend(posx,posy,0.89,0.89); |
581 |
|
if(title!="") leg->SetHeader(title.c_str()); |
582 |
< |
if(data->GetName()!="nothing") leg->AddEntry(data,"Data","p"); |
582 |
> |
if(data->GetName()!="nothing") leg->AddEntry(data,"Data","lp"); |
583 |
|
leg->SetFillColor(kWhite); |
584 |
|
leg->SetBorderSize(0); |
585 |
|
leg->SetLineColor(kWhite); |
586 |
|
|
587 |
< |
TH1F *fakehistos[(this->collection).size()]; |
588 |
< |
bool donealready[(this->collection).size()]; |
589 |
< |
for(int i=0;i<(int)(this->collection).size();i++) donealready[i]=false; |
587 |
> |
int maxIgroup=0; |
588 |
> |
for(int isample=0;isample<(int)(this->collection).size();isample++) { |
589 |
> |
if((this->collection)[isample].groupindex>maxIgroup) maxIgroup=(this->collection)[isample].groupindex; |
590 |
> |
} |
591 |
> |
maxIgroup++; |
592 |
> |
|
593 |
> |
TH1F *fakehistos[maxIgroup]; |
594 |
> |
bool donealready[maxIgroup]; |
595 |
> |
|
596 |
> |
for(int i=0;i<maxIgroup;i++) donealready[i]=false; |
597 |
> |
|
598 |
|
for(int isample=0;isample<(int)(this->collection).size();isample++) { |
599 |
|
if((this->collection)[isample].is_data||(this->collection)[isample].is_signal) continue; |
555 |
– |
|
600 |
|
if(!donealready[(this->collection)[isample].groupindex]) { |
601 |
+ |
assert((this->collection)[isample].groupindex<maxIgroup); |
602 |
|
fakehistos[(this->collection)[isample].groupindex] = new TH1F(GetNumericHistoName().c_str(),"",1,0,1); |
603 |
|
fakehistos[(this->collection)[isample].groupindex]->Fill(1); |
604 |
|
fakehistos[(this->collection)[isample].groupindex]->SetFillColor(this->GetColor(isample)); |
605 |
|
leg->AddEntry(fakehistos[(this->collection)[isample].groupindex],((this->collection)[isample].samplename).c_str(),"f"); |
606 |
|
donealready[(this->collection)[isample].groupindex]=true; |
607 |
+ |
PlottingSetup::FakeHistoHeap.push_back(fakehistos[(this->collection)[isample].groupindex]); |
608 |
|
} |
609 |
|
} |
610 |
|
DrawPrelim(); |
613 |
|
} |
614 |
|
|
615 |
|
TLegend* samplecollection::allbglegend(string title="",float posx=0.65, float posy=0.60) { |
570 |
– |
Int_t currlevel=gErrorIgnoreLevel; |
571 |
– |
gErrorIgnoreLevel=5000; |
616 |
|
TH1F *blub = new TH1F("nothing","nothing",1,0,1); |
617 |
< |
gErrorIgnoreLevel=currlevel;//we know this possibly replaces a previous histo, but we don't care since it's fake anyway. |
618 |
< |
return this->allbglegend(title,blub,posx,posy); |
617 |
> |
TLegend *leg = this->allbglegend(title,blub,posx,posy); |
618 |
> |
PlottingSetup::FakeHistoHeap.push_back(blub); |
619 |
> |
return leg; |
620 |
|
} |
621 |
|
|
622 |
|
|
650 |
|
|
651 |
|
} |
652 |
|
|
653 |
< |
void samplecollection::PickUpFromThisFile(int isamp, string cut, vector<string> &output, vector<string> &pickupfile) { |
654 |
< |
int lumi,eventNum,runNum; |
653 |
> |
void samplecollection::PickUpFromThisFile(int isamp, string cut, vector<string> &output, vector<string> &pickupfile, bool QuietMode) { |
654 |
> |
int lumi,runNum; |
655 |
> |
ULong64_t eventNum; |
656 |
> |
|
657 |
|
float jzb[30]; |
658 |
|
(this->collection)[isamp].events->SetBranchAddress("jzb",&jzb); |
659 |
|
(this->collection)[isamp].events->SetBranchAddress("lumi",&runNum); |
664 |
|
|
665 |
|
TTreeFormula *select = new TTreeFormula("select", cut.c_str()&&essentialcut, (this->collection)[isamp].events); |
666 |
|
int npickedup=0; |
667 |
+ |
stringstream filetext; |
668 |
|
for (Int_t entry = 0 ; entry < (this->collection)[isamp].events->GetEntries() ; entry++) { |
669 |
|
(this->collection)[isamp].events->LoadTree(entry); |
670 |
|
if (select->EvalInstance()) { |
671 |
|
(this->collection)[isamp].events->GetEntry(entry); |
672 |
< |
dout << runNum << ":" << lumi << ":" << eventNum << endl; |
672 |
> |
if(!QuietMode) dout << runNum << ":" << lumi << ":" << eventNum << endl; |
673 |
> |
filetext.str(""); |
674 |
> |
filetext << runNum << ":" << lumi << ":" << eventNum << endl; |
675 |
> |
output.push_back(filetext.str()); |
676 |
|
npickedup++; |
677 |
|
} |
678 |
|
} |
679 |
< |
dout << "Printed out a total of " << npickedup << " events" << endl; |
679 |
> |
if(!QuietMode) dout << "Printed out a total of " << npickedup << " events" << endl; |
680 |
|
} |
681 |
|
|
682 |
|
|
683 |
|
|
684 |
< |
void samplecollection::PickUpEvents(string cut) { |
684 |
> |
void samplecollection::PickUpEvents(string cut, string filename, bool QuietMode=false) { |
685 |
|
vector<string> output; |
686 |
|
vector<string> pickupfile; |
687 |
< |
for (int isamp=0;isamp<(int)this->collection.size();isamp++) |
687 |
> |
for (unsigned int isamp=0;isamp<this->collection.size();isamp++) |
688 |
|
{ |
689 |
|
if((this->collection)[isamp].is_data) { |
690 |
|
//we have a data sample ! |
691 |
< |
this->PickUpFromThisFile(isamp,cut,output,pickupfile); |
691 |
> |
this->PickUpFromThisFile(isamp,cut,output,pickupfile,QuietMode); |
692 |
|
} |
693 |
|
} |
694 |
+ |
|
695 |
|
//do something with output and of course the pickup file! |
696 |
+ |
ofstream myfile(filename.c_str()); |
697 |
+ |
for(unsigned int ievent=0;ievent<output.size();ievent++) myfile << output[ievent]; |
698 |
+ |
myfile.close(); |
699 |
+ |
|
700 |
|
} |
701 |
|
|
702 |
|
//________________________________________________________________________________________ |