ROOTPWA
plotCoherence.C
Go to the documentation of this file.
1 
2 //
3 // Copyright 2009 Sebastian Neubert
4 //
5 // This file is part of rootpwa
6 //
7 // rootpwa is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // rootpwa is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with rootpwa. If not, see <http://www.gnu.org/licenses/>.
19 //
21 //-----------------------------------------------------------
22 // File and Version Information:
23 // $Id$
24 //
25 // Description:
26 // Draws coherence of (wave A - wave B) from tree.
27 //
28 //
29 // Author List:
30 // Sebastian Neubert TUM (original author)
31 //
32 //
33 //-----------------------------------------------------------
34 
35 
36 #include <iostream>
37 #include <sstream>
38 
39 #include "TGraphErrors.h"
40 #include "TAxis.h"
41 #include "TPad.h"
42 #include "TLine.h"
43 #include "TLegend.h"
44 #include "TList.h"
45 
46 #include "reportingUtils.hpp"
47 #include "plotCoherence.h"
48 
49 
50 using namespace std;
51 using namespace rpwa;
52 
53 
54 // signature with wave indices
55 TMultiGraph*
56 plotCoherence(const unsigned int nmbTrees, // number of fitResult trees
57  TTree** trees, // array of fitResult trees
58  const int waveIndexA, // index of first wave
59  const int waveIndexB, // index of second wave
60  const bool saveEps, // if set, EPS file with name wave ID is created
61  const int* graphColors, // array of colors for graph line and marker
62  const bool drawLegend, // if set legend is drawn
63  const string& graphTitle, // name and title of graph (default is wave IDs)
64  const char* drawOption, // draw option for graph
65  const string& selectExpr, // TTree::Draw() selection expression
66  const string& branchName) // fitResult branch name
67 {
68  for (unsigned int i = 0; i < nmbTrees; ++i)
69  if (!trees[i]) {
70  printErr << "null pointer to tree[" << i << "]. aborting." << endl;
71  return 0;
72  }
73  string waveNameA, waveNameB;
74  {
75  // get wave names (assume same wave set in all bins)
76  fitResult* massBin = new fitResult();
77  trees[0]->SetBranchAddress(branchName.c_str(), &massBin);
78  trees[0]->GetEntry(0);
79  waveNameA = massBin->waveName(waveIndexA).Data();
80  waveNameB = massBin->waveName(waveIndexB).Data();
81  }
82  printInfo << "plotting coherence of waves '" << waveNameA << "' [" << waveIndexA << "] "
83  << "and '" << waveNameB << "' [" << waveIndexB << "]" << endl;
84  if (selectExpr != "")
85  cout << " using selection criterion '" << selectExpr << "'" << endl;
86 
87  // create multiGraph
88  TMultiGraph* graph = new TMultiGraph();
89  {
90  if (graphTitle != "") {
91  graph->SetName (graphTitle.c_str());
92  graph->SetTitle(graphTitle.c_str());
93  } else {
94  stringstream name;
95  name << "coherence_" << waveNameA << "_" << waveNameB;
96  stringstream title;
97  title << "Coherence(" << waveNameA << " [" << waveIndexA << "], "
98  << waveNameB << " [" << waveIndexB << "])";
99  graph->SetName(name.str().c_str());
100  graph->SetTitle(title.str().c_str());
101  }
102  }
103 
104  // fill multiGraph
105  for (unsigned int i = 0; i < nmbTrees; ++i) {
106 
107  // get wave index for this tree (assume same wave set in all bins)
108  fitResult* massBin = new fitResult();
109  trees[i]->SetBranchAddress(branchName.c_str(), &massBin);
110  trees[i]->GetEntry(0);
111  const int waveIndexAThisTree = massBin->waveIndex(waveNameA);
112  const int waveIndexBThisTree = massBin->waveIndex(waveNameB);
113  if (waveIndexAThisTree < 0) {
114  printInfo << "cannot find wave '" << waveNameA << "' in tree '" << trees[i]->GetTitle() << "'. "
115  << "skipping." << endl;
116  continue;
117  }
118  if (waveIndexBThisTree < 0) {
119  printInfo << "cannot find wave '" << waveNameB << "' in tree '" << trees[i]->GetTitle() << "'. "
120  << "skipping." << endl;
121  continue;
122  }
123 
124  // build and run TTree::Draw() expression
125  stringstream drawExpr;
126  drawExpr << branchName << ".coherence(" << waveIndexAThisTree << ","
127  << waveIndexBThisTree << "):"
128  << branchName << ".coherenceErr(" << waveIndexAThisTree << ","
129  << waveIndexBThisTree << "):"
130  << branchName << ".massBinCenter() >> h" << waveIndexAThisTree << "_"
131  << waveIndexBThisTree << "_" << i;
132  cout << " running TTree::Draw() expression '" << drawExpr.str() << "' "
133  << "on tree '" << trees[i]->GetName() << "', '" << trees[i]->GetTitle() << "'" << endl;
134  trees[i]->Draw(drawExpr.str().c_str(), selectExpr.c_str(), "goff");
135 
136  // extract data from TTree::Draw() result and build graph
137  const int nmbBins = trees[i]->GetSelectedRows();
138  vector<double> x(nmbBins), xErr(nmbBins);
139  vector<double> y(nmbBins), yErr(nmbBins);
140  for (int j = 0; j < nmbBins; ++j) {
141  x [j] = trees[i]->GetV3()[j] * 0.001; // convert mass to GeV
142  xErr[j] = 0;
143  const double val = trees[i]->GetV1()[j];
144  const double valErr = trees[i]->GetV2()[j];
145  y [j] = (isnan(val)) ? 0 : val;
146  yErr[j] = (isnan(valErr)) ? 0 : valErr;
147  }
148  TGraphErrors* g = new TGraphErrors(nmbBins,
149  &(*(x.begin())), // mass
150  &(*(y.begin())), // coherence
151  &(*(xErr.begin())), // mass error
152  &(*(yErr.begin()))); // coherence error
153 
154  // beautify graph
155  stringstream graphName;
156  graphName << graph->GetName() << "_" << i;
157  g->SetName (graphName.str().c_str());
158  g->SetTitle(graphName.str().c_str());
159  g->SetMarkerStyle(21);
160  g->SetMarkerSize(0.5);
161  if (graphColors) {
162  g->SetMarkerColor(graphColors[i]);
163  g->SetLineColor (graphColors[i]);
164  }
165  graph->Add(g);
166  }
167 
168  // draw graph
169  graph->Draw(drawOption);
170  graph->GetXaxis()->SetTitle("Mass [GeV]");
171  graph->GetYaxis()->SetTitle("Coherence");
172  graph->SetMinimum(-0.2);
173  graph->SetMaximum( 1.2);
174  gPad->Update();
175  TLine line;
176  line.SetLineStyle(3);
177  line.DrawLine(graph->GetXaxis()->GetXmin(), 0, graph->GetXaxis()->GetXmax(), 0);
178 
179  // add legend
180  if (drawLegend && (nmbTrees > 1)) {
181  TLegend* legend = new TLegend(0.65, 0.80, 0.99, 0.99);
182  legend->SetFillColor(10);
183  legend->SetBorderSize(1);
184  legend->SetMargin(0.2);
185  for (unsigned int i = 0; i < nmbTrees; ++i) {
186  TGraph* g = static_cast<TGraph*>(graph->GetListOfGraphs()->At(i));
187  legend->AddEntry(g, trees[i]->GetTitle(), "LPE");
188  }
189  legend->Draw();
190  }
191 
192  // create EPS file
193  if (saveEps)
194  gPad->SaveAs(((string)graph->GetName() + ".eps").c_str());
195 
196  return graph;
197 }