00001 00012 #ifdef _MSC_VER 00013 #include "msdevstudio/MSconfig.h" 00014 #endif 00015 00016 #include "NTupleFCN.h" 00017 00018 #include "datasrcs/DataPointTuple.h" 00019 #include "datasrcs/DataSource.h" 00020 #include "datasrcs/TupleCut.h" 00021 00022 #include "functions/FunctionBase.h" 00023 00024 #include <algorithm> 00025 #include <functional> 00026 00027 using std::bind2nd; 00028 using std::count; 00029 using std::find_if; 00030 using std::not_equal_to; 00031 using std::vector; 00032 00033 using namespace hippodraw; 00034 00035 NTupleFCN:: 00036 NTupleFCN ( ) 00037 : m_fit_cut ( 0 ), 00038 m_fit_range ( false ), 00039 m_ntuple ( 0 ) 00040 { 00041 } 00042 00043 NTupleFCN:: 00044 NTupleFCN ( const NTupleFCN & fcn ) 00045 : StatedFCN ( fcn ), 00046 m_fit_cut ( 0 ), 00047 m_fit_range ( fcn.m_fit_range ), 00048 m_ntuple ( fcn.m_ntuple ) 00049 { 00050 } 00051 00052 NTupleFCN:: 00053 NTupleFCN ( const DataSource * ntuple, FunctionBase * function ) 00054 : StatedFCN ( function ), 00055 m_fit_cut ( 0 ), 00056 m_fit_range ( false ), 00057 m_ntuple ( ntuple ) 00058 { 00059 } 00060 00061 namespace dp2 = hippodraw::DataPoint2DTuple; 00062 namespace dp3 = hippodraw::DataPoint3DTuple; 00063 00064 void 00065 NTupleFCN:: 00066 setDataSource ( const DataSource * ntuple ) 00067 { 00068 unsigned int size = dp2::SIZE; 00069 if ( ntuple -> columns () == dp3::SIZE ) size = dp3::SIZE; 00070 vector < int > indices ( size ); 00071 00072 if ( size == dp2::SIZE ) { 00073 indices [ dp2::X ] = dp2::X; 00074 indices [ dp2::Y ] = dp2::Y; 00075 indices [ dp2::XERR ] = dp2::XERR; 00076 indices [ dp2::YERR ] = dp2::YERR; 00077 } 00078 00079 if ( size == dp3::SIZE ) { 00080 indices [ dp3::X ] = dp3::X; 00081 indices [ dp3::Y ] = dp3::Y; 00082 indices [ dp3::Z ] = dp3::Z; 00083 indices [ dp3::XERR ] = dp3::XERR; 00084 indices [ dp3::YERR ] = dp3::YERR; 00085 indices [ dp3::ZERR ] = dp3::ZERR; 00086 } 00087 int dimension = size == dp2::SIZE ? 1 : 2; 00088 00089 setDataSource ( ntuple, dimension, indices ); 00090 } 00091 00092 void 00093 NTupleFCN:: 00094 setDataSource ( const DataSource * ntuple, 00095 int dimension, 00096 const std::vector < int > & indices ) 00097 { 00098 m_ntuple = ntuple; 00099 m_indices = indices; 00100 m_dimen = dimension; 00101 } 00102 00103 int 00104 NTupleFCN:: 00105 getErrorColumn () const 00106 { 00107 int ie = -1; 00108 if ( m_dimen == 1 ) { 00109 ie = m_indices [ dp2::YERR ]; 00110 } 00111 else { 00112 ie = m_indices [ dp3::ZERR ]; 00113 } 00114 return ie; 00115 } 00116 00117 bool 00118 NTupleFCN:: 00119 hasErrors ( ) const 00120 { 00121 int ie = getErrorColumn (); 00122 const vector < double > & errors = m_ntuple -> getColumn ( ie ); 00123 00124 if ( errors.empty() ) return false; 00125 00126 vector < double >::const_iterator first 00127 = find_if ( errors.begin(), errors.end (), 00128 bind2nd ( not_equal_to < double > (), 0.0 ) ); 00129 00130 return first != errors.end (); 00131 } 00132 00133 bool 00134 NTupleFCN:: 00135 setUseErrors ( bool yes ) 00136 { 00137 bool didit = false; 00138 if ( yes ) { 00139 if ( hasErrors () ) { 00140 m_has_errors = true; 00141 didit = true; 00142 } 00143 else m_has_errors = false; 00144 } 00145 else { 00146 m_has_errors = false; 00147 didit = true; 00148 } 00149 return didit; 00150 } 00151 00152 int 00153 NTupleFCN:: 00154 degreesOfFreedom () const 00155 { 00156 int ie = getErrorColumn (); 00157 00158 const vector < double > & errors = m_ntuple -> getColumn ( ie ); 00159 int number_points = errors.size(); 00160 if ( m_has_errors ) { 00161 int zeros = count ( errors.begin(), errors.end(), 0.0 ); 00162 number_points -= zeros; 00163 } 00164 00165 vector< double > free_parms; 00166 return number_points - getNumberFreeParms (); 00167 } 00168 00169 void 00170 NTupleFCN:: 00171 reset ( std::vector < std::vector < double > > & alpha, 00172 std::vector < double > & beta, 00173 unsigned int size ) 00174 { 00175 beta.clear (); 00176 beta.resize ( size, 0.0 ); 00177 00178 alpha.resize ( size ); 00179 00180 for ( unsigned int i = 0; i < alpha.size (); i++ ) { 00181 alpha[i].clear (); 00182 alpha[i].resize ( size, 0.0 ); 00183 } 00184 } 00185 00188 void 00189 NTupleFCN:: 00190 calcAlphaBeta ( std::vector < std::vector < double > > & alpha, 00191 std::vector < double > & beta ) 00192 { 00193 int ix = m_indices [ dp2::X ]; 00194 int iy = m_indices [ dp2::Y ]; 00195 int ie = m_indices [ dp2::YERR ]; 00196 unsigned int num_parms = getNumberFreeParms (); 00197 reset ( alpha, beta, num_parms ); 00198 00199 unsigned int rows = m_ntuple -> rows (); 00200 for ( unsigned int i = 0; i < rows; i++ ) { 00201 if ( acceptRow ( i ) ) { 00202 const vector < double > & row = m_ntuple -> getRow ( i ); 00203 00204 double err = ie < 0 ? 0. : row [ ie ]; 00205 if ( err == 0.0 && m_has_errors ) continue; 00206 if ( m_has_errors == false ) err = 1.0; 00207 00208 double x = row [ ix ]; 00209 double y = row [ iy ]; 00210 00211 double y_diff = y - m_function -> operator () ( x ); 00212 vector < double > derives; 00213 fillFreeDerivatives ( derives, x ); 00214 00215 for ( unsigned int j = 0; j < num_parms; j++ ) { 00216 double t = derives[j] / ( err * err ); 00217 00218 for ( unsigned int k = 0; k <= j; k++ ) { 00219 alpha[j][k] = alpha[j][k] + t * derives[k]; 00220 } 00221 00222 beta[j] += t * y_diff; 00223 } 00224 } 00225 } 00226 } 00227 00230 void 00231 NTupleFCN:: 00232 setFitCut ( TupleCut * cut ) 00233 { 00234 int ix = m_indices [ dp2::X ]; 00235 cut -> setColumn ( ix ); 00236 00237 m_fit_cut = cut; 00238 } 00239 00240 void 00241 NTupleFCN:: 00242 setFitRange ( bool yes ) 00243 { 00244 m_fit_range = yes; 00245 } 00246 00247 bool 00248 NTupleFCN:: 00249 acceptRow ( unsigned int row ) const 00250 { 00251 bool yes = true; 00252 if ( m_fit_cut != 0 && 00253 m_fit_cut -> isEnabled () && 00254 m_fit_range ) { 00255 yes = m_fit_cut -> acceptRow ( m_ntuple, row ); 00256 } 00257 00258 return yes; 00259 }