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