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