00001
00012
00013 #ifdef _MSC_VER
00014 #include "msdevstudio/MSconfig.h"
00015 #endif
00016
00017
00018 #include <boost/python.hpp>
00019
00020 #include "PyFunctionRep.h"
00021
00022 #include "PyApp.h"
00023 #include "PyDataRep.h"
00024 #include "QtDisplay.h"
00025
00026 #include "controllers/FunctionController.h"
00027 #include "datareps/FunctionRep.h"
00028 #include "functions/FunctionBase.h"
00029 #include "pattern/FactoryException.h"
00030 #include "plotters/PlotterBase.h"
00031
00032 using std::vector;
00033 using namespace boost::python;
00034
00035 namespace hippodraw {
00036 namespace Python {
00037
00038 void
00039 export_Function()
00040 {
00041 class_ < PyFunctionRep >
00042 ( "Function",
00043 "This class wraps a FunctionBase object with a DataRep. This allows\n"
00044 "it to be drawn in a Display. It also provides interface to member\n"
00045 "functions of FunctionBase, although the user could obtain a\n"
00046 "reference to the FunctionBase itself to do so.",
00047 init < const std::string &, PyDataRep * >
00048 ( "Function ( string, DataRep ) -> Function\n"
00049 "Function ( FunctionBase, DataRep ) -> Function\n"
00050 "\n"
00051 "The first form creates a function using the string to find the\n"
00052 "FunctionBase in the FunctionFactory. The second form creates a\n"
00053 "using an existing FunctionBase object. Both forms use the DataRep\n"
00054 "as target for fitting and drawing\n" ) )
00055
00056 .def ( init < FunctionBase *, PyDataRep * >
00057 ( ) )
00058
00059 .def ( init < FunctionBase * >
00060 ( ) )
00061
00062 .def ( "addTo", &PyFunctionRep::addTo,
00063 "addTo ( Display ) -> None\n"
00064 "\n"
00065 "Adds the Function to a Display. taking the Display's selected\n"
00066 "DataRep as its target." )
00067
00068 .def ( "parmNames", &PyFunctionRep::parmNames,
00069 return_value_policy < copy_const_reference > (),
00070 "parmNames ( None ) -> list\n"
00071 "\n"
00072 "Returns a list of parameter names." )
00073
00074 .def ( "parameters", &PyFunctionRep::parameters,
00075 return_value_policy < copy_const_reference > (),
00076 "parameters ( None ) -> list\n"
00077 "\n"
00078 "Returns a list of the function's parameter values." )
00079
00080 .def ( "principleErrors", &PyFunctionRep::principleErrors,
00081 return_value_policy < copy_const_reference > (),
00082 "principleErrors ( None ) -> list\n"
00083 "\n"
00084 "Returns the errors on the parameters." )
00085
00086 .def ( "errors", &PyFunctionRep::principleErrors,
00087 return_value_policy < copy_const_reference > (),
00088 "errors ( None ) - > list\n"
00089 "\n"
00090 "Returns the errors on the parameters. The errors are calculated\n"
00091 "by a fitter, thus the values returned are only valid after\n"
00092 "having done a fit." )
00093
00094 .def ( "fit", &PyFunctionRep::fitFunction,
00095 "fit ( None ) -> boolean\n"
00096 "\n"
00097 "Attempts to fit the the function to the target DataRep.\n"
00098 "Uses the currently selected fitter, unless one was explicitly\n"
00099 "set. Note the fit is always done to linear sum if more than one\n"
00100 "function is on the data." )
00101
00102 .def ( "setParameters", &PyFunctionRep::setParameters,
00103 "setParameters ( list ) -> None\n"
00104 "\n"
00105 "Sets the function's parameter values." )
00106
00107 .def ( "valueAt", &PyFunctionRep::operator(),
00108 "valueAt ( x ) -> value\n"
00109 "\n"
00110 "Returns the function's value at given coordinate." )
00111
00112 .def ( "chiSquared", &PyFunctionRep::objectiveValue,
00113 "chiSquare ( None ) -> value\n"
00114 "\n"
00115 "Returns the Chi-Squared." )
00116
00117 .def ( "objectiveValue", &PyFunctionRep::objectiveValue,
00118 "objectiveValue ( None ) -> value\n"
00119 "\n"
00120 "Returns the objective Value that the fitter minimizes.\n"
00121 "Typically it is the Chi-Squared." )
00122
00123 .def ( "degreesOfFreedom", &PyFunctionRep::degreesOfFreedom,
00124 "degressOfFreedom ( None ) -> value\n"
00125 "\n"
00126 "Returns the number of degrees of freedom a fitter would have." )
00127
00128
00129
00130
00131
00132
00133 .def ( "setFixedFlags", &PyFunctionRep::setFixedFlags,
00134 "setFixedFlags ( list ) -> None\n"
00135 "\n"
00136 "Set which parameters should be held fixed during fitting." )
00137
00138 .def ( "setFitter", &PyFunctionRep::setFitter,
00139 "setFitter ( string ) -> None\n"
00140 "\n"
00141 "Sets the fitter by name from fitter factory." )
00142
00143 .def ( "getFitterName", &PyFunctionRep::getFitterName,
00144 return_value_policy < copy_const_reference > (),
00145 "getFitterName ( None ) -> string\n"
00146 "\n"
00147 "Returns the current fitter name." )
00148
00149 .def ( "createResidualsDisplay",
00150 &PyFunctionRep::createResidualsDisplay,
00151 return_value_policy < manage_new_object > (),
00152 "createResidualsDisplay ( None ) -> Display\n"
00153 "\n"
00154 "Returns residuals Display object. The residuals display is an\n"
00155 "XY plot showing the difference between the function values and\n"
00156 "the target DataRep values." )
00157
00158 .def ( "setFitRange",
00159 &PyFunctionRep::setFitRange,
00160 "setFitRange ( low, high ) -> None\n"
00161 "\n"
00162 "Sets the range of the coordinate axis that is used for fitting." )
00163
00164 .def ( "setFitRangeEnabled",
00165 &PyFunctionRep::setFitRangeEnabled,
00166 "setFitRange ( boolean ) -> None\n"
00167 "\n"
00168 "Enabled use of the fit range" )
00169
00170 ;
00171 }
00172
00173 }
00174 }
00175
00176 using namespace hippodraw;
00177
00178 PyFunctionRep::PyFunctionRep ( const std::string & name, PyDataRep * rep )
00179 {
00180 PyApp::lock ();
00181 try {
00182 FunctionController * controller = FunctionController::instance ();
00183 DataRep * datarep = rep -> getDataRep ();
00184 m_rep = controller -> createFunctionRep ( name, datarep );
00185 m_target = 0;
00186 }
00187 catch ( const FactoryException & e ) {
00188 PyApp::unlock ();
00189 throw e;
00190 }
00191 PyApp::unlock ();
00192 }
00193
00194 PyFunctionRep::PyFunctionRep ( FunctionBase * function, PyDataRep * rep )
00195 {
00196 PyApp::lock ();
00197 try {
00198 FunctionController * controller = FunctionController::instance ();
00199 DataRep * datarep = rep -> getDataRep ();
00200 m_rep = controller -> createFunctionRep ( function, datarep );
00201 m_target = 0;
00202 }
00203 catch ( const FactoryException & e ) {
00204 PyApp::unlock ();
00205 throw e;
00206 }
00207 PyApp::unlock ();
00208 }
00209
00210 PyFunctionRep::
00211 PyFunctionRep ( FunctionBase * function )
00212 {
00213 PyApp::lock ();
00214 try {
00215 FunctionController * controller = FunctionController::instance ();
00216 m_rep = controller -> createFunctionRep ( function, 0 );
00217 m_target = 0;
00218 }
00219 catch ( const FactoryException & e ) {
00220 PyApp::unlock ();
00221 throw e;
00222 }
00223 PyApp::unlock ();
00224 }
00225
00226 DataRep * PyFunctionRep::getRep () const
00227 {
00228 return m_rep;
00229 }
00230
00231 void PyFunctionRep::addTo ( QtDisplay * display )
00232 {
00233 PyApp::lock();
00234 FunctionController * controller = FunctionController::instance ();
00235 m_target = display->display ();
00236
00237 try {
00238 controller->addFunction ( m_target, m_rep );
00239 m_target -> setActivePlot ( -1, true );
00240 }
00241 catch ( const std::runtime_error & e ) {
00242 PyApp::unlock ();
00243 throw e;
00244 }
00245 PyApp::unlock ();
00246 }
00247
00248 const vector < std::string > & PyFunctionRep::parmNames () const
00249 {
00250 PyApp::lock();
00251 const vector < std::string > & vec = m_rep->parmNames();
00252 PyApp::unlock ();
00253
00254 return vec;
00255 }
00256
00257
00258 const vector < double > & PyFunctionRep::parameters () const
00259 {
00260 PyApp::lock();
00261 const vector < double > & vec = m_rep->parameters ();
00262 PyApp::unlock ();
00263
00264 return vec;
00265 }
00266
00267 const vector < double > & PyFunctionRep::principleErrors () const
00268 {
00269 PyApp::lock();
00270 const vector < double > & vec = m_rep -> principleErrors();
00271 PyApp::unlock ();
00272
00273 return vec;
00274 }
00275
00276 void PyFunctionRep::setParameters ( const std::vector<double> & params )
00277 {
00278 PyApp::lock();
00279 m_rep->setParameters(params);
00280 PyApp::unlock ();
00281 }
00282
00283 bool PyFunctionRep::fitFunction ()
00284 {
00285 PyApp::lock();
00286 FunctionController * controller = FunctionController::instance ();
00287 bool ok = controller -> fitFunction ( m_target, m_rep );
00288 PyApp::unlock ();
00289
00290 return ok;
00291 }
00292
00293 double
00294 PyFunctionRep::
00295 operator () ( double x )
00296 {
00297 FunctionController * controller = FunctionController::instance ();
00298 FunctionRep * rep = controller->getComposite ( m_target, m_rep );
00299 FunctionBase * function = 0;
00300 if ( rep != 0 ) {
00301 function = rep->getFunction ();
00302 }
00303 else {
00304 function = m_rep->getFunction();
00305 }
00306
00307 return function ->operator() ( x );
00308 }
00309
00315 double
00316 PyFunctionRep::
00317 objectiveValue()
00318 {
00319 PyApp::lock();
00320 FunctionController * controller = FunctionController::instance ();
00321 double value;
00322 if (m_target) {
00323 const DataRep * datarep = m_target -> getDataRep ( 0 );
00324 value = controller->getObjectiveValue( m_target, datarep );
00325 } else {
00326 value = 0;
00327 }
00328 PyApp::unlock ();
00329
00330 return value;
00331 }
00332 const vector < vector < double > > &
00333 PyFunctionRep::
00334 covarianceMatrix ( )
00335 {
00336 PyApp::lock();
00337 FunctionController * controller = FunctionController::instance ();
00338 const vector < vector < double > > & covariance
00339 = controller -> getCovarianceMatrix ( m_target );
00340 PyApp::unlock ();
00341
00342 return covariance;
00343 }
00344
00345 int
00346 PyFunctionRep::
00347 degreesOfFreedom ()
00348 {
00349 PyApp::lock();
00350 FunctionController * controller = FunctionController::instance ();
00351 int value = 0;
00352 if (m_target) {
00353 value = controller->getDegreesOfFreedom(m_target);
00354 }
00355 PyApp::unlock ();
00356
00357 return value;
00358 }
00359
00360 void
00361 PyFunctionRep::
00362 setFixedFlags ( const std::vector < int > & flags )
00363 {
00364 PyApp::lock();
00365
00366 m_rep->setFixedFlags ( flags );
00367
00368 PyApp::unlock ();
00369 }
00370
00371 void
00372 PyFunctionRep::
00373 setFitter ( const std::string & name )
00374 {
00375 FunctionController * controller = FunctionController::instance ();
00376 controller -> setFitter ( m_rep, name );
00377 }
00378
00379 const std::string &
00380 PyFunctionRep::
00381 getFitterName ( ) const
00382 {
00383 return m_rep -> getFitterName ();
00384 }
00385
00386 QtDisplay *
00387 PyFunctionRep::
00388 createResidualsDisplay () const
00389 {
00390 FunctionController * controller = FunctionController::instance();
00391 PlotterBase * plotter
00392 = controller -> createResidualsDisplay ( m_target, m_rep );
00393 QtDisplay * display = new QtDisplay ( plotter );
00394
00395 return display;
00396 }
00397
00398 void
00399 PyFunctionRep::
00400 setFitRange ( double low, double high )
00401 {
00402 const Range range ( low, high );
00403
00404 m_rep -> setCutRange ( range );
00405 }
00406
00408 void
00409 PyFunctionRep::
00410 setFitRangeEnabled ( bool yes )
00411 {
00412 m_rep -> setCutRange ( yes );
00413 }