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 }