1 #include "SystematicTools.hxx" 2 #include "WeightTools.hxx" 3 #include <TGraphAsymmErrors.h> 14 Systematic errors are propagated using toy experiments. The covariance for the bins \(i\) and \(j\) reads:
17 C_{ij} = \sum_{t=1}^{N_{toys}} [(N_i^t)^W-N_i^{avg}] [(N_j^t)^W-N_j^{avg}]\cdot w^t
20 In the above expression \(w^t\) is the toy experiment weight (i.e. the probability of this toy to occur). When random throws are used to generate the toy, it is just:
23 w^t = \frac{1}{N_{toys}}
26 \((N_i^t)^W\) is the number of selected events for toy \(t\) and bin \(i\) once weight systematics (efficiency-like and normalization systematics,
27 described above) have been applied (hence the superindex ``W''):
30 (N_i^t)^W = \sum_{e=1}^{N_{events}} (W^t)_e \cdot (\delta_i^t)_e
34 being \((W^t)_e\) the total weight for toy \(t\) and event \(e\). This will be the product of individual weights for each systematic, \((W^t)_e = \prod_{s=1}^{N_s} (W^t)_e^s \).
35 The expression \((\delta_i^t)_e\) has value 1 or 0 depending on whether the selection was passed
36 for event \(e\) and toy \(t\) and the event felt in bin \(i\).
38 Finally, \(N_i^{avg}\) is the average number of events for bin \(i\) when no weight systematics
42 N_i^{avg} = \sum_{t=1}^{N_{toys}} w^t \cdot N_i^t = \sum_{t=1}^{N_{toys}} w^t \cdot \sum_{e=1}^{N_{events}} (\delta_i^t)_e
49 SystematicsTools::SystematicsTools(){
57 void SystematicsTools::FillSystematicHistos(TTree* tree,
const std::string& var,
int nx,
double* xbins,
const std::string& cut,
int NTOYS,
const std::string& uopt,
58 TH2_h* h2, TH2_h* h1w){
60 if(errdebug) std::cout<<
"FillSystematicHistos \n============================= "<<std::endl;
74 if (cut2==
"") cut2=
"1==1";
76 cut2 = weightTools::ApplyWeights(tree,cut2,uopt);
80 tree->Project(
"h2",(
"toy_index:"+var).c_str(),(
"("+cut2+
")").c_str());
92 for (
int i=0;i<nx;i++)
93 for (
int j=0;j<NTOYS;j++)
94 h1w->SetBinContent(i+1,j+1,h2->GetBinContent(i+1,j+1));
107 TH2_h h2(
"h2",
"h2",nx,xbins,NTOYS,0,NTOYS);
108 TH2_h h1w(
"h1w",
"h1w",nx,xbins,NTOYS,0,NTOYS);
111 TH2_h h1(
"h1",
"h1",nx,xbins,NTOYS,0,NTOYS);
114 FillSystematicHistos(tree,var,nx,xbins,cut,NTOYS,uopt,&h2,&h1w);
121 const TMatrixD& SystematicsTools::GetSystematicCovBase(
HistoStack* hs1,
HistoStack* hs2,
const std::string& uopt,
const std::string& group){
130 GetSystematicHistos(group,hs1, hs2,h2,h1w);
131 return GetSystematicCovBase(*h2,*h1w,uopt);
135 std::vector<std::string>::iterator it;
136 for (it=syst_groups.begin();it!=syst_groups.end();it++){
137 GetSystematicHistos(*it,hs1, hs2,h2,h1w);
138 const TMatrixD& C = GetSystematicCovBase(*h2,*h1w,uopt);
139 if (it==syst_groups.begin()){
140 int nx = h2->GetNbinsX();
141 _covTotal.ResizeTo(nx, nx);
145 _covTotal = _covTotal + C;
152 void SystematicsTools::GetSystematicHistos(
const std::string& group,
HistoStack* hs1,
HistoStack* hs2, TH2_h*& h2, TH2_h*& h1w){
171 TH2_h h1w_1p(*h1w_1);
173 if (h2_2->GetNbinsY() > h2_1->GetNbinsY()){
174 h2_1p = TH2_h(*h2_2);
175 h1w_1p = TH2_h(*h1w_2);
176 for (Int_t i=0;i<h2_2->GetNbinsX();i++){
177 for (Int_t j=0;j<h2_2->GetNbinsY();j++){
178 h2_1p.SetBinContent(i+1,j+1,h2_1->GetBinContent(i+1,1));
179 h1w_1p.SetBinContent(i+1,j+1,h1w_1->GetBinContent(i+1,1));
186 h2 =
new TH2_h(*h2_2);
187 h2->Divide(&h2_1p, h2_2);
189 h1w =
new TH2_h(*h1w_2);
190 h1w->Divide(&h1w_1p, h1w_2);
195 const TMatrixD& SystematicsTools::GetSystematicCov(
HistoStack* hs,
const std::string& uopt,
const std::string& group){
197 if(errdebug) std::cout<<
"GetSystematicCov \n============================= "<<std::endl;
200 if (uopt.find(
"DUMMY")!=std::string::npos){
210 return GetSystematicCovBase(NULL,hs,uopt,group);
214 const TMatrixD& SystematicsTools::GetRatioSystematicCov(
HistoStack* hs1,
HistoStack* hs2,
const std::string& uopt,
const std::string& group){
216 if(errdebug) std::cout<<
"GetSystematicCov \n============================= "<<std::endl;
223 return GetSystematicCovBase(hs1,hs2,uopt+
" RATIO",group);
227 TH2_h* h1, * h2_1, *h1w_1;
236 TH2_h h1w_1p(*h1w_1);
238 if (h2_2->GetNbinsY() > h2_1->GetNbinsY()){
239 h2_1p = TH2_h(*h2_2);
240 h1w_1p = TH2_h(*h1w_2);
241 for (Int_t i=0;i<h2_2->GetNbinsX();i++){
242 for (Int_t j=0;j<h2_2->GetNbinsY();j++){
243 h2_1p.SetBinContent(i+1,j+1,h2_1->GetBinContent(i+1,1));
244 h1w_1p.SetBinContent(i+1,j+1,h1w_1->GetBinContent(i+1,1));
251 TH2_h h2_ratio(*h2_2);
252 h2_ratio.Divide(&h2_1p, h2_2);
254 TH2_h h1w_ratio(*h1w_2);
255 h1w_ratio.Divide(&h1w_1p, h1w_2);
258 return GetSystematicCovBase(h2_ratio,h1w_ratio,uopt+
" RATIO");
263 const TMatrixD& SystematicsTools::GetSystematicCov(TTree* tree,
const std::string& var,
int nx,
double* xbins,
const std::string& cut,
int NTOYS,
const std::string& uopt){
265 if(errdebug) std::cout<<
"GetSystematicCov \n============================= "<<std::endl;
274 if (CheckSystComputed(tree,NULL,var,nx,xbins,cut,
"",1,NTOYS,uopt)){
279 TH2_h h2(
"h2",
"h2",nx,xbins,NTOYS,0,NTOYS);
280 TH2_h h1w(
"h1w",
"h1w",nx,xbins,NTOYS,0,NTOYS);
283 TH2_h h1(
"h1",
"h1",nx,xbins,NTOYS,0,NTOYS);
286 FillSystematicHistos(tree,var,nx,xbins,cut,NTOYS,uopt,&h2,&h1w);
289 return GetSystematicCovBase(h2,h1w, uopt);
293 const TMatrixD& SystematicsTools::GetSystematicCovBase(TH2_h& h2,TH2_h& h1w,
const std::string& uopt){
302 int nx = h2.GetNbinsX();
303 int NTOYS = h2.GetNbinsY();
306 std::vector< std::vector<double> > na;
307 std::vector< std::vector<double> > wa;
308 std::vector<double> avg;
310 std::vector<double> wpdf;
311 std::vector<double> na_tot;
312 std::vector<double> norm;
319 na_tot.resize(NTOYS);
323 for (
int itoy=0;itoy<NTOYS;itoy++){
329 for (
int i=0;i<nx;i++){
334 for (
int itoy=0;itoy<NTOYS;itoy++){
338 na[i][itoy]=h1w.GetBinContent(i+1,itoy+1);
342 avg[i]+=h2.GetBinContent(i+1,itoy+1)*wpdf[itoy];
344 if (h2.GetBinContent(i+1,itoy+1)>0)
345 wa[i][itoy]=na[i][itoy]/h2.GetBinContent(i+1,itoy+1);
350 if (IsValidWeight(wa[i][itoy]))
351 na_tot[itoy]+=na[i][itoy];
359 if (uopt.find(
"SHAPEONLY")!=std::string::npos){
360 for (
int itoy=0;itoy<NTOYS;itoy++){
362 norm[itoy] = avg_tot/na_tot[itoy];
369 _cov.ResizeTo(nx, nx);
370 for (
int i=0;i<nx;i++){
371 for (
int j=0;j<nx;j++){
373 for (
int itoy=0;itoy<NTOYS;itoy++){
376 if (!IsValidWeight(wa[i][itoy]))
continue;
377 if (!IsValidWeight(wa[j][itoy]))
continue;
378 if (na[i][itoy]< 0 || na[j][itoy]<0)
continue;
379 _cov(i,j) += (norm[itoy]*na[i][itoy]- avg[i])*(norm[itoy]*na[j][itoy]- avg[j])*wpdf[itoy];
386 if (uopt.find(
"RELATIVE")!=std::string::npos){
387 if (avg[i]*avg[j]!=0 && ((avg[i]>1 && avg[j]>1) || uopt.find(
"RATIO")!=std::string::npos)){
388 _cov(i,j) /= (avg[i]*avg[j]);
400 bool SystematicsTools::CheckSystComputed(TTree* tree1, TTree* tree2,
const std::string& var,
int nx,
double* xbins,
const std::string& cut1,
const std::string& cut2,
double norm,
int NTOYS,
const std::string& uopt){
408 if (_syst_computed && _tree1_syst==tree1 && _tree2_syst==tree2 && _var_syst==var && _nbins_syst==nx && _cut_syst1==cut1 && _cut_syst2==cut2 && _norm_syst==norm && _NTOYS_syst==NTOYS && _uopt_syst == uopt){
411 for (
int i=0;i<=nx;i++){
412 if (xbins[i] != _xbins_syst[i]) diff=
true;
429 for (
int i=0;i<=nx;i++){
430 _xbins_syst[i] = xbins[i];
439 bool SystematicsTools::TreeHasVar(TTree* tree,
const std::string& var){
442 if (tree->FindLeaf(var.c_str()))
450 int SystematicsTools::GetVarFromTree(TTree* tree,
const std::string& var){
453 if (!TreeHasVar(tree,var))
return 0;
455 TH1F h0(
"v",
"v",1,0,1);
456 tree->Project(
"v",
"0.5",(
"(1==1)*"+var).c_str(),
"",1);
457 return (
int)(h0.GetBinContent(1));
462 std::string SystematicsTools::GetString(
int code){
465 std::stringstream scode;
472 bool SystematicsTools::IsValidWeight(Double_t weight){
476 if (!TMath::Finite(weight))
return false;
477 if (weight!=weight)
return false;
478 if (weight<0 || weight>10)
return false;
std::vector< std::string > GetSystHistosGroups() const
get the vector of groups of systemtic histos
void AddSystHistos(TH2_h *h1, TH2_h *h2, TH2_h *h1w)
Add histos for updating systematics when using several files.
void GetSystHistos(const std::string &group, TH2_h *&h1, TH2_h *&h2, TH2_h *&h1w)
Get Histos for updating systematics when using several files.