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_c2d 00005 #define inlib_histo_c2d 00006 00007 #include "base_cloud" 00008 00009 #include <inlib/mnmx> 00010 00011 #include "h2d" 00012 00013 namespace inlib { 00014 namespace histo { 00015 00016 class c2d : public base_cloud { 00017 public: 00018 bool set_title(const std::string&); 00019 unsigned int dimension() const {return 2;} 00020 bool reset(); 00021 unsigned int entries() const; 00022 public: 00023 double sum_of_weights() const; 00024 bool convert_to_histogram(); 00025 bool is_converted() const; 00026 bool scale(double); 00027 public: 00028 bool fill(double,double,double = 1); 00029 double lower_edge_x() const; 00030 double upper_edge_x() const; 00031 double lower_edge_y() const; 00032 double upper_edge_y() const; 00033 double value_x(unsigned int) const; 00034 double value_y(unsigned int) const; 00035 double weight(unsigned int) const; 00036 double mean_x() const; 00037 double mean_y() const; 00038 double rms_x() const; 00039 double rms_y() const; 00040 bool convert(unsigned int,double,double, 00041 unsigned int,double,double); 00042 bool convert(const std::vector<double>&,const std::vector<double>&); 00043 const histo::h2d& histogram() const; 00044 bool fill_histogram(histo::h2d& a_histo) const { 00045 unsigned int number = m_xs.size(); 00046 for(unsigned int index=0;index<number;index++) { 00047 if(!a_histo.fill(m_xs[index],m_ys[index],m_ws[index])) return false; 00048 } 00049 return true; 00050 } 00051 bool set_conversion_parameters(unsigned int,double,double, 00052 unsigned int,double,double); 00053 public: 00054 c2d(); 00055 c2d(const std::string&,int=-1); 00056 virtual ~c2d(){delete m_histo;} 00057 public: 00058 c2d(const c2d& a_from) 00059 :base_cloud(a_from) 00060 ,m_xs(a_from.m_xs) 00061 ,m_ys(a_from.m_ys) 00062 ,m_lower_x(a_from.m_lower_x) 00063 ,m_upper_x(a_from.m_upper_x) 00064 ,m_lower_y(a_from.m_lower_y) 00065 ,m_upper_y(a_from.m_upper_y) 00066 ,m_Sxw(a_from.m_Sxw) 00067 ,m_Sx2w(a_from.m_Sx2w) 00068 ,m_Syw(a_from.m_Syw) 00069 ,m_Sy2w(a_from.m_Sy2w) 00070 ,m_cnv_x_num(a_from.m_cnv_x_num) 00071 ,m_cnv_x_min(a_from.m_cnv_x_min) 00072 ,m_cnv_x_max(a_from.m_cnv_x_max) 00073 ,m_cnv_y_num(a_from.m_cnv_y_num) 00074 ,m_cnv_y_min(a_from.m_cnv_y_min) 00075 ,m_cnv_y_max(a_from.m_cnv_y_max) 00076 ,m_histo(0) 00077 { 00078 if(a_from.m_histo) { 00079 m_histo = new histo::h2d(*a_from.m_histo); 00080 } 00081 } 00082 00083 c2d& operator=(const c2d& a_from) { 00084 base_cloud::operator=(a_from); 00085 m_xs = a_from.m_xs; 00086 m_ys = a_from.m_ys; 00087 m_lower_x = a_from.m_lower_x; 00088 m_upper_x = a_from.m_upper_x; 00089 m_lower_y = a_from.m_lower_y; 00090 m_upper_y = a_from.m_upper_y; 00091 m_Sxw = a_from.m_Sxw; 00092 m_Sx2w = a_from.m_Sx2w; 00093 m_Syw = a_from.m_Syw; 00094 m_Sy2w = a_from.m_Sy2w; 00095 m_cnv_x_num = a_from.m_cnv_x_num; 00096 m_cnv_x_min = a_from.m_cnv_x_min; 00097 m_cnv_x_max = a_from.m_cnv_x_max; 00098 m_cnv_y_num = a_from.m_cnv_y_num; 00099 m_cnv_y_min = a_from.m_cnv_y_min; 00100 m_cnv_y_max = a_from.m_cnv_y_max; 00101 delete m_histo; 00102 m_histo = 0; 00103 if(a_from.m_histo) { 00104 m_histo = new histo::h2d(*a_from.m_histo); 00105 } 00106 return *this; 00107 } 00108 protected: 00109 void clear(); 00110 protected: 00111 std::vector<double> m_xs; 00112 std::vector<double> m_ys; 00113 double m_lower_x; 00114 double m_upper_x; 00115 double m_lower_y; 00116 double m_upper_y; 00117 double m_Sxw; 00118 double m_Sx2w; 00119 double m_Syw; 00120 double m_Sy2w; 00121 // 00122 unsigned int m_cnv_x_num; 00123 double m_cnv_x_min; 00124 double m_cnv_x_max; 00125 unsigned int m_cnv_y_num; 00126 double m_cnv_y_min; 00127 double m_cnv_y_max; 00128 histo::h2d* m_histo; 00129 }; 00130 00131 }} 00132 00133 namespace inlib { 00134 namespace histo { 00135 00136 inline 00137 c2d::c2d() 00138 :base_cloud(UNLIMITED()) 00139 ,m_lower_x(0) 00140 ,m_upper_x(0) 00141 ,m_lower_y(0) 00142 ,m_upper_y(0) 00143 ,m_Sxw(0) 00144 ,m_Sx2w(0) 00145 ,m_Syw(0) 00146 ,m_Sy2w(0) 00147 ,m_cnv_x_num(0) 00148 ,m_cnv_x_min(0) 00149 ,m_cnv_x_max(0) 00150 ,m_cnv_y_num(0) 00151 ,m_cnv_y_min(0) 00152 ,m_cnv_y_max(0) 00153 ,m_histo(0) 00154 {} 00155 00156 inline 00157 c2d::c2d(const std::string& a_title,int aLimit) 00158 :base_cloud(aLimit) 00159 ,m_lower_x(0) 00160 ,m_upper_x(0) 00161 ,m_lower_y(0) 00162 ,m_upper_y(0) 00163 ,m_Sxw(0) 00164 ,m_Sx2w(0) 00165 ,m_Syw(0) 00166 ,m_Sy2w(0) 00167 ,m_cnv_x_num(0) 00168 ,m_cnv_x_min(0) 00169 ,m_cnv_x_max(0) 00170 ,m_cnv_y_num(0) 00171 ,m_cnv_y_min(0) 00172 ,m_cnv_y_max(0) 00173 ,m_histo(0) 00174 { 00175 set_title(a_title); 00176 } 00177 00178 inline 00179 bool c2d::is_converted() const {return m_histo ? true : false;} 00180 00181 inline 00182 void c2d::clear(){ 00183 m_lower_x = 0; 00184 m_upper_x = 0; 00185 m_lower_y = 0; 00186 m_upper_y = 0; 00187 m_Sw = 0; 00188 m_Sxw = 0; 00189 m_Sx2w = 0; 00190 m_Syw = 0; 00191 m_Sy2w = 0; 00192 m_xs.clear(); 00193 m_ys.clear(); 00194 m_ws.clear(); 00195 } 00196 00197 inline 00198 bool c2d::convert( 00199 unsigned int aBinsX,double aLowerEdgeX,double aUpperEdgeX 00200 ,unsigned int aBinsY,double aLowerEdgeY,double aUpperEdgeY 00201 ) { 00202 if(m_histo) return true; // Done. 00203 m_histo = new histo::h2d(this->title(), 00204 aBinsX,aLowerEdgeX,aUpperEdgeX, 00205 aBinsY,aLowerEdgeY,aUpperEdgeY); 00206 if(!m_histo) return false; 00207 bool status = fill_histogram(*m_histo); 00208 clear(); 00209 return status; 00210 } 00211 00212 inline 00213 bool c2d::convert_to_histogram(){ 00214 if( (m_cnv_x_num<=0) || (m_cnv_x_max<=m_cnv_x_min) || 00215 (m_cnv_y_num<=0) || (m_cnv_y_max<=m_cnv_y_min) ) { 00216 double dx = 0.01 * (upper_edge_x() - lower_edge_x())/BINS(); 00217 double dy = 0.01 * (upper_edge_y() - lower_edge_y())/BINS(); 00218 return convert(BINS(),lower_edge_x(),upper_edge_x()+dx, 00219 BINS(),lower_edge_y(),upper_edge_y()+dy); 00220 } else { 00221 return convert(m_cnv_x_num,m_cnv_x_min,m_cnv_x_max, 00222 m_cnv_y_num,m_cnv_y_min,m_cnv_y_max); 00223 } 00224 } 00225 00226 00227 inline 00228 bool c2d::set_title(const std::string& a_title){ 00229 m_title = a_title; 00230 if(m_histo) m_histo->set_title(a_title); 00231 return true; 00232 } 00233 00234 inline 00235 bool c2d::scale(double a_scale) { 00236 if(m_histo) { 00237 return m_histo->scale(a_scale); 00238 } else { 00239 unsigned int number = m_ws.size(); 00240 for(unsigned int index=0;index<number;index++) m_ws[index] *= a_scale; 00241 m_Sw *= a_scale; 00242 m_Sxw *= a_scale; 00243 m_Sx2w *= a_scale; 00244 m_Syw *= a_scale; 00245 m_Sy2w *= a_scale; 00246 return true; 00247 } 00248 } 00249 00250 inline 00251 bool c2d::reset() { 00252 clear(); 00253 delete m_histo; 00254 m_histo = 0; 00255 return true; 00256 } 00257 00258 inline 00259 bool c2d::fill(double aX,double aY,double aW){ 00260 if(!m_histo && (m_limit!=UNLIMITED()) && ((int)m_xs.size()>=m_limit)){ 00261 convert_to_histogram(); 00262 } 00263 00264 if(m_histo) { 00265 return m_histo->fill(aX,aY,aW); 00266 } else { 00267 if(m_xs.size()) { 00268 m_lower_x = inlib::mn<double>(aX,m_lower_x); 00269 m_upper_x = inlib::mx<double>(aX,m_upper_x); 00270 } else { 00271 m_lower_x = aX; 00272 m_upper_x = aX; 00273 } 00274 if(m_ys.size()) { 00275 m_lower_y = inlib::mn<double>(aY,m_lower_y); 00276 m_upper_y = inlib::mx<double>(aY,m_upper_y); 00277 } else { 00278 m_lower_y = aY; 00279 m_upper_y = aY; 00280 } 00281 m_xs.push_back(aX); 00282 m_ys.push_back(aY); 00283 m_ws.push_back(aW); 00284 m_Sw += aW; 00285 double xw = aX * aW; 00286 m_Sxw += xw; 00287 m_Sx2w += aX * xw; 00288 double yw = aY * aW; 00289 m_Syw += yw; 00290 m_Sy2w += aY * yw; 00291 return true; 00292 } 00293 } 00294 00295 inline 00296 bool c2d::convert(const std::vector<double>& aEdgesX,const std::vector<double>& aEdgesY) { 00297 if(m_histo) return true; 00298 m_histo = new histo::h2d(this->title(), 00299 aEdgesX,aEdgesY); 00300 if(!m_histo) return false; 00301 bool status = fill_histogram(*m_histo); 00302 clear(); 00303 return status; 00304 } 00305 00306 inline 00307 bool c2d::set_conversion_parameters( 00308 unsigned int aCnvXnumber,double aCnvXmin,double aCnvXmax 00309 ,unsigned int aCnvYnumber,double aCnvYmin,double aCnvYmax 00310 ){ 00311 m_cnv_x_num = aCnvXnumber; 00312 m_cnv_x_min = aCnvXmin; 00313 m_cnv_x_max = aCnvXmax; 00314 m_cnv_y_num = aCnvYnumber; 00315 m_cnv_y_min = aCnvYmin; 00316 m_cnv_y_max = aCnvYmax; 00317 return true; 00318 } 00319 00320 inline 00321 const h2d& c2d::histogram() const { 00322 if(!m_histo) const_cast<c2d&>(*this).convert_to_histogram(); 00323 return *m_histo; 00324 } 00325 00326 inline 00327 unsigned int c2d::entries() const { 00328 return m_histo ? m_histo->all_entries() : m_ws.size(); 00329 } 00330 00331 inline 00332 double c2d::sum_of_weights() const { 00333 return (m_histo ? m_histo->sum_bin_heights() : m_Sw); 00334 } 00335 00336 inline 00337 double c2d::lower_edge_x() const { 00338 return m_histo ? m_histo->axis_x().lower_edge() : m_lower_x; 00339 } 00340 inline 00341 double c2d::lower_edge_y() const { 00342 return m_histo ? m_histo->axis_y().lower_edge() : m_lower_y; 00343 } 00344 inline 00345 double c2d::upper_edge_x() const { 00346 return m_histo ? m_histo->axis_x().upper_edge() : m_upper_x; 00347 } 00348 inline 00349 double c2d::upper_edge_y() const { 00350 return m_histo ? m_histo->axis_y().upper_edge() : m_upper_y; 00351 } 00352 inline 00353 double c2d::value_x(unsigned int aIndex) const { 00354 return m_histo ? 0 : m_xs[aIndex]; 00355 } 00356 inline 00357 double c2d::value_y(unsigned int aIndex) const { 00358 return m_histo ? 0 : m_ys[aIndex]; 00359 } 00360 inline 00361 double c2d::weight(unsigned int aIndex) const { 00362 return m_histo ? 0 : m_ws[aIndex]; 00363 } 00364 00365 inline 00366 double c2d::mean_x() const { 00367 return m_histo ? m_histo->mean_x() : (m_Sw?m_Sxw/m_Sw:0); 00368 } 00369 inline 00370 double c2d::mean_y() const { 00371 return m_histo ? m_histo->mean_y() : (m_Sw?m_Syw/m_Sw:0); 00372 } 00373 inline 00374 double c2d::rms_x() const { 00375 double rms = 0; //FIXME nan. 00376 if(m_histo) { 00377 rms = m_histo->rms_x(); 00378 } else { 00379 if(m_Sw==0) { 00380 } else { 00381 double mean = m_Sxw / m_Sw; 00382 rms = ::sqrt(::fabs( (m_Sx2w / m_Sw) - mean * mean)); 00383 } 00384 } 00385 return rms; 00386 } 00387 inline 00388 double c2d::rms_y() const { 00389 double rms = 0; //FIXME nan. 00390 if(m_histo) { 00391 rms = m_histo->rms_y(); 00392 } else { 00393 if(m_Sw==0) { 00394 } else { 00395 double mean = m_Syw / m_Sw; 00396 rms = ::sqrt(::fabs( (m_Sy2w / m_Sw) - mean * mean)); 00397 } 00398 } 00399 return rms; 00400 } 00401 00402 }} 00403 00404 #endif