Warning, /include/Geant4/tools/histo/axis is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_histo_axis
0005 #define tools_histo_axis
0006
0007 #include <string>
0008 #include <vector>
0009
0010 namespace tools {
0011 namespace histo {
0012
0013 enum { axis_UNDERFLOW_BIN = -2, axis_OVERFLOW_BIN = -1 }; //AIDA casing.
0014
0015 //TC is for a coordinate.
0016 //TO is for an offset used to identify a bin.
0017
0018 template <class TC,class TO>
0019 class axis {
0020 public:
0021 typedef unsigned int bn_t;
0022 public:
0023 enum { UNDERFLOW_BIN = axis_UNDERFLOW_BIN, OVERFLOW_BIN = axis_OVERFLOW_BIN };
0024 public:
0025 bool is_fixed_binning() const {return m_fixed;}
0026 TC lower_edge() const {return m_minimum_value;}
0027 TC upper_edge() const {return m_maximum_value;}
0028 bn_t bins() const {return m_number_of_bins;}
0029 const std::vector<TC>& edges() const {return m_edges;}
0030
0031 TC bin_width(int a_bin) const {
0032 if(a_bin==UNDERFLOW_BIN) {
0033 return 0; //FIXME return DBL_MAX;
0034 } else if(a_bin==OVERFLOW_BIN) {
0035 return 0; //FIXME return DBL_MAX;
0036 } else if((a_bin<0) ||(a_bin>=(int)m_number_of_bins)) {
0037 return 0;
0038 } else {
0039 if(m_fixed) {
0040 return m_bin_width;
0041 } else {
0042 return (m_edges[a_bin+1]-m_edges[a_bin]);
0043 }
0044 }
0045 }
0046
0047 TC bin_lower_edge(int a_bin) const {
0048 if(a_bin==UNDERFLOW_BIN) {
0049 return 0; //FIXME return -DBL_MAX;
0050 } else if(a_bin==OVERFLOW_BIN) {
0051 return 0; //FIXME return bin_upper_edge(m_number_of_bins-1);
0052 } else if((a_bin<0) ||(a_bin>=(int)m_number_of_bins)) {
0053 return 0;
0054 } else {
0055 if(m_fixed) {
0056 return (m_minimum_value + a_bin * m_bin_width);
0057 } else {
0058 return m_edges[a_bin];
0059 }
0060 }
0061 }
0062
0063 TC bin_upper_edge(int a_bin) const {
0064 if(a_bin==UNDERFLOW_BIN) {
0065 return 0; //FIXME bin_lower_edge(0)
0066 } else if(a_bin==OVERFLOW_BIN) {
0067 return 0; //FIXME return DBL_MAX;
0068 } else if((a_bin<0) ||(a_bin>=(int)m_number_of_bins)) {
0069 return 0;
0070 } else {
0071 if(m_fixed) {
0072 return (m_minimum_value + (a_bin + 1) * m_bin_width);
0073 } else {
0074 return m_edges[a_bin+1];
0075 }
0076 }
0077 }
0078
0079 TC bin_center(int a_bin) const {
0080 if(a_bin==UNDERFLOW_BIN) {
0081 return 0; //FIXME : -INF
0082 } else if(a_bin==OVERFLOW_BIN) {
0083 return 0; //FIXME : +INF
0084 } else if(a_bin<0) {
0085 return 0; //FIXME : -INF
0086 } else if(a_bin>=(int)m_number_of_bins) {
0087 return 0; //FIXME : +INF
0088 } else {
0089 if(m_fixed) {
0090 return (m_minimum_value + (a_bin + 0.5) * m_bin_width);
0091 } else {
0092 return (m_edges[a_bin] + m_edges[a_bin+1])/2.;
0093 }
0094 }
0095 }
0096
0097 int coord_to_index(TC a_value) const {
0098 if( a_value < m_minimum_value) {
0099 return UNDERFLOW_BIN;
0100 } else if( a_value >= m_maximum_value) {
0101 return OVERFLOW_BIN;
0102 } else {
0103 if(m_fixed) {
0104 return (int)((a_value - m_minimum_value)/m_bin_width);
0105 } else {
0106 for(bn_t index=0;index<m_number_of_bins;index++) {
0107 if((m_edges[index]<=a_value)&&(a_value<m_edges[index+1])) {
0108 return index;
0109 }
0110 }
0111 // Should never pass here...
0112 return UNDERFLOW_BIN;
0113 }
0114 }
0115 }
0116
0117 bool coord_to_absolute_index(TC a_value,bn_t& a_index) const {
0118 if( a_value < m_minimum_value) {
0119 a_index = 0;
0120 return true;
0121 } else if( a_value >= m_maximum_value) {
0122 a_index = m_number_of_bins+1;
0123 return true;
0124 } else {
0125 if(m_fixed) {
0126 a_index = (bn_t)((a_value - m_minimum_value)/m_bin_width)+1;
0127 return true;
0128 } else {
0129 for(bn_t index=0;index<m_number_of_bins;index++) {
0130 if((m_edges[index]<=a_value)&&(a_value<m_edges[index+1])) {
0131 a_index = index+1;
0132 return true;
0133 }
0134 }
0135 // Should never pass here...
0136 a_index = 0;
0137 return false;
0138 }
0139 }
0140 }
0141
0142 bool in_range_to_absolute_index(int a_in,bn_t& a_out) const {
0143 // a_in is given in in-range indexing :
0144 // - [0,n-1] for in-range bins
0145 // - UNDERFLOW_BIN for the iaxis underflow bin
0146 // - OVERFLOW_BIN for the iaxis overflow bin
0147 // Return the absolute indexing in [0,n+1].
0148 if(a_in==UNDERFLOW_BIN) {
0149 a_out = 0;
0150 return true;
0151 } else if(a_in==OVERFLOW_BIN) {
0152 a_out = m_number_of_bins+1;
0153 return true;
0154 } else if((a_in>=0)&&(a_in<(int)m_number_of_bins)){
0155 a_out = a_in + 1;
0156 return true;
0157 } else {
0158 return false;
0159 }
0160 }
0161
0162 public:
0163 // Partition :
0164 bool configure(const std::vector<TC>& a_edges) {
0165 // init :
0166 m_number_of_bins = 0;
0167 m_minimum_value = 0;
0168 m_maximum_value = 0;
0169 m_fixed = true;
0170 m_bin_width = 0;
0171 m_edges.clear();
0172 // setup :
0173 if(a_edges.size()<=1) return false;
0174 bn_t number = (bn_t)a_edges.size()-1;
0175 for(bn_t index=0;index<number;index++) {
0176 if((a_edges[index]>=a_edges[index+1])) {
0177 return false;
0178 }
0179 }
0180 m_edges = a_edges;
0181 m_number_of_bins = number;
0182 m_minimum_value = a_edges[0];
0183 m_maximum_value = a_edges[m_number_of_bins];
0184 m_fixed = false;
0185 return true;
0186 }
0187
0188 bool configure(bn_t aNumber,TC aMin,TC aMax) {
0189 // init :
0190 m_number_of_bins = 0;
0191 m_minimum_value = 0;
0192 m_maximum_value = 0;
0193 m_fixed = true;
0194 m_bin_width = 0;
0195 m_edges.clear();
0196 // setup :
0197 if(aNumber<=0) return false;
0198 if(aMax<=aMin) return false;
0199 m_number_of_bins = aNumber;
0200 m_minimum_value = aMin;
0201 m_maximum_value = aMax;
0202 m_bin_width = (aMax - aMin)/ aNumber;
0203 m_fixed = true;
0204 return true;
0205 }
0206
0207 bool is_compatible(const axis& a_axis) const {
0208 if(m_number_of_bins!=a_axis.m_number_of_bins) return false;
0209 if(m_minimum_value!=a_axis.m_minimum_value) return false;
0210 if(m_maximum_value!=a_axis.m_maximum_value) return false;
0211 return true;
0212 }
0213
0214 public:
0215 axis()
0216 :m_offset(0)
0217 ,m_number_of_bins(0)
0218 ,m_minimum_value(0)
0219 ,m_maximum_value(0)
0220 ,m_fixed(true)
0221 ,m_bin_width(0)
0222 {}
0223
0224 virtual ~axis(){}
0225 public:
0226 axis(const axis& a_from)
0227 :m_offset(a_from.m_offset)
0228 ,m_number_of_bins(a_from.m_number_of_bins)
0229 ,m_minimum_value(a_from.m_minimum_value)
0230 ,m_maximum_value(a_from.m_maximum_value)
0231 ,m_fixed(a_from.m_fixed)
0232 ,m_bin_width(a_from.m_bin_width)
0233 ,m_edges(a_from.m_edges)
0234 {}
0235
0236 axis& operator=(const axis& a_from) {
0237 if(&a_from==this) return *this;
0238 m_offset = a_from.m_offset;
0239 m_number_of_bins = a_from.m_number_of_bins;
0240 m_minimum_value = a_from.m_minimum_value;
0241 m_maximum_value = a_from.m_maximum_value;
0242 m_fixed = a_from.m_fixed;
0243 m_bin_width = a_from.m_bin_width;
0244 m_edges = a_from.m_edges;
0245 return *this;
0246 }
0247 public:
0248 bool equals(const axis& a_from) const {
0249 if(&a_from==this) return true;
0250 if(m_offset!=a_from.m_offset) return false;
0251 if(m_number_of_bins!=a_from.m_number_of_bins) return false;
0252 if(m_minimum_value!=a_from.m_minimum_value) return false;
0253 if(m_maximum_value!=a_from.m_maximum_value) return false;
0254 if(m_fixed!=a_from.m_fixed) return false;
0255 if(m_bin_width!=a_from.m_bin_width) return false;
0256 if(m_edges!=a_from.m_edges) return false;
0257 return true;
0258 }
0259
0260 bool operator==(const axis& a_from) const {return equals(a_from);}
0261 bool operator!=(const axis& a_from) const {return !equals(a_from);}
0262
0263 public:
0264 TO m_offset;
0265 bn_t m_number_of_bins;
0266 TC m_minimum_value;
0267 TC m_maximum_value;
0268 bool m_fixed;
0269 // Fixed size bins :
0270 TC m_bin_width;
0271 // Variable size bins :
0272 std::vector<TC> m_edges;
0273 };
0274
0275 }}
0276
0277 #endif
0278
0279
0280
0281