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

Last change on this file since 19344 was 19304, checked in by tbretz, 6 years ago
Replaced \circ by #circ because the old one looks weird.
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.