inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/histo/axis
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_histo_axis
00005 #define inlib_histo_axis
00006 
00007 #include <string>
00008 #include <vector>
00009 
00010 namespace inlib {
00011 namespace histo {
00012 
00013 //TC is for a coordinate.
00014 
00015 template <class TC>
00016 class axis {
00017 public:
00018   typedef unsigned int bn_t;
00019 public:
00020   enum { UNDERFLOW_BIN = -2, OVERFLOW_BIN = -1 }; //AIDA casing.
00021 public:
00022   bool is_fixed_binning() const {return m_fixed;}
00023   TC lower_edge() const {return m_minimum_value;}
00024   TC upper_edge() const {return m_maximum_value;}
00025   bn_t bins() const {return m_number_of_bins;}
00026   const std::vector<TC>& edges() const {return m_edges;}
00027 
00028   TC bin_width(int aBin) const {
00029     if(aBin==UNDERFLOW_BIN) {
00030       return 0; //FIXME return DBL_MAX;
00031     } else if(aBin==OVERFLOW_BIN) {
00032       return 0; //FIXME return DBL_MAX;
00033     } else if((aBin<0) ||(aBin>=(int)m_number_of_bins)) {
00034       return 0;
00035     } else {
00036       if(m_fixed) {
00037         return m_bin_width;
00038       } else {
00039         return (m_edges[aBin+1]-m_edges[aBin]);
00040       }
00041     }
00042   }
00043 
00044   TC bin_lower_edge(int aBin) const {
00045     if(aBin==UNDERFLOW_BIN) {
00046       return 0; //FIXME return -DBL_MAX;
00047     } else if(aBin==OVERFLOW_BIN) {
00048       return 0; //FIXME return bin_upper_edge(m_number_of_bins-1);
00049     } else if((aBin<0) ||(aBin>=(int)m_number_of_bins)) {
00050       return 0;
00051     } else {
00052       if(m_fixed) {
00053         return (m_minimum_value + aBin * m_bin_width);
00054       } else {
00055         return m_edges[aBin];
00056       }
00057     }
00058   }
00059 
00060   TC bin_upper_edge(int aBin) const {
00061     if(aBin==UNDERFLOW_BIN) {
00062       return 0; //FIXME bin_lower_edge(0)
00063     } else if(aBin==OVERFLOW_BIN) {
00064       return 0; //FIXME return DBL_MAX;
00065     } else if((aBin<0) ||(aBin>=(int)m_number_of_bins)) {
00066       return 0;
00067     } else {
00068       if(m_fixed) {
00069         return (m_minimum_value + (aBin + 1) * m_bin_width);
00070       } else {
00071         return m_edges[aBin+1];
00072       }
00073     }
00074   }
00075 
00076   TC bin_center(int aBin) const {
00077     if(aBin==UNDERFLOW_BIN) {
00078       return 0; //FIXME : -INF
00079     } else if(aBin==OVERFLOW_BIN) {
00080       return 0; //FIXME : +INF
00081     } else if(aBin<0) {
00082       return 0; //FIXME : -INF
00083     } else if(aBin>=(int)m_number_of_bins) {
00084       return 0; //FIXME : +INF
00085     } else {
00086       if(m_fixed) {
00087         return (m_minimum_value + (aBin + 0.5) * m_bin_width);
00088       } else {
00089         return (m_edges[aBin] + m_edges[aBin+1])/2.;
00090       }
00091     }
00092   }
00093 
00094   int coord_to_index(TC aValue) const {
00095     if( aValue <  m_minimum_value) {
00096       return UNDERFLOW_BIN;
00097     } else if( aValue >= m_maximum_value) {
00098       return OVERFLOW_BIN;
00099     } else {
00100       if(m_fixed) {
00101         return (int)((aValue - m_minimum_value)/m_bin_width);
00102       } else {
00103         for(bn_t index=0;index<m_number_of_bins;index++) {
00104           if((m_edges[index]<=aValue)&&(aValue<m_edges[index+1])) {
00105             return index;
00106           }
00107         }
00108         // Should never pass here...
00109         return UNDERFLOW_BIN;
00110       }
00111     }
00112   }
00113 
00114   bool coord_to_absolute_index(TC aValue,bn_t& a_index) const {
00115     if( aValue <  m_minimum_value) {
00116       a_index = 0;
00117       return true;
00118     } else if( aValue >= m_maximum_value) {
00119       a_index = m_number_of_bins+1;
00120       return true; 
00121     } else {
00122       if(m_fixed) {
00123         a_index = (bn_t)((aValue - m_minimum_value)/m_bin_width)+1;
00124         return true;
00125       } else {
00126         for(bn_t index=0;index<m_number_of_bins;index++) {
00127           if((m_edges[index]<=aValue)&&(aValue<m_edges[index+1])) {
00128             a_index = index+1;
00129             return true;
00130           }
00131         }
00132         // Should never pass here...
00133         a_index = 0;
00134         return false;
00135       }
00136     }
00137   }
00138 
00139   bool in_range_to_absolute_index(int a_in,bn_t& a_out) const {
00140     // a_in is given in in-range indexing :
00141     //  - [0,n-1] for in-range bins
00142     //  - UNDERFLOW_BIN for the iaxis underflow bin
00143     //  - OVERFLOW_BIN for the iaxis overflow bin
00144     // Return the absolute indexing in [0,n+1].
00145     if(a_in==UNDERFLOW_BIN) {
00146       a_out = 0;
00147       return true;
00148     } else if(a_in==OVERFLOW_BIN) {
00149       a_out = m_number_of_bins+1;
00150       return true;
00151     } else if((a_in>=0)&&(a_in<(int)m_number_of_bins)){
00152       a_out = a_in + 1;
00153       return true;
00154     } else {
00155       return false;
00156     }
00157   }
00158 
00159 public:
00160   // Partition :
00161   bool configure(const std::vector<TC>& aEdges) {
00162     // init :
00163     m_number_of_bins = 0;
00164     m_minimum_value = 0;
00165     m_maximum_value = 0;
00166     m_fixed = true;
00167     m_bin_width = 0;
00168     m_edges.clear();
00169     // setup :
00170     if(aEdges.size()<=1) return false;
00171     bn_t number = aEdges.size()-1;
00172     for(bn_t index=0;index<number;index++) {
00173       if((aEdges[index]>=aEdges[index+1])) {
00174         return false;
00175       }
00176     }
00177     m_edges = aEdges;
00178     m_number_of_bins = number;
00179     m_minimum_value = aEdges[0];
00180     m_maximum_value = aEdges[m_number_of_bins];
00181     m_fixed = false;
00182     return true;
00183   }
00184 
00185   bool configure(bn_t aNumber,TC aMin,TC aMax) {
00186     // init :
00187     m_number_of_bins = 0;
00188     m_minimum_value = 0;
00189     m_maximum_value = 0;
00190     m_fixed = true;
00191     m_bin_width = 0;
00192     m_edges.clear();
00193     // setup :
00194     if(aNumber<=0) return false;
00195     if(aMax<=aMin) return false;
00196     m_number_of_bins = aNumber;
00197     m_minimum_value = aMin;
00198     m_maximum_value = aMax;
00199     m_bin_width = (aMax - aMin)/ aNumber;
00200     m_fixed = true;
00201     return true;
00202   }
00203   
00204   bool is_compatible(const axis& a_axis) const {
00205     if(m_number_of_bins!=a_axis.m_number_of_bins) return false;
00206     if(m_minimum_value!=a_axis.m_minimum_value) return false;
00207     if(m_maximum_value!=a_axis.m_maximum_value) return false;
00208     return true;
00209   }
00210   
00211 public:
00212   axis()
00213   :m_offset(0)
00214   ,m_number_of_bins(0)
00215   ,m_minimum_value(0)
00216   ,m_maximum_value(0)
00217   ,m_fixed(true)
00218   ,m_bin_width(0)
00219   {}
00220 
00221   virtual ~axis(){}
00222 public:
00223   axis(const axis& a_axis)
00224   :m_offset(a_axis.m_offset)
00225   ,m_number_of_bins(a_axis.m_number_of_bins)
00226   ,m_minimum_value(a_axis.m_minimum_value)
00227   ,m_maximum_value(a_axis.m_maximum_value)
00228   ,m_fixed(a_axis.m_fixed)
00229   ,m_bin_width(a_axis.m_bin_width)
00230   ,m_edges(a_axis.m_edges)
00231   {}
00232 
00233   axis& operator=(const axis& a_axis) {
00234     m_offset = a_axis.m_offset;
00235     m_number_of_bins = a_axis.m_number_of_bins;
00236     m_minimum_value = a_axis.m_minimum_value;
00237     m_maximum_value = a_axis.m_maximum_value;
00238     m_fixed = a_axis.m_fixed;
00239     m_bin_width = a_axis.m_bin_width;
00240     m_edges = a_axis.m_edges;
00241     return *this;
00242   }
00243 
00244 public:
00245   bn_t m_offset;
00246   bn_t m_number_of_bins;
00247   TC m_minimum_value;
00248   TC m_maximum_value;
00249   bool m_fixed;
00250   // Fixed size bins :
00251   TC m_bin_width;
00252   // Variable size bins :
00253   std::vector<TC> m_edges;
00254 };
00255 
00256 }}
00257 
00258 #endif
00259 
00260 
00261 
00262 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines