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_h1 00005 #define inlib_histo_h1 00006 00007 #include "b1" 00008 00009 namespace inlib { 00010 namespace histo { //have that for h1 ? 00011 00012 //TC is for a coordinate. 00013 //TN is for a number of entries. 00014 //TW is for a weight. 00015 //TH is for a height. Should be the same as TW. 00016 00017 template <class TC,class TN,class TW,class TH> 00018 class h1 : public b1<TC,TN,TW,TH> { 00019 typedef b1<TC,TN,TW,TH> parent; 00020 public: 00021 typedef typename b1<TC,TN,TW,TH>::bn_t bn_t; 00022 protected: 00023 virtual TH get_bin_height(int a_offset) const { //TH should be the same as TW 00024 return parent::m_bin_Sw[a_offset]; 00025 } 00026 public: 00027 virtual TH bin_error(int aI) const { //TH should be the same as TW 00028 if(parent::m_bin_number==0) return 0; 00029 bn_t offset; 00030 if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0; 00031 return ::sqrt(parent::m_bin_Sw2[offset]); 00032 } 00033 00034 public: 00035 bool multiply(TW aFactor){ 00036 if(!parent::base_multiply(aFactor)) return false; 00037 this->update_fast_getters(); 00038 return true; 00039 } 00040 bool scale(TW aFactor) {return multiply(aFactor);} 00041 00042 void copy_from_data(const histo_data<TC,TN,TW>& a_from) { 00043 parent::base_from_data(a_from); 00044 } 00045 histo_data<TC,TN,TW> get_histo_data() const { 00046 return parent::base_get_data(); 00047 } 00048 00049 bool reset() { 00050 parent::base_reset(); 00051 this->update_fast_getters(); 00052 return true; 00053 } 00054 00055 bool fill(TC aX,TW aWeight = 1) { 00056 //m_coords[0] = aX; 00057 //return fill_bin(m_coords,aWeight); 00058 if(parent::m_dimension<=0) return false; 00059 00060 bn_t offset; 00061 if(!parent::m_axes[0].coord_to_absolute_index(aX,offset)) return false; 00062 00063 parent::m_bin_entries[offset]++; 00064 parent::m_bin_Sw[offset] += aWeight; 00065 parent::m_bin_Sw2[offset] += aWeight * aWeight; 00066 00067 TC xw = aX * aWeight; 00068 TC x2w = aX * xw; 00069 parent::m_bin_Sxw[offset][0] += xw; 00070 parent::m_bin_Sx2w[offset][0] += x2w; 00071 return true; 00072 } 00073 00074 bool add(const h1& a_histo){ 00075 parent::base_add(a_histo); 00076 this->update_fast_getters(); 00077 return true; 00078 } 00079 bool subtract(const h1& a_histo){ 00080 parent::base_subtract(a_histo); 00081 this->update_fast_getters(); 00082 return true; 00083 } 00084 00085 bool multiply(const h1& a_histo) { 00086 if(!parent::base_multiply(a_histo)) return false; 00087 this->update_fast_getters(); 00088 return true; 00089 } 00090 00091 bool divide(const h1& a_histo) { 00092 if(!parent::base_divide(a_histo)) return false; 00093 this->update_fast_getters(); 00094 return true; 00095 } 00096 00097 bool gather_bins(unsigned int a_factor) { //for exa 2,3. 00098 if(!a_factor) return false; 00099 00100 // actual bin number must be a multiple of a_factor. 00101 00102 const histo::axis<TC>& _axis = this->axis(); 00103 00104 bn_t n = _axis.bins(); 00105 if(!n) return false; 00106 00107 bn_t new_n = n/a_factor; 00108 if(a_factor*new_n!=n) return false; 00109 00110 h1* new_h = 0; 00111 if(_axis.is_fixed_binning()) { 00112 new_h = new h1(parent::m_title, 00113 new_n,_axis.lower_edge(),_axis.upper_edge()); 00114 } else { 00115 const std::vector<TC>& _edges = _axis.edges(); 00116 std::vector<TC> new_edges(new_n+1); 00117 for(bn_t ibin=0;ibin<new_n;ibin++) { 00118 new_edges[ibin] = _edges[ibin*a_factor]; 00119 } 00120 new_edges[new_n] = _edges[n]; //upper edge. 00121 new_h = new h1(parent::m_title,new_edges); 00122 } 00123 if(!new_h) return false; 00124 00125 bn_t offset,new_offset,offac; 00126 for(bn_t ibin=0;ibin<new_n;ibin++) { 00127 new_offset = ibin+1; 00128 offset = a_factor*ibin+1; 00129 for(unsigned int ifac=0;ifac<a_factor;ifac++) { 00130 offac = offset+ifac; 00131 new_h->m_bin_entries[new_offset] += parent::m_bin_entries[offac]; 00132 new_h->m_bin_Sw[new_offset] += parent::m_bin_Sw[offac]; 00133 new_h->m_bin_Sw2[new_offset] += parent::m_bin_Sw2[offac]; 00134 new_h->m_bin_Sxw[new_offset][0] += parent::m_bin_Sxw[offac][0]; 00135 new_h->m_bin_Sx2w[new_offset][0] += parent::m_bin_Sx2w[offac][0]; 00136 } 00137 } 00138 00139 //underflow : 00140 new_offset = 0; 00141 offac = 0; 00142 new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac]; 00143 new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac]; 00144 new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac]; 00145 new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0]; 00146 new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0]; 00147 00148 //overflow : 00149 new_offset = new_n+1; 00150 offac = n+1; 00151 new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac]; 00152 new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac]; 00153 new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac]; 00154 new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0]; 00155 new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0]; 00156 00157 *this = *new_h; 00158 return true; 00159 } 00160 00161 public: 00162 h1(const std::string& a_title, 00163 bn_t aXnumber,TC aXmin,TC aXmax) 00164 : parent(a_title,aXnumber,aXmin,aXmax){} 00165 00166 h1(const std::string& a_title, 00167 const std::vector<TC>& aEdges) 00168 : parent(a_title,aEdges){} 00169 00170 virtual ~h1(){} 00171 public: 00172 h1(const h1& a_from): parent(a_from){} 00173 h1& operator=(const h1& a_from){ 00174 parent::operator=(a_from); 00175 return *this; 00176 } 00177 }; 00178 00179 }} 00180 00181 #endif 00182 00183 00184 00185