00001
00012
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016
00017
00018 #ifdef _MSC_VER
00019 #include "msdevstudio/MSconfig.h"
00020 #endif
00021
00022 #include "FunctionProjector.h"
00023
00024 #include "ProjectorHelper.h"
00025
00026 #include "axes/AxisModelBase.h"
00027 #include "binners/BinsFunction.h"
00028 #include "datasrcs/DataPointTuple.h"
00029 #include "datasrcs/NTuple.h"
00030 #include "functions/FunctionBase.h"
00031 #include "functions/FunctionFactory.h"
00032 #include "minimizers/Fitter.h"
00033
00034 #include <cassert>
00035 #include <cmath>
00036
00037 using namespace hippodraw;
00038
00039 using std::copy;
00040 using std::list;
00041 using std::string;
00042 using std::vector;
00043
00044 string FunctionProjector::s_x_label ("X");
00045
00046 FunctionProjector::FunctionProjector ( const std::string & name,
00047 ProjectorBase * targetProjector )
00048 : ProjectorBase (),
00049 m_target ( targetProjector ),
00050 m_fitter ( 0 )
00051 {
00052 assert ( targetProjector );
00053
00054 FunctionFactory * factory = FunctionFactory::instance();
00055 m_function = factory->create ( name );
00056 assert ( m_function != 0 );
00057
00058 m_binner = new BinsFunction ();
00059 setNumberOfBins ( 50 );
00060
00061 addPointReps();
00062 }
00063
00064 FunctionProjector::FunctionProjector ( FunctionBase * function,
00065 ProjectorBase * targetProjector )
00066 : ProjectorBase (),
00067 m_target ( targetProjector ),
00068 m_fitter ( 0 )
00069 {
00070 assert ( targetProjector );
00071 m_function = function;
00072 assert ( m_function != 0 );
00073
00074 m_binner = new BinsFunction ();
00075 setNumberOfBins ( 50 );
00076
00077 addPointReps();
00078 }
00079
00081 FunctionProjector::FunctionProjector ( const FunctionProjector & plotter )
00082 {
00083 }
00084
00085 FunctionProjector::~FunctionProjector ()
00086 {
00087 delete m_function;
00088 delete m_fitter;
00089 delete m_binner;
00090 }
00091
00093 ProjectorBase * FunctionProjector::clone ()
00094 {
00095 return 0;
00096 }
00097
00098 FunctionBase * FunctionProjector::function () const
00099 {
00100 return m_function;
00101 }
00102
00103 void FunctionProjector::setNumberOfBins ( int nb )
00104 {
00105 m_binner->setNumberOfBins ( Axes::X, nb );
00106 }
00107
00108 bool FunctionProjector:: hasSavedParameters () const
00109 {
00110 return m_save_parms.empty() == false;
00111 }
00112
00113 void FunctionProjector::saveParameters ()
00114 {
00115 assert ( m_function != 0 );
00116
00117 m_save_parms = m_function->getParameters ();
00118 }
00119
00120 void FunctionProjector::restoreParameters ()
00121 {
00122 assert ( m_function != 0 );
00123 assert ( ! m_save_parms.empty () );
00124
00125 m_function->setParameters ( m_save_parms );
00126
00127 setDirty ( true );
00128 }
00129
00130 void
00131 FunctionProjector::
00132 setFitter ( Fitter * fitter )
00133 {
00134 m_fitter = fitter;
00135 }
00136
00137 Fitter *
00138 FunctionProjector::
00139 getFitter ( ) const
00140 {
00141 return m_fitter;
00142 }
00143
00144 void FunctionProjector::initializeFunction ( ProjectorBase * projector )
00145 {
00146 assert ( m_function != 0 );
00147
00148 m_target = projector;
00149 projector->prepareValues();
00150 ProjectorHelper helper ( projector -> getProjectedValues () );
00151 m_function->initialParameters ( & helper );
00152
00153 saveParameters ();
00154 }
00155
00156 bool
00157 FunctionProjector::
00158 fitFunction ( )
00159 {
00160
00161 assert ( m_function != 0 && m_target != 0 );
00162 assert ( m_fitter != 0 );
00163 m_target -> prepareValues ();
00164
00165 if ( hasSavedParameters() == false ) {
00166 saveParameters ();
00167 }
00168
00169 bool ok = m_fitter->calcBestFit ();
00170
00171 setDirty ( true );
00172
00173 return ok;
00174 }
00175
00176
00177 void FunctionProjector::prepareValues ()
00178 {
00179 m_binner->setFunction ( m_function );
00180
00181 if ( isDirty () ) {
00182 m_binner->createValuesArray ( m_values );
00183 if ( m_proj_values == 0 ) {
00184 m_proj_values = createNTuple ();
00185 }
00186 else {
00187 fillProjectedValues ( m_proj_values );
00188 }
00189 setDirty ( false );
00190 }
00191
00192 }
00193
00194 const string & FunctionProjector::getTitle() const
00195 {
00196 return m_function->name ();
00197 }
00198
00199 void
00200 FunctionProjector::
00201 setRange ( hippodraw::Axes::Type axis, bool )
00202 {
00203 AxisModelBase * model = 0;
00204
00205 if ( axis == Axes::X ) model = m_x_axis;
00206 else model = m_y_axis;
00207
00208 const Range & range = model->getRange( false );
00209 m_binner->setRange ( axis, range );
00210
00211 setDirty ( true );
00212 }
00213
00214 const std::string & FunctionProjector::getXLabel () const
00215 {
00216 return s_x_label;
00217 }
00218
00219 const string & FunctionProjector::getYLabel ( bool ) const
00220 {
00221 return m_function->name ();
00222 }
00223
00224 void FunctionProjector::prepareAxis ( const Range & x_view,
00225 const Range & y_view )
00226 {
00227 const Range & rangex = m_x_axis->getRange (false);
00228 m_binner->setRangeOn ( Axes::X, rangex, x_view );
00229
00230 const Range & rangey = m_y_axis->getRange (false);
00231 m_binner->setRangeOn ( Axes::Y, rangey, y_view );
00232
00233 setDirty ( true );
00234 }
00235
00237 Range FunctionProjector::valueRange() const
00238 {
00239 return Range ( 0, 0 );
00240 }
00241
00242 int
00243 FunctionProjector::
00244 getNumberOfEntries () const
00245 {
00246
00247
00248 return -1;
00249 }
00250
00251 Range
00252 FunctionProjector::
00253 dataRangeOn ( hippodraw::Axes::Type axis ) const
00254 {
00255 if ( axis == Axes::X ) return m_x_axis->getRange ( false );
00256
00257 return m_y_axis->getRange ( false );
00258 }
00259
00260 double FunctionProjector::objectiveValue () const
00261 {
00262 return m_fitter->objectiveValue ();
00263 }
00264
00269 const vector < double > &
00270 FunctionProjector::
00271 principleErrors() const
00272 {
00273 int num_parms = m_save_parms.size ();
00274 m_principleErrors.clear();
00275 m_principleErrors.resize( num_parms, 0.0 );
00276 if ( m_fitter != 0 ) {
00277 m_fitter -> calcCovariance ( m_covariance );
00278 int n = m_covariance.size();
00279 if ( n != 0 ) {
00280 const vector < int > & fixed = m_fitter -> getFixedFlags ();
00281 int ic = 0;
00282 for( int i = 0; i < num_parms; i++ ) {
00283 if ( fixed [ i ] == 0 ) {
00284 m_principleErrors[i] = sqrt( m_covariance[ic][ic] );
00285 ic++;
00286 }
00287 else {
00288 m_principleErrors[i] = 0.0;
00289 }
00290 }
00291 }
00292 }
00293
00294 return m_principleErrors;
00295 }
00296
00297 void
00298 FunctionProjector::
00299 setPrincipleErrors ( std::vector < double > :: const_iterator begin,
00300 std::vector < double > :: const_iterator end )
00301 {
00302 unsigned int size = std::distance ( begin, end );
00303 assert ( size == m_principleErrors.size () );
00304
00305 copy ( begin, end, m_principleErrors.begin() );
00306 }
00307
00308 int FunctionProjector::degreesOfFreedom () const
00309 {
00310 return m_fitter->calcDegreesOfFreedom ();
00311 }
00312
00313 double
00314 FunctionProjector::
00315 getPosOn ( hippodraw::Axes::Type ) const
00316 {
00317 return 0.0;
00318 }
00319
00320 void
00321 FunctionProjector::
00322 setAxisModel ( hippodraw::Axes::Type axis,
00323 AxisModelBase * axis_model )
00324 {
00325 assert ( axis == Axes::X || axis == Axes::Y );
00326
00327
00328 if ( axis == Axes::X ) {
00329 m_x_axis = axis_model;
00330 }
00331 if ( axis == Axes::Y ) {
00332 m_y_axis = axis_model;
00333 }
00334
00335 const Range & range = axis_model->getRange (false);
00336 m_binner->setRange ( axis, range );
00337 }
00338
00339 const string & FunctionProjector::getZLabel() const
00340 {
00341 assert ( false );
00342
00343 return m_z_label;
00344 }
00345
00346 void FunctionProjector::addPointReps()
00347 {
00348 }
00349
00350 bool
00351 FunctionProjector::
00352 isEmpty () const
00353 {
00354 return m_binner == 0;
00355 }
00356
00357 void FunctionProjector::setParameters ( const std::vector<double> ¶ms )
00358 {
00359 assert ( m_function != 0 );
00360
00361 std::vector<double> myParams = m_function->getParameters();
00362
00363 if ( myParams.size() == params.size() ) {
00364 m_function->setParameters ( params );
00365 setDirty ( true );
00366 }
00367 }
00368
00369 const vector < vector < double > > &
00370 FunctionProjector::
00371 covariance ( ) const
00372 {
00373 if ( m_covariance.empty () ) {
00374 m_fitter -> calcCovariance ( m_covariance );
00375 }
00376
00377 return m_covariance;
00378 }
00379
00380 namespace dp = hippodraw::DataPoint2DTuple;
00381
00382 DataSource *
00383 FunctionProjector::
00384 createNTuple () const
00385 {
00386 unsigned int columns = dp::SIZE;
00387 NTuple * ntuple = new NTuple ( columns );
00388 vector < string > labels;
00389
00390 labels.push_back ( "X" );
00391 labels.push_back ( "Y" );
00392 labels.push_back ( "nil" );
00393 labels.push_back ( "nil" );
00394
00395 ntuple -> setLabels ( labels );
00396
00397 unsigned int size = m_values.size();
00398 ntuple -> reserve ( size );
00399
00400 fillProjectedValues ( ntuple );
00401
00402 return ntuple;
00403 }
00404
00405 void
00406 FunctionProjector::
00407 fillProjectedValues ( DataSource * ntuple, bool ) const
00408 {
00409 ntuple -> clear ();
00410
00411 vector < double > row ( dp::SIZE );
00412
00413 list < vector < double > >::const_iterator first = m_values.begin();
00414 while ( first != m_values.end () ) {
00415 const vector < double > & value = *first++;
00416 row = value;
00417 ntuple -> addRow ( row );
00418 }
00419 }
00420
00421 void
00422 FunctionProjector::
00423 fillDataSource ( DataSource * ntuple, bool ) const
00424 {
00425 ntuple -> clear ();
00426
00427 vector < double > row ( dp::SIZE );
00428
00429 list < vector < double > >::const_iterator first = m_values.begin();
00430 while ( first != m_values.end () ) {
00431 const vector < double > & value = *first++;
00432 row = value;
00433 ntuple -> addRow ( row );
00434 }
00435 }
00436
00437 void
00438 FunctionProjector::
00439 setFitCut ( TupleCut * cut )
00440 {
00441 m_fitter -> setFitCut ( cut );
00442 }
00443
00444 void
00445 FunctionProjector::
00446 setFitRange ( bool yes )
00447 {
00448 m_fitter -> setFitRange ( yes );
00449 }