inlib
1.2.0
|
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