StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMultiH2F.cxx
1 // //
3 // StMultiH2F allows multiple similar TH2F histograms to be //
4 // easily plotted on one graph //
5 // //
7 
8 #ifdef __HP_aCC
9 #include <Stiostream.h>
10 #else
11 #include "Stiostream.h"
12 #endif
13 #include "StMultiH2F.h"
14 #include "TString.h"
15 #include "TLegend.h"
16 #include "TPad.h"
17 #include "TDirectory.h"
18 
19 ClassImp(StMultiH2F)
20 
21 StMultiH2F::StMultiH2F() : subHists(0) {}
22 
23 StMultiH2F::StMultiH2F(const char *name,const char *title,Int_t nbinsx,
24  Axis_t xlow,Axis_t xup,Int_t nbinsy,Axis_t ylow,
25  Axis_t yup,Int_t nbinsz) :
26  TH3F(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,-0.5,-0.5+nbinsz),
27  subHists(0) {}
28 
29 StMultiH2F::~StMultiH2F() {
30  if (subHists) {
31  int zbins = TMath::Min(GetNbinsZ(),StMultiH2FMaxBins);
32  for (int zbin=0; zbin<zbins; zbin++) delete subHists[zbin];
33  }
34 }
35 
36 void StMultiH2F::Draw(Option_t *option) {
37  // Probably only the "box" and "cont" options are reasonable here
38 
39  int x0 = fXaxis.GetFirst();
40  int x1 = fXaxis.GetLast();
41  int y0 = fYaxis.GetFirst();
42  int y1 = fYaxis.GetLast();
43  fXaxis.SetRange();
44  fYaxis.SetRange();
45  int zbins = TMath::Min(GetNbinsZ(),StMultiH2FMaxBins);
46 
47  // dummy histogram pointer(s)
48  if (!subHists) { subHists = new TH2D*[zbins]; memset(subHists,0,zbins*sizeof(TH2D*)); }
49 
50  if (zbins == 1) {
51  delete subHists[0];
52  subHists[0] = XYProjection(GetName());
53  subHists[0]->SetStats((!TestBit(kNoStats)));
54  TAxis* taxisX = subHists[0]->GetXaxis();
55  TAxis* taxisY = subHists[0]->GetYaxis();
56  fXaxis.Copy(*taxisX);
57  fYaxis.Copy(*taxisY);
58  taxisX->SetRange(x0,x1);
59  taxisY->SetRange(y0,y1);
60  fXaxis.SetRange(x0,x1);
61  fYaxis.SetRange(y0,y1);
62  subHists[0]->Draw(option);
63  return;
64  }
65 
66  // overlay the z bins of the 3d histogram into a 2d histogram
67  // using different box colors
68 
69  // make a legend
70  TLegend *legend = new TLegend(0.80,0.84,0.98,0.98,"Legend","NDC");
71  legend->SetFillColor(0);
72  legend->SetFillStyle(0);
73  legend->SetMargin(0.25);
74 
75  int zbin;
76  double maxval = -999999.;
77  int maxbin = -1;
78 
79  TString n0;
80  for (zbin=0; zbin<zbins; zbin++) {
81  if ((zbin >= 10) || (names[zbin].IsNull())) n0 = GetName();
82  else n0 = names[zbin];
83  int slice = zbin+1;
84  delete subHists[zbin];
85  subHists[zbin] = XYProjection(n0.Data(),slice);
86  subHists[zbin]->SetLineColor(60+40*(zbin/(zbins-1)));
87  subHists[zbin]->SetStats(kFALSE);
88  TAxis* taxisX = subHists[zbin]->GetXaxis();
89  TAxis* taxisY = subHists[zbin]->GetYaxis();
90  fXaxis.Copy(*taxisX);
91  fYaxis.Copy(*taxisY);
92  taxisX->SetRange(x0,x1);
93  taxisY->SetRange(y0,y1);
94 
95  double binmax = subHists[zbin]->GetMaximum();
96  if (binmax > maxval) {
97  maxval = binmax;
98  maxbin = zbin;
99  }
100  legend->AddEntry(subHists[zbin],n0.Data(),"l");
101  }
102 
103  subHists[maxbin]->SetTitle(GetTitle());
104  subHists[maxbin]->Draw(option);
105  TString sameoption = option; sameoption += "same";
106  for (zbin=0; zbin<zbins; zbin++) {
107  if (zbin != maxbin) subHists[zbin]->Draw(sameoption.Data());
108  }
109 
110  // Draw statistics for full set if stats are turned on
111  if (!TestBit(kNoStats)) {
112  delete subHists[0];
113  subHists[0] = XYProjection(GetName());
114  subHists[0]->Reset();
115  subHists[0]->SetEntries(GetEntries());
116  subHists[0]->SetStats(kTRUE);
117  subHists[0]->Draw(sameoption.Data());
118  legend->SetX1(0.59);
119  legend->SetX2(0.77);
120  }
121 
122  legend->Draw();
123 
124  fXaxis.SetRange(x0,x1);
125  fYaxis.SetRange(y0,y1);
126 }
127 
128 TH2D* StMultiH2F::XYProjection(const char* name, Int_t zbin) {
129  static char buf[256];
130  if (zbin<0) sprintf(buf,"%s.",name);
131  else sprintf(buf,"%s_%d_%s",GetName(),zbin,name);
132 
133  TList* tgList = gDirectory->GetList();
134  TH2D* temp = (TH2D*) tgList->FindObject(buf);
135  if (temp) tgList->Remove(temp);
136 
137  if (zbin<0) fZaxis.SetRange();
138  else fZaxis.SetRange(zbin,zbin);
139  temp = (TH2D*) Project3D("yx");
140  temp->SetName(buf);
141  TAttLine::Copy(*temp);
142  TAttFill::Copy(*temp);
143  TAttMarker::Copy(*temp);
144  temp->GetXaxis()->SetRange(fXaxis.GetFirst(),fXaxis.GetLast());
145  temp->GetYaxis()->SetRange(fYaxis.GetFirst(),fYaxis.GetLast());
146  return temp; // up to the user of this function delete
147 }
148 
149 void StMultiH2F::SavePrimitive(ostream& out, Option_t* option) {
150  // Save primitive as a C++ statement(s) on output stream out
151 
152  bool nonEqiX = kFALSE;
153  bool nonEqiY = kFALSE;
154  int i;
155 
156  // Check if the histogram has equidistant X bins or not. If not, we
157  // create an array holding the bins.
158  if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
159  nonEqiX = kTRUE;
160  out << " Double_t xAxis[" << GetXaxis()->GetXbins()->fN
161  << "] = {";
162  for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
163  if (i != 0) out << ", ";
164  out << GetXaxis()->GetXbins()->fArray[i];
165  }
166  out << "}; " << endl;
167  }
168 
169  // Check if the histogram has equidistant Y bins or not. If not, we
170  // create an array holding the bins.
171  if (GetYaxis()->GetXbins()->fN && GetYaxis()->GetXbins()->fArray) {
172  nonEqiY = kTRUE;
173  out << " Double_t yAxis[" << GetYaxis()->GetXbins()->fN
174  << "] = {";
175  for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
176  if (i != 0) out << ", ";
177  out << GetYaxis()->GetXbins()->fArray[i];
178  }
179  out << "}; " << endl;
180  }
181 
182  char quote = '"';
183  out <<" "<<endl;
184  out <<" TH1 *" << GetName() << " = new " << ClassName() << "("
185  << quote << GetName() << quote << "," << quote << GetTitle() << quote
186  << "," << GetXaxis()->GetNbins();
187  if (nonEqiX)
188  out << ", xAxis";
189  else
190  out << "," << GetXaxis()->GetXmin()
191  << "," << GetXaxis()->GetXmax();
192  if (nonEqiY)
193  out << ", yAxis";
194  else
195  out << "," << GetYaxis()->GetXmin()
196  << "," << GetYaxis()->GetXmax();
197  out << "," << GetZaxis()->GetNbins() << ");" << endl;
198 
199  // save bin contents
200  int bin;
201  for (bin=0;bin<fNcells;bin++) {
202  double bc = GetBinContent(bin);
203  if (bc) {
204  out<<" "<<GetName()<<"->SetBinContent("<<bin<<","<<bc<<");"<<endl;
205  }
206  }
207 
208  // save bin errors
209  if (fSumw2.fN) {
210  for (bin=0;bin<fNcells;bin++) {
211  double be = GetBinError(bin);
212  if (be) {
213  out <<" "<<GetName()<<"->SetBinError("<<bin<<","<<be<<");"<<endl;
214  }
215  }
216  }
217 
218  for (bin=0;bin<GetZaxis()->GetNbins();bin++) {
219  if (!(names[bin].IsNull()))
220  out <<" "<<GetName()<< "->Rebin(" << bin << ","
221  << quote << names[bin] << quote << ");" << endl;
222  }
223 
224  TH1::SavePrimitiveHelp(out, option);
225 }
226 
227 // $Id: StMultiH2F.cxx,v 1.8 2016/05/27 18:02:41 genevb Exp $
228 // $Log: StMultiH2F.cxx,v $
229 // Revision 1.8 2016/05/27 18:02:41 genevb
230 // Garbage collection (Coverity), remove unnecessary ROOT types
231 //
232 // Revision 1.7 2015/07/20 18:27:47 genevb
233 // fix minor bug with SavePrimitive
234 //
235 // Revision 1.6 2013/11/21 22:22:48 genevb
236 // Protect against array out-of-bounds, use inherited axis handles
237 //
238 // Revision 1.5 2008/07/10 21:26:59 genevb
239 // Allow SavePrimitive of fully drawn TPad to work properly
240 //
241 // Revision 1.4 2008/07/09 20:52:38 genevb
242 // Implement SavePrimitive functions
243 //
244 // Revision 1.3 2007/04/24 17:45:33 genevb
245 // Patched for problems with limited axis ranges
246 //
247 // Revision 1.2 2007/04/12 22:39:13 genevb
248 // Remove drawing of underflows
249 //
250 // Revision 1.1 2007/03/13 16:22:31 genevb
251 // Introduce StMultiH2F class
252 //
253 //