source: trunk/MagicSoft/Mars/mhbase/MBinning.cc@ 5812

Last change on this file since 5812 was 5803, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 8.9 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, 01/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MBinning
28//
29// This is a MParCOntainer storing a binning for a histogram. Doing this
30// you are able to distribute a single binning to several histograms
31// in your parameter list.
32//
33// In some classes the title of the container is used to set the
34// axis-title of the corresponding axis in your histogram.
35//
36// For all the features supported see the function descriptions in
37// MBinning and MH
38//
39//////////////////////////////////////////////////////////////////////////////
40#include "MBinning.h"
41
42#include <ctype.h> // tolower
43#include <fstream>
44
45#include <TH1.h> // InheritsFrom
46
47#include "MLog.h"
48#include "MLogManip.h"
49
50#include "MParList.h"
51
52#include "MH.h"
53
54ClassImp(MBinning);
55
56using namespace std;
57
58const TString MBinning::gsDefName = "MBinning";
59const TString MBinning::gsDefTitle = "Container describing the binning of an axis";
60
61// --------------------------------------------------------------------------
62//
63// Default Constructor. It sets name and title only. Typically you won't
64// need to change this.
65//
66MBinning::MBinning(const char *name, const char *title)
67{
68 //
69 // set the name and title of this object
70 //
71 fName = name ? name : gsDefName.Data();
72 fTitle = title ? title : gsDefTitle.Data();
73
74 SetEdges(10, 0, 1);
75 fType = kIsDefault;
76}
77
78// --------------------------------------------------------------------------
79//
80// Instantiate MBinning with nbins number of bins between lo (lower edge)
81// and hi (upper edge), name name and title title.
82//
83MBinning::MBinning(Int_t nbins, Axis_t lo, Axis_t hi, const char *name, const char *opt, const char *title)
84{
85 fName = name ? name : gsDefName.Data();
86 fTitle = title ? title : gsDefTitle.Data();
87
88 SetEdges(nbins, lo, hi, opt);
89}
90
91// --------------------------------------------------------------------------
92//
93// Search in the parameter list for the binning with name "name". If found,
94// set the edges and title accordingly. Default is name of object.
95// return kTRUE if object found, kFALSE otherwise.
96//
97Bool_t MBinning::SetEdges(const MParList &list, const char *name)
98{
99 MBinning *bins = (MBinning*)list.FindObject(name ? name : fName.Data(), "MBinning");
100 if (!bins)
101 return kFALSE;
102
103 SetEdges(*bins);
104 return kTRUE;
105}
106
107// --------------------------------------------------------------------------
108//
109// Setup the edges stored in MBinning from the TAxis axe
110//
111void MBinning::SetEdges(const TAxis &axe)
112{
113 const TArrayD &arr = *axe.GetXbins();
114 if (arr.GetSize()>0)
115 {
116 SetEdges(arr);
117 return;
118 }
119
120 SetEdges(axe.GetNbins(), axe.GetXmin(), axe.GetXmax());
121}
122
123// --------------------------------------------------------------------------
124//
125// Add a new upper edge to the edges stored in MBinning. The new upper
126// edge must be greater than the current greatest. Using this you can
127// enhance a histogram bin-by-bin, eg:
128// TH1F h("", "", 2, 0, 1);
129// MBinning b;
130// b.SetEdges(h);
131// b.AddEdge(2);
132// b.Apply(h);
133// b.AddEdge(3);
134// b.Apply(h);
135// [...]
136//
137void MBinning::AddEdge(Axis_t up)
138{
139 const Int_t n = fEdges.GetSize();
140
141 if (up<=fEdges[n-1])
142 {
143 *fLog << warn << dbginf << "WARNING - New upper edge not greater than old upper edge... ignored." << endl;
144 return;
145 }
146
147 fEdges.Set(n+1);
148 fEdges[n] = up;
149
150 fType = kIsUserArray;
151}
152
153void MBinning::RemoveFirstEdge()
154{
155 const Int_t n = fEdges.GetSize();
156 for (int i=0; i<n-1; i++)
157 fEdges[i] = fEdges[i+1];
158 fEdges.Set(n-1);
159}
160
161void MBinning::RemoveLastEdge()
162{
163 fEdges.Set(fEdges.GetSize()-1);
164}
165
166// --------------------------------------------------------------------------
167//
168// Set the edges in MBinning from a histogram-axis. Which axis is
169// specified by axis ('x', 'y', 'z')
170//
171void MBinning::SetEdges(const TH1 &h, const Char_t axis)
172{
173 switch (tolower(axis))
174 {
175 case 'x':
176 SetEdges(*h.GetXaxis());
177 return;
178 case 'y':
179 SetEdges(*h.GetYaxis());
180 return;
181 case 'z':
182 SetEdges(*h.GetZaxis());
183 return;
184 default:
185 *fLog << warn << "MBinning::SetEdges: Axis '" << axis << "' unknown... using x." << endl;
186 SetEdges(*h.GetXaxis());
187 }
188}
189
190// --------------------------------------------------------------------------
191//
192// Specify the number of bins <nbins> (not the number of edges), the
193// lowest <lo> and highest <up> Edge (of your histogram)
194//
195void MBinning::SetEdges(const Int_t nbins, const Axis_t lo, Axis_t up)
196{
197 const Double_t binsize = nbins<=0 ? 0 : (up-lo)/nbins;
198 fEdges.Set(nbins+1);
199 for (int i=0; i<=nbins; i++)
200 fEdges[i] = binsize*i + lo;
201
202 fType = kIsLinear;
203}
204
205// --------------------------------------------------------------------------
206//
207// Calls SetEdgesLog if opt contains "log"
208// Calls SetEdgesCos if opt contains "cos"
209// Calls SetEdges in all other cases
210//
211void MBinning::SetEdges(const Int_t nbins, const Axis_t lo, Axis_t up, const char *opt)
212{
213 const TString o(opt);
214 if (o.Contains("log", TString::kIgnoreCase))
215 {
216 SetEdgesLog(nbins, lo, up);
217 return;
218 }
219 if (o.Contains("cos", TString::kIgnoreCase))
220 {
221 SetEdgesCos(nbins, lo, up);
222 return;
223 }
224 SetEdges(nbins, lo, up);
225}
226
227// --------------------------------------------------------------------------
228//
229// Specify the number of bins <nbins> (not the number of edges), the
230// lowest <lo> and highest <up> Edge (of your histogram)
231//
232void MBinning::SetEdgesLog(const Int_t nbins, const Axis_t lo, Axis_t up)
233{
234 // if (lo==0) ...
235
236 const Double_t binsize = log10(up/lo)/nbins;
237 fEdges.Set(nbins+1);
238 for (int i=0; i<=nbins; i++)
239 fEdges[i] = pow(10, binsize*i) * lo;
240
241 fType = kIsLogarithmic;
242}
243
244// --------------------------------------------------------------------------
245//
246// Specify the number of bins <nbins> (not the number of edges), the
247// lowest [deg] <lo> and highest [deg] <up> Edge (of your histogram)
248//
249void MBinning::SetEdgesCos(const Int_t nbins, const Axis_t lo, Axis_t up)
250{
251 // if (lo==0) ...
252 const Axis_t ld = lo/kRad2Deg;
253 const Axis_t ud = up/kRad2Deg;
254
255 const Double_t binsize = (cos(ld)-cos(ud))/nbins;
256 fEdges.Set(nbins+1);
257 for (int i=0; i<=nbins; i++)
258 fEdges[i] = acos(cos(ld)-binsize*i)*kRad2Deg;
259
260 fType = kIsCosinic;
261}
262
263// --------------------------------------------------------------------------
264//
265// Apply this binning to the given histogram.
266// (By definition this works only for 1D-histograms. For 2D- and 3D-
267// histograms use MH::SetBinning directly)
268//
269void MBinning::Apply(TH1 &h) const
270{
271 if (h.InheritsFrom("TH2") || h.InheritsFrom("TH3"))
272 {
273 *fLog << warn << "MBinning::Apply: '" << h.GetName() << "' is not a basic TH1 object... no binning applied." << endl;
274 return;
275 }
276
277 MH::SetBinning(&h, this);
278}
279
280// --------------------------------------------------------------------------
281//
282// Implementation of SavePrimitive. Used to write the call to a constructor
283// to a macro. In the original root implementation it is used to write
284// gui elements to a macro-file.
285//
286void MBinning::StreamPrimitive(ofstream &out) const
287{
288 out << " MBinning " << GetUniqueName();
289 if (fName!=gsDefName || fTitle!=gsDefTitle)
290 {
291 out << "(\"" << fName << "\"";
292 if (fTitle!=gsDefTitle)
293 out << ", \"" << fTitle << "\"";
294 out <<")";
295 }
296 out << ";" << endl;
297
298 if (IsDefault())
299 return;
300
301 if (IsLinear() || IsLogarithmic() || IsCosinic())
302 {
303 out << " " << GetUniqueName() << ".SetEdges";
304 if (IsLogarithmic())
305 out << "Log";
306 if (IsCosinic())
307 out << "Cos";
308 out << "(" << GetNumBins() << ", " << GetEdgeLo() << ", " << GetEdgeHi() << ");" << endl;
309 return;
310 }
311
312 out << " {" << endl;
313 out << " TArrayD dummy;" << endl;
314 for (int i=0; i<GetNumEdges(); i++)
315 out << " dummy[" << i << "]=" << GetEdges()[i] << ";" << endl;
316 out << " " << GetUniqueName() << ".SetEdges(dummy);" << endl;
317 out << " }" << endl;
318}
Note: See TracBrowser for help on using the repository browser.