source: trunk/Mars/mhbase/MHn.cc@ 9944

Last change on this file since 9944 was 9858, checked in by tbretz, 14 years ago
Implemented TProfile3D in MH3 and MHn and the possibility to skip the reset of the histograms in the SetupFill.
File size: 18.2 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-2010
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MHn
28//
29//
30// Initialization
31// --------------
32//
33// MHn is a histogram class which derives from MH as all Mars histogram
34// classes do, i.e. to fill the histogram use MFillH. (Example below)
35//
36// After instantisation of MHn add the histograms of your interest using
37// AddHist. Before the next AddHist is called you can now set the options
38// of your histogram using InitName, InitTitle, SetLog, SetAutoRange,
39// SetScale and SetDrawOption.
40//
41//
42// Layout
43// ------
44//
45// The layout of the histograms on the screen depends on the number of
46// initialized histograms and the option SetLayout. For details see below.
47//
48// SetLayout(MHn::kSimple)
49// < default > SetLayout(MHn::kComplex)
50// ========================= ==========================
51// +-----------------+
52// |1 |
53// | |
54// | |
55// | |
56// | |
57// +-----------------+
58//
59// +-----------------+ +--------+--------+
60// |1 | |1 |2 |
61// | | | | |
62// +-----------------+ | | |
63// |2 | | | |
64// | | | | |
65// +-----------------+ +--------+--------+
66//
67// +--------+--------+ +-----+-----+-----+
68// |1 |2 | |1 |3 |
69// | | | | | |
70// +--------+--------+ +-----+ +
71// |3 | | |2 | |
72// | | | | | |
73// +--------+--------+ +-----+-----+-----+
74//
75// +--------+--------+ +------+----------+
76// |1 |2 | |1 |4 |
77// | | | +------+ |
78// +--------+--------+ |2 | |
79// |3 |4 | +------+ |
80// | | | |3 | |
81// +--------+--------+ +------+----------+
82//
83// +-----+-----+-----+ +--------+--------+
84// |1 |2 |3 | |1 |2 |
85// | | | | +--------+--------|
86// +-----+-----+-----+ |3 |4 |
87// |4 |5 | | +--------+ |
88// | | | | |5 | |
89// +-----+-----+-----+ +--------+--------+
90//
91// +-----+-----+-----+ +--------+--------+
92// |1 |2 |3 | |1 |2 |
93// | | | | +--------+--------+
94// +-----+-----+-----+ |3 |4 |
95// |4 |5 |6 | +--------+--------+
96// | | | | |5 |6 |
97// +-----+-----+-----+ +--------+--------+
98//
99//
100// For example:
101// ------------
102// // Instatiate the MHn class with default name and title
103// MHn hres("Energy2", "Energy Residual (lg E_{est} - lg E_{mc})");
104//
105// // Initialize your first histogram (here a 2D histogram with x- and y-axis)
106// hres.AddHist("MMcEvt.fEnergy", "log10(MEnergyEst.fVal)-log10(MMcEvt.fEnergy)");
107// // Initialize the name of the histogram (ResEmc) and the title of the
108// // binnings ((here BinningEnergy for x-axis and BinningEnergyResidual for y-axis)
109// hres.InitName("ResEmc;Energy;EnergyResidual");
110// // Initialize the title of the histogram and the axis titles
111// hres.InitTitle(";E_{mc} [GeV];\\Delta lg E;");
112// // Initialize the draw option for the histogram
113// hres.SetDrawOption("colz profx");
114// // for more details on the options and more options see below
115// // or the class reference of MH3
116//
117// // Initialize a second histogram
118// hres.AddHist("MPointingPos.fZd", "log10(MEnergyEst.fVal)-log10(MMcEvt.fEnergy)");
119// hres.InitName("ResTheta;Theta;EnergyResidual");
120// hres.InitTitle(";Zd [\\circ];\\Delta lg E;");
121// hres.SetDrawOption("colz profx");
122//
123// // Note that only AddHist is mandatory. All other options can be omitted
124//
125// // Initialize the filling task which can now be added to the tasklist
126// MFillH fill(&hres);
127// ...
128//
129/////////////////////////////////////////////////////////////////////////////
130#include "MHn.h"
131
132#include <TCanvas.h>
133
134#include "MLog.h"
135#include "MLogManip.h"
136
137#include "MH3.h"
138#include "MString.h"
139
140ClassImp(MHn);
141
142using namespace std;
143
144MHn::MHn(const char *name, const char *title) : fLayout(kSimple), fNum(0)
145{
146 fName = name ? name : "MHn";
147 fTitle = title ? title : "Generalized histogram class for up to six histograms";
148
149 memset(fHist, 0, 6*sizeof(MH3*));
150}
151
152MHn::~MHn()
153{
154 for (int i=0; i<fNum; i++)
155 if (fHist[i])
156 delete fHist[i];
157}
158
159// --------------------------------------------------------------------------
160//
161// If a histogram with the same name is found, the pad-number with a
162// training underscore is added.
163//
164// FIXME: How do we handle identical names with different axes?
165//
166void MHn::InitHist()
167{
168 TString name = fName;
169
170 for (int i=0; i<fNum; i++)
171 if (name==fHist[i]->GetName())
172 {
173 name += MString::Format("_%d", fNum);
174 break;
175 }
176
177 fHist[fNum]->SetName(fName);
178 fHist[fNum]->SetTitle(fTitle);
179
180 fHist[fNum]->SetAutoRangeX();
181
182 fNum++;
183}
184
185// --------------------------------------------------------------------------
186//
187// Add a new 1D-MH3 histogram. An internal pointer is set to it, so that
188// InitName and InitTitle can be used for this histogram until a new
189// histogram is added using AddHist
190//
191// e.g. AddHist("MHillas.fSize")
192//
193Bool_t MHn::AddHist(const char *memberx)
194{
195 if (fNum==8)
196 {
197 *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
198 return kFALSE;
199 }
200
201 fHist[fNum] = new MH3(memberx);
202
203 InitHist();
204
205 return kTRUE;
206}
207
208// --------------------------------------------------------------------------
209//
210// Add a new 2D-MH3 histogram. An internal pointer is set to it, so that
211// InitName and InitTitle can be used for this histogram until a new
212// histogram is added using AddHist
213//
214// e.g. AddHist("MHillas.fLength", "MHillas.fSize")
215//
216Bool_t MHn::AddHist(const char *memberx, const char *membery, MH3::Type_t type)
217{
218 if (fNum==8)
219 {
220 *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
221 return kFALSE;
222 }
223
224 fHist[fNum] = new MH3(memberx, membery, type);
225
226 InitHist();
227
228 return kTRUE;
229}
230
231// --------------------------------------------------------------------------
232//
233// Add a new 3D-MH3 histogram. An internal pointer is set to it, so that
234// InitName and InitTitle can be used for this histogram until a new
235// histogram is added using AddHist
236//
237// e.g. AddHist("MHillas.fWidth", "MHillas.fLength", "MHillas.fSize")
238//
239Bool_t MHn::AddHist(const char *memberx, const char *membery, const char *memberz, MH3::Type_t type)
240{
241 if (fNum==8)
242 {
243 *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
244 return kFALSE;
245 }
246
247 fHist[fNum] = new MH3(memberx, membery, memberz, type);
248
249 InitHist();
250
251 return kTRUE;
252}
253
254// --------------------------------------------------------------------------
255//
256// Add a new 3D-MH3 histogram. An internal pointer is set to it, so that
257// InitName and InitTitle can be used for this histogram until a new
258// histogram is added using AddHist
259//
260// e.g. AddHist("MHillas.fWidth", "MHillas.fLength", "MHillas.fSize", "MWeight.fVal")
261//
262Bool_t MHn::AddHist(const char *memberx, const char *membery, const char *memberz, const char *weight)
263{
264 if (fNum==8)
265 {
266 *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
267 return kFALSE;
268 }
269
270 fHist[fNum] = new MH3(memberx, membery, memberz, weight);
271
272 InitHist();
273
274 return kTRUE;
275}
276
277// --------------------------------------------------------------------------
278//
279// Set the draw option of the n-th MH3. See MH3 for more details of the
280// meaning of it.
281//
282Bool_t MHn::SetDrawOption(Int_t n, const char *opt)
283{
284 if (n<0 || n>=fNum)
285 {
286 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... SetDrawOption ignored." << endl;
287 return kFALSE;
288 }
289
290 fDrawOption[n] = opt;
291
292 return kTRUE;
293}
294
295// --------------------------------------------------------------------------
296//
297// Set the name of the n-th MH3. See MH3 for more details of the meaning
298// of the name. If the given name starts with a semicolon fName is prepend
299// to the string.
300//
301Bool_t MHn::InitName(Int_t n, const char *nam)
302{
303 if (n<0 || n>=fNum)
304 {
305 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... InitName ignored." << endl;
306 return kFALSE;
307 }
308
309 TString name = TString(nam).Strip(TString::kBoth);
310
311 if (name[0]==';')
312 name.Prepend(fName);
313
314 fHist[n]->SetName(name);
315
316 return kTRUE;
317}
318
319// --------------------------------------------------------------------------
320//
321// Set the title of the n-th MH3. See MH3 for more details of the meaning
322// of the title. If the given title starts with a semicolon fTitle is prepend
323// to the string.
324//
325Bool_t MHn::InitTitle(Int_t n, const char *tit)
326{
327 if (n<0 || n>=fNum)
328 {
329 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... InitTitle ignored." << endl;
330 return kFALSE;
331 }
332
333 TString title = TString(tit).Strip(TString::kBoth);
334
335 if (title[0]==';')
336 title.Prepend(fTitle);
337
338 fHist[n]->SetTitle(title);
339
340 return kTRUE;
341}
342
343// --------------------------------------------------------------------------
344//
345// Set additional scale factors for the current histogram
346//
347void MHn::SetScale(Double_t x, Double_t y, Double_t z) const
348{
349 if (fHist[fNum-1])
350 fHist[fNum-1]->SetScale(x, y, z);
351}
352
353// --------------------------------------------------------------------------
354//
355// Enable or disable displaying log-scale for the current histogram.
356// Normally it is retrieved from the corresponding MBinning
357//
358void MHn::SetLog(Bool_t x, Bool_t y, Bool_t z) const
359{
360 if (fHist[fNum-1])
361 fHist[fNum-1]->SetLog(x, y, z);
362}
363
364// --------------------------------------------------------------------------
365//
366// Set the axis range in Finalize automatically to the histogram region
367// containing contents. This is the default for the x-axis.
368// This function can be used to enable this behaviour also for the other
369// axis, or disable it for the x-axis of the current histogram.
370//
371void MHn::SetAutoRange(Bool_t x, Bool_t y, Bool_t z) const
372{
373 if (fHist[fNum-1])
374 fHist[fNum-1]->SetAutoRange(x, y, z);
375}
376
377// --------------------------------------------------------------------------
378//
379// Call Sumw2 for trhe current histogram, enabling errors.
380//
381void MHn::Sumw2() const
382{
383 if (fHist[fNum-1])
384 fHist[fNum-1]->Sumw2();
385}
386
387// --------------------------------------------------------------------------
388//
389// Force the given binning(s) for the current histogram. The binnings
390// do not get owned. The user is responsible for deleting them.
391//
392void MHn::SetBinnings(MBinning *x, MBinning *y, MBinning *z) const
393{
394 if (fHist[fNum-1])
395 fHist[fNum-1]->SetBinnings(x, y, z);
396}
397
398// --------------------------------------------------------------------------
399//
400// call MH3::InitLabels for the current histogram
401//
402void MHn::InitLabels(MH3::Labels_t labels) const
403{
404 if (fHist[fNum-1])
405 fHist[fNum-1]->InitLabels(labels);
406}
407
408// --------------------------------------------------------------------------
409//
410// call MH3::DefaultLabelX for the current histogram
411//
412void MHn::DefaultLabelX(const char *name)
413{
414 if (fHist[fNum-1])
415 fHist[fNum-1]->DefaultLabelX(name);
416}
417
418// --------------------------------------------------------------------------
419//
420// call MH3::DefaultLabelY for the current histogram
421//
422void MHn::DefaultLabelY(const char *name)
423{
424 if (fHist[fNum-1])
425 fHist[fNum-1]->DefaultLabelY(name);
426}
427
428// --------------------------------------------------------------------------
429//
430// call MH3::DefaultLabelZ for the current histogram
431//
432void MHn::DefaultLabelZ(const char *name)
433{
434 if (fHist[fNum-1])
435 fHist[fNum-1]->DefaultLabelZ(name);
436}
437
438// --------------------------------------------------------------------------
439//
440// call MH3::DefineLabelX for the current histogram
441//
442void MHn::DefineLabelX(Int_t label, const char *name)
443{
444 if (fHist[fNum-1])
445 fHist[fNum-1]->DefineLabelX(label, name);
446}
447
448// --------------------------------------------------------------------------
449//
450// call MH3::DefineLabelY for the current histogram
451//
452void MHn::DefineLabelY(Int_t label, const char *name)
453{
454 if (fHist[fNum-1])
455 fHist[fNum-1]->DefineLabelY(label, name);
456}
457
458// --------------------------------------------------------------------------
459//
460// call MH3::DefineLabelZ for the current histogram
461//
462void MHn::DefineLabelZ(Int_t label, const char *name)
463{
464 if (fHist[fNum-1])
465 fHist[fNum-1]->DefineLabelZ(label, name);
466}
467
468// --------------------------------------------------------------------------
469//
470// call MH3::DefineLabelsX for the current histogram
471//
472void MHn::DefineLabelsX(const TString &labels)
473{
474 if (fHist[fNum-1])
475 fHist[fNum-1]->DefineLabelsX(labels);
476}
477
478// --------------------------------------------------------------------------
479//
480// call MH3::DefineLabelsY for the current histogram
481//
482void MHn::DefineLabelsY(const TString &labels)
483{
484 if (fHist[fNum-1])
485 fHist[fNum-1]->DefineLabelsY(labels);
486}
487
488// --------------------------------------------------------------------------
489//
490// call MH3::DefineLabelsZ for the current histogram
491//
492void MHn::DefineLabelsZ(const TString &labels)
493{
494 if (fHist[fNum-1])
495 fHist[fNum-1]->DefineLabelsZ(labels);
496}
497
498// --------------------------------------------------------------------------
499//
500// call MH3::SetWeight for the current histogram
501//
502void MHn::SetWeight(const char *phrase)
503{
504 if (fHist[fNum-1])
505 fHist[fNum-1]->SetWeight(phrase);
506}
507
508// --------------------------------------------------------------------------
509//
510// call MH3::SetConversion for the current histogram
511//
512void MHn::SetConversion(const char *func)
513{
514 if (fHist[fNum-1])
515 fHist[fNum-1]->SetConversion(func);
516}
517
518// --------------------------------------------------------------------------
519//
520// Call SetupFill for all initialized histograms
521//
522Bool_t MHn::SetupFill(const MParList *plist)
523{
524 for (int i=0; i<fNum; i++)
525 {
526 TestBit(kDoNotReset) ? fHist[i]->SetBit(kDoNotReset) : fHist[i]->ResetBit(kDoNotReset);
527
528 if (!fHist[i]->SetupFill(plist))
529 return kFALSE;
530 }
531
532 return kTRUE;
533}
534
535// --------------------------------------------------------------------------
536//
537// Call Fill for all initialized histograms
538//
539Int_t MHn::Fill(const MParContainer *par, const Stat_t w)
540{
541 for (int i=0; i<fNum; i++)
542 {
543 const Int_t rc = fHist[i]->Fill(par, w);
544 if (rc!=kTRUE)
545 return rc;
546 }
547
548 return kTRUE;
549}
550
551// --------------------------------------------------------------------------
552//
553// Call Finalize for all initialized histograms
554//
555Bool_t MHn::Finalize()
556{
557 for (int i=0; i<fNum; i++)
558 if (!fHist[i]->Finalize())
559 return kFALSE;
560
561 return kTRUE;
562}
563
564// --------------------------------------------------------------------------
565//
566void MHn::Draw(Option_t *opt)
567{
568 TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
569 pad->SetBorderMode(0);
570
571 const Bool_t same = TString(opt).Contains("same");
572
573 if (!same)
574 {
575 AppendPad();
576
577 const Int_t id = fNum + fLayout*10;
578
579 switch (id)
580 {
581 case 0: // 0
582 case 10: // 0
583 return;
584 case 1: // 1
585 case 11: // 1
586 break;
587
588 case 2: // 2
589 pad->Divide(1,2, 1e-5, 1e-5);
590 break;
591 case 3: // 3
592 pad->Divide(2,2, 1e-5, 1e-5);
593 delete pad->GetPad(4);
594 break;
595 case 4: // 4
596 pad->Divide(2,2, 1e-5, 1e-5);
597 break;
598 case 5: // 5
599 pad->Divide(3,2, 1e-5, 1e-5);
600 delete pad->GetPad(6);
601 break;
602 case 6: // 6
603 pad->Divide(3,2, 1e-5, 1e-5);
604 break;
605
606 case 12: // 2
607 pad->Divide(2,1, 1e-5, 1e-5);
608 break;
609 case 13: // 3
610 pad->Divide(2,2, 1e-5, 1e-5);
611 pad->GetPad(1)->SetPad(0.01, 0.505, 0.33, 0.99);
612 pad->GetPad(2)->SetPad(0.01, 0.01, 0.33, 0.495);
613 pad->GetPad(3)->SetPad(0.34, 0.01, 0.99, 0.99);
614 delete pad->GetPad(4);
615 break;
616 case 14: // 4
617 pad->Divide(2,2, 1e-5, 1e-5);
618 break;
619 case 15: // 5
620 pad->Divide(2,3, 1e-5, 1e-5);
621 pad->GetPad(4)->SetPad(0.51, 0.01, 0.99, 0.65);
622 delete pad->GetPad(6);
623 break;
624 case 16: // 6
625 pad->Divide(2,3);
626 break;
627 }
628 }
629
630 for (int i=0; i<fNum; i++)
631 {
632 TString dopt(fDrawOption[i]);
633 if (same)
634 dopt += " same";
635
636 pad->cd(i+1);
637 fHist[i]->Draw(dopt);
638 }
639}
640
641void MHn::RecursiveRemove(TObject *obj)
642{
643 for (int i=0; i<6; i++)
644 {
645 if (!fHist[i])
646 continue;
647
648 if (obj==fHist[i])
649 fHist[i] = 0;
650 else
651 fHist[i]->RecursiveRemove(obj);
652 }
653
654 MH::RecursiveRemove(obj);
655}
Note: See TracBrowser for help on using the repository browser.