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

Last change on this file since 9829 was 9821, checked in by tbretz, 14 years ago
Added the possibility to set a conversion function which is applied before the histogram is displayed.
File size: 17.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// Set the draw option of the n-th MH3. See MH3 for more details of the
257// meaning of it.
258//
259Bool_t MHn::SetDrawOption(Int_t n, const char *opt)
260{
261 if (n<0 || n>=fNum)
262 {
263 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... SetDrawOption ignored." << endl;
264 return kFALSE;
265 }
266
267 fDrawOption[n] = opt;
268
269 return kTRUE;
270}
271
272// --------------------------------------------------------------------------
273//
274// Set the name of the n-th MH3. See MH3 for more details of the meaning
275// of the name. If the given name starts with a semicolon fName is prepend
276// to the string.
277//
278Bool_t MHn::InitName(Int_t n, const char *nam)
279{
280 if (n<0 || n>=fNum)
281 {
282 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... InitName ignored." << endl;
283 return kFALSE;
284 }
285
286 TString name = TString(nam).Strip(TString::kBoth);
287
288 if (name[0]==';')
289 name.Prepend(fName);
290
291 fHist[n]->SetName(name);
292
293 return kTRUE;
294}
295
296// --------------------------------------------------------------------------
297//
298// Set the title of the n-th MH3. See MH3 for more details of the meaning
299// of the title. If the given title starts with a semicolon fTitle is prepend
300// to the string.
301//
302Bool_t MHn::InitTitle(Int_t n, const char *tit)
303{
304 if (n<0 || n>=fNum)
305 {
306 *fLog << err << "ERROR - Histogram " << n << " not yet initialized... InitTitle ignored." << endl;
307 return kFALSE;
308 }
309
310 TString title = TString(tit).Strip(TString::kBoth);
311
312 if (title[0]==';')
313 title.Prepend(fTitle);
314
315 fHist[n]->SetTitle(title);
316
317 return kTRUE;
318}
319
320// --------------------------------------------------------------------------
321//
322// Set additional scale factors for the current histogram
323//
324void MHn::SetScale(Double_t x, Double_t y, Double_t z) const
325{
326 if (fHist[fNum-1])
327 fHist[fNum-1]->SetScale(x, y, z);
328}
329
330// --------------------------------------------------------------------------
331//
332// Enable or disable displaying log-scale for the current histogram.
333// Normally it is retrieved from the corresponding MBinning
334//
335void MHn::SetLog(Bool_t x, Bool_t y, Bool_t z) const
336{
337 if (fHist[fNum-1])
338 fHist[fNum-1]->SetLog(x, y, z);
339}
340
341// --------------------------------------------------------------------------
342//
343// Set the axis range in Finalize automatically to the histogram region
344// containing contents. This is the default for the x-axis.
345// This function can be used to enable this behaviour also for the other
346// axis, or disable it for the x-axis of the current histogram.
347//
348void MHn::SetAutoRange(Bool_t x, Bool_t y, Bool_t z) const
349{
350 if (fHist[fNum-1])
351 fHist[fNum-1]->SetAutoRange(x, y, z);
352}
353
354// --------------------------------------------------------------------------
355//
356// Call Sumw2 for trhe current histogram, enabling errors.
357//
358void MHn::Sumw2() const
359{
360 if (fHist[fNum-1])
361 fHist[fNum-1]->Sumw2();
362}
363
364// --------------------------------------------------------------------------
365//
366// Force the given binning(s) for the current histogram. The binnings
367// do not get owned. The user is responsible for deleting them.
368//
369void MHn::SetBinnings(MBinning *x, MBinning *y, MBinning *z) const
370{
371 if (fHist[fNum-1])
372 fHist[fNum-1]->SetBinnings(x, y, z);
373}
374
375// --------------------------------------------------------------------------
376//
377// call MH3::InitLabels for the current histogram
378//
379void MHn::InitLabels(MH3::Labels_t labels) const
380{
381 if (fHist[fNum-1])
382 fHist[fNum-1]->InitLabels(labels);
383}
384
385// --------------------------------------------------------------------------
386//
387// call MH3::DefaultLabelX for the current histogram
388//
389void MHn::DefaultLabelX(const char *name)
390{
391 if (fHist[fNum-1])
392 fHist[fNum-1]->DefaultLabelX(name);
393}
394
395// --------------------------------------------------------------------------
396//
397// call MH3::DefaultLabelY for the current histogram
398//
399void MHn::DefaultLabelY(const char *name)
400{
401 if (fHist[fNum-1])
402 fHist[fNum-1]->DefaultLabelY(name);
403}
404
405// --------------------------------------------------------------------------
406//
407// call MH3::DefaultLabelZ for the current histogram
408//
409void MHn::DefaultLabelZ(const char *name)
410{
411 if (fHist[fNum-1])
412 fHist[fNum-1]->DefaultLabelZ(name);
413}
414
415// --------------------------------------------------------------------------
416//
417// call MH3::DefineLabelX for the current histogram
418//
419void MHn::DefineLabelX(Int_t label, const char *name)
420{
421 if (fHist[fNum-1])
422 fHist[fNum-1]->DefineLabelX(label, name);
423}
424
425// --------------------------------------------------------------------------
426//
427// call MH3::DefineLabelY for the current histogram
428//
429void MHn::DefineLabelY(Int_t label, const char *name)
430{
431 if (fHist[fNum-1])
432 fHist[fNum-1]->DefineLabelY(label, name);
433}
434
435// --------------------------------------------------------------------------
436//
437// call MH3::DefineLabelZ for the current histogram
438//
439void MHn::DefineLabelZ(Int_t label, const char *name)
440{
441 if (fHist[fNum-1])
442 fHist[fNum-1]->DefineLabelZ(label, name);
443}
444
445// --------------------------------------------------------------------------
446//
447// call MH3::DefineLabelsX for the current histogram
448//
449void MHn::DefineLabelsX(const TString &labels)
450{
451 if (fHist[fNum-1])
452 fHist[fNum-1]->DefineLabelsX(labels);
453}
454
455// --------------------------------------------------------------------------
456//
457// call MH3::DefineLabelsY for the current histogram
458//
459void MHn::DefineLabelsY(const TString &labels)
460{
461 if (fHist[fNum-1])
462 fHist[fNum-1]->DefineLabelsY(labels);
463}
464
465// --------------------------------------------------------------------------
466//
467// call MH3::DefineLabelsZ for the current histogram
468//
469void MHn::DefineLabelsZ(const TString &labels)
470{
471 if (fHist[fNum-1])
472 fHist[fNum-1]->DefineLabelsZ(labels);
473}
474
475// --------------------------------------------------------------------------
476//
477// call MH3::SetWeight for the current histogram
478//
479void MHn::SetWeight(const char *phrase)
480{
481 if (fHist[fNum-1])
482 fHist[fNum-1]->SetWeight(phrase);
483}
484
485// --------------------------------------------------------------------------
486//
487// call MH3::SetConversion for the current histogram
488//
489void MHn::SetConversion(const char *func)
490{
491 if (fHist[fNum-1])
492 fHist[fNum-1]->SetConversion(func);
493}
494
495// --------------------------------------------------------------------------
496//
497// Call SetupFill for all initialized histograms
498//
499Bool_t MHn::SetupFill(const MParList *plist)
500{
501 for (int i=0; i<fNum; i++)
502 if (!fHist[i]->SetupFill(plist))
503 return kFALSE;
504
505 return kTRUE;
506}
507
508// --------------------------------------------------------------------------
509//
510// Call Fill for all initialized histograms
511//
512Int_t MHn::Fill(const MParContainer *par, const Stat_t w)
513{
514 for (int i=0; i<fNum; i++)
515 {
516 const Int_t rc = fHist[i]->Fill(par, w);
517 if (rc!=kTRUE)
518 return rc;
519 }
520
521 return kTRUE;
522}
523
524// --------------------------------------------------------------------------
525//
526// Call Finalize for all initialized histograms
527//
528Bool_t MHn::Finalize()
529{
530 for (int i=0; i<fNum; i++)
531 if (!fHist[i]->Finalize())
532 return kFALSE;
533
534 return kTRUE;
535}
536
537// --------------------------------------------------------------------------
538//
539void MHn::Draw(Option_t *opt)
540{
541 TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
542 pad->SetBorderMode(0);
543
544 const Bool_t same = TString(opt).Contains("same");
545
546 if (!same)
547 {
548 AppendPad();
549
550 const Int_t id = fNum + fLayout*10;
551
552 switch (id)
553 {
554 case 0: // 0
555 case 10: // 0
556 return;
557 case 1: // 1
558 case 11: // 1
559 break;
560
561 case 2: // 2
562 pad->Divide(1,2, 1e-5, 1e-5);
563 break;
564 case 3: // 3
565 pad->Divide(2,2, 1e-5, 1e-5);
566 delete pad->GetPad(4);
567 break;
568 case 4: // 4
569 pad->Divide(2,2, 1e-5, 1e-5);
570 break;
571 case 5: // 5
572 pad->Divide(3,2, 1e-5, 1e-5);
573 delete pad->GetPad(6);
574 break;
575 case 6: // 6
576 pad->Divide(3,2, 1e-5, 1e-5);
577 break;
578
579 case 12: // 2
580 pad->Divide(2,1, 1e-5, 1e-5);
581 break;
582 case 13: // 3
583 break;
584 case 14: // 4
585 pad->Divide(2,2, 1e-5, 1e-5);
586 break;
587 case 15: // 5
588 pad->Divide(2,3, 1e-5, 1e-5);
589 pad->GetPad(4)->SetPad(0.51, 0.01, 0.99, 0.65);
590 delete pad->GetPad(6);
591 break;
592 case 16: // 6
593 pad->Divide(2,3);
594 break;
595 }
596 }
597
598 for (int i=0; i<fNum; i++)
599 {
600 TString dopt(fDrawOption[i]);
601 if (same)
602 dopt += " same";
603
604 pad->cd(i+1);
605 fHist[i]->Draw(dopt);
606 }
607}
608
609void MHn::RecursiveRemove(TObject *obj)
610{
611 for (int i=0; i<6; i++)
612 {
613 if (!fHist[i])
614 continue;
615
616 if (obj==fHist[i])
617 fHist[i] = 0;
618 else
619 fHist[i]->RecursiveRemove(obj);
620 }
621
622 MH::RecursiveRemove(obj);
623}
Note: See TracBrowser for help on using the repository browser.