Diana Software
QGHistogram.cc
Go to the documentation of this file.
1 #include "QGHistogram.hh"
2 #include <algorithm>
3 #include <cmath>
4 #include <iostream>
5 #include <set>
6 #include <sstream>
7 #include <typeinfo>
8 #include "QChain.hh"
9 #include "QGCanvasWindow.hh"
10 #include "QGCutsFrame.hh"
11 #include "QGFileHandler.hh"
12 #include "QGHistogramEditWindow.hh"
14 #include "QGPlotFrame.hh"
15 #include "QGPlotStyleFrame.hh"
16 #include "QGTextFileKeys.hh"
17 #include "TCanvas.h"
18 #include "TRootEmbeddedCanvas.h"
19 #include "TString.h"
20 #include "TStyle.h"
21 #include "TPaveStats.h"
22 
23 #ifdef WIN32
24  #include <float.h>
25  #define isfinite(x) _finite(x)
26 #else
27 using std::isfinite;
28 #endif
29 
31 
32 using std::cout;
33 using std::endl;
34 using std::flush;
35 using std::list;
36 using std::set;
37 using std::string;
38 using std::stringstream;
39 using std::vector;
40 
41 list<QGHistogram*> QGHistogram::fHistograms;
42 
44 TH1D(), QGPlot(),
45 fAutoSetNumberOfBins(true), fAutoSetXMax(true), fAutoSetXMin(true),
46 fBinWidth(0), fIsBinWidthSet(false), fNumberOfUniqueDataPoints(0),
47 fStyleHistogram(new TH1D())
48 {
49  this->SetLineColor(0);
50  fHistograms.push_back(this);
51  SetName();
52  SetBit(kCanDelete, kFALSE);
53  GetYaxis()->SetTitleOffset(1.35);
54  MakeStylePlot();
55 }
56 
58 TH1D(histogram), QGPlot(histogram),
59 fAutoSetNumberOfBins(histogram.fAutoSetNumberOfBins), fAutoSetXMax(histogram.fAutoSetXMax),
60 fAutoSetXMin(histogram.fAutoSetXMin), fBinWidth(histogram.fBinWidth),
61 fDataPoints(histogram.fDataPoints), fIsBinWidthSet(histogram.fIsBinWidthSet),
62 fNumberOfUniqueDataPoints(histogram.fNumberOfUniqueDataPoints), fStyleHistogram(new TH1D())
63 {
64  fHistograms.push_back(this);
65  SetName();
66  SetBit(kCanDelete, kFALSE);
67  MakeStylePlot();
68 }
69 
71 {
72  if (fPlotEditWindow) {
73  fPlotEditWindow->CloseWindow();
74  fPlotEditWindow = 0;
75  }
76  if (find(fHistograms.begin(), fHistograms.end(), this) != fHistograms.end()) {
77  fHistograms.erase(find(fHistograms.begin(), fHistograms.end(), this));
78  }
79  delete fStyleHistogram;
80 }
81 
83 {
84  if (fDataPoints.size() != 0) {
85  if (fAutoSetXMin) {
86  SetXMin(*min_element(fDataPoints.begin(), fDataPoints.end()) - 0.5);
87  if (QGHistogramEditWindow *editWindow = dynamic_cast<QGHistogramEditWindow*>(fPlotEditWindow)) {
88  editWindow->GetHistogramParametersFrame()->SetXMin(GetXMin());
89  }
90  }
91  if (fAutoSetXMax) {
92  SetXMax(*max_element(fDataPoints.begin(), fDataPoints.end()) + 0.5);
93  if (QGHistogramEditWindow *editWindow = dynamic_cast<QGHistogramEditWindow*>(fPlotEditWindow)) {
94  editWindow->GetHistogramParametersFrame()->SetXMax(GetXMax());
95  }
96  }
98  Double_t xRange = GetXMax() - GetXMin();
99  if (fIsBinWidthSet && fBinWidth > 0) {
100  SetNumberOfBins( (int) ceil(xRange / fBinWidth) );
101  }
102  else {
103  Int_t xRangeIntPart = (Int_t) (GetXMax() - GetXMin());
104  Double_t xRangeFracPart = xRange - xRangeIntPart;
105  if (xRange < 1000.0 && xRangeFracPart == 0.0) {
106  SetNumberOfBins(xRangeIntPart);
107  } else {
108  SetNumberOfBins(100);
109  }
110  }
111  if (QGHistogramEditWindow *editWindow = dynamic_cast<QGHistogramEditWindow*>(fPlotEditWindow)) {
112  editWindow->GetHistogramParametersFrame()->SetNumberOfBins(GetNumberOfBins());
113  }
114  }
115  } else {
116  if (fAutoSetXMin) {
117  SetXMin(0);
118  }
119  if (fAutoSetXMax) {
120  SetXMax(GetXMin() + 1);
121  }
122  if (fAutoSetNumberOfBins) {
123  SetNumberOfBins(1);
124  }
125  if (QGHistogramEditWindow *editWindow = dynamic_cast<QGHistogramEditWindow*>(fPlotEditWindow)) {
126  editWindow->GetHistogramParametersFrame()->SetXMin(GetXMin());
127  editWindow->GetHistogramParametersFrame()->SetXMax(GetXMax());
128  editWindow->GetHistogramParametersFrame()->SetNumberOfBins(GetNumberOfBins());
129  }
130  }
131  fAutoSetXMin = false;
132  fAutoSetXMax = false;
133  fAutoSetNumberOfBins = false;
134 }
135 
137 {
138  SetFillStyle(1001); // solid
139  Color_t color = 0; // white
140  Color_t line_color = 1; //black
141  set<Color_t> existingLineColors;
142  list<QGHistogram*>::const_iterator histogramIter;
143  for (histogramIter = fHistograms.begin(); histogramIter != fHistograms.end(); ++histogramIter) {
144  existingLineColors.insert((*histogramIter)->GetLineColor());
145  }
146  //Insert colors that are too light to see
147  existingLineColors.insert(10);
148  existingLineColors.insert(5);
149  while (existingLineColors.count(line_color) != 0)
150  ++line_color;
151  SetFillColor(color);
152  SetLineColor(line_color);
153  MakeStylePlot();
154 }
155 
157 {
158  Reset();
160 
161  // Set style
162  if (fStyleHistogram) {
163  fStyleHistogram->TAttFill::Copy(*this);
164  fStyleHistogram->TAttLine::Copy(*this);
165  fStyleHistogram->TAttMarker::Copy(*this);
166  if (fPlotEditWindow) {
167  fPlotEditWindow->GetPlotStyleFrame()->GetEmbeddedCanvas()->GetCanvas()->cd();
168  fDrawOption = fStyleHistogram->GetDrawOption();
169  if (fDrawOption.find("AH") == 0
170  || fDrawOption.find("ah") == 0) {
171  fDrawOption.erase(0, 2);
172  }
173  else if (fDrawOption.find("A") == 0
174  || fDrawOption.find("a") == 0) {
175  fDrawOption.erase(0, 1);
176  }
177  if (fCanvasWindow) {
178  fCanvasWindow->GetPlotFrame()->GetEmbeddedCanvas()->GetCanvas()->cd();
179  }
180  }
181  }
182 
183  // Fill with data
184  vector<Double_t>::const_iterator iter;
185  for (iter = fDataPoints.begin(); iter != fDataPoints.end(); ++iter) {
186  if (GetXMin() <= *iter && *iter < GetXMax()) {
187  Fill(*iter);
188  }
189  }
190 
191  string xAxisLabel = GetXVariable();
192  stringstream yAxisLabelStream;
193  yAxisLabelStream.precision(4);
194  yAxisLabelStream << "counts / " << (GetXMax()-GetXMin())/GetNumberOfBins() << flush;
195  string yAxisLabel = yAxisLabelStream.str();
196  if (GetXUnits() != "") {
197  xAxisLabel += " (" + GetXUnits() + ")";
198  yAxisLabel += " " + GetXUnits();
199  }
200  GetXaxis()->SetTitle(xAxisLabel.c_str());
201  GetYaxis()->SetTitle(yAxisLabel.c_str());
202  if (fCanvasWindow) {
203  bool drawSuperimposed = false;
204  if (fSuperimpose) {
205  if (fCanvasWindow->GetDrawnPlots().size() != 0) {
206  if (typeid(*fCanvasWindow->GetDrawnPlots().back()) == typeid(*this)) {
207  drawSuperimposed = true;
208  }
209  }
210  }
211  if (drawSuperimposed) {
212  fCanvasWindow->GetPlotFrame()->GetEmbeddedCanvas()->GetCanvas()->RecursiveRemove(this);
213  string drawOption = fDrawOption + "sames";
214  Draw(drawOption.c_str());
215 
218  } else {
219  Draw(fDrawOption.c_str());
222  }
223  if (gPad) {
224  gPad->Update();
225  if(drawSuperimposed) {
226  TPaveStats *s = (TPaveStats*) this->GetListOfFunctions()->FindObject("stats");
227  if(s) s->SetTextColor(this->GetLineColor());
228 
229  }
230  gPad->Modified();
231  }
232  }
233 }
234 
236 {
237  if (!fPlotEditWindow) {
239  fPlotEditWindow->SetPlot(this);
240 
241  fPlotEditWindow->GetPlotStyleFrame()->GetEmbeddedCanvas()->GetCanvas()->SetEditable(kTRUE);
242  fPlotEditWindow->GetPlotStyleFrame()->GetEmbeddedCanvas()->GetCanvas()->cd();
244  fPlotEditWindow->GetPlotStyleFrame()->GetEmbeddedCanvas()->GetCanvas()->SetEditable(kFALSE);
245  }
246 }
247 
249 {
250  MakeStylePlot();
251  string drawOption = "A";
252  if (fDrawOption.size() != 0) {
253  drawOption += fDrawOption;
254  }
255  else {
256  drawOption += "H";
257  }
258  fStyleHistogram->Draw(drawOption.c_str());
259  if (gPad) {
260  gPad->Update();
261  }
262 }
263 
265 {
266  QGHistogram *histogram = new QGHistogram(*this);
267  histogram->AutoSetStyle();
268  histogram->DisplayEditWindow();
269 }
270 
272 {
273  if (fCanvasWindow) {
274  fCanvasWindow->GetPlotFrame()->GetEmbeddedCanvas()->GetCanvas()->cd();
275  fCanvasWindow->GetPlotFrame()->GetEmbeddedCanvas()->GetCanvas()->RecursiveRemove(this);
276  fCanvasWindow->GetPlotFrame()->GetEmbeddedCanvas()->GetCanvas()->Update();
278  // check whether this was the first drawn plot and if so redraw remaining plots in order to have axes
279  }
280 }
281 
283 {
284  Reset();
285  fDataPoints.clear();
286  if (chain == 0) {
289  chain = fCanvasWindow->GetFileHandler()->GetQChain();
290  } else {
291  cout << "Cannot generate the histogram because there is no file open" << endl;
292  }
293  }
294  }
295  if (chain) {
296  if (fXVariable == "") {
297  cout << "Enter an x-axis variable for the histogram" << endl;
298  } else {
299  chain->SetEstimate(chain->GetEntries());
300  chain->Draw(fXVariable.c_str(), fCutsString.c_str(), "goff");
301  Long64_t N = chain->GetSelectedRows();
302  if (N > 0) {
303  Double_t *dataPoints = chain->GetV1();
304  fDataPoints.reserve(N);
305  Int_t numberNotFinite = 0;
306  for (Int_t i = 0; i < N; ++i) {
307  if (isfinite(dataPoints[i])) {
308  fDataPoints.push_back(dataPoints[i]);
309  } else {
310  ++numberNotFinite;
311  }
312  }
313  if (numberNotFinite != 0) {
314  cout << "Warning: " << numberNotFinite << " Inf/NaN values found and ignored" << endl;
315  }
316  }
317  }
318  }
319 }
320 
321 const char *QGHistogram::GetName() const
322 {
323  return TH1D::GetName();
324 }
325 
327 {
328  if (fPlotEditWindow) {
329  if (QGHistogramEditWindow *histogramEditWindow = dynamic_cast<QGHistogramEditWindow*>(fPlotEditWindow)) {
330  SetXVariable(histogramEditWindow->GetHistogramParametersFrame()->GetXVariable());
331  SetXUnits(histogramEditWindow->GetHistogramParametersFrame()->GetXUnits());
332  if (histogramEditWindow->GetHistogramParametersFrame()->IsXMinSet()) {
333  SetXMin(histogramEditWindow->GetHistogramParametersFrame()->GetXMin());
334  fAutoSetXMin = false;
335  } else {
336  fAutoSetXMin = true;
337  }
338  if (histogramEditWindow->GetHistogramParametersFrame()->IsXMaxSet()) {
339  SetXMax(histogramEditWindow->GetHistogramParametersFrame()->GetXMax());
340  fAutoSetXMax = false;
341  } else {
342  fAutoSetXMax = true;
343  }
344  if (histogramEditWindow->GetHistogramParametersFrame()->IsNumberOfBinsSet()) {
345  SetNumberOfBins(histogramEditWindow->GetHistogramParametersFrame()->GetNumberOfBins());
346  fAutoSetNumberOfBins = false;
347  } else {
348  fAutoSetNumberOfBins = true;
349  }
350  fIsBinWidthSet = histogramEditWindow->GetHistogramParametersFrame()->IsBinWidthSet();
351  if (fIsBinWidthSet) {
352  fBinWidth = histogramEditWindow->GetHistogramParametersFrame()->GetBinWidth();
353  }
354  else {
355  fBinWidth = 0;
356  }
357  SetSuperimpose(histogramEditWindow->GetHistogramParametersFrame()->IsSuperimposeSet());
358  } else {
359  cout << "QGHistogram::GetParametersFromEditWindow() Warning: dynamic_cast<QGHistogramEditWindow*> failed" << endl;
360  }
361  }
362 }
363 
364 Double_t QGHistogram::GetXMin() const
365 {
366  return GetXaxis()->GetXmin();
367 }
368 
369 Double_t QGHistogram::GetXMax() const
370 {
371  return GetXaxis()->GetXmax();
372 }
373 
375 {
376  return GetXaxis()->GetNbins();
377 }
378 
380 {
381  fStyleHistogram->Reset();
382  fStyleHistogram->SetBit(kCanDelete, kFALSE);
383  fStyleHistogram->SetStats(kFALSE);
384  fStyleHistogram->SetBins(5, 0, 5);
385  fStyleHistogram->SetBinContent(1, 0);
386  fStyleHistogram->SetBinContent(2, 2);
387  fStyleHistogram->SetBinContent(3, 3);
388  fStyleHistogram->SetBinContent(4, 1);
389  fStyleHistogram->SetBinContent(5, 0);
390  TAttFill::Copy(*fStyleHistogram);
391  TAttLine::Copy(*fStyleHistogram);
392  TAttMarker::Copy(*fStyleHistogram);
393 }
394 
395 void QGHistogram::SetName(const char *name)
396 {
397  if (name) {
398  string oldName = TH1D::GetName();
399  string newName = name;
400  if (newName != oldName) {
401  if (IsNameInUse(name)) {
402  TH1D::SetName(GeneratePlotName(name).c_str());
403  } else {
404  TH1D::SetName(name);
405  }
406  }
407  } else {
408  TH1D::SetName(GeneratePlotName("Histogram").c_str());
409  }
410  string styleHistogramName = string(GetName()) + "_StyleHistogram";
411  if (fStyleHistogram) {
412  fStyleHistogram->SetName(styleHistogramName.c_str());
413  }
414 }
415 
416 void QGHistogram::SetNumberOfBins(Int_t numberOfBins)
417 {
418  SetBins(numberOfBins, GetXMin(), GetXMax());
419 }
420 
421 void QGHistogram::SetProperty(const string& key, const string& value)
422 {
423  QGPlot::SetProperty(key, value);
424  TString valueTString(value);
425  if (key == MIN_KEY) {
426  if (valueTString.IsFloat()) {
427  SetXMin(valueTString.Atof());
428  fAutoSetXMin = false;
429  }
430  }
431  else if (key == MAX_KEY) {
432  if (valueTString.IsFloat()) {
433  SetXMax(valueTString.Atof());
434  fAutoSetXMax = false;
435  }
436  }
437  else if (key == NUMBER_OF_BINS_KEY) {
438  if (valueTString.IsFloat()) {
439  SetNumberOfBins(valueTString.Atoi());
440  fAutoSetNumberOfBins = false;
441  }
442  }
443  else if (key == BIN_WIDTH_KEY) {
444  if (valueTString.IsFloat()) {
445  SetBinWidth(valueTString.Atof());
446  fAutoSetNumberOfBins = true;
447  }
448  }
449  else if (key == FILL_COLOR_KEY) {
450  if (valueTString.IsFloat()) {
451  SetFillColor(valueTString.Atoi());
452  }
453  }
454  else if (key == FILL_STYLE_KEY) {
455  if (valueTString.IsFloat()) {
456  SetFillStyle(valueTString.Atoi());
457  }
458  }
459  else if (key == LINE_COLOR_KEY) {
460  if (valueTString.IsFloat()) {
461  SetLineColor(valueTString.Atoi());
462  }
463  }
464  else if (key == LINE_STYLE_KEY) {
465  if (valueTString.IsFloat()) {
466  SetLineStyle(valueTString.Atoi());
467  }
468  }
469  else if (key == LINE_WIDTH_KEY) {
470  if (valueTString.IsFloat()) {
471  SetLineWidth(valueTString.Atoi());
472  }
473  }
474  else if (key == MARKER_COLOR_KEY) {
475  if (valueTString.IsFloat()) {
476  SetMarkerColor(valueTString.Atoi());
477  }
478  }
479  else if (key == MARKER_SIZE_KEY) {
480  if (valueTString.IsFloat()) {
481  SetMarkerSize(valueTString.Atof());
482  }
483  }
484  else if (key == MARKER_STYLE_KEY) {
485  if (valueTString.IsFloat()) {
486  SetMarkerStyle(valueTString.Atoi());
487  }
488  }
489 }
490 
491 void QGHistogram::SetXMax(Double_t xMax)
492 {
493  SetBins(GetNumberOfBins(), GetXMin(), xMax);
494 }
495 
496 void QGHistogram::SetXMin(Double_t xMin)
497 {
498  SetBins(GetNumberOfBins(), xMin, GetXMax());
499 }
int N
Definition: CheckOF.C:24
ahisto2 SetLineColor(kRed)
ahisto2 Draw()
histo Fill(1.1)
#define BIN_WIDTH_KEY
#define FILL_COLOR_KEY
#define MAX_KEY
#define NUMBER_OF_BINS_KEY
#define MARKER_SIZE_KEY
#define MARKER_COLOR_KEY
#define MIN_KEY
#define LINE_STYLE_KEY
#define LINE_WIDTH_KEY
#define FILL_STYLE_KEY
#define LINE_COLOR_KEY
#define MARKER_STYLE_KEY
ClassImp(QObject)
TChain used in diana.
Definition: QChain.hh:23
void RemoveFromDrawnPlots(QGPlot *plot)
Remove pointer to a plot from the list of drawn plots.
void AddToDrawnPlots(QGPlot *plot)
Add pointer to a plot to the list of drawn plots.
QGPlotFrame * GetPlotFrame()
Get pointer to the plot frame.
QGFileHandler * GetFileHandler() const
Get pointer to file handler.
void ClearDrawnPlots()
Clears the collection of drawn plots.
std::list< QGPlot * > & GetDrawnPlots()
Get collection of drawn plots.
bool IsFileOpen()
Check whether a file is open.
QChain * GetQChain()
Get a pointer to the chian.
Class for histogram edit window.
Class for GUI histograms.
Definition: QGHistogram.hh:19
void SetNumberOfBins(Int_t numberOfBins)
Set number of bins.
Definition: QGHistogram.cc:416
virtual ~QGHistogram()
Destructor.
Definition: QGHistogram.cc:70
bool fAutoSetNumberOfBins
Flag to automatically set the number of bins.
Definition: QGHistogram.hh:113
void DrawStyleHistogram()
Draw a mini-histogram showing the style of this histogram.
Definition: QGHistogram.cc:248
void Erase()
Erase histogram.
Definition: QGHistogram.cc:271
Double_t GetXMax() const
Get x-max.
Definition: QGHistogram.cc:369
void AutoSetStyle()
Automatically set the histogram style.
Definition: QGHistogram.cc:136
Int_t GetNumberOfBins() const
Get number of bins.
Definition: QGHistogram.cc:374
Double_t GetXMin() const
Get x-min.
Definition: QGHistogram.cc:364
QGHistogram()
Default constructor.
Definition: QGHistogram.cc:43
void SetProperty(const std::string &key, const std::string &value)
Set property (used for opening a session)
Definition: QGHistogram.cc:421
std::string fDrawOption
Draw option.
Definition: QGHistogram.hh:128
bool fAutoSetXMin
Flag to automatically set the x-axis minimum.
Definition: QGHistogram.hh:119
void Duplicate()
Duplicate the histogram.
Definition: QGHistogram.cc:264
void Display()
Display histogram.
Definition: QGHistogram.cc:156
TH1D * fStyleHistogram
Mini-histogram to show style of this histogram.
Definition: QGHistogram.hh:140
void SetXMax(Double_t xMax)
Set x-max.
Definition: QGHistogram.cc:491
void MakeStylePlot()
Make style plot.
Definition: QGHistogram.cc:379
Double_t fBinWidth
Bin width.
Definition: QGHistogram.hh:122
const char * GetName() const
Get name of histogram.
Definition: QGHistogram.cc:321
bool fAutoSetXMax
Flag to automatically set the x-axis maximum.
Definition: QGHistogram.hh:116
std::vector< Double_t > fDataPoints
Collection of points underlying the histogram, useful for instant rebinning.
Definition: QGHistogram.hh:125
void DisplayEditWindow()
Display edit window for the histogram.
Definition: QGHistogram.cc:235
void SetName(const char *name=0)
Set name of histogram.
Definition: QGHistogram.cc:395
void Generate(QChain *chain=0)
Generate histogram.
Definition: QGHistogram.cc:282
void SetXMin(Double_t xMin)
Set x-min.
Definition: QGHistogram.cc:496
void AutoSetAxisParameters()
Automatically set axis parameters.
Definition: QGHistogram.cc:82
void GetParametersFromEditWindow()
Get parameters from edit window.
Definition: QGHistogram.cc:326
bool fIsBinWidthSet
Whether or not bin width is set.
Definition: QGHistogram.hh:134
void SetBinWidth(Double_t binWidth)
Set bin width.
Definition: QGHistogram.hh:94
static std::list< QGHistogram * > fHistograms
Collection of pointers to all QGHistograms.
Definition: QGHistogram.hh:131
QGPlotStyleFrame * GetPlotStyleFrame()
Get pointer to the plot style frame.
virtual void SetPlot(QGPlot *plot)=0
Set plot, pure virtual function must be overriden by derived classes.
TRootEmbeddedCanvas * GetEmbeddedCanvas()
Get pointer to canvas.
Definition: QGPlotFrame.hh:26
TRootEmbeddedCanvas * GetEmbeddedCanvas()
Get pointer to embedded canvas.
Base class for GUI plots including histograms, scatter plots, pulses, and graphical cuts.
Definition: QGPlot.hh:21
virtual void SetSuperimpose(bool flag=false)
Set whether the plot should be superimposed.
Definition: QGPlot.hh:132
virtual std::string GeneratePlotName(const std::string &baseName) const
Generate a name for the plot.
Definition: QGPlot.cc:98
virtual bool IsNameInUse(const std::string &name) const
Check whether string is the name of any plot.
Definition: QGPlot.cc:168
std::string fXVariable
X-axis variable.
Definition: QGPlot.hh:172
QGPlotEditWindow * fPlotEditWindow
Pointer to plot edit window.
Definition: QGPlot.hh:163
virtual const std::string & GetXUnits() const
Get x-axis units.
Definition: QGPlot.hh:87
virtual void SetProperty(const std::string &key, const std::string &value)
Set property (used for opening a session)
Definition: QGPlot.cc:245
std::string fCutsString
Cuts in a single string.
Definition: QGPlot.hh:157
virtual void SetXVariable(const std::string &x)
Set X-axis variable.
Definition: QGPlot.cc:270
virtual const std::string & GetXVariable() const
Get x-axis variable.
Definition: QGPlot.hh:90
bool fSuperimpose
Indicates whether plot should be superimposed on existing plot.
Definition: QGPlot.hh:169
QGCanvasWindow * fCanvasWindow
Canvas window to which plot is associated.
Definition: QGPlot.hh:151
virtual void SetXUnits(const std::string &units)
Set X-axis units.
Definition: QGPlot.hh:138