Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_histo_axis 5 #define tools_histo_axis 6 7 #include <string> 8 #include <vector> 9 10 namespace tools { 11 namespace histo { 12 13 enum { axis_UNDERFLOW_BIN = -2, axis_OVERFLOW_ 14 15 //TC is for a coordinate. 16 //TO is for an offset used to identify a bin. 17 18 template <class TC,class TO> 19 class axis { 20 public: 21 typedef unsigned int bn_t; 22 public: 23 enum { UNDERFLOW_BIN = axis_UNDERFLOW_BIN, O 24 public: 25 bool is_fixed_binning() const {return m_fixe 26 TC lower_edge() const {return m_minimum_valu 27 TC upper_edge() const {return m_maximum_valu 28 bn_t bins() const {return m_number_of_bins;} 29 const std::vector<TC>& edges() const {return 30 31 TC bin_width(int a_bin) const { 32 if(a_bin==UNDERFLOW_BIN) { 33 return 0; //FIXME return DBL_MAX; 34 } else if(a_bin==OVERFLOW_BIN) { 35 return 0; //FIXME return DBL_MAX; 36 } else if((a_bin<0) ||(a_bin>=(int)m_numbe 37 return 0; 38 } else { 39 if(m_fixed) { 40 return m_bin_width; 41 } else { 42 return (m_edges[a_bin+1]-m_edges[a_bin 43 } 44 } 45 } 46 47 TC bin_lower_edge(int a_bin) const { 48 if(a_bin==UNDERFLOW_BIN) { 49 return 0; //FIXME return -DBL_MAX; 50 } else if(a_bin==OVERFLOW_BIN) { 51 return 0; //FIXME return bin_upper_edge( 52 } else if((a_bin<0) ||(a_bin>=(int)m_numbe 53 return 0; 54 } else { 55 if(m_fixed) { 56 return (m_minimum_value + a_bin * m_bi 57 } else { 58 return m_edges[a_bin]; 59 } 60 } 61 } 62 63 TC bin_upper_edge(int a_bin) const { 64 if(a_bin==UNDERFLOW_BIN) { 65 return 0; //FIXME bin_lower_edge(0) 66 } else if(a_bin==OVERFLOW_BIN) { 67 return 0; //FIXME return DBL_MAX; 68 } else if((a_bin<0) ||(a_bin>=(int)m_numbe 69 return 0; 70 } else { 71 if(m_fixed) { 72 return (m_minimum_value + (a_bin + 1) 73 } else { 74 return m_edges[a_bin+1]; 75 } 76 } 77 } 78 79 TC bin_center(int a_bin) const { 80 if(a_bin==UNDERFLOW_BIN) { 81 return 0; //FIXME : -INF 82 } else if(a_bin==OVERFLOW_BIN) { 83 return 0; //FIXME : +INF 84 } else if(a_bin<0) { 85 return 0; //FIXME : -INF 86 } else if(a_bin>=(int)m_number_of_bins) { 87 return 0; //FIXME : +INF 88 } else { 89 if(m_fixed) { 90 return (m_minimum_value + (a_bin + 0.5 91 } else { 92 return (m_edges[a_bin] + m_edges[a_bin 93 } 94 } 95 } 96 97 int coord_to_index(TC a_value) const { 98 if( a_value < m_minimum_value) { 99 return UNDERFLOW_BIN; 100 } else if( a_value >= m_maximum_value) { 101 return OVERFLOW_BIN; 102 } else { 103 if(m_fixed) { 104 return (int)((a_value - m_minimum_valu 105 } else { 106 for(bn_t index=0;index<m_number_of_bin 107 if((m_edges[index]<=a_value)&&(a_val 108 return index; 109 } 110 } 111 // Should never pass here... 112 return UNDERFLOW_BIN; 113 } 114 } 115 } 116 117 bool coord_to_absolute_index(TC a_value,bn_t 118 if( a_value < m_minimum_value) { 119 a_index = 0; 120 return true; 121 } else if( a_value >= m_maximum_value) { 122 a_index = m_number_of_bins+1; 123 return true; 124 } else { 125 if(m_fixed) { 126 a_index = (bn_t)((a_value - m_minimum_ 127 return true; 128 } else { 129 for(bn_t index=0;index<m_number_of_bin 130 if((m_edges[index]<=a_value)&&(a_val 131 a_index = index+1; 132 return true; 133 } 134 } 135 // Should never pass here... 136 a_index = 0; 137 return false; 138 } 139 } 140 } 141 142 bool in_range_to_absolute_index(int a_in,bn_ 143 // a_in is given in in-range indexing : 144 // - [0,n-1] for in-range bins 145 // - UNDERFLOW_BIN for the iaxis underflo 146 // - OVERFLOW_BIN for the iaxis overflow 147 // Return the absolute indexing in [0,n+1] 148 if(a_in==UNDERFLOW_BIN) { 149 a_out = 0; 150 return true; 151 } else if(a_in==OVERFLOW_BIN) { 152 a_out = m_number_of_bins+1; 153 return true; 154 } else if((a_in>=0)&&(a_in<(int)m_number_o 155 a_out = a_in + 1; 156 return true; 157 } else { 158 return false; 159 } 160 } 161 162 public: 163 // Partition : 164 bool configure(const std::vector<TC>& a_edge 165 // init : 166 m_number_of_bins = 0; 167 m_minimum_value = 0; 168 m_maximum_value = 0; 169 m_fixed = true; 170 m_bin_width = 0; 171 m_edges.clear(); 172 // setup : 173 if(a_edges.size()<=1) return false; 174 bn_t number = (bn_t)a_edges.size()-1; 175 for(bn_t index=0;index<number;index++) { 176 if((a_edges[index]>=a_edges[index+1])) { 177 return false; 178 } 179 } 180 m_edges = a_edges; 181 m_number_of_bins = number; 182 m_minimum_value = a_edges[0]; 183 m_maximum_value = a_edges[m_number_of_bins 184 m_fixed = false; 185 return true; 186 } 187 188 bool configure(bn_t aNumber,TC aMin,TC aMax) 189 // init : 190 m_number_of_bins = 0; 191 m_minimum_value = 0; 192 m_maximum_value = 0; 193 m_fixed = true; 194 m_bin_width = 0; 195 m_edges.clear(); 196 // setup : 197 if(aNumber<=0) return false; 198 if(aMax<=aMin) return false; 199 m_number_of_bins = aNumber; 200 m_minimum_value = aMin; 201 m_maximum_value = aMax; 202 m_bin_width = (aMax - aMin)/ aNumber; 203 m_fixed = true; 204 return true; 205 } 206 207 bool is_compatible(const axis& a_axis) const 208 if(m_number_of_bins!=a_axis.m_number_of_bi 209 if(m_minimum_value!=a_axis.m_minimum_value 210 if(m_maximum_value!=a_axis.m_maximum_value 211 return true; 212 } 213 214 public: 215 axis() 216 :m_offset(0) 217 ,m_number_of_bins(0) 218 ,m_minimum_value(0) 219 ,m_maximum_value(0) 220 ,m_fixed(true) 221 ,m_bin_width(0) 222 {} 223 224 virtual ~axis(){} 225 public: 226 axis(const axis& a_from) 227 :m_offset(a_from.m_offset) 228 ,m_number_of_bins(a_from.m_number_of_bins) 229 ,m_minimum_value(a_from.m_minimum_value) 230 ,m_maximum_value(a_from.m_maximum_value) 231 ,m_fixed(a_from.m_fixed) 232 ,m_bin_width(a_from.m_bin_width) 233 ,m_edges(a_from.m_edges) 234 {} 235 236 axis& operator=(const axis& a_from) { 237 if(&a_from==this) return *this; 238 m_offset = a_from.m_offset; 239 m_number_of_bins = a_from.m_number_of_bins 240 m_minimum_value = a_from.m_minimum_value; 241 m_maximum_value = a_from.m_maximum_value; 242 m_fixed = a_from.m_fixed; 243 m_bin_width = a_from.m_bin_width; 244 m_edges = a_from.m_edges; 245 return *this; 246 } 247 public: 248 bool equals(const axis& a_from) const { 249 if(&a_from==this) return true; 250 if(m_offset!=a_from.m_offset) return false 251 if(m_number_of_bins!=a_from.m_number_of_bi 252 if(m_minimum_value!=a_from.m_minimum_value 253 if(m_maximum_value!=a_from.m_maximum_value 254 if(m_fixed!=a_from.m_fixed) return false; 255 if(m_bin_width!=a_from.m_bin_width) return 256 if(m_edges!=a_from.m_edges) return false; 257 return true; 258 } 259 260 bool operator==(const axis& a_from) const {r 261 bool operator!=(const axis& a_from) const {r 262 263 public: 264 TO m_offset; 265 bn_t m_number_of_bins; 266 TC m_minimum_value; 267 TC m_maximum_value; 268 bool m_fixed; 269 // Fixed size bins : 270 TC m_bin_width; 271 // Variable size bins : 272 std::vector<TC> m_edges; 273 }; 274 275 }} 276 277 #endif 278 279 280 281