source: trunk/MagicSoft/Mars/mhbase/MHn.cc@ 9271

Last change on this file since 9271 was 9153, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 16.6 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// 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
139ClassImp(MHn);
140
141using namespace std;
142
143MHn::MHn(const char *name, const char *title) : fLayout(kSimple), fNum(0)
144{
145 fName = name ? name : "MHn";
146 fTitle = title ? title : "Generalized histogram class for up to six histograms";
147
148 memset(fHist, 0, 6*sizeof(MH3*));
149}
150
151MHn::~MHn()
152{
153 for (int i=0; i<fNum; i++)
154 if (fHist[i])
155 delete fHist[i];
156}
157
158// --------------------------------------------------------------------------
159//
160// If a histogram with the same name is found, the pad-number with a
161// training underscore is added.
162//
163// FIXME: How do we handle identical names with different axes?
164//
165void MHn::InitHist()
166{
167 TString name = fName;
168
169 for (int i=0; i<fNum; i++)
170 if (name==fHist[i]->GetName())
171 {
172 name += Form("_%d", fNum);
173 break;
174 }
175
176 fHist[fNum]->SetName(fName);
177 fHist[fNum]->SetTitle(fTitle);
178
179 fHist[fNum]->SetAutoRangeX();
180
181 fNum++;
182}
183
184// --------------------------------------------------------------------------
185//
186// Add a new 1D-MH3 histogram. An internal pointer is set to it, so that
187// InitName and InitTitle can be used for this histogram until a new
188// histogram is added using AddHist
189//
190// e.g. AddHist("MHillas.fSize")
191//
192Bool_t MHn::AddHist(const char *memberx)
193{
194 if (fNum==8)
195 {
196 *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
197 return kFALSE;
198 }
199
200 fHist[fNum] = new MH3(memberx);
201
202 InitHist();
203
204 return kTRUE;
205}
206
207// --------------------------------------------------------------------------
208//
209// Add a new 2D-MH3 histogram. An internal pointer is set to it, so that
210// InitName and InitTitle can be used for this histogram until a new
211// histogram is added using AddHist
212//
213// e.g. AddHist("MHillas.fLength", "MHillas.fSize")
214//
215Bool_t MHn::AddHist(const char *memberx, const char *membery, MH3::Type_t type)
216{
217 if (fNum==8)
218 {
219 *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
220 return kFALSE;
221 }
222
223 fHist[fNum] = new MH3(memberx, membery, type);
224
225 InitHist();
226
227 return kTRUE;
228}
229
230// --------------------------------------------------------------------------
231//
232// Add a new 3D-MH3 histogram. An internal pointer is set to it, so that
233// InitName and InitTitle can be used for this histogram until a new
234// histogram is added using AddHist
235//
236// e.g. AddHist("MHillas.fWidth", "MHillas.fLength", "MHillas.fSize")
237//
238Bool_t MHn::AddHist(const char *memberx, const char *membery, const char *memberz, MH3::Type_t type)
239{
240 if (fNum==8)
241 {
242 *fLog << err << "ERROR - MHn doesn't support more than six histograms... AddHist ignored." << endl;
243 return kFALSE;
244 }
245
246 fHist[fNum] = new MH3(memberx, membery, memberz, type);
247
248 InitHist();
249
250 return kTRUE;
251}
252
253// --------------------------------------------------------------------------
254//
255// Set the draw option of the n-th MH3. See MH3 for more details of the
256// meaning of it.
257//
258Bool_t MHn::SetDrawOption(Int_t n, const char *opt)
259{
260 if (n<0 || n>=fNum)
261 {
262 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... SetDrawOption ignored." << endl;
263 return kFALSE;
264 }
265
266 fDrawOption[n] = opt;
267
268 return kTRUE;
269}
270
271// --------------------------------------------------------------------------
272//
273// Set the name of the n-th MH3. See MH3 for more details of the meaning
274// of the name. If the given name starts with a semicolon fName is prepend
275// to the string.
276//
277Bool_t MHn::InitName(Int_t n, const char *nam)
278{
279 if (n<0 || n>=fNum)
280 {
281 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... InitName ignored." << endl;
282 return kFALSE;
283 }
284
285 TString name = TString(nam).Strip(TString::kBoth);
286
287 if (name[0]==';')
288 name.Prepend(fName);
289
290 fHist[n]->SetName(name);
291
292 return kTRUE;
293}
294
295// --------------------------------------------------------------------------
296//
297// Set the title of the n-th MH3. See MH3 for more details of the meaning
298// of the title. If the given title starts with a semicolon fTitle is prepend
299// to the string.
300//
301Bool_t MHn::InitTitle(Int_t n, const char *tit)
302{
303 if (n<0 || n>=fNum)
304 {
305 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... InitTitle ignored." << endl;
306 return kFALSE;
307 }
308
309 TString title = TString(tit).Strip(TString::kBoth);
310
311 if (title[0]==';')
312 title.Prepend(fTitle);
313
314 fHist[n]->SetTitle(title);
315
316 return kTRUE;
317}
318
319// --------------------------------------------------------------------------
320//
321// Set additional scale factors for the current histogram
322//
323void MHn::SetScale(Double_t x, Double_t y, Double_t z) const
324{
325 if (fHist[fNum-1])
326 fHist[fNum-1]->SetScale(x, y, z);
327}
328
329// --------------------------------------------------------------------------
330//
331// Enable or disable displaying log-scale for the current histogram.
332// Normally it is retrieved from the corresponding MBinning
333//
334void MHn::SetLog(Bool_t x, Bool_t y, Bool_t z) const
335{
336 if (fHist[fNum-1])
337 fHist[fNum-1]->SetLog(x, y, z);
338}
339
340// --------------------------------------------------------------------------
341//
342// Set the axis range in Finalize automatically to the histogram region
343// containing contents. This is the default for the x-axis.
344// This function can be used to enable this behaviour also for the other
345// axis, or disable it for the x-axis of the current histogram.
346//
347void MHn::SetAutoRange(Bool_t x, Bool_t y, Bool_t z) const
348{
349 if (fHist[fNum-1])
350 fHist[fNum-1]->SetAutoRange(x, y, z);
351}
352
353// --------------------------------------------------------------------------
354//
355// Call Sumw2 for trhe current histogram, enabling errors.
356//
357void MHn::Sumw2() const
358{
359 if (fHist[fNum-1])
360 fHist[fNum-1]->Sumw2();
361}
362
363// --------------------------------------------------------------------------
364//
365// Force the given binning(s) for the current histogram. The binnings
366// do not get owned. The user is responsible for deleting them.
367//
368void MHn::SetBinnings(MBinning *x, MBinning *y, MBinning *z) const
369{
370 if (fHist[fNum-1])
371 fHist[fNum-1]->SetBinnings(x, y, z);
372}
373
374// --------------------------------------------------------------------------
375//
376// call MH3::InitLabels for the current histogram
377//
378void MHn::InitLabels(MH3::Labels_t labels) const
379{
380 if (fHist[fNum-1])
381 fHist[fNum-1]->InitLabels(labels);
382}
383
384// --------------------------------------------------------------------------
385//
386// call MH3::DefaultLabelX for the current histogram
387//
388void MHn::DefaultLabelX(const char *name)
389{
390 if (fHist[fNum-1])
391 fHist[fNum-1]->DefaultLabelX(name);
392}
393
394// --------------------------------------------------------------------------
395//
396// call MH3::DefaultLabelY for the current histogram
397//
398void MHn::DefaultLabelY(const char *name)
399{
400 if (fHist[fNum-1])
401 fHist[fNum-1]->DefaultLabelY(name);
402}
403
404// --------------------------------------------------------------------------
405//
406// call MH3::DefaultLabelZ for the current histogram
407//
408void MHn::DefaultLabelZ(const char *name)
409{
410 if (fHist[fNum-1])
411 fHist[fNum-1]->DefaultLabelZ(name);
412}
413
414// --------------------------------------------------------------------------
415//
416// call MH3::DefineLabelX for the current histogram
417//
418void MHn::DefineLabelX(Int_t label, const char *name)
419{
420 if (fHist[fNum-1])
421 fHist[fNum-1]->DefineLabelX(label, name);
422}
423
424// --------------------------------------------------------------------------
425//
426// call MH3::DefineLabelY for the current histogram
427//
428void MHn::DefineLabelY(Int_t label, const char *name)
429{
430 if (fHist[fNum-1])
431 fHist[fNum-1]->DefineLabelY(label, name);
432}
433
434// --------------------------------------------------------------------------
435//
436// call MH3::DefineLabelZ for the current histogram
437//
438void MHn::DefineLabelZ(Int_t label, const char *name)
439{
440 if (fHist[fNum-1])
441 fHist[fNum-1]->DefineLabelZ(label, name);
442}
443
444// --------------------------------------------------------------------------
445//
446// call MH3::DefineLabelsX for the current histogram
447//
448void MHn::DefineLabelsX(const TString &labels)
449{
450 if (fHist[fNum-1])
451 fHist[fNum-1]->DefineLabelsX(labels);
452}
453
454// --------------------------------------------------------------------------
455//
456// call MH3::DefineLabelsY for the current histogram
457//
458void MHn::DefineLabelsY(const TString &labels)
459{
460 if (fHist[fNum-1])
461 fHist[fNum-1]->DefineLabelsY(labels);
462}
463
464// --------------------------------------------------------------------------
465//
466// call MH3::DefineLabelsZ for the current histogram
467//
468void MHn::DefineLabelsZ(const TString &labels)
469{
470 if (fHist[fNum-1])
471 fHist[fNum-1]->DefineLabelsZ(labels);
472}
473
474// --------------------------------------------------------------------------
475//
476// call MH3::SetWeight for the current histogram
477//
478void MHn::SetWeight(const char *phrase)
479{
480 if (fHist[fNum-1])
481 fHist[fNum-1]->SetWeight(phrase);
482}
483
484// --------------------------------------------------------------------------
485//
486// Call SetupFill for all initialized histograms
487//
488Bool_t MHn::SetupFill(const MParList *plist)
489{
490 for (int i=0; i<fNum; i++)
491 if (!fHist[i]->SetupFill(plist))
492 return kFALSE;
493
494 return kTRUE;
495}
496
497// --------------------------------------------------------------------------
498//
499// Call Fill for all initialized histograms
500//
501Int_t MHn::Fill(const MParContainer *par, const Stat_t w)
502{
503 for (int i=0; i<fNum; i++)
504 {
505 const Int_t rc = fHist[i]->Fill(par, w);
506 if (rc!=kTRUE)
507 return rc;
508 }
509
510 return kTRUE;
511}
512
513// --------------------------------------------------------------------------
514//
515// Call Finalize for all initialized histograms
516//
517Bool_t MHn::Finalize()
518{
519 for (int i=0; i<fNum; i++)
520 if (!fHist[i]->Finalize())
521 return kFALSE;
522
523 return kTRUE;
524}
525
526// --------------------------------------------------------------------------
527//
528void MHn::Draw(Option_t *opt)
529{
530 TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
531 pad->SetBorderMode(0);
532
533 const Bool_t same = TString(opt).Contains("same");
534
535 if (!same)
536 {
537 AppendPad();
538
539 const Int_t id = fNum + fLayout*10;
540
541 switch (id)
542 {
543 case 0: // 0
544 case 10: // 0
545 return;
546 case 1: // 1
547 case 11: // 1
548 break;
549
550 case 2: // 2
551 pad->Divide(1,2, 1e-5, 1e-5);
552 break;
553 case 3: // 3
554 pad->Divide(2,2, 1e-5, 1e-5);
555 delete pad->GetPad(4);
556 break;
557 case 4: // 4
558 pad->Divide(2,2, 1e-5, 1e-5);
559 break;
560 case 5: // 5
561 pad->Divide(3,2, 1e-5, 1e-5);
562 delete pad->GetPad(6);
563 break;
564 case 6: // 6
565 pad->Divide(3,2, 1e-5, 1e-5);
566 break;
567
568 case 12: // 2
569 pad->Divide(2,1, 1e-5, 1e-5);
570 break;
571 case 13: // 3
572 break;
573 case 14: // 4
574 pad->Divide(2,2, 1e-5, 1e-5);
575 break;
576 case 15: // 5
577 pad->Divide(2,3, 1e-5, 1e-5);
578 pad->GetPad(4)->SetPad(0.51, 0.01, 0.99, 0.65);
579 delete pad->GetPad(6);
580 break;
581 case 16: // 6
582 pad->Divide(2,3);
583 break;
584 }
585 }
586
587 for (int i=0; i<fNum; i++)
588 {
589 TString dopt(fDrawOption[i]);
590 if (same)
591 dopt += " same";
592
593 pad->cd(i+1);
594 fHist[i]->Draw(dopt);
595 }
596}
Note: See TracBrowser for help on using the repository browser.