source: trunk/MagicSoft/Mars/mhbase/MH3.cc@ 8696

Last change on this file since 8696 was 8695, checked in by tbretz, 17 years ago
*** empty log message ***
File size: 21.8 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 2002 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2007
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MH3
28//
29// With this histogram you can fill a histogram with up to three
30// variables from Mars parameter containers in an eventloop.
31//
32// In the constructor you can give up to three variables which should be
33// filled in the histogram. Dependend on the number of given variables
34// (data members) a TH1D, TH2D or TH3D is created.
35// Specify the data mamber like the following:
36// "MHillas.fLength"
37// Where MHillas is the name of the parameter container in the parameter
38// list and fLength is the name of the data member which should be filled
39// in the histogram. Assuming that your MHillas container has a different
40// name (MyHillas) the name to give would be:
41// "MyHillas.fLength"
42//
43// If you want to use a different unit for histogramming use SetScaleX,
44// SetScaleY and SetScaleZ.
45//
46//
47// Binning name
48// ============
49//
50// The axis binning is retrieved from the parameter list, too. Create a
51// MBinning with the name "Binning" plus the name of your MH3 container
52// plus the axis name ("X", "Y" or "Z") and add it to the parameter list.
53//
54// If the binning should have a different name than the histogram name
55// the binning name can be added to the name, eg.:
56// SetName("MyHistName;MyXBins;MyYBins")
57// Instead of BinningMyHistName[XYZ] the parameter list will be searched
58// for BinningMyXBinning, BinningMyYBins and BinningMyHistNameZ
59//
60//
61// Axis titles
62// ===========
63//
64// 1) If no other title is given the rule for this axis is used.
65// 2) If the MBinning used for this axis has a non-default Title
66// (MBinning::HasTitle) this title is used for the corresponding axis
67// 3) If the MH3 has a non-default title (MH3::SetTitle called)
68// this title is set as the histogram title. It can be used to overwrite
69// the axis titles. For more information see TH1::SetTitle, eg.
70// SetTitle("MyHist;x[mm];y[cm];Counts");
71//
72//
73// For example:
74// MH3 myhist("MHillas.fLength");
75// myhist.SetName("MyHist");
76// myhist.SetScaleX(geomcam.GetConvMm2Deg()); //convert length to degree
77// MBinning bins("BinningMyHistX");
78// bins.SetEdges(10, 0, 150);
79// plist.AddToList(&myhist);
80// plist.AddToList(&bins);
81//
82//
83// Class Version 2:
84// ----------------
85// - MDataChain *fData[3]; // Object from which the data is filled
86// + MData *fData[3]; // Object from which the data is filled
87//
88// Class Version 3:
89// ----------------
90// - Byte_t fStyleBits
91//
92/////////////////////////////////////////////////////////////////////////////
93#include "MH3.h"
94
95#include <ctype.h> // tolower
96#include <fstream>
97
98//#include <TPad.h>
99#include <TStyle.h>
100#include <TCanvas.h>
101
102#include <TH2.h>
103#include <TH3.h>
104#include <TProfile.h>
105#include <TProfile2D.h>
106
107#include "MLog.h"
108#include "MLogManip.h"
109
110#include "MParList.h"
111#include "MBinning.h"
112#include "MDataPhrase.h"
113
114ClassImp(MH3);
115
116using namespace std;
117
118const TString MH3::gsDefName = "MH3";
119const TString MH3::gsDefTitle = "Container for a n-D Mars Histogram";
120
121// --------------------------------------------------------------------------
122//
123// Default constructor.
124//
125MH3::MH3(const unsigned int dim)
126 : fDimension(dim>3?3:dim), fHist(NULL), fStyleBits(0)
127{
128 switch (fDimension)
129 {
130 case 1:
131 fHist = new TH1D;
132 fHist->SetYTitle("Counts");
133 break;
134 case 2:
135 fHist = new TH2D;
136 fHist->SetZTitle("Counts");
137 break;
138 case 3:
139 fHist = new TH3D;
140 break;
141 }
142
143 fData[0] = NULL;
144 fData[1] = NULL;
145 fData[2] = NULL;
146
147 fName = gsDefName;
148 fTitle = gsDefTitle;
149
150 if (fHist)
151 {
152 fHist->SetDirectory(NULL);
153 fHist->UseCurrentStyle();
154 }
155
156 fScale[0] = 1;
157 fScale[1] = 1;
158 fScale[2] = 1;
159}
160
161// --------------------------------------------------------------------------
162//
163// Creates an TH1D. memberx is filled into the X-bins. For a more detailed
164// description see the class description above.
165//
166MH3::MH3(const char *memberx)
167 : fDimension(1), fStyleBits(0)
168{
169 fHist = new TH1D;
170
171 fData[0] = new MDataPhrase(memberx);
172 fData[1] = NULL;
173 fData[2] = NULL;
174
175 fName = gsDefName;
176 fTitle = gsDefTitle;
177
178 fHist->UseCurrentStyle();
179 fHist->SetDirectory(NULL);
180 fHist->SetYTitle("Counts");
181
182 fScale[0] = 1;
183 fScale[1] = 1;
184 fScale[2] = 1;
185}
186
187MH3::MH3(const TH1 &h1)
188 : fDimension(1), fStyleBits(0)
189{
190 if (h1.InheritsFrom(TH3::Class()))
191 fDimension = 3;
192 if (h1.InheritsFrom(TH2::Class()))
193 fDimension = 2;
194
195 fData[0] = NULL;
196 fData[1] = NULL;
197 fData[2] = NULL;
198
199 switch (fDimension)
200 {
201 case 3:
202 fData[2] = new MDataPhrase(h1.GetZaxis()->GetTitle());
203 case 2:
204 fData[1] = new MDataPhrase(h1.GetYaxis()->GetTitle());
205 case 1:
206 fData[0] = new MDataPhrase(h1.GetXaxis()->GetTitle());
207 }
208
209 fName = gsDefName;
210 fTitle = gsDefTitle;
211
212 fHist = (TH1*)h1.Clone();
213 fHist->SetDirectory(NULL);
214
215 fScale[0] = 1;
216 fScale[1] = 1;
217 fScale[2] = 1;
218}
219
220// --------------------------------------------------------------------------
221//
222// Creates an TH2D. memberx is filled into the X-bins. membery is filled
223// into the Y-bins. For a more detailed description see the class
224// description above.
225//
226MH3::MH3(const char *memberx, const char *membery)
227 : fDimension(2), fStyleBits(0)
228{
229 fHist = new TH2D;
230
231 fData[0] = new MDataPhrase(memberx);
232 fData[1] = new MDataPhrase(membery);
233 fData[2] = NULL;
234
235 fName = gsDefName;
236 fTitle = gsDefTitle;
237
238 fHist->UseCurrentStyle();
239 fHist->SetDirectory(NULL);
240 fHist->SetZTitle("Counts");
241
242 fScale[0] = 1;
243 fScale[1] = 1;
244 fScale[2] = 1;
245}
246
247// --------------------------------------------------------------------------
248//
249// Creates an TH3D. memberx is filled into the X-bins. membery is filled
250// into the Y-bins. membery is filled into the Z-bins. For a more detailed
251// description see the class description above.
252//
253MH3::MH3(const char *memberx, const char *membery, const char *memberz)
254 : fDimension(3), fStyleBits(0)
255{
256 fHist = new TH3D;
257
258 fData[0] = new MDataPhrase(memberx);
259 fData[1] = new MDataPhrase(membery);
260 fData[2] = new MDataPhrase(memberz);
261
262 fName = gsDefName;
263 fTitle = gsDefTitle;
264
265 fHist->UseCurrentStyle();
266 fHist->SetDirectory(NULL);
267
268 fScale[0] = 1;
269 fScale[1] = 1;
270 fScale[2] = 1;
271}
272
273// --------------------------------------------------------------------------
274//
275// Deletes the histogram
276//
277MH3::~MH3()
278{
279 delete fHist;
280
281 for (int i=0; i<3; i++)
282 if (fData[i])
283 delete fData[i];
284}
285
286// --------------------------------------------------------------------------
287//
288// Return the data members used by the data chain to be used in
289// MTask::AddBranchToList
290//
291TString MH3::GetDataMember() const
292{
293 TString str=fData[0]->GetDataMember();
294 if (fData[1])
295 {
296 str += ";";
297 str += fData[1]->GetDataMember();
298 }
299 if (fData[2])
300 {
301 str += ";";
302 str += fData[2]->GetDataMember();
303 }
304 return str;
305}
306
307// --------------------------------------------------------------------------
308//
309// Setup the Binning for the histograms automatically if the correct
310// instances of MBinning are found in the parameter list
311// For a more detailed description see class description above.
312//
313Bool_t MH3::SetupFill(const MParList *plist)
314{
315 // reset histogram (necessary if the same eventloop is run more than once)
316 fHist->Reset();
317
318 // Tokenize name into name and binnings names
319 TObjArray *tok = fName.Tokenize(";");
320
321 const TString name = (*tok)[0] ? (*tok)[0]->GetName() : fName.Data();
322
323 TString bx = (*tok)[1] ? (*tok)[1]->GetName() : Form("%sX", name.Data());
324 TString by = (*tok)[2] ? (*tok)[2]->GetName() : Form("%sY", name.Data());
325 TString bz = (*tok)[3] ? (*tok)[3]->GetName() : Form("%sZ", name.Data());
326
327 bx.Prepend("Binning");
328 by.Prepend("Binning");
329 bz.Prepend("Binning");
330
331 delete tok;
332
333
334 MBinning *binsx = NULL;
335 MBinning *binsy = NULL;
336 MBinning *binsz = NULL;
337
338 switch (fDimension)
339 {
340 case 3:
341 binsz = (MBinning*)plist->FindObject(bz, "MBinning");
342 if (!binsz)
343 {
344 *fLog << err << dbginf << "MBinning '" << bz << "' not found... aborting." << endl;
345 return kFALSE;
346 }
347 if (fData[2] && !fData[2]->PreProcess(plist))
348 return kFALSE;
349 if (fData[2])
350 fHist->SetZTitle(fData[2]->GetTitle());
351 if (binsz->HasTitle())
352 fHist->SetZTitle(binsz->GetTitle());
353 if (binsz->IsLogarithmic())
354 fHist->SetBit(kIsLogz);
355 case 2:
356 binsy = (MBinning*)plist->FindObject(by, "MBinning");
357 if (!binsy)
358 {
359 *fLog << err << dbginf << "MBinning '" << by << "' not found... aborting." << endl;
360 return kFALSE;
361 }
362 if (fData[1] && !fData[1]->PreProcess(plist))
363 return kFALSE;
364 if (fData[1])
365 fHist->SetYTitle(fData[1]->GetTitle());
366 if (binsy->HasTitle())
367 fHist->SetYTitle(binsy->GetTitle());
368 if (binsy->IsLogarithmic())
369 fHist->SetBit(kIsLogy);
370 case 1:
371 binsx = (MBinning*)plist->FindObject(bx, "MBinning");
372 if (!binsx)
373 {
374 if (fDimension==1)
375 binsx = (MBinning*)plist->FindObject("Binning"+fName, "MBinning");
376
377 if (!binsx)
378 {
379 *fLog << err << dbginf << "Neither '" << bx << "' nor '" << binsx << fName << "' found... aborting." << endl;
380 return kFALSE;
381 }
382 }
383 if (fData[0] && !fData[0]->PreProcess(plist))
384 return kFALSE;
385 if (fData[0]!=NULL)
386 fHist->SetXTitle(fData[0]->GetTitle());
387 if (binsx->HasTitle())
388 fHist->SetXTitle(binsx->GetTitle());
389 if (binsx->IsLogarithmic())
390 fHist->SetBit(kIsLogx);
391 }
392
393 TString title("Histogram for ");
394 title += name;
395 title += Form(" (%dD)", fDimension);
396
397 fHist->SetName(name);
398 fHist->SetTitle(fTitle==gsDefTitle ? title : fTitle);
399 fHist->SetDirectory(0);
400
401 switch (fDimension)
402 {
403 case 1:
404 SetBinning(fHist, binsx);
405 return kTRUE;
406 case 2:
407 SetBinning((TH2*)fHist, binsx, binsy);
408 return kTRUE;
409 case 3:
410 SetBinning((TH3*)fHist, binsx, binsy, binsz);
411 return kTRUE;
412 }
413
414 *fLog << err << "ERROR - MH3 has " << fDimension << " dimensions!" << endl;
415 return kFALSE;
416}
417
418// --------------------------------------------------------------------------
419//
420// Set the name of the histogram ant the MH3 container
421//
422void MH3::SetName(const char *name)
423{
424 if (fHist)
425 {
426 if (gPad)
427 {
428 const TString pfx(Form("%sProfX", fHist->GetName()));
429 const TString pfy(Form("%sProfY", fHist->GetName()));
430
431 TProfile *p = 0;
432 if ((p=dynamic_cast<TProfile*>(gPad->FindObject(pfx))))
433 p->SetName(Form("%sProfX", name));
434 if ((p=dynamic_cast<TProfile*>(gPad->FindObject(pfy))))
435 p->SetName(Form("%sProfY", name));
436 }
437
438 fHist->SetName(name);
439 fHist->SetDirectory(0);
440
441 }
442 MParContainer::SetName(name);
443}
444
445// --------------------------------------------------------------------------
446//
447// Set the title of the histogram ant the MH3 container
448//
449void MH3::SetTitle(const char *title)
450{
451 if (fHist)
452 fHist->SetTitle(title);
453 MParContainer::SetTitle(title);
454}
455
456// --------------------------------------------------------------------------
457//
458// Fills the one, two or three data members into our histogram
459//
460Bool_t MH3::Fill(const MParContainer *par, const Stat_t w)
461{
462 Double_t x=0;
463 Double_t y=0;
464 Double_t z=0;
465
466 switch (fDimension)
467 {
468 case 3:
469 z = fData[2]->GetValue()*fScale[2];
470 case 2:
471 y = fData[1]->GetValue()*fScale[1];
472 case 1:
473 x = fData[0]->GetValue()*fScale[0];
474 }
475
476 switch (fDimension)
477 {
478 case 3:
479 ((TH3*)fHist)->Fill(x, y, z, w);
480 return kTRUE;
481 case 2:
482 ((TH2*)fHist)->Fill(x, y, w);
483 return kTRUE;
484 case 1:
485 fHist->Fill(x, w);
486 return kTRUE;
487 }
488
489 return kFALSE;
490}
491
492// --------------------------------------------------------------------------
493//
494// If an auto range bit is set the histogram range of the corresponding
495// axis is set to show only the non-empty bins (with a single empty bin
496// on both sides)
497//
498Bool_t MH3::Finalize()
499{
500 Bool_t autorangex=TESTBIT(fStyleBits, 0);
501 Bool_t autorangey=TESTBIT(fStyleBits, 1);
502 //Bool_t autorangez=TESTBIT(fStyleBits, 2);
503
504 Int_t lo, hi;
505
506 if (autorangex)
507 {
508 GetRangeX(*fHist, lo, hi);
509 cout << "====> " << GetName() << " " << fHist->GetName() << ": " << lo << " " << hi <<" " << fHist->GetNbinsX() << endl;
510 fHist->GetXaxis()->SetRange(lo-2, hi+1);
511 }
512 if (autorangey)
513 {
514 GetRangeY(*fHist, lo, hi);
515 fHist->GetYaxis()->SetRange(lo-2, hi+1);
516 }
517 /*
518 if (autorangez)
519 {
520 GetRangeZ(*fHist, lo, hi);
521 fHist->GetZaxis()->SetRange(lo-2, hi+1);
522 }
523 */
524 return kTRUE;
525}
526
527// --------------------------------------------------------------------------
528//
529// Setup a inversed deep blue sea palette for the fCenter histogram.
530//
531void MH3::SetColors() const
532{
533 // FIXME: This must be redone each time the canvas is repainted....
534 gStyle->SetPalette(51, NULL);
535 Int_t c[50];
536 for (int i=0; i<50; i++)
537 c[49-i] = gStyle->GetColorPalette(i);
538 gStyle->SetPalette(50, c);
539}
540
541void MH3::Paint(Option_t *o)
542{
543 TProfile *p=0;
544
545 const TString pfx(Form("%sProfX", fHist->GetName()));
546 if ((p=dynamic_cast<TProfile*>(gPad->FindObject(pfx))))
547 {
548 Int_t col = p->GetLineColor();
549 p = ((TH2*)fHist)->ProfileX(pfx, -1, -1, "s");
550 p->SetLineColor(col);
551 }
552
553 const TString pfy(Form("%sProfY", fHist->GetName()));
554 if ((p=dynamic_cast<TProfile*>(gPad->FindObject(pfy))))
555 {
556 Int_t col = p->GetLineColor();
557 p = ((TH2*)fHist)->ProfileY(pfy, -1, -1, "s");
558 p->SetLineColor(col);
559 }
560/*
561 if (fHist->TestBit(kIsLogx) && fHist->GetEntries()>0) gPad->SetLogx();
562 if (fHist->TestBit(kIsLogy) && fHist->GetEntries()>0) gPad->SetLogy();
563 if (fHist->TestBit(kIsLogz) && fHist->GetEntries()>0) gPad->SetLogz();
564 */
565}
566
567// --------------------------------------------------------------------------
568//
569// Creates a new canvas and draws the histogram into it.
570//
571// Possible options are:
572// PROFX: Draw a x-profile into the histogram (for 2D histograms only)
573// PROFY: Draw a y-profile into the histogram (for 2D histograms only)
574// ONLY: Draw the profile histogram only (for 2D histograms only)
575// BLUE: Draw the profile in blue color instead of the histograms line color
576//
577// If the kIsLog?-Bit is set the axis is displayed lkogarithmically.
578// eg this is set when applying a logarithmic MBinning
579//
580// Be careful: The histogram belongs to this object and won't get deleted
581// together with the canvas.
582//
583void MH3::Draw(Option_t *opt)
584{
585 TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(fHist);
586 pad->SetBorderMode(0);
587 pad->SetGridx();
588 pad->SetGridy();
589
590 if (fHist->TestBit(kIsLogx)) pad->SetLogx();
591 if (fHist->TestBit(kIsLogy)) pad->SetLogy();
592 if (fHist->TestBit(kIsLogz)) pad->SetLogz();
593
594 fHist->SetFillStyle(4000);
595
596 TString str(opt);
597 str.ToLower();
598
599 const Bool_t only = str.Contains("only") && fDimension==2;
600 const Bool_t same = str.Contains("same") && fDimension<3;
601 const Bool_t blue = str.Contains("blue") && fDimension==2;
602 const Bool_t profx = str.Contains("profx") && fDimension==2;
603 const Bool_t profy = str.Contains("profy") && fDimension==2;
604
605 str.ReplaceAll("only", "");
606 str.ReplaceAll("blue", "");
607 str.ReplaceAll("profx", "");
608 str.ReplaceAll("profy", "");
609 str.ReplaceAll(" ", "");
610
611 if (same && fDimension==1)
612 {
613 fHist->SetLineColor(kBlue);
614 fHist->SetMarkerColor(kBlue);
615 }
616
617 // FIXME: We may have to remove all our own options from str!
618 if (!only)
619 fHist->Draw(str);
620
621 AppendPad();
622
623 TProfile *p=0;
624 if (profx)
625 {
626 const TString pfx(Form("%sProfX", fHist->GetName()));
627
628 if (same && (p=dynamic_cast<TProfile*>(gPad->FindObject(pfx))))
629 *fLog << warn << "TProfile " << pfx << " already in pad." << endl;
630
631 p = ((TH2*)fHist)->ProfileX(pfx, -1, -1, "s");
632 p->UseCurrentStyle();
633 p->SetLineColor(blue ? kBlue : fHist->GetLineColor());
634 p->SetBit(kCanDelete);
635 p->SetDirectory(NULL);
636 p->SetXTitle(fHist->GetXaxis()->GetTitle());
637 p->SetYTitle(fHist->GetYaxis()->GetTitle());
638 p->Draw(only&&!same?"":"same");
639 }
640 if (profy)
641 {
642 const TString pfy(Form("%sProfY", fHist->GetName()));
643
644 if (same && (p=dynamic_cast<TProfile*>(gPad->FindObject(pfy))))
645 *fLog << warn << "TProfile " << pfy << " already in pad." << endl;
646
647 p = ((TH2*)fHist)->ProfileY(pfy, -1, -1, "s");
648 p->UseCurrentStyle();
649 p->SetLineColor(blue ? kBlue : fHist->GetLineColor());
650 p->SetBit(kCanDelete);
651 p->SetDirectory(NULL);
652 p->SetYTitle(fHist->GetXaxis()->GetTitle());
653 p->SetXTitle(fHist->GetYaxis()->GetTitle());
654 p->Draw(only&&!same?"":"same");
655 }
656
657 //AppendPad("log");
658}
659
660// --------------------------------------------------------------------------
661//
662// Implementation of SavePrimitive. Used to write the call to a constructor
663// to a macro. In the original root implementation it is used to write
664// gui elements to a macro-file.
665//
666void MH3::StreamPrimitive(ostream &out) const
667{
668 TString name = GetUniqueName();
669
670 out << " MH3 " << name << "(\"";
671 out << fData[0]->GetRule() << "\"";
672 if (fDimension>1)
673 out << ", \"" << fData[1]->GetRule() << "\"";
674 if (fDimension>2)
675 out << ", \"" << fData[2]->GetRule() << "\"";
676
677 out << ");" << endl;
678
679 if (fName!=gsDefName)
680 out << " " << name << ".SetName(\"" << fName << "\");" << endl;
681
682 if (fTitle!=gsDefTitle)
683 out << " " << name << ".SetTitle(\"" << fTitle << "\");" << endl;
684
685 switch (fDimension)
686 {
687 case 3:
688 if (fScale[2]!=1)
689 out << " " << name << ".SetScaleZ(" << fScale[2] << ");" << endl;
690 case 2:
691 if (fScale[1]!=1)
692 out << " " << name << ".SetScaleY(" << fScale[1] << ");" << endl;
693 case 1:
694 if (fScale[0]!=1)
695 out << " " << name << ".SetScaleX(" << fScale[0] << ");" << endl;
696 }
697}
698
699// --------------------------------------------------------------------------
700//
701// Used to rebuild a MH3 object of the same type (data members,
702// dimension, ...)
703//
704MParContainer *MH3::New() const
705{
706 MH3 *h = NULL;
707
708 if (fData[0] == NULL)
709 h=new MH3(fDimension);
710 else
711 switch (fDimension)
712 {
713 case 1:
714 h=new MH3(fData[0]->GetRule());
715 break;
716 case 2:
717 h=new MH3(fData[0]->GetRule(), fData[1]->GetRule());
718 break;
719 case 3:
720 h=new MH3(fData[0]->GetRule(), fData[1]->GetRule(), fData[2]->GetRule());
721 break;
722 }
723 switch (fDimension)
724 {
725 case 3:
726 h->SetScaleZ(fScale[2]);
727 case 2:
728 h->SetScaleY(fScale[1]);
729 case 1:
730 h->SetScaleX(fScale[0]);
731 }
732 return h;
733}
734
735TString MH3::GetRule(const Char_t axis) const
736{
737 switch (tolower(axis))
738 {
739 case 'x':
740 return fData[0] ? fData[0]->GetRule() : TString("");
741 case 'y':
742 return fData[1] ? fData[1]->GetRule() : TString("");
743 case 'z':
744 return fData[2] ? fData[2]->GetRule() : TString("");
745 default:
746 return "<n/a>";
747 }
748}
749
750// --------------------------------------------------------------------------
751//
752// Returns the total number of bins in a histogram (excluding under- and
753// overflow bins)
754//
755Int_t MH3::GetNbins() const
756{
757 Int_t num = 1;
758
759 switch (fDimension)
760 {
761 case 3:
762 num *= fHist->GetNbinsZ()+2;
763 case 2:
764 num *= fHist->GetNbinsY()+2;
765 case 1:
766 num *= fHist->GetNbinsX()+2;
767 }
768
769 return num;
770}
771
772// --------------------------------------------------------------------------
773//
774// Returns the total number of bins in a histogram (excluding under- and
775// overflow bins) Return -1 if bin is underflow or overflow
776//
777Int_t MH3::FindFixBin(Double_t x, Double_t y, Double_t z) const
778{
779 const TAxis &axex = *fHist->GetXaxis();
780 const TAxis &axey = *fHist->GetYaxis();
781 const TAxis &axez = *fHist->GetZaxis();
782
783 Int_t binz = 0;
784 Int_t biny = 0;
785 Int_t binx = 0;
786
787 switch (fDimension)
788 {
789 case 3:
790 binz = axez.FindFixBin(z);
791 if (binz>axez.GetLast() || binz<axez.GetFirst())
792 return -1;
793 case 2:
794 biny = axey.FindFixBin(y);
795 if (biny>axey.GetLast() || biny<axey.GetFirst())
796 return -1;
797 case 1:
798 binx = axex.FindFixBin(x);
799 if (binx<axex.GetFirst() || binx>axex.GetLast())
800 return -1;
801 }
802
803 const Int_t nx = fHist->GetNbinsX()+2;
804 const Int_t ny = fHist->GetNbinsY()+2;
805
806 return binx + nx*(biny +ny*binz);
807}
Note: See TracBrowser for help on using the repository browser.