/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz, 01/2002 ! ! Copyright: MAGIC Software Development, 2000-2003 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // // MBinning // // // ////////////////////////////////////////////////////////////////////////////// #include "MBinning.h" #include // tolower #include #include // InheritsFrom #include "MLog.h" #include "MLogManip.h" #include "MH.h" ClassImp(MBinning); using namespace std; static const TString gsDefName = "MBinning"; static const TString gsDefTitle = "Container describing the binning of an axis"; // -------------------------------------------------------------------------- // // Default Constructor. It sets name and title only. Typically you won't // need to change this. // MBinning::MBinning(const char *name, const char *title) { // // set the name and title of this object // fName = name ? name : gsDefName.Data(); fTitle = title ? title : gsDefTitle.Data(); SetEdges(10, 0, 1); fType = kIsDefault; } MBinning::MBinning(Int_t nbins, Axis_t lo, Axis_t hi, const char *name, const char *opt, const char *title) { fName = name ? name : gsDefName.Data(); fTitle = title ? title : gsDefTitle.Data(); SetEdges(nbins, lo, hi, opt); } void MBinning::SetEdges(const TAxis &axe) { const TArrayD &arr = *((TAxis&)axe).GetXbins(); if (arr.GetSize()>0) { SetEdges(arr); return; } SetEdges(axe.GetNbins(), axe.GetXmin(), axe.GetXmax()); } void MBinning::SetEdges(const TH1 &h, const Char_t axis) { TH1 &hist = (TH1&)h; // get rid of const qualifier switch (tolower(axis)) { case 'x': SetEdges(*hist.GetXaxis()); return; case 'y': SetEdges(*hist.GetYaxis()); return; case 'z': SetEdges(*hist.GetZaxis()); return; default: *fLog << warn << "MBinning::SetEdges: Axis '" << axis << "' unknown... using x." << endl; SetEdges(*hist.GetXaxis()); } } // -------------------------------------------------------------------------- // // Specify the number of bins (not the number of edges), the // lowest and highest Edge (of your histogram) // void MBinning::SetEdges(const Int_t nbins, const Axis_t lo, Axis_t up) { const Double_t binsize = (up-lo)/nbins; fEdges.Set(nbins+1); for (int i=0; i<=nbins; i++) fEdges[i] = binsize*i + lo; fType = kIsLinear; } // -------------------------------------------------------------------------- // // Calls SetEdgesLog if opt contains "log" // Calls SetEdgesCos if opt contains "cos" // Calls SetEdges in all other cases // void MBinning::SetEdges(const Int_t nbins, const Axis_t lo, Axis_t up, const char *opt) { const TString o(opt); if (o.Contains("log", TString::kIgnoreCase)) { SetEdgesLog(nbins, lo, up); return; } if (o.Contains("cos", TString::kIgnoreCase)) { SetEdgesCos(nbins, lo, up); return; } SetEdges(nbins, lo, up); } // -------------------------------------------------------------------------- // // Specify the number of bins (not the number of edges), the // lowest and highest Edge (of your histogram) // void MBinning::SetEdgesLog(const Int_t nbins, const Axis_t lo, Axis_t up) { // if (lo==0) ... const Double_t binsize = log10(up/lo)/nbins; fEdges.Set(nbins+1); for (int i=0; i<=nbins; i++) fEdges[i] = pow(10, binsize*i) * lo; fType = kIsLogarithmic; } // -------------------------------------------------------------------------- // // Specify the number of bins (not the number of edges), the // lowest [deg] and highest [deg] Edge (of your histogram) // void MBinning::SetEdgesCos(const Int_t nbins, const Axis_t lo, Axis_t up) { // if (lo==0) ... const Axis_t ld = lo/kRad2Deg; const Axis_t ud = up/kRad2Deg; const Double_t binsize = (cos(ld)-cos(ud))/nbins; fEdges.Set(nbins+1); for (int i=0; i<=nbins; i++) fEdges[i] = acos(cos(ld)-binsize*i)*kRad2Deg; fType = kIsCosinic; } // -------------------------------------------------------------------------- // // Apply this binning to the given histogram. // (By definition this works only for 1D-histograms. For 2D- and 3D- // histograms use MH::SetBinning directly) // void MBinning::Apply(TH1 &h) { if (h.InheritsFrom("TH2") || h.InheritsFrom("TH3")) { *fLog << warn << "MBinning::Apply: '" << h.GetName() << "' is not a basic TH1 object... no binning applied." << endl; return; } MH::SetBinning(&h, this); } // -------------------------------------------------------------------------- // // Implementation of SavePrimitive. Used to write the call to a constructor // to a macro. In the original root implementation it is used to write // gui elements to a macro-file. // void MBinning::StreamPrimitive(ofstream &out) const { out << " MBinning " << GetUniqueName(); if (fName!=gsDefName || fTitle!=gsDefTitle) { out << "(\"" << fName << "\""; if (fTitle!=gsDefTitle) out << ", \"" << fTitle << "\""; out <<")"; } out << ";" << endl; if (IsDefault()) return; if (IsLinear() || IsLogarithmic() || IsCosinic()) { out << " " << GetUniqueName() << ".SetEdges"; if (IsLogarithmic()) out << "Log"; if (IsCosinic()) out << "Cos"; out << "(" << GetNumBins() << ", " << GetEdgeLo() << ", " << GetEdgeHi() << ");" << endl; return; } out << " {" << endl; out << " TArrayD dummy;" << endl; for (int i=0; i