ComPWA
Common Partial-Wave-Analysis Framework
DalitzPlot.cpp
Go to the documentation of this file.
1 // Copyright (c) 2013, 2017 The ComPWA Team.
2 // This file is part of the ComPWA framework, check
3 // https://github.com/ComPWA/ComPWA/license.txt for details.
4 
5 #include <numeric>
6 #include <stdio.h>
7 
8 #include "DalitzPlot.hpp"
9 #include "HistTools.hpp"
10 
11 #include "Core/Event.hpp"
12 #include "Core/Logging.hpp"
13 #include "Core/ProgressBar.hpp"
14 #include "Data/DataSet.hpp"
16 
17 #include "Math/ProbFuncMathCore.h"
18 #include "TCanvas.h"
19 #include "TLegend.h"
20 #include "TStyle.h"
21 
22 namespace ComPWA {
23 namespace Tools {
24 namespace Plotting {
25 
27 
28 void phspContour(unsigned int SysX, unsigned int SysY, unsigned int n,
29  double *CoordX, double *CoordY) {
30 
31  unsigned int num = n;
32  if (num % 2 != 0) {
33  num -= 1;
34  LOG(INFO) << "DalitzKinematics::phspContour() | "
35  "Setting size to a even number. Assure that the size of "
36  "your arrays is "
37  << num * 2 + 1 << "!";
38  }
39  return;
40 }
41 
43  int Bins)
44  : Name(Name), Kinematics(Kinematics), Bins(Bins), GlobalScale(1.0) {
45  Kinematics.createAllSubsystems();
46 
47  gStyle->SetOptStat(10); // entries only
48  gStyle->SetOptTitle(0);
49  gStyle->SetLineWidth(3);
50  gStyle->SetMarkerStyle(20);
51 }
52 
53 void DalitzPlot::fill(const ComPWA::EventCollection &Data, bool Normalize,
54  const std::string &Name, const std::string &Title,
55  Color_t Color) {
56 
57  Data::DataSet DataSet = Kinematics.convert(Data);
58 
59  DalitzHisto Histogram(Kinematics, Name, Title, Bins, Color);
60  Histogram.setStats(0);
61 
62  Histogram.fill(DataSet);
63 
64  if (Normalize)
65  GlobalScale = Histogram.integral();
66 
67  PlotHistograms.push_back(std::move(Histogram));
68 }
69 
71  bool Normalize, const std::string &Name,
72  const std::string &Title, Color_t Color) {
73  Data::DataSet DataSet = Kinematics.convert(Data);
74  DalitzHisto Histogram(Kinematics, Name, Title, Bins, Color);
75  Histogram.setStats(0);
76  auto Intensities = Intensity.evaluate(DataSet.Data);
77  Histogram.fill(DataSet, Intensities);
78 
79  if (Normalize)
80  GlobalScale = Histogram.integral();
81 
82  PlotHistograms.push_back(std::move(Histogram));
83 }
84 
86  for (auto &Plot : PlotHistograms)
87  Plot.scale(GlobalScale / Plot.integral());
88 
89  //=== generate contour
90  double PointsX[4001], PointsY[4001];
91  phspContour(0, 1, 2000, PointsX, PointsY);
92  TGraph ContourM23M13(4001, PointsX, PointsY);
93  ContourM23M13.SetMarkerStyle(1);
94  ContourM23M13.SetLineColor(kRed);
95  ContourM23M13.SetMarkerColor(kRed);
96  ContourM23M13.SetMarkerSize(0.0);
97  ContourM23M13.SetTitle("phspContour");
98  ContourM23M13.SetFillColor(kWhite);
99  phspContour(0, 2, 2000, PointsX, PointsY);
100  TGraph ContourM23M12(4001, PointsX, PointsY);
101  ContourM23M12.SetMarkerStyle(1);
102  ContourM23M12.SetLineColor(kRed);
103  ContourM23M12.SetMarkerColor(kRed);
104  ContourM23M12.SetMarkerSize(0.0);
105  ContourM23M12.SetTitle("phspContour");
106  ContourM23M12.SetFillColor(kWhite);
107  phspContour(2, 1, 2000, PointsX, PointsY);
108  TGraph ContourM12M13(4001, PointsX, PointsY);
109  ContourM12M13.SetMarkerStyle(1);
110  ContourM12M13.SetLineColor(kRed);
111  ContourM12M13.SetMarkerColor(kRed);
112  ContourM12M13.SetMarkerSize(0.0);
113  ContourM12M13.SetTitle("phspContour");
114  ContourM12M13.SetFillColor(kWhite);
115 
116  //----- plotting invariant mass distributions -----
117  TCanvas *Canvas = new TCanvas("invmass", "invmass", 50, 50, 2400, 800);
118  Canvas->Divide(3, 1);
119  Canvas->cd(1);
120  CreateHist("mSq_(1,2)"); // Plotting mKKsq
121  Canvas->cd(2);
122  CreateHist("mSq_(0,2)"); // Plotting mKSK+sq
123  Canvas->cd(3);
124  CreateHist("mSq_(0,1)"); // Plotting mKSK+sq
125 
126  //----- Write to TFile -----
127  TFile *File = new TFile(Name + ".root", "recreate");
128  if (File->IsZombie()) {
129  std::cout << "Error opening output file" << std::endl;
130  exit(-1);
131  }
132  ContourM12M13.Write("m12m13_contour", TObject::kOverwrite, 0);
133  ContourM23M12.Write("m23m12_contour", TObject::kOverwrite, 0);
134  ContourM23M13.Write("m23m13_contour", TObject::kOverwrite, 0);
135  Canvas->Write("invmass", TObject::kOverwrite, 0);
136 
137  // Save data trees and histograms
138  File->mkdir("hist");
139  File->cd("hist");
140  for (auto &Plot : PlotHistograms)
141  Plot.write();
142 
143  // Write some canvas to single files
144  Canvas->Print(Name + "-invmass.pdf");
145 
146  File->Close();
147 }
148 
149 void DalitzPlot::CreateHist(std::string Name) {
150  if (!PlotHistograms.size())
151  return;
152 
153  std::vector<TH1D *> Histograms;
154  std::vector<TString> Options;
155  Histograms.push_back(PlotHistograms.at(0).getHistogram(Name));
156  Options.push_back("E1");
157  for (unsigned int t = 1; t < PlotHistograms.size(); ++t) {
158  Histograms.push_back(PlotHistograms.at(t).getHistogram(Name));
159  Options.push_back("Sames,Hist");
160  }
161 
162  drawPull(Histograms, Options);
163 }
164 
165 //===================== DalitzHisto =====================
167  std::string Title, unsigned int Bins, Color_t Color)
168  : Name(Name), Title(Title), NumBins(Bins), Integral(0.0) {
169 
170  // Initialize TTree
171  Tree = std::unique_ptr<TTree>(new TTree(TString(Name), TString(Title)));
172 
173  // Adding branches to TTree
174  Tree->Branch("sample", &BranchPoint);
175  Tree->Branch("efficiency", &BranchEff, "eff/D");
176  Tree->Branch("weight", &BranchWeight, "weight/D");
177 
178  char label[60];
179 
180  // mass23sq
181  auto sys23(Kinematics.registerSubSystem({1}, {2}, {0}, {}));
182  auto m23sq_limit = Kinematics.getInvariantMassBounds(std::get<0>(sys23));
183  double m23sq_min = m23sq_limit.first;
184  double m23sq_max = m23sq_limit.second;
185  TH1D hist = TH1D(TString(Name + "m23sq"), TString(Title), NumBins, m23sq_min,
186  m23sq_max);
187  double binWidth = (double)(m23sq_min - m23sq_max) / NumBins;
188  sprintf(label, "Entries /%f.3", binWidth);
189  hist.GetYaxis()->SetTitle("# [" + TString(label) + "]");
190  hist.GetXaxis()->SetTitle("m_{23}^{2} [GeV/c^{2}]");
191  hist.Sumw2();
192  Hists1D.insert(std::make_pair(std::get<0>(sys23), hist));
193 
194  // mass13sq
195  auto sys13(Kinematics.registerSubSystem({0}, {2}, {1}, {}));
196  auto m13sq_limit = Kinematics.getInvariantMassBounds(std::get<0>(sys13));
197  double m13sq_min = m13sq_limit.first;
198  double m13sq_max = m13sq_limit.second;
199  hist = TH1D(TString(Name + "m13sq"), TString(Title), NumBins, m13sq_min,
200  m13sq_max);
201  binWidth = (double)(m13sq_min - m13sq_max) / NumBins;
202  sprintf(label, "Entries /%f.3", binWidth);
203  hist.GetYaxis()->SetTitle("# [" + TString(label) + "]");
204  hist.GetXaxis()->SetTitle("m_{13}^{2} [GeV/c^{2}]");
205  hist.Sumw2();
206  Hists1D.insert(std::make_pair(std::get<0>(sys13), hist));
207 
208  // mass12sq
209  auto sys12(Kinematics.registerSubSystem({0}, {1}, {2}, {}));
210  auto m12sq_limit = Kinematics.getInvariantMassBounds(std::get<0>(sys12));
211  double m12sq_min = m12sq_limit.first;
212  double m12sq_max = m12sq_limit.second;
213  hist = TH1D(TString(Name + "m12sq"), TString(Title), NumBins, m12sq_min,
214  m12sq_max);
215  binWidth = (double)(m12sq_min - m12sq_max) / NumBins;
216  sprintf(label, "Entries /%f.3", binWidth);
217  hist.GetYaxis()->SetTitle("# [" + TString(label) + "]");
218  hist.GetXaxis()->SetTitle("m_{12}^{2} [GeV/c^{2}]");
219  hist.Sumw2();
220  Hists1D.insert(std::make_pair(std::get<0>(sys12), hist));
221 
222  TH2D hist2d = TH2D(TString(Name + "_m23sqm13sq"), TString(Title), NumBins,
223  m23sq_min, m23sq_max, NumBins, m13sq_min, m13sq_max);
224  hist2d.GetXaxis()->SetTitle("m_{KK}^{2} [GeV^{2}/c^{4}]");
225  hist2d.GetYaxis()->SetTitle("m_{K_{S}K^{+}}^{2} [GeV^{2}/c^{4}]");
226  Hists2D.insert(std::make_pair(
227  std::make_pair(std::get<0>(sys23), std::get<0>(sys13)), hist2d));
228 
229  hist2d = TH2D(TString(Name + "_m23sqm12sq"), TString(Title), NumBins,
230  m23sq_min, m23sq_max, NumBins, m12sq_min, m12sq_max);
231  hist2d.GetXaxis()->SetTitle("m_{KK}^{2} [GeV^{2}/c^{4}");
232  hist2d.GetYaxis()->SetTitle("m_{K_{S}K^{-}}^{2} [GeV^{2}/c^{4}]");
233  Hists2D.insert(std::make_pair(
234  std::make_pair(std::get<0>(sys23), std::get<0>(sys12)), hist2d));
235 
236  hist2d = TH2D(TString(Name + "_m12sqm13sq"), TString(Title), NumBins,
237  m12sq_min, m12sq_max, NumBins, m13sq_min, m13sq_max);
238  hist2d.GetXaxis()->SetTitle("m_{K_{S}K^{-}}^{2} [GeV^{2}/c^{4}]");
239  hist2d.GetYaxis()->SetTitle("m_{K_{S}K^{+}}^{2} [GeV^{2}/c^{4}]");
240  Hists2D.insert(std::make_pair(
241  std::make_pair(std::get<0>(sys12), std::get<0>(sys13)), hist2d));
242 
243  hist2d = TH2D(TString(Name + "_m23sqCosTheta"), TString(Title), NumBins,
244  m23sq_min, m23sq_max, NumBins, -1, 1);
245  hist2d.GetXaxis()->SetTitle("m_{KK}^{2} [GeV^{2}/c^{4}]");
246  hist2d.GetYaxis()->SetTitle("#cos(#Theta)_{KK}");
247  Hists2D.insert(std::make_pair(
248  std::make_pair(std::get<0>(sys12), std::get<0>(sys12)), hist2d));
249 
250  for (auto &x : Hists2D) {
251  x.second.GetXaxis()->SetNdivisions(508);
252  x.second.GetZaxis()->SetTitle("Entries");
253  }
254 
255  setColor(Color);
256  return;
257 }
258 
259 void DalitzHisto::fill(const Data::DataSet &sample,
260  std::vector<double> Intensities) {
261  if (Intensities.size() == 0) {
262  Intensities = std::vector<double>(sample.Weights.size(), 1.0);
263  }
264  if (!sample.Data.size())
265  throw std::runtime_error("DalitzHist::fill() | Empty data sample.");
266  if (Intensities.size() != sample.Weights.size())
267  throw std::runtime_error("DalitzHist::fill() | Vector of weights and "
268  "sample do not have the same length");
269 
270  double weight =
271  std::accumulate(sample.Weights.begin(), sample.Weights.end(), 0.0);
272 
273  Integral += weight;
274 
275  std::vector<double> weights;
276  for (size_t i = 0; i < Intensities.size(); ++i) {
277  weights.push_back(sample.Weights[i] * Intensities[i]);
278  }
279 
280  for (auto &h1 : Hists1D) {
281  auto const &data = sample.Data.at(h1.first);
282  for (size_t i = 0; i < data.size(); ++i) {
283  h1.second.Fill(data[i], weights[i]);
284  }
285  }
286 
287  for (auto &h2 : Hists2D) {
288  auto const &data1 = sample.Data.at(h2.first.first);
289  auto const &data2 = sample.Data.at(h2.first.second);
290  for (size_t i = 0; i < data1.size(); ++i) {
291  h2.second.Fill(data1[i], data2[i], weights[i]);
292  }
293  }
294 
295  auto const &m23sq = sample.Data.at("mSq_(1,2)");
296  auto const &m13sq = sample.Data.at("mSq_(0,2)");
297  auto const &m12sq = sample.Data.at("mSq_(0,1)");
298  for (size_t i = 0; i < weights.size(); ++i) {
299  BranchPoint = {m23sq[i], m13sq[i], m12sq[i]};
300  BranchWeight = weights[i];
301  BranchEff = 1.0;
302  Tree->Fill();
303  }
304 }
305 
306 void DalitzHisto::setStats(bool b) {
307  for (auto &x : Hists1D) {
308  x.second.SetStats(b);
309  }
310  for (auto &x : Hists2D) {
311  x.second.SetStats(b);
312  }
313 }
314 
315 void DalitzHisto::scale(double w) {
316  for (auto &x : Hists1D) {
317  x.second.Scale(w);
318  }
319  for (auto &x : Hists2D) {
320  x.second.Scale(w);
321  }
322 }
323 
324 void DalitzHisto::setColor(Color_t color) {
325  for (auto &x : Hists1D) {
326  x.second.SetLineColor(color);
327  x.second.SetMarkerColor(color);
328  }
329 }
330 
331 TH1D *DalitzHisto::getHistogram(std::string Name) { return &Hists1D.at(Name); }
332 
333 TH2D *DalitzHisto::getHistogram2D(std::pair<std::string, std::string> Names) {
334  return &Hists2D.at(Names);
335 }
336 
338  Tree->Write(TString(Name) + "Tree");
339  gDirectory->mkdir(TString(Name) + "_hist");
340  gDirectory->cd(TString(Name) + "_hist");
341  for (auto const &x : Hists1D) {
342  x.second.Write();
343  }
344  for (auto const &x : Hists2D) {
345  x.second.Write();
346  }
347  gDirectory->cd("../");
348 }
349 
350 } // namespace Plotting
351 } // namespace Tools
352 } // namespace ComPWA
void fill(const ComPWA::EventCollection &Data, bool Normalize=false, const std::string &Name="", const std::string &Title="", Color_t Color=kBlack)
Definition: DalitzPlot.cpp:53
virtual ComPWA::Data::DataSet convert(const EventCollection &Events) const =0
void setStats(bool b)
Switch on/off stats.
Definition: DalitzPlot.cpp:306
std::vector< double > BranchPoint
Definition: DalitzPlot.hpp:82
ComPWA::DataMap Data
Definition: DataSet.hpp:18
cmplx FADDEEVA() w(cmplx z, double relerr)
Definition: Faddeeva.cc:668
std::vector< double > Weights
Definition: DataSet.hpp:19
std::map< std::pair< std::string, std::string >, TH2D > Hists2D
Definition: DalitzPlot.hpp:75
const std::pair< double, double > & getInvariantMassBounds(const std::string &InvariantMassName) const
Get phase space bounds for the registered invariant mass with name InvariantMassName.
Collection of useful routines to plot histograms, e.g.
Implementation of the ComPWA::Kinematics interface for amplitude models using the helicity formalism...
void fill(const ComPWA::Data::DataSet &DataSet, std::vector< double > Intensities={})
Definition: DalitzPlot.cpp:259
virtual OutputType evaluate(const InputTypes &... args) noexcept=0
std::tuple< std::string, std::string, std::string > registerSubSystem(const SubSystem &NewSys)
Add NewSys to list of SubSystems and return a tuple of names, that id the registered kinematic variab...
TPad * drawPull(std::vector< TH1D *> Histogram, std::vector< TString > DrawOptions, double Min=0, double Max=0)
Definition: HistTools.hpp:150
TH2D * getHistogram2D(std::pair< std::string, std::string > Names)
Get 2D histogram.
Definition: DalitzPlot.cpp:333
void CreateHist(std::string Name)
Definition: DalitzPlot.cpp:149
void setColor(Color_t Color)
set line color
Definition: DalitzPlot.cpp:324
DalitzHisto(const DalitzHisto &that)=delete
Disable copy constructor since TTree is not copyable.
TH1D * getHistogram(std::string Name)
Get 1D histogram.
Definition: DalitzPlot.cpp:331
void phspContour(unsigned int SysX, unsigned int SysY, unsigned int n, double *CoordX, double *CoordY)
Definition: DalitzPlot.cpp:28
Simple class to create and fill Dalitz plots.
Definition: DalitzPlot.hpp:42
std::vector< DalitzHisto > PlotHistograms
Definition: DalitzPlot.hpp:112
DalitzPlot(ComPWA::Physics::HelicityFormalism::HelicityKinematics &Kinematics, const std::string &Name, int bins=100)
Definition: DalitzPlot.cpp:42
The Kinematics interface defines the conversion of Events to a DataSet.
Definition: Kinematics.hpp:19
void scale(double w)
Scale all distributions.
Definition: DalitzPlot.cpp:315
double integral()
GetIntegral.
Definition: DalitzPlot.hpp:71
std::map< std::string, TH1D > Hists1D
Definition: DalitzPlot.hpp:74
Interface template for a general Function of the form OutputType Function(InputTypes) The concept clo...
Definition: Function.hpp:24
std::unique_ptr< TTree > Tree
Definition: DalitzPlot.hpp:79