ROOTPWA
plotWeightedEvts_Kpipi.C
Go to the documentation of this file.
1 /*
2  * IMPORTANT:
3  *
4  * The naming scheme of histogram files is critical in this program.
5  * More complex diagrams, that are automatically generated, rely on the specific scheme defined below.
6  * The program requests names for the Monte Carlo histograms to contain "MC_"
7  * or end with "MC". (the reason for _ is that the string doesnt no accidentally contain another "MC")
8  * The Data histograms must have the same filename as the corresponding MC histogram but "Data" replaced for "MC".
9  *
10  * Also for each massbin create a directory and create the same filenames for each variable
11  */
12 
13 #include "TTree.h"
14 #include "TFile.h"
15 #include "TList.h"
16 #include "TLatex.h"
17 
18 #include "TLorentzVector.h"
19 #include "TVector3.h"
20 #include "TLorentzRotation.h"
21 #include "TH1D.h"
22 #include "TH2D.h"
23 #include "TClonesArray.h"
24 #include "TROOT.h"
25 #include "TMath.h"
26 #include "TPad.h"
27 #include "TCanvas.h"
28 #include "TString.h"
29 #include <iostream>
30 #include <vector>
31 #include "NParticleEvent.h"
32 #include "TPRegexp.h"
33 
34 using namespace std;
35 
36 TString massbin;
37 TString mass;
38 
39 int nbninsm = 150;
40 int nbinsang = 80;
41 
42 
43 
44 struct GJHistBunch {
45  // base histograms
46  std::vector<TH1D*> isobar_mass;
47  std::vector<TH1D*> costheta_GJF;
48  std::vector<TH1D*> phi_GJF;
49  TH1D* costheta_GJF_MC_raw;
50  std::vector<TH2D*> costheta_GJF_tprime;
51 
52  // difference histograms
53  TH1D* isobar_mass_diff;
54  TH1D* costheta_GJF_diff;
55  TH1D* phi_GJF_diff;
56  TH2D* costheta_GJF_tprime_diff;
57 };
58 
59 struct HelicityHistBunch {
60  // base histograms
61  std::vector<TH1D*> costheta_HF;
62  std::vector<TH1D*> phi_HF;
63 
64  // difference histograms
65  TH1D* costheta_HF_diff;
66  TH1D* phi_HF_diff;
67 };
68 
69 struct HelicityAngles {
70  double cosTheta;
71  double phi;
72 };
73 
74 int getTotalCharge(std::pair<int, int> p) {
75  return p.first + p.second;
76 }
77 
78 TString stripUnits(TString s) {
79  //std::cout<<"stripunits-in: "<<s<<std::endl;
80  TPRegexp re("^(.*)\\s*(\\[.*])\\s*$");
81  re.Substitute(s,"$1");
82  //std::cout<<"stripunits-out: "<<s<<std::endl;
83  return s;
84 }
85 
86 TString getUnits(TString s) {
87  //std::cout << "getunits-in: " << s << std::endl;
88  TPRegexp re("^.*(\\[.*])\\s*$");
89  if(re.MatchB(s) > 0)
90  re.Substitute(s,"$1");
91  else
92  s = "";
93  //std::cout << "getunits-out: " << s << std::endl;
94  return s;
95 }
96 
97 GJHistBunch GJHistBunchFactory(TString name_prefix) {
98  GJHistBunch temp;
99  TH1D* hMIsobarMC = new TH1D("hMIsobarMC_" + name_prefix, name_prefix + " Isobar Mass (MC)", nbninsm, 0.0, 3.0);
100  hMIsobarMC->SetXTitle("isobar mass [GeV]");
101  hMIsobarMC->SetYTitle("# of events");
102  temp.isobar_mass.push_back(hMIsobarMC);
103  TH1D* hMIsobarData = new TH1D("hMIsobarData_" + name_prefix, name_prefix + " Isobar Mass (DATA)", nbninsm,
104  0.0, 3.0);
105  hMIsobarData->SetXTitle("isobar mass [GeV]");
106  hMIsobarData->SetYTitle("# of events");
107  temp.isobar_mass.push_back(hMIsobarData);
108  temp.isobar_mass[0]->Sumw2();
109 
110  TH1D* hGJMC = new TH1D("hGJMC_" + name_prefix, name_prefix + " Isobar Cos Gottfried-Jackson Theta (MC)", nbinsang, -1, 1);
111  hGJMC->SetXTitle("isobar cos(#theta_{GJ})");
112  hGJMC->SetYTitle("# of events");
113  temp.costheta_GJF.push_back(hGJMC);
114  TH1D* hGJData = new TH1D("hGJData_" + name_prefix, name_prefix + " Isobar Cos Gottfried-Jackson Theta (DATA)", nbinsang, -1,
115  1);
116  hGJData->SetXTitle("isobar cos(#theta_{GJ})");
117  hGJData->SetYTitle("# of events");
118  temp.costheta_GJF.push_back(hGJData);
119  temp.costheta_GJF[0]->Sumw2();
120 
121  temp.costheta_GJF_MC_raw = new TH1D("hGJMC_raw" + name_prefix,
122  "Cos Gottfried-Jackson Theta (unweighted MC)", nbinsang, -1, 1);
123  temp.costheta_GJF_MC_raw->SetXTitle("isobar cos(#theta_{GJ})");
124  temp.costheta_GJF_MC_raw->SetYTitle("# of events");
125 
126  TH2D* hGJtMC = new TH2D("hGJtMC_" + name_prefix, name_prefix + " Isobar Cos GJ Theta vs t' (MC)", nbinsang, -1, 1, 20, 0,
127  0.01);
128  hGJtMC->SetXTitle("isobar cos(#theta_{GJ})");
129  hGJtMC->SetYTitle("t' [GeV]");
130  temp.costheta_GJF_tprime.push_back(hGJtMC);
131  TH2D* hGJtData = new TH2D("hGJtData_" + name_prefix, name_prefix + " Isobar Cos GJ Theta vs t' (DATA)", nbinsang, -1, 1, 20,
132  0, 0.01);
133  hGJData->SetXTitle("isobar cos(#theta_{GJ})");
134  hGJData->SetYTitle("t' [GeV]");
135  temp.costheta_GJF_tprime.push_back(hGJtData);
136 
137  TH1D* hTYMC = new TH1D("hTYMC_" + name_prefix, name_prefix + " Isobar Treiman-Yang Phi (MC)", nbinsang, -TMath::Pi(),
138  TMath::Pi());
139  hTYMC->SetXTitle("isobar #phi_{TY} [rad]");
140  hTYMC->SetYTitle("# of events");
141  TH1D* hTYData = new TH1D("hTYData_" + name_prefix, name_prefix + " Isobar Treiman-Yang Phi (DATA)", nbinsang, -TMath::Pi(),
142  TMath::Pi());
143  hTYData->SetXTitle("isobar #phi_{TY} [rad]");
144  hTYData->SetYTitle("# of events");
145  temp.phi_GJF.push_back(hTYMC);
146  temp.phi_GJF.push_back(hTYData);
147  temp.phi_GJF[0]->Sumw2();
148 
149  return temp;
150 }
151 
153  HelicityHistBunch temp;
154  TH1D* hHThetaMC = new TH1D("hHThetaMC_" + name_prefix, name_prefix + " Isobar Helicity Cos Theta (MC)", nbinsang, -1, 1);
155  hHThetaMC->SetXTitle("cos(#theta_{hel} of negative particle from isobar)");
156  hHThetaMC->SetYTitle("# of events");
157  temp.costheta_HF.push_back(hHThetaMC);
158  TH1D* hHThetaData = new TH1D("hHThetaData_" + name_prefix, name_prefix + " Isobar Helicity Cos Theta (DATA)", nbinsang, -1,
159  1);
160  hHThetaData->SetXTitle("cos(#theta_{hel}) of negative particle from isobar");
161  hHThetaData->SetYTitle("# of events");
162  temp.costheta_HF.push_back(hHThetaData);
163  temp.costheta_HF[0]->Sumw2();
164 
165  TH1D* hHPhiMC = new TH1D("hHPhiMC_" + name_prefix, name_prefix + " Isobar Helicity Phi (MC)", nbinsang, -TMath::Pi(),
166  TMath::Pi());
167  hHPhiMC->SetXTitle("#phi_{hel} [rad] of negative particle from isobar");
168  hHPhiMC->SetYTitle("# of events");
169  TH1D* hHPhiData = new TH1D("hHPhiData_" + name_prefix, name_prefix + " Isobar Helicity Phi (DATA)", nbinsang, -TMath::Pi(),
170  TMath::Pi());
171  hHPhiData->SetXTitle("#phi_{hel} [rad] of negative particle from isobar");
172  hHPhiData->SetYTitle("# of events");
173  temp.phi_HF.push_back(hHPhiMC);
174  temp.phi_HF.push_back(hHPhiData);
175  temp.phi_HF[0]->Sumw2();
176 
177  return temp;
178 }
179 
180 void fillWeightedHelicityAnglePlots(const HelicityAngles &ha, double weight, unsigned int tree_index, HelicityHistBunch &hhb) {
181  hhb.costheta_HF[tree_index]->Fill(ha.cosTheta, weight);
182  hhb.phi_HF[tree_index]->Fill(ha.phi, weight);
183 }
184 
185 void fillWeightedGJAnglePlots(const TLorentzVector &isobar, double weight, double tprime, unsigned int tree_index, GJHistBunch &hBunch) {
186  hBunch.costheta_GJF[tree_index]->Fill(isobar.CosTheta(), weight);
187  if (tree_index == 0)
188  hBunch.costheta_GJF_MC_raw->Fill(isobar.CosTheta());
189  hBunch.costheta_GJF_tprime[tree_index]->Fill(isobar.CosTheta(), tprime, weight);
190  hBunch.phi_GJF[tree_index]->Fill(isobar.Phi(), weight);
191  hBunch.isobar_mass[tree_index]->Fill(isobar.M(), weight);
192 }
193 
194 HelicityAngles calculateHelicityAngles(const NParticleState &isobar, TLorentzVector *beam = NULL) {
195  HelicityAngles temp;
196 
197  TVector3 zaxis_gjf;
198  if(beam != NULL) {
199  zaxis_gjf = beam->Vect().Unit();
200  }
201  else {
202  zaxis_gjf = TVector3(0,0,1);
203  }
204  // create helicity frame coordinate system
205  TVector3 zaxis = isobar.p().Vect().Unit();
206  TVector3 yaxis = zaxis_gjf.Cross(zaxis).Unit();
207  TVector3 xaxis = yaxis.Cross(zaxis);
208 
209  // boost NParticleState into isobar rest frame
210  TLorentzVector particle;
211  if(isobar.getParticle(0)->q() == -1)
212  particle = isobar.getParticle(0)->p();
213  else
214  particle = isobar.getParticle(1)->p();
215  const TVector3 boost_vec = isobar.p().BoostVector();
216  particle.Boost(-boost_vec);
217  // theta
218  double theta = zaxis.Angle(particle.Vect());
219  temp.cosTheta = TMath::Cos(theta);
220  double fX = xaxis.Dot(particle.Vect());
221  double fY = yaxis.Dot(particle.Vect());
222  if(fX == 0.0 && fY == 0.0)
223  temp.phi = 0.0;
224  else
225  temp.phi = TMath::ATan2(fY,fX);
226 
227  return temp;
228 }
229 
230 
231 void makeDifferencePlots(TFile *outfile) {
232  outfile->cd();
233  TList *dirlist = outfile->GetListOfKeys();
234  TIter diriter(dirlist);
235  TDirectory *dir;
236 
237  std::cout << "scanning directories and creating diff histograms..." << std::endl;
238  while ((dir = (TDirectory *) diriter())) {
239  std::string dirname = dir->GetName();
240  // check if directory is mass bin dir
241  unsigned int pointpos = dirname.find(".");
242  if (pointpos == 0 || pointpos == dirname.size())
243  continue;
244 
245  outfile->cd(dir->GetName());
246 
247  // make list of MC Histograms
248  TList mclist;
249  TList *histlist = gDirectory->GetListOfKeys();
250  TIter histiter(histlist);
251  TObject *obj;
252  while ((obj = histiter())) {
253  TString s(obj->GetName());
254  if (s.EndsWith("MC"))
255  mclist.Add(obj);
256  else if (s.Contains("MC_"))
257  mclist.Add(obj);
258  }
259  histiter = TIter(&mclist);
260  TH1D *diffhist, *reldiffhist, *mchist, *datahist;
261  double scale;
262  while ((mchist = (TH1D*) histiter())) {
263  // generate difference histograms
264  std::string hnamemc(mchist->GetName());
265  int pos = hnamemc.find("MC");
266  // create new string with MC exchanged for Diff
267  std::string hnamediff(hnamemc);
268  hnamediff.erase(pos, 2);
269  hnamediff.insert(pos, "Diff");
270  // create new string with MC exchanged for RelDiff
271  std::string hnamereldiff(hnamemc);
272  hnamereldiff.erase(pos, 2);
273  hnamereldiff.insert(pos, "RelDiff");
274  // create new string with MC exchanged for Data
275  std::string hnamedata(hnamemc);
276  hnamedata.erase(pos, 2);
277  hnamedata.insert(pos, "Data");
278 
279  outfile->GetObject((std::string(dir->GetName()) + "/" + hnamediff).c_str(), diffhist);
280  outfile->GetObject((std::string(dir->GetName()) + "/" + hnamereldiff).c_str(), reldiffhist);
281  outfile->GetObject((std::string(dir->GetName()) + "/" + hnamedata).c_str(), datahist);
282  outfile->GetObject((std::string(dir->GetName()) + "/" + hnamemc).c_str(), mchist);
283  if (!diffhist) {
284  if (datahist) {
285  outfile->cd(dir->GetName());
286  scale = datahist->Integral();
287  scale = scale / (mchist->Integral());
288  mchist->Scale(scale);
289 
290  diffhist = new TH1D(*mchist);
291  diffhist->SetName(hnamediff.c_str());
292  diffhist->SetTitle("");
293  diffhist->Add(datahist, -1.);
294  diffhist->SetYTitle("# of events difference(MC-Data)");
295  diffhist->Write();
296 
297  reldiffhist = new TH1D(*diffhist);
298  reldiffhist->SetName(hnamereldiff.c_str());
299  reldiffhist->Divide(datahist);
300  reldiffhist->SetYTitle("relative difference((MC-Data)/Data)");
301  reldiffhist->Write();
302  }
303  }
304  }
305 
306  histiter = TIter(&mclist);
307  TH2D *diffhist2d, *reldiffhist2d, *mchist2d, *datahist2d;
308  scale = 1.0;
309  while ((mchist2d = (TH2D*) histiter())) {
310  // generate difference histograms
311  std::string hnamemc(mchist2d->GetName());
312  int pos = hnamemc.find("MC");
313  // create new string with MC exchanged for Diff
314  std::string hnamediff(hnamemc);
315  hnamediff.erase(pos, 2);
316  hnamediff.insert(pos, "Diff");
317  // create new string with MC exchanged for RelDiff
318  std::string hnamereldiff(hnamemc);
319  hnamereldiff.erase(pos, 2);
320  hnamereldiff.insert(pos, "RelDiff");
321  // create new string with MC exchanged for Data
322  std::string hnamedata(hnamemc);
323  hnamedata.erase(pos, 2);
324  hnamedata.insert(pos, "Data");
325 
326  outfile->GetObject((std::string(dir->GetName()) + "/" + hnamediff).c_str(), diffhist2d);
327  outfile->GetObject((std::string(dir->GetName()) + "/" + hnamereldiff).c_str(), reldiffhist2d);
328  outfile->GetObject((std::string(dir->GetName()) + "/" + hnamedata).c_str(), datahist2d);
329  outfile->GetObject((std::string(dir->GetName()) + "/" + hnamemc).c_str(), mchist2d);
330  if (!diffhist2d) {
331  if (datahist2d) {
332  outfile->cd(dir->GetName());
333  scale = datahist2d->Integral();
334  scale = scale / (mchist2d->Integral());
335  mchist2d->Scale(scale);
336 
337  diffhist2d = new TH2D(*mchist2d);
338  diffhist2d->SetName(hnamediff.c_str());
339  diffhist2d->SetTitle("diff(MC-Data)");
340  diffhist2d->Add(datahist2d, -1.);
341  double max = diffhist2d->GetMaximum();
342  if(max < TMath::Abs(diffhist2d->GetMinimum()))
343  max = TMath::Abs(diffhist2d->GetMinimum());
344  diffhist2d->SetMaximum(max);
345  diffhist2d->SetMinimum(-max);
346  diffhist2d->Write();
347 
348  reldiffhist2d = new TH2D(*diffhist2d);
349  reldiffhist2d->SetName(hnamereldiff.c_str());
350  reldiffhist2d->SetTitle("rel. diff((MC-Data)/Data)");
351  reldiffhist2d->Divide(datahist2d);
352  reldiffhist2d->SetMaximum();
353  reldiffhist2d->SetMinimum();
354  max = reldiffhist2d->GetMaximum();
355  if (max < TMath::Abs(reldiffhist2d->GetMinimum()))
356  max = TMath::Abs(reldiffhist2d->GetMinimum());
357  reldiffhist2d->SetMaximum(max);
358  reldiffhist2d->SetMinimum(-max);
359  reldiffhist2d->Write();
360  }
361  }
362  }
363  }
364 }
365 
366 TH2D* createDalitzHistogram(TString name, TString title, double mass, unsigned int treeentries) {
367  double rangelow = 0.0;
368  double rangehigh = pow(mass-0.1, 2);
369  unsigned int nbins = 0;
370  nbins = 0.6*TMath::Sqrt(treeentries)*(rangehigh-rangelow);
371  std::cout<<"nbins for mass "<<mass<<": "<<nbins<<std::endl;
372  // lower bound is 20 bins
373  if(nbins < 20) nbins = 20;
374  // upper bound is 130 bins
375  if(nbins > 130) nbins = 130;
376  TH2D* phist = new TH2D(name, title, nbins, rangelow, rangehigh, nbins, rangelow, rangehigh);
377  return phist;
378 }
379 
380 
381 void plotWeightedEvts_Kpipi(TTree* mctr, TTree* datatr, TString outfilename = "kineplots.root",
382  TString mass_ = "000") {
383  cout << " running histo creator " << endl;
384  double massval = 0.0;
385  unsigned int datatreeentries = 0;
386  mass = mass_;
387  if (mass != "000") {
388  massbin = ("_m") + mass;
389  massbin.ReplaceAll(" ", "");
390  }
391 
392  std::string binname(mass.Data());
393  unsigned int pointpos = binname.find(".");
394  if(pointpos == 0 || pointpos == binname.size())
395  std::cout<<"Warning: Bad massbin name!"<<std::endl;
396  std::string masshigh = binname.substr(pointpos+1);
397  massval = atof(masshigh.c_str());
398  massval /=1000;
399  datatreeentries = datatr->GetEntries();
400 
401 
402  gROOT->SetStyle("Plain");
403  TFile* outfile = TFile::Open(outfilename, "UPDATE");
404  outfile->cd();
405  gDirectory->cd();
406  if (!gDirectory->GetDirectory(mass)) {
407  gDirectory->mkdir(mass);
408  }
409  gDirectory->cd(mass);
410 
411  // --------------- global diagrams
412  std::vector<TH1D*> hM;
413  TH1D* hMMC = new TH1D("hResMassMC", "Mass (MC)", 60, 0.5, 2.5);
414  hM.push_back(hMMC);
415  TH1D* hMData = new TH1D("hResMassData", "Mass (DATA)", 60, 0.5, 2.5);
416  hM.push_back(hMData);
417 
418  vector<TH1D*> hThetaLab;
419  TH1D* hThetaLabMC = new TH1D("hThetaLabMC", "Cos Theta Lab (MC)", nbninsm, 0.997, 1);
420  hThetaLab.push_back(hThetaLabMC);
421  TH1D* hThetaLabData = new TH1D("hThetaLabData", "Cos Theta Lab (Data)", nbninsm, 0.997, 1);
422  hThetaLab.push_back(hThetaLabData);
423  hThetaLab[0]->Sumw2();
424 
425  // Dalitz plots
426  std::vector<TH2D*> dalitz_neutral;
427  /* TH2D* dalitz = createDalitzHistogram("hDalitzMC",
428  "Dalitz Plot #pi^{0}#pi^{0} vs. #pi^{-}#pi^{0} (MC)", massval, datatreeentries);
429  dalitz->SetXTitle("mass^{2}(#pi^{0}#pi^{0}) [GeV^{2}/c^{4}]");
430  dalitz->SetYTitle("mass^{2}(#pi^{-}#pi^{0}) [GeV^{2}/c^{4}]");
431  dalitz->SetStats(0);
432  dalitz_neutral.push_back(dalitz);
433  dalitz = createDalitzHistogram("hDalitzData",
434  "Dalitz Plot #pi^{0}#pi^{0} vs. #pi^{-}#pi^{0} (Data)", massval, datatreeentries);
435  dalitz->SetXTitle("mass^{2}(#pi^{0}#pi^{0}) [GeV^{2}/c^{4}]");
436  dalitz->SetYTitle("mass^{2}(#pi^{-}#pi^{0}) [GeV^{2}/c^{4}]");
437  dalitz->SetStats(0);
438  dalitz_neutral.push_back(dalitz);*/
439 TH2D* dalitz = createDalitzHistogram("hDalitzMC",
440  "Dalitz Plot K^{-}#pi^{+} vs. #pi^{-}#pi^{+} (MC)", massval, datatreeentries);
441  dalitz->SetXTitle("mass^{2}(#pi^{-}#pi^{+}) [GeV^{2}/c^{4}]");
442  dalitz->SetYTitle("mass^{2}(K^{-}#pi^{+}) [GeV^{2}/c^{4}]");
443  dalitz->SetStats(0);
444  dalitz_neutral.push_back(dalitz);
445  dalitz = createDalitzHistogram("hDalitzData",
446  "Dalitz Plot K^{-}#pi^{+} vs. #pi^{-}#pi^{+} (MC)", massval, datatreeentries);
447  dalitz->SetXTitle("mass^{2}(#pi^{-}#pi^{+}) [GeV^{2}/c^{4}]");
448  dalitz->SetYTitle("mass^{2}(K^{-}#pi^{+}) [GeV^{2}/c^{4}]");
449  dalitz->SetStats(0);
450  dalitz_neutral.push_back(dalitz);
451  /*std::vector<TH2D*> dalitz_charged;
452  dalitz = new TH2D("hDalitzChargedMC", "Dalitz Plot #pi^{-}#pi^{0} vs. #pi^{-}#pi^{0} (MC)", nbninsm, 0.0,
453  2.2, nbninsm, 0.0, 2.2);
454  dalitz_charged.push_back(dalitz);
455  dalitz = new TH2D("hDalitzChargedData", "Dalitz Plot #pi^{-}#pi^{0} vs. #pi^{-}#pi^{0} (Data)", nbninsm,
456  0.0, 2.2, nbninsm, 0.0, 2.2);
457  dalitz_charged.push_back(dalitz);*/
458 
459  // --------------- generate histogram bunches
460  // K-pi+ isobar
461  // GJ Histogram Bunch
462  GJHistBunch GJHB_Kpi_isobar = GJHistBunchFactory("Kpi");
463  // Helicity Histogram Bunch
464  HelicityHistBunch HHB_Kpi_isobar = HelicityHistBunchFactory("Kpi");
465 
466  // pi-pi+ isobar
467  // GJ Histogram Bunch MC
468  GJHistBunch GJHB_pipi_isobar = GJHistBunchFactory("pipi");
469  // Helicity Histogram Bunch
470  HelicityHistBunch HHB_pipi_isobar = HelicityHistBunchFactory("pipi");
471 
472  double avweight = 1;
473 
474  /*TH1D* hCosTheta[2] = {new TH1D("hCosThetaMC", "Cos Theta (Data)", nbninsm, -1, 1), new TH1D("hCosThetaData", "Cos Theta (MC)", nbninsm, -1, 1) };
475  TH1D* foohTY[2] = {new TH1D("foohTYMC_", " Isobar Treiman-Yang Phi (MC)", nbinsang, -TMath::Pi(),
476  TMath::Pi()), new TH1D("foohTYData_", " Isobar Treiman-Yang Phi (DATA)", nbinsang, -TMath::Pi(),
477  TMath::Pi()) };
478  hCosTheta[0]->Sumw2();
479  foohTY[0]->Sumw2();
480 
481  TH1D* hhCosTheta[2] = {new TH1D("hhCosThetaMC", "Cos Theta (Data)", nbninsm, -1, 1), new TH1D("hhCosThetaData", "Cos Theta (MC)", nbninsm, -1, 1) };
482  TH1D* hfoohTY[2] = {new TH1D("hfoohTYMC_", " Isobar Treiman-Yang Phi (MC)", nbinsang, -TMath::Pi(),
483  TMath::Pi()), new TH1D("hfoohTYData_", " Isobar Treiman-Yang Phi (DATA)", nbinsang, -TMath::Pi(),
484  TMath::Pi()) };
485  hhCosTheta[0]->Sumw2();
486  hfoohTY[0]->Sumw2();*/
487 
488  //Loop both over data and mc tree
489  // itree = 0: mc tree
490  // itree = 1: data tree
491  for (unsigned int itree = 0; itree < 2; ++itree) {
492  TTree* tr = (itree == 0) ? mctr : datatr;
493  if (tr == NULL)
494  continue;
495 
496  double weight = 1;
497  double impweight = 1;
498  double maxweight = 0;
499  TClonesArray* p = new TClonesArray("TLorentzVector");
500  TLorentzVector* beam = NULL;
501  UInt_t qbeam = -1;
502  std::vector<int>* q = NULL;
503  if (itree == 0)
504  tr->SetBranchAddress("weight", &weight);
505  if (itree == 0)
506  tr->SetBranchAddress("impweight", &impweight);
507  tr->SetBranchAddress("p", &p);
508  tr->SetBranchAddress("beam", &beam);
509  tr->SetBranchAddress("qbeam", &qbeam);
510  tr->SetBranchAddress("q", &q);
511 
512  TVector3 vertex;
513 
514  int _qbeam = -1;
515  NParticleEvent event(p, q, beam, &_qbeam, &vertex);
516 
517  // loop over tree entries
518  unsigned int nevt = tr->GetEntries();
519  for (unsigned int i = 0; i < nevt-1; ++i) {
520  //int percent = i*100/nevt;
521  // if (percent % 10 == 0)
522  // std::cout << i << "% " << std::endl;
523  tr->GetEntry(i);
524  // in case its data tree (itree=1) put weights to 1
525  if (itree == 1) {
526  weight = 1;
527  impweight = 1;
528  }
529  if (weight == 0)
530  continue;
531 
532  _qbeam = -1;// (int) qbeam;
533  // this builds all subsystems
534  event.refresh();
535  //cout << i << " of " << nevt << endl;
536  if (impweight != 0)
537  weight /= impweight;
538 
539  if (weight > maxweight)
540  maxweight = weight;
541  if (itree == 0)
542  avweight += weight;
543 
544  double tprime = event.tprime();
545  //cout << tprime << endl;
546  unsigned int npart = event.nParticles();
547  // loop over pions
548  for (unsigned int ipart = 0; ipart < npart; ++ipart) {
549  TLorentzVector p = event.getParticle(ipart).p();
550  hThetaLab[itree]->Fill(p.CosTheta(), weight);
551  }
552 
553  // ----dalitz plots
554  // make all combinations
555  std::vector<std::pair<std::pair<int, int>, double> > comb;
556  for(unsigned int i=0; i < npart; i++) {
557  for(unsigned int j=0; j < i; j++) {
558  TLorentzVector lv = event.getParticle(i).p() + event.getParticle(j).p();
559  double mass2 = lv.M2();
560  std::pair<int, int> charge(event.getParticle(i).q(), event.getParticle(j).q());
561  std::pair<std::pair<int, int>, double> temp;
562  temp = make_pair(charge, mass2);
563  comb.push_back(temp);
564  }
565  }
566  /*
567  // now fill corresponding dalitz plots
568  // this part is pi-pi0pi0 specific
569 
570  // put pi0 pi0 combination to front of vector to make combination picks easier later on
571  for(unsigned int i = 0; i < comb.size(); i++) {
572  if(getTotalCharge(comb[i].first) == 0) {
573  if(i == 0) break;
574  else {
575  std::pair<std::pair<int, int>, double> temp = comb[0];
576  comb[0] = comb[i];
577  comb[i] = temp;
578  break;
579  }
580  }
581  }
582  // now actually fill the histograms
583  dalitz_neutral[itree]->Fill(comb[0].second, comb[1].second, weight);
584  //dalitz_charged[itree]->Fill(comb[1].second, comb[2].second, weight);
585  */
586 // now fill corresponding dalitz plots
587  // this part is pi-pi0pi0 specific (old)
588  // K-pi+pi- (new)
589 
590  // put K- pi+ and then pi- pi+ combination to front of vector to make combination picks easier later on
591  for(unsigned int i = 0; i < comb.size(); i++) {
592  // first pass put the charged combination to the end
593  if(comb[i].first.first < 0 && comb[i].first.second < 0) {
594  if (i==2) break;
595  else {
596  std::pair<std::pair<float, float>, double> temp = comb[2];
597  comb[2] = comb[i];
598  comb[i] = temp;
599  }
600  }
601  }
602  // second pass swap the havier combination to the front
603  if (fabs(comb[1].first.first)+fabs(comb[1].first.second) > fabs(comb[0].first.first)+fabs(comb[0].first.second)){
604  std::pair<std::pair<float, float>, double> temp = comb[0];
605  comb[0] = comb[1];
606  comb[1] = temp;
607  }
608  // now actually fill the histograms
609  dalitz_neutral[itree]->Fill(comb[1].second, comb[0].second, weight);
610 
611  /* unsigned int index = 0;
612  TLorentzVector fsParticles[3];
613  TLorentzVector beam = *event.beam();
614  TLorentzVector X(0, 0, 0, 0);
615  for (unsigned int is = 0; is < 3; ++is) {
616  if (event.getParticle(is).q() == -1)
617  index = is;
618  fsParticles[is] = event.getParticle(is).p();
619  X += fsParticles[is];
620  }
621  TVector3 xboost = X.BoostVector();
622  for (unsigned int is = 0; is < 3; ++is) {
623  fsParticles[is].Boost(-xboost);
624  }
625  beam.Boost(-xboost);
626  TVector3 zaxis = beam.Vect().Unit();
627  TVector3 yaxis = beam.Vect().Cross(X.Vect()).Unit();
628  TVector3 xaxis = yaxis.Cross(zaxis);
629 
630  double phi = 0.0;
631  double theta = zaxis.Angle(fsParticles[index].Vect());
632  double cosTheta = TMath::Cos(theta);
633  double fX = xaxis.Dot(fsParticles[index].Vect());
634  double fY = yaxis.Dot(fsParticles[index].Vect());
635  if (!(fX == 0.0 && fY == 0.0))
636  phi = TMath::ATan2(fY, fX);
637 
638  hCosTheta[itree]->Fill(cosTheta, weight);
639  foohTY[itree]->Fill(phi, weight);
640 
641  TLorentzVector isobar(0, 0, 0, 0);
642  unsigned int hindex = 0;
643  for (unsigned int is = 0; is < 3; ++is) {
644  if (is == index)
645  continue;
646  isobar += fsParticles[is];
647  hindex = is;
648  }
649 
650  // create helicity frame coordinate system
651  TVector3 hzaxis = isobar.Vect().Unit();
652  TVector3 hyaxis = zaxis.Cross(hzaxis).Unit();
653  TVector3 hxaxis = hyaxis.Cross(hzaxis);
654 
655  // boost NParticleState into isobar rest frame
656  const TVector3 hboost = isobar.BoostVector();
657  fsParticles[hindex].Boost(-hboost);
658  // theta
659  double htheta = hzaxis.Angle(fsParticles[hindex].Vect());
660  double hcosTheta = TMath::Cos(htheta);
661  double hfX = hxaxis.Dot(fsParticles[hindex].Vect());
662  double hfY = hyaxis.Dot(fsParticles[hindex].Vect());
663  double hphi = 0.0;
664  if (!(hfX == 0.0 && hfY == 0.0))
665  hphi = TMath::ATan2(hfY, hfX);
666 
667  hhCosTheta[itree]->Fill(hcosTheta, weight);
668  hfoohTY[itree]->Fill(hphi, weight);*/
669 
670  // transform into GJ
671  event.toGJ();
672  // build again to get particles in GJF
673  event.build();
674 
675  /*TLorentzVector temp(0,0,0,0);
676  //cout<<"number of particles in event: "<<event.nParticles()<<endl;
677  for (unsigned int is = 0; is < 3; ++is) {
678  temp += event.getParticle(is).p();
679  }
680  temp.Dump();*/
681 
682  // loop over all states that contain n-1 final state particles
683  // and plot angles
684  unsigned int nstates = event.nStates();
685  //cout<<"number of substates: "<<event.nStates()<<endl;
686  for (unsigned int is = 0; is < nstates; ++is) {
687 
688  const NParticleState& state = event.getState(is);
689  if (state.n() == npart) {
690  hM[itree]->Fill(state.p().M());
691 
692  }
693  if (state.n() == 2 && state.q() == 0){
694  float sum_mass = state.getParticle(0)->p().M()+state.getParticle(1)->p().M();
695  if (fabs(sum_mass-0.633) < 0.010) {
696  // this is an isobar decaying into K-pi+ final state particles
697  fillWeightedGJAnglePlots(state.p(), weight, tprime, itree, GJHB_Kpi_isobar);
698  fillWeightedHelicityAnglePlots(calculateHelicityAngles(state), weight, itree, HHB_Kpi_isobar);
699  }
700  else {
701  if (fabs(sum_mass-0.279) < 0.010) {
702  // this is an isobar decaying into pi-pi+ final state particles
703  fillWeightedGJAnglePlots(state.p(), weight, tprime, itree, GJHB_pipi_isobar);
704  fillWeightedHelicityAnglePlots(calculateHelicityAngles(state), weight, itree, HHB_pipi_isobar);
705  }
706  }
707  }
708  }
709 
710  }// end loop over events
711  if (itree == 0)
712  avweight /= (double) nevt;
713  cout << "Maxweight=" << maxweight << endl;
714  cout << "Average weight=" << avweight << endl;
715  }// end loop over trees
716 
717  outfile->Write();
718  makeDifferencePlots(outfile);
719 
720  TList* Hlist = gDirectory->GetList();
721  Hlist->Remove(mctr);
722  Hlist->Remove(datatr);
723  //Hlist->Remove("hWeights");
724  int nobj = Hlist->GetEntries();
725  std::cout << "Found " << nobj << " Objects in HList" << std::endl;
726 
727  outfile->Close();
728 
729  gROOT->cd();
730 
731 }