laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauCalcChiSq.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2008 University of Warwick
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17 
18 /*
19 Laura++ package authors:
20 John Back
21 Paul Harrison
22 Thomas Latham
23 */
24 
25 // Code to produce an adaptive binning scheme and calculate the 2D chi-square between
26 // two datasets (e.g. low-stat data and high-stat toyMC).
27 // To run the code, do "./CalcChiSq chiSqInput.txt", where chiSqInput.txt is
28 // an input control file, and contains the following lines:
29 // Low_stat_file_name Low_stat_histo_name
30 // High_stat_file_name High_stat_histo_name
31 // Min_bin_content N_free_params Low/high stat_histo_ratio
32 
33 // Note that the low and high stat histograms must have the same bin axes
34 // ranges and number of bins.
35 
36 // It works by using the low stat (first) histogram to find a binning scheme such
37 // that the total number of entries in each bin is >= Min_bin_content. The number
38 // of entries in the histogram is divided by the desired minimum bin content to
39 // give a target number of bins. The largest number of bins that can be expressed
40 // as a product of powers of four, nine, 25, 49 and 121 that does not exceed the
41 // target value is chosen. The histogram is the recursively subdivided in 2x2, 3x3,
42 // 5x5, 7x7 or 11x11 bins. For each stage of the subdivision, each bin is first
43 // divided into equally populated bins in x then each of these is further divded
44 // into equally popiulated bins in y.
45 
46 // The (Pearson) chi-squared is then the sum of the chi-squared contributions
47 // of all bins:
48 // (low_stat_number - high_stat_number)^2/(high_stat_number)
49 // The nDof = number of bins - number of free params - 1
50 
51 #include "LauCalcChiSq.hh"
52 
53 #include "TAxis.h"
54 #include "TFile.h"
55 #include "TMath.h"
56 #include "TSystem.h"
57 #include "TTree.h"
58 
59 #include "TCanvas.h"
60 #include "TColor.h"
61 #include "TStyle.h"
62 
63 #include <iostream>
64 #include <fstream>
65 #include <cstdlib>
66 #include <cmath>
67 
69 
70 
71 LauCalcChiSq::LauCalcChiSq(const TString& inputFileName) :
72  inputFileName_(inputFileName),
73  fileName1_(""),
74  fileName2_(""),
75  treeName1_(""),
76  treeName2_(""),
77  xName1_(""),
78  xName2_(""),
79  yName1_(""),
80  yName2_(""),
81  minContent_(10.0),
82  histo1_(0),
83  histo2_(0),
84  chiSqHisto_(0),
85  chiSqSignedHisto_(0),
86  xMin_(0.0),
87  xMax_(0.0),
88  yMin_(0.0),
89  yMax_(0.0),
90  nParams_(0),
91  scaleFactor_(1.0),
92  verbose_(kFALSE)
93 {
94 }
95 
97 {
98 }
99 
101 {
102  std::cout<<"Running chi-squared algorithm"<<std::endl;
103  this->initialiseHistos();
104 
105  std::cout<<"Calculating chi-squared"<<std::endl;
106  this->calculateChiSq();
107 
108  //make plots
109  this->makePlots();
110 
111  // Output the various histograms
112  std::cout<<"Writing out histogram output"<<std::endl;
113 
114  TFile* outFile = new TFile("checkHistos.root", "recreate");
115 
116  histo1_->SetDirectory(outFile);
117  histo2_->SetDirectory(outFile);
118  pullHisto_->SetDirectory(outFile);
119  chiSqHisto_->SetDirectory(outFile);
120  chiSqSignedHisto_->SetDirectory(outFile);
121 
122  outFile->Write();
123  outFile->Close();
124 
125  std::cout<<"Done"<<std::endl;
126 }
127 
129 {
130  Float_t toyVal(0.), dataVal(0.);
131  Int_t minContent(0), ndof(0);
132  Float_t diff(0.), chiSq(0.), totalChiSq(0.);
133 
134  minContent = histo1_->GetBinContent(1);
135 
136  for(Int_t i=1; i<=histo1_->GetNumberOfBins(); ++i) {
137  //keep track of actual minimum
138  if(histo1_->GetBinContent(i)<minContent) {
139  minContent=histo1_->GetBinContent(i);
140  }
141 
142  // Calculate Pearson chi-square for this bin, using the
143  // second histogram for the expected distribution
144  chiSq = 0.;
145  toyVal = histo2_->GetBinContent(i);
146  dataVal = histo1_->GetBinContent(i);
147  diff = dataVal-toyVal;
148  if(toyVal>0) chiSq = (diff*diff)/toyVal;
149  totalChiSq += chiSq;
150 
151  chiSqHisto_->SetBinContent(i, chiSq);
152 
153  if(diff>0) {
154  chiSqSignedHisto_->SetBinContent(i, chiSq);
155  pullHisto_->SetBinContent(i, sqrt(chiSq));
156  } else {
157  chiSqSignedHisto_->SetBinContent(i, -chiSq);
158  pullHisto_->SetBinContent(i, -sqrt(chiSq));
159  }
160  }
161 
162  ndof = histo1_->GetNumberOfBins()-nParams_-1;
163 
164  std::cout<<"Total ChiSq/nDof = "<<totalChiSq<<"/"<<ndof<<" = "<<totalChiSq/ndof<<std::endl;
165  std::cout << "Actual minimum entries per bin: " << minContent << std::endl;
166 }
167 
169 {
170  gStyle->SetPalette(1,0);
171  const Int_t NRGBs = 5;
172  const Int_t NCont = 255;
173  Double_t stops[NRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00};
174  Double_t red[NRGBs] = { 0.00, 0.00, 0.87, 1.00, 0.51};
175  Double_t green[NRGBs] = { 0.00, 0.81, 1.00, 0.20, 0.00};
176  Double_t blue[NRGBs] = { 0.51, 1.00, 0.12, 0.00, 0.00};
177  TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont);
178  gStyle->SetNumberContours(NCont);
179  gStyle->SetOptStat(0000);
180 
181  TCanvas can;
182 
183  can.SetTopMargin(0.05);
184  can.SetRightMargin(0.17);
185  can.SetBottomMargin(0.16);
186  can.SetLeftMargin(0.14);
187 
188  histo1_->SetLabelFont(62,"x");
189  histo1_->SetLabelFont(62,"y");
190  histo1_->SetTitleFont(62,"x");
191  histo1_->SetTitleFont(62,"y");
192  histo1_->SetTitleSize(0.06,"x");
193  histo1_->SetTitleSize(0.06,"y");
194  histo1_->SetLabelSize(0.05,"x");
195  histo1_->SetLabelSize(0.05,"y");
196  histo1_->SetXTitle(xName1_);
197  histo1_->SetYTitle(yName1_);
198  histo1_->Draw("colz");
199  can.SaveAs("data.pdf");
200 
201  histo2_->SetLabelFont(62,"x");
202  histo2_->SetLabelFont(62,"y");
203  histo2_->SetTitleFont(62,"x");
204  histo2_->SetTitleFont(62,"y");
205  histo2_->SetTitleSize(0.06,"x");
206  histo2_->SetTitleSize(0.06,"y");
207  histo2_->SetLabelSize(0.05,"x");
208  histo2_->SetLabelSize(0.05,"y");
209  histo2_->SetXTitle(xName1_);
210  histo2_->SetYTitle(yName1_);
211  histo2_->Draw("colz");
212  can.SaveAs("toy.pdf");
213 
214  if(-1.*pullHisto_->GetMinimum() > pullHisto_->GetMaximum()) pullHisto_->SetMaximum(-1.*pullHisto_->GetMinimum());
215  else pullHisto_->SetMinimum(-1.*pullHisto_->GetMaximum());
216 
217  pullHisto_->SetLabelFont(62,"x");
218  pullHisto_->SetLabelFont(62,"y");
219  pullHisto_->SetTitleFont(62,"x");
220  pullHisto_->SetTitleFont(62,"y");
221  pullHisto_->SetTitleSize(0.06,"x");
222  pullHisto_->SetTitleSize(0.06,"y");
223  pullHisto_->SetLabelSize(0.05,"x");
224  pullHisto_->SetLabelSize(0.05,"y");
225  pullHisto_->SetXTitle(xName1_);
226  pullHisto_->SetYTitle(yName1_);
227  pullHisto_->Draw("colz");
228  can.SaveAs("pull.pdf");
229 
230  chiSqHisto_->SetLabelFont(62,"x");
231  chiSqHisto_->SetLabelFont(62,"y");
232  chiSqHisto_->SetTitleFont(62,"x");
233  chiSqHisto_->SetTitleFont(62,"y");
234  chiSqHisto_->SetTitleSize(0.06,"x");
235  chiSqHisto_->SetTitleSize(0.06,"y");
236  chiSqHisto_->SetLabelSize(0.05,"x");
237  chiSqHisto_->SetLabelSize(0.05,"y");
238  chiSqHisto_->SetXTitle(xName1_);
239  chiSqHisto_->SetYTitle(yName1_);
240  chiSqHisto_->Draw("colz");
241  can.SaveAs("chiSq.pdf");
242 
243  chiSqSignedHisto_->SetLabelFont(62,"x");
244  chiSqSignedHisto_->SetLabelFont(62,"y");
245  chiSqSignedHisto_->SetTitleFont(62,"x");
246  chiSqSignedHisto_->SetTitleFont(62,"y");
247  chiSqSignedHisto_->SetTitleSize(0.06,"x");
248  chiSqSignedHisto_->SetTitleSize(0.06,"y");
249  chiSqSignedHisto_->SetLabelSize(0.05,"x");
250  chiSqSignedHisto_->SetLabelSize(0.05,"y");
251  chiSqSignedHisto_->SetXTitle(xName1_);
252  chiSqSignedHisto_->SetYTitle(yName1_);
253  chiSqSignedHisto_->Draw("colz");
254  can.SaveAs("chiSqSigned.pdf");
255 
256 }
257 
259 {
260 
261  // Open the input control file:
262  // Low_stat_file_name Low_stat_tree_name Low_stat_x_axis_name Low_stat_y_axis_name
263  // High_stat_file_name High_stat_tree_name High_stat_x_axis_name High_stat_y_axis_name
264  // Min_bin_content N_free_params Low/high_stat_histo_ratio xMin xMax yMin yMax
265  std::ifstream getData(inputFileName_.Data());
266 
267  // get the info on the low stat histo
268  getData >> fileName1_ >> treeName1_ >> xName1_ >> yName1_;
269  if (!getData.good()) {
270  std::cerr<<"Error. Could not read first line of the input file "<<inputFileName_<<std::endl;
271  gSystem->Exit(EXIT_FAILURE);
272  }
273 
274  // open the file that contains the low stat histogram
275  TFile * file1 = TFile::Open(fileName1_.Data(), "read");
276 
277  if (file1 == 0) {gSystem->Exit(EXIT_FAILURE);}
278 
279  // retrieve the low stat histogram
280  TTree* tree1 = dynamic_cast<TTree*>(file1->Get(treeName1_.Data()));
281 
282  if (tree1 == 0) {
283  std::cerr<<"Error. Could not find the tree "<<treeName1_
284  <<" in the file "<<fileName1_<<std::endl;
285  gSystem->Exit(EXIT_FAILURE);
286  }
287 
288  // get the info on the high stat histogram
289  getData >> fileName2_ >> treeName2_ >> xName2_ >> yName2_;
290  if (!getData.good()) {
291  std::cerr<<"Error. Could not read the second line of the input file "<<inputFileName_<<std::endl;
292  gSystem->Exit(EXIT_FAILURE);
293  }
294 
295  // if both histograms are in the same file then just retrieve the
296  // high stat histogram from the file we already have open
297  TFile * file2(0);
298  TTree* tree2(0);
299  if ( fileName2_ == fileName1_ ) {
300  tree2 = dynamic_cast<TTree*>(file1->Get(treeName2_.Data()));
301  }
302  // otherwise open the other file and retrieve the high stat histogram from there
303  else {
304  file2 = TFile::Open(fileName2_.Data(), "read");
305 
306  if (file2 == 0) {gSystem->Exit(EXIT_FAILURE);}
307 
308  tree2 = dynamic_cast<TTree*>(file2->Get(treeName2_.Data()));
309  }
310 
311  if (tree2 == 0) {
312  std::cerr<<"Error. Could not find the tree "<<treeName2_
313  <<" in the file "<<fileName2_<<std::endl;
314  gSystem->Exit(EXIT_FAILURE);
315  }
316 
317  // get the info on the minimum content, number of parameters and scalefactor
318  Int_t nParameters(0);
319  Float_t minContent(0.0), scaleFactor(1.0), xMin(0.0), xMax(1.0), yMin(0.0), yMax(1.0);
320  getData >> minContent >> nParameters >> scaleFactor >> xMin >> xMax >> yMin >> yMax;
321  if (getData.good()) {
322  minContent_ = minContent;
323  nParams_ = nParameters;
324  scaleFactor_ = scaleFactor;
325  xMin_ = xMin;
326  xMax_ = xMax;
327  yMin_ = yMin;
328  yMax_ = yMax;
329  }
330 
331  // close the text file
332  getData.close();
333 
334  std::cout<<"Using the files and trees: "<<fileName1_<<"; "<<treeName1_
335  <<" and "<<fileName2_<<"; "<<treeName2_<<std::endl;
336  std::cout<<"Relative scaling factor histo1/histo2 set to "<<scaleFactor_<<std::endl;
337  std::cout<<"Minimum bin content is "<<minContent_<<std::endl;
338  std::cout<<"Number of free parameters is "<<nParams_<<std::endl;
339 
340  Double_t x;
341  Double_t y;
342 
343  tree1->SetBranchAddress(xName1_.Data(),&x);
344  tree1->SetBranchAddress(yName1_.Data(),&y);
345 
346  Int_t nEntries = tree1->GetEntries();
347 
348  Double_t* xs = new Double_t[nEntries];
349  Double_t* ys = new Double_t[nEntries];
350 
351  for ( Int_t i=0; i < nEntries; ++i ) {
352  tree1->GetEntry( i );
353  xs[i] = x;
354  ys[i] = y;
355  }
356 
357  theHisto_ = new TH2Poly("theHisto_", "", xMin_, xMax_, yMin_, yMax_);
358 
359  //select the number of divisions to get us closest to minContent entries per bin
360  std::vector<Int_t> divisions;
361  this->pickBinning(xs,ys,nEntries,divisions);
362 
363  //perform the adaptive bining based on histo1_
364  this->getHisto(xMin_, xMax_, yMin_, yMax_, xs, ys, nEntries, divisions);
365 
366  histo1_ = dynamic_cast<TH2Poly*>(theHisto_->Clone("histo1_"));
367  histo2_ = dynamic_cast<TH2Poly*>(theHisto_->Clone("histo2_"));
368  pullHisto_ = dynamic_cast<TH2Poly*>(theHisto_->Clone("pullHisto_"));
369  chiSqHisto_ = dynamic_cast<TH2Poly*>(theHisto_->Clone("chiSqHisto_"));
370  chiSqSignedHisto_ = dynamic_cast<TH2Poly*>(theHisto_->Clone("chiSqSignedHisto_"));
371  delete[] xs;
372  delete[] ys;
373 
374  //fill the two histograms from the trees
375  TString drawString1, drawString2, weightString2;
376  drawString1 += yName1_;
377  drawString1 += ":";
378  drawString1 += xName1_;
379  drawString1 += ">>histo1_";
380  drawString2 += yName2_;
381  drawString2 += ":";
382  drawString2 += xName2_;
383  drawString2 += ">>histo2_";
384  weightString2 += scaleFactor_;
385 
386  tree1->Draw(drawString1);
387  tree2->Draw(drawString2,weightString2);
388 
389  histo1_->SetDirectory(0);
390  histo2_->SetDirectory(0);
391  pullHisto_->SetDirectory(0);
392  chiSqHisto_->SetDirectory(0);
393  chiSqSignedHisto_->SetDirectory(0);
394 
395  // close the file(s) containing the trees
396  if (file1 != 0) {file1->Close();}
397  delete file1;
398  if (file2 != 0) {file2->Close();}
399  delete file2;
400 }
401 
402 void LauCalcChiSq::pickBinning(const Double_t* xs, const Double_t* ys, const Int_t nEntries, std::vector<Int_t>& divisions)
403 {
404  //first check how many events we have within the histogram limits
405  Int_t nIn(0);
406  for(Int_t i=0; i<nEntries; ++i) {
407  if(xs[i]<xMax_ && xs[i] >= xMin_ && ys[i]<yMax_ && ys[i] >= yMin_) {
408  ++nIn;
409  }
410  }
411 
412  //aim to have exactly minContent events in each bin
413  Int_t nBinsTarget = nIn / minContent_;
414 
415  std::cout << "Target is " << minContent_ << " entries per bin" << std::endl;
416  std::cout << "Aiming to divide " << nIn << " entries between " << nBinsTarget << " bins" << std::endl;
417 
418  //we will iteratively sub-divide histogram bins into either 4, 9, 25, 49 or 121
419  //here we figure out how many 4s, 9s, 25s, 49s and 121s to use to best match our target without exceeding it
420  Int_t nDivisions(0), nNines(0), nTwentyFives(0), nFortyNines(0), nEleventyElevens(0), nBins(1);
421  Int_t nDivisionsBest(0), nNinesBest(0), nTwentyFivesBest(0), nFortyNinesBest(0), nEleventyElevensBest(0), nBinsBest(1);
422 
423  do {
424  ++nDivisions;
425  for(nNines=0; nNines<=nDivisions; ++nNines) {
426  for(nTwentyFives=0; nTwentyFives<=nDivisions-nNines; ++nTwentyFives) {
427  for(nFortyNines=0; nFortyNines<=nDivisions-nNines-nTwentyFives; ++nFortyNines) {
428  for(nEleventyElevens=0; nEleventyElevens<=nDivisions-nNines-nTwentyFives-nFortyNines; ++nEleventyElevens) {
429  nBins = TMath::Power(4,nDivisions-nNines-nTwentyFives-nFortyNines-nEleventyElevens)
430  *TMath::Power(9,nNines)*TMath::Power(25,nTwentyFives)
431  *TMath::Power(49,nFortyNines)*TMath::Power(121,nEleventyElevens);
432  if(nBins < nBinsTarget && nBins > nBinsBest) {
433  //keep track of the best number of bins so far
434  nBinsBest = nBins;
435  nDivisionsBest = nDivisions;
436  nNinesBest = nNines;
437  nTwentyFivesBest = nTwentyFives;
438  nFortyNinesBest = nFortyNines;
439  nEleventyElevensBest = nEleventyElevens;
440  }
441  }
442  }
443  }
444  }
445  } while(TMath::Power(4,nDivisions+1) < nBinsTarget);//if 4^n > target then we've gone far enough
446 
447  std::cout << "Using " << nBinsBest << " bins" << std::endl;
448 
449  //fill the vector with the divisions that we want to make
450  for(Int_t i=0; i<nEleventyElevensBest; ++i) {
451  divisions.push_back(11);
452  }
453  for(Int_t i=0; i<nFortyNinesBest; ++i) {
454  divisions.push_back(7);
455  }
456  for(Int_t i=0; i<nTwentyFivesBest; ++i) {
457  divisions.push_back(5);
458  }
459  for(Int_t i=0; i<nNinesBest; ++i) {
460  divisions.push_back(3);
461  }
462  for(Int_t i=0; i<nDivisionsBest-nNinesBest-nTwentyFivesBest-nFortyNinesBest-nEleventyElevensBest; ++i) {
463  divisions.push_back(2);
464  }
465 }
466 
467 void LauCalcChiSq::getHisto(const Double_t xMin, const Double_t xMax, const Double_t yMin, const Double_t yMax, const Double_t* xs, const Double_t* ys, const Int_t nEntries, const std::vector<Int_t>& divisions, const UInt_t iter)
468 {
469 
470  //If it's the last iteration create the bin and return
471  if(iter == divisions.size()) {
472  Double_t * x_new = new Double_t[5];
473  Double_t * y_new = new Double_t[5];
474  x_new[0] = xMin; x_new[1] = xMin; x_new[2] = xMax; x_new[3] = xMax; x_new[4] = xMin;
475  y_new[0] = yMin; y_new[1] = yMax; y_new[2] = yMax; y_new[3] = yMin; y_new[4] = yMin;
476  theHisto_->AddBin(5, x_new, y_new);
477  if(verbose_) std::cout << "Adding bin from (" << xMin << "," << yMin << ") to (" << xMax << "," << yMax << ")" << std::endl;
478  return;
479  }
480 
481  //If not the last iteration then divide the bin
482  Int_t n_divx=divisions[iter];
483  Int_t n_divy=divisions[iter];
484 
485  if(verbose_) std::cout << "Dividing bin from (" << xMin << "," << yMin << ") to (" << xMax << "," << yMax << ") into " << n_divx << " by " << n_divy << " subbins" << std::endl;
486 
487  Double_t *xIn = new Double_t[nEntries];
488  Double_t *yIn = new Double_t[nEntries];
489  Int_t *xIndex = new Int_t [nEntries+2];
490  Int_t *yIndex = new Int_t [nEntries+2];
491 
492  Int_t xCountIn = 0;
493  for(Int_t i = 0; i<nEntries; ++i) {
494  if ((xs[i]<xMin)||(xs[i]>xMax)||(ys[i]<yMin)||(ys[i]>yMax)) continue;
495  xIn[xCountIn] = xs[i];
496  ++xCountIn;
497  }
498 
499  //find the delimitting x and y values for the sub bins
500  Double_t xLimits[n_divx + 1];
501  Double_t yLimits[n_divx][n_divy + 1];
502 
503  //first sort entries in x and divide bin into equally populated bins in x
504  TMath::Sort(xCountIn, xIn, xIndex, false);
505 
506  xLimits[0] = xMin;
507  xLimits[n_divx] = xMax;
508  for (Int_t nDivx = 0; nDivx < n_divx; ++nDivx){
509  if (nDivx < (n_divx-1)){
510  xLimits[nDivx+1] = xIn[xIndex[xCountIn*(nDivx+1)/n_divx]];
511  }
512 
513  //for each bin in x divide into equally populated bins in y
514  yLimits[nDivx][0] = yMin;
515  yLimits[nDivx][n_divy] = yMax;
516  Int_t yCountIn = 0;
517 
518  for(Int_t i = 0; i<nEntries; ++i) {
519  if ((xs[i]<xMin)||(xs[i]>xMax)||(ys[i]<yMin)||(ys[i]>yMax)) continue;
520  if ((xs[i]<xLimits[nDivx])||(xs[i]>=xLimits[nDivx+1])||(ys[i]<yMin)||(ys[i]>yMax)) continue;
521  yIn[yCountIn] = ys[i];
522  ++yCountIn;
523  }
524 
525  TMath::Sort(yCountIn, yIn, yIndex, false);
526 
527  for (Int_t nDivy = 1; nDivy < n_divy; ++nDivy){
528  yLimits[nDivx][nDivy] = yIn[yIndex[yCountIn*nDivy/n_divy]];
529  }
530  }
531 
532  delete[] xIn;
533  delete[] yIn;
534  delete[] xIndex;
535  delete[] yIndex;
536 
537  //call for each sub bin
538  for (Int_t nDivx = 0; nDivx < n_divx; ++nDivx){
539  for (Int_t nDivy = 0; nDivy < n_divy; ++nDivy){
540  this->getHisto(xLimits[nDivx], xLimits[nDivx + 1], yLimits[nDivx][nDivy], yLimits[nDivx][nDivy + 1], xs, ys, nEntries, divisions,iter+1);
541  }
542  }
543 }
544 
TH2Poly * chiSqSignedHisto_
Histogram (constructed from template) filled with signed chisq of tree1 vs tree2. ...
TString treeName2_
Name of the high stats data tree.
TString xName1_
Name of the x-coordinate branch in tree 1.
File containing declaration of LauCalcChiSq class.
Bool_t verbose_
Verbose flag.
ClassImp(LauAbsCoeffSet)
Int_t nParams_
Number of free parameters in fit (used for calculating the ndof)
void getHisto(const Double_t xMin, const Double_t xMax, const Double_t yMin, const Double_t yMax, const Double_t *xs, const Double_t *ys, const Int_t nEntries, const std::vector< Int_t > &divisions, const UInt_t iter=0)
Create the template histogram based on the binning scheme.
void calculateChiSq()
Calculate the chisq from the data histograms.
Float_t yMax_
Maximum y coordinate of histograms.
Float_t xMax_
Maximum x coordinate of histograms.
TString yName1_
Name of the y-coordinate branch in tree 1.
TString fileName2_
Name of the high stats data file.
TH2Poly * histo1_
Histogram (constructed from template) filled from tree 1.
TString fileName1_
Name of the low stats data file.
TH2Poly * pullHisto_
Histogram (constructed from template) filled with pulls of tree1 vs tree2.
void run()
Run the calculations.
Float_t yMin_
Minimum y coordinate of histograms.
Float_t xMin_
Minimum x coordinate of histograms.
TString xName2_
Name of the x-coordinate branch in tree 2.
TString inputFileName_
Name of the config file.
TH2Poly * theHisto_
Template histogram constructed from the binning scheme.
void pickBinning(const Double_t *xs, const Double_t *ys, const Int_t nEntries, std::vector< Int_t > &divisions)
Choose the binning scheme.
void initialiseHistos()
Read the config file, read the data and create histograms.
Utility class to allow the calculation of the chisq of the fit to the Dalitz plot.
Definition: LauCalcChiSq.hh:50
TH2Poly * histo2_
Histogram (constructed from template) filled from tree 2.
TString treeName1_
Name of the low stats data tree.
Float_t scaleFactor_
Scalefactor between low and high stats data samples.
TH2Poly * chiSqHisto_
Histogram (constructed from template) filled with chisq of tree1 vs tree2.
virtual ~LauCalcChiSq()
Destructor.
Definition: LauCalcChiSq.cc:96
TString yName2_
Name of the y-coordinate branch in tree 2.
Float_t minContent_
The minimum bin content.
void makePlots()
Create plots.