00001
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #else
00015 #ifdef _MSC_VER
00016 #include "msdevstudio/MSconfig.h"
00017 #endif
00018 #endif
00019
00020 #include "FunctionController.h"
00021 #include "Gammaq.h"
00022 #include "DisplayController.h"
00023
00024 #include "datasrcs/DataSourceController.h"
00025 #include "datareps/FunctionRep.h"
00026 #include "datasrcs/NTuple.h"
00027 #include "datasrcs/TupleCut.h"
00028
00029 #include "functions/FunctionBase.h"
00030 #include "functions/FunctionFactory.h"
00031
00032 #include "minimizers/Fitter.h"
00033 #include "minimizers/FitterFactory.h"
00034 #include "minimizers/NTupleFCN.h"
00035 #include "minimizers/NumLinAlg.h"
00036
00037 #include "plotters/PlotterBase.h"
00038 #include "plotters/CompositePlotter.h"
00039 #include "projectors/BinningProjector.h"
00040 #include "projectors/FunctionProjector.h"
00041 #include "projectors/NTupleProjector.h"
00042
00043 #include <algorithm>
00044 #include <functional>
00045 #include <iterator>
00046
00047 #ifdef SSTREAM_DEFECT
00048 #include <strstream>
00049 using std::ostrstream;
00050 #else
00051 #include <sstream>
00052 using std::ostringstream;
00053 #endif
00054
00055 #include <cfloat>
00056
00057 using namespace hippodraw;
00058 using namespace hippodraw::Numeric;
00059
00060 #ifdef ITERATOR_MEMBER_DEFECT
00061 using namespace std;
00062 #else
00063 using std::distance;
00064 using std::find;
00065 using std::find_if;
00066 using std::list;
00067 using std::mem_fun;
00068 using std::string;
00069 using std::vector;
00070 using std::sqrt;
00071 using std::cos;
00072 using std::sin;
00073 using std::atan;
00074 using std::min;
00075 using std::max;
00076 using std::abs;
00077 #endif
00078
00079 FunctionController * FunctionController::s_instance = 0;
00080
00081 FunctionController::FunctionController ( )
00082 : m_plotter ( 0 ),
00083 m_x ( 0 ),
00084 m_y ( 0 ),
00085 m_confid_count ( 0 )
00086 {
00087 m_deltaXSq.resize( 6 );
00088
00089 m_deltaXSq[ 0 ] = 15.1;
00090 m_deltaXSq[ 1 ] = 18.4;
00091 m_deltaXSq[ 2 ] = 21.1;
00092 m_deltaXSq[ 3 ] = 23.5;
00093 m_deltaXSq[ 4 ] = 25.7;
00094 m_deltaXSq[ 5 ] = 27.8;
00095 }
00096
00097 FunctionController::~FunctionController ( )
00098 {
00099 }
00100
00101 FunctionController * FunctionController::instance ( )
00102 {
00103 if ( s_instance == 0 ) {
00104 s_instance = new FunctionController ( );
00105 }
00106 return s_instance;
00107 }
00108
00109 const vector < string > &
00110 FunctionController::
00111 getFitterNames () const
00112 {
00113 FitterFactory * factory = FitterFactory::instance ();
00114
00115 return factory -> names ();
00116 }
00117
00118 int FunctionController::
00119 getUniqueNonFunctionIndex ( const PlotterBase * plotter ) const
00120 {
00121 int index = -1;
00122 int count = 0;
00123
00124 int number = plotter->getNumDataReps ();
00125 for ( int i = 0; i < number; i++ ) {
00126 DataRep * r = plotter->getDataRep ( i );
00127 FunctionRep * fr = dynamic_cast < FunctionRep * > ( r );
00128 if ( fr != 0 ) continue;
00129 index = i;
00130 count++;
00131 }
00132 if ( count != 1 ) index = -1;
00133
00134 return index;
00135 }
00136
00137 void
00138 FunctionController::
00139 findFunctions ( const PlotterBase * plotter ) const
00140 {
00141 m_func_reps.clear ();
00142 int number = plotter->getNumDataReps ();
00143
00144 for ( int i = 0; i < number; i++ ) {
00145 DataRep * rep = plotter->getDataRep ( i );
00146 FunctionRep * frep = dynamic_cast < FunctionRep * > ( rep );
00147 if ( frep == 0 ) continue;
00148 m_func_reps.push_back ( frep );
00149 }
00150 }
00151
00152 FunctionRep *
00153 FunctionController::
00154 createFunctionRep ( const std::string & name,
00155 DataRep * rep )
00156 {
00157 FunctionRep * frep = new FunctionRep ( name, rep );
00158
00159 return frep;
00160 }
00161
00162 FunctionRep *
00163 FunctionController::
00164 createFunctionRep ( FunctionBase * function,
00165 DataRep * rep )
00166 {
00167 FunctionRep * frep = new FunctionRep ( function, rep );
00168
00169 const vector < string > & fitters = getFitterNames ();
00170 setFitter ( frep, fitters[0] );
00171
00172 return frep;
00173 }
00174
00175 FunctionBase *
00176 FunctionController::
00177 addFunction ( PlotterBase * plotter, const std::string & name )
00178 {
00179 DataRep * rep = plotter -> getDataRep ( 0 );
00180 addFunction ( plotter, name, rep );
00181 FunctionRep * frep = getFunctionRep ( plotter );
00182
00183 return frep -> getFunction ();
00184 }
00185
00186 int FunctionController::addFunction ( PlotterBase * plotter,
00187 const std::string & name,
00188 DataRep * rep )
00189 {
00190 FunctionRep * func_rep = createFunctionRep ( name, rep );
00191 func_rep -> initializeWith ( rep );
00192 return addFunctionRep ( plotter, rep, func_rep );
00193 }
00194
00195 int FunctionController::addFunction ( PlotterBase * plotter,
00196 FunctionRep * func_rep )
00197 {
00198 int index = plotter->activePlotIndex ();
00199
00200 if ( index < 0 ) {
00201 index = getUniqueNonFunctionIndex ( plotter );
00202 }
00203 if ( index < 0 ) return -1;
00204 plotter->setActivePlot ( index, false );
00205 DataRep * drep = plotter->getDataRep ( index );
00206 func_rep -> initializeWith ( drep );
00207 return addFunctionRep ( plotter, drep, func_rep );
00208 }
00209
00210
00211 void
00212 FunctionController::
00213 addDataRep ( PlotterBase * plotter, DataRep * rep )
00214 {
00215 FunctionRep * frep = dynamic_cast < FunctionRep * > ( rep );
00216 if ( frep == 0 ) {
00217 DisplayController * controller = DisplayController::instance ();
00218 controller -> addDataRep ( plotter, rep );
00219 }
00220 else {
00221 if ( frep -> isComposite () == false ) {
00222 DataRep * target = frep -> getTarget ();
00223 addFunctionRep ( plotter, target, frep );
00224 }
00225 }
00226 }
00227
00228 int
00229 FunctionController::
00230 addFunctionRep ( PlotterBase * plotter,
00231 DataRep * drep,
00232 FunctionRep * func_rep )
00233 {
00234 plotter->addDataRep ( func_rep );
00235 findFunctions ( plotter );
00236
00237 FunctionBase * function = func_rep->getFunction ();
00238 if ( function->isComposite () ) {
00239 buildComposite ( function );
00240 }
00241 func_rep->notifyObservers ();
00242 const vector < string > & fitters = getFitterNames ();
00243 setFitter ( func_rep, fitters[0] );
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 if ( function->isComposite () == false ) {
00254 int count = 0;
00255 vector< FunctionRep * >:: const_iterator it = m_func_reps.begin ();
00256 for ( ; it != m_func_reps.end (); ++it ) {
00257 FunctionRep * localfp = *it;
00258 FunctionBase * localfunction = localfp->getFunction ();
00259 const string & name = localfunction->name ();
00260
00261 if ( name != "Linear Sum" ){
00262 count ++;
00263 }
00264 else{
00265
00266
00267 localfunction->addToComposite ( function );
00268 count = 0;
00269 break;
00270 }
00271 }
00272
00273 if ( count > 1 ){
00274 addFunction ( plotter, "Linear Sum", drep );
00275 }
00276
00277 }
00278
00279 int retval = findIndex ( func_rep );
00280 return retval;
00281
00282 }
00283
00284 void FunctionController::buildComposite ( const PlotterBase * plotter )
00285 {
00286 FunctionRep * composite_rep = getComposite ( plotter );
00287 if ( composite_rep == 0 ) return;
00288
00289 FunctionBase * composite = composite_rep->getFunction ();
00290 buildComposite ( composite );
00291 }
00292
00293 void FunctionController::buildComposite ( FunctionBase * composite )
00294 {
00295 vector< FunctionRep * > :: const_iterator it = m_func_reps.begin ();
00296
00297 for ( ; it != m_func_reps.end (); ++it ) {
00298 FunctionBase * function = (*it)->getFunction ();
00299 if ( function != composite ) {
00300 composite->addToComposite ( function );
00301 }
00302 }
00303 }
00304
00305 void FunctionController::removeFunction ( PlotterBase * plotter,
00306 unsigned int index )
00307 {
00308 findFunctions ( plotter );
00309 assert ( index < m_func_reps.size () );
00310
00311 vector < FunctionRep * > :: iterator it = m_func_reps.begin () + index;
00312 FunctionRep * frep = *it;
00313 m_func_reps.erase ( it );
00314
00315 plotter->removeDataRep ( frep );
00316
00317 FunctionBase * function = frep -> getFunction();
00318
00319 for ( unsigned int i = 0; i < m_func_reps.size(); i++ ){
00320 FunctionBase * curFunction = m_func_reps[i]->getFunction();
00321 if ( curFunction->isComposite() ){
00322 curFunction->removeFromComposite ( function );
00323 m_func_reps[i]->setDirty ( true );
00324 }
00325 }
00326
00327
00328
00329 vector < FunctionRep * >::iterator iter = m_func_reps.begin ();
00330
00331
00332
00333 while ( iter != m_func_reps.end() ){
00334 FunctionBase * func = ( *iter )->getFunction();
00335 if ( func->isComposite() ) {
00336 if ( func->count() < 2 ) {
00337 plotter->removeDataRep ( *iter );
00338 delete *iter;
00339 iter = m_func_reps.erase ( iter );
00340 }
00341 else {
00342 iter ++;
00343 }
00344 }
00345 else {
00346 iter ++;
00347 }
00348 }
00349 delete frep;
00350 }
00351
00352 int FunctionController::findIndex ( const FunctionRep * fp )
00353 {
00354 vector< FunctionRep * >::iterator it
00355 = find ( m_func_reps.begin (), m_func_reps.end (), fp );
00356
00357 if ( it == m_func_reps.end () ) return -1;
00358
00359 #ifdef DISTANCE_DEFECT
00360 return it - m_func_reps.begin ();
00361 #else
00362 return distance ( m_func_reps.begin (), it );
00363 #endif
00364 }
00365
00366 bool
00367 FunctionController::
00368 hasFunction ( const PlotterBase * plotter, const DataRep * rep )
00369 {
00370 bool yes = false;
00371 assert ( plotter != 0 );
00372
00373 findFunctions ( plotter );
00374
00375 if ( m_func_reps.empty () == false ) {
00376 if ( rep != 0 ) {
00377 vector< FunctionRep * >:: const_iterator it = m_func_reps.begin ();
00378
00379 for ( ; it != m_func_reps.end (); ++it ) {
00380 FunctionRep * fp = *it;
00381 if ( fp->getTarget() == rep ) {
00382 yes = true;
00383 break;
00384 }
00385 }
00386 }
00387 else {
00388 yes = true;
00389 }
00390 }
00391
00392 return yes;
00393 }
00394
00395 const vector< string > &
00396 FunctionController::
00397 functionNames ( PlotterBase * plotter, DataRep * rep )
00398 {
00399 findFunctions ( plotter );
00400
00401 m_f_names.clear ();
00402 vector< FunctionRep * >:: const_iterator it = m_func_reps.begin ();
00403
00404 for ( ; it != m_func_reps.end (); ++it ) {
00405 FunctionRep * fp = *it;
00406 if ( rep != 0 && fp->getTarget() != rep ) continue;
00407 FunctionBase * function = fp->getFunction ();
00408 const string & name = function->name ();
00409 m_f_names.push_back ( name );
00410 }
00411
00412 return m_f_names;
00413 }
00414
00415 const std::vector < FunctionRep * > &
00416 FunctionController::
00417 getFunctionReps ( const PlotterBase * plotter ) const
00418 {
00419 FunctionController * tmp = const_cast< FunctionController * > ( this );
00420 tmp->findFunctions ( plotter );
00421
00422 return m_func_reps;
00423 }
00424
00425 FunctionRep *
00426 FunctionController::
00427 getComposite ( const PlotterBase * plotter ) const
00428 {
00429 FunctionController * tmp = const_cast< FunctionController * > ( this );
00430 tmp->findFunctions ( plotter );
00431
00432 #ifdef MEMFUN_DEFECT
00433 vector < FunctionRep * >::iterator first = m_func_reps.begin();
00434 while ( first != m_func_reps.end() ) {
00435 FunctionRep * frep = *first++;
00436 if ( frep->isComposite () ) break;
00437 }
00438 #else
00439 vector < FunctionRep * >::const_iterator first
00440 = find_if ( m_func_reps.begin(), m_func_reps.end(),
00441 mem_fun ( &FunctionRep::isComposite ) );
00442 #endif
00443
00444 if ( first == m_func_reps.end() ) return 0;
00445
00446 return *first;
00447 }
00448
00449 const vector < double > &
00450 FunctionController::
00451 getErrors ( const PlotterBase * plotter )
00452 {
00453 FunctionRep * rep = getFunctionRep ( plotter );
00454
00455 return rep -> principleErrors ();
00456 }
00457
00458 void
00459 FunctionController::
00460 setErrorsFromComposite ( const PlotterBase * plotter,
00461 const FunctionRep * composite )
00462 {
00463 const vector < double > & errors = composite -> principleErrors();
00464 vector < double >::const_iterator begin = errors.begin();
00465
00466 getFunctionReps ( plotter );
00467 vector < FunctionRep * >::iterator first = m_func_reps.begin();
00468
00469 while ( first != m_func_reps.end() ) {
00470 FunctionRep * rep = *first++;
00471 if ( rep -> isComposite() ) continue;
00472 ProjectorBase * pbase = rep -> getProjector ();
00473 FunctionProjector * projector
00474 = dynamic_cast < FunctionProjector * > ( pbase );
00475 assert ( projector );
00476 const vector < double > & t = projector -> principleErrors ();
00477 unsigned int number = t.size();
00478 projector->setPrincipleErrors ( begin,
00479 begin + number );
00480 begin += number;
00481 }
00482
00483 }
00484
00485 bool
00486 FunctionController::
00487 fitFunction ( PlotterBase * plotter, unsigned int )
00488 {
00489 FunctionRep * rep = getFunctionRep ( plotter );
00490
00491 return fitFunction ( plotter, rep );
00492 }
00493
00494 bool
00495 FunctionController::
00496 fitFunction ( PlotterBase * plotter, FunctionRep * rep )
00497 {
00498 FunctionRep * composite = getComposite ( plotter );
00499 bool ok = false;
00500 if ( composite != 0 ) {
00501 ok = composite -> fitFunction ();
00502 setErrorsFromComposite ( plotter, composite );
00503 }
00504 else {
00505 ok = rep -> fitFunction ();
00506 }
00507
00508 return ok;
00509 }
00510
00511 void
00512 FunctionController::
00513 tryFitFunction ( PlotterBase * plotter, const DataRep * datarep )
00514 {
00515 saveParameters ( plotter );
00516 double chi_sq = getObjectiveValue ( plotter, datarep );
00517 FunctionRep * func_rep = getFunctionRep ( plotter, datarep );
00518 bool ok = fitFunction ( plotter, func_rep );
00519 if ( ok ) {
00520 double new_chi_sq = getObjectiveValue ( plotter, datarep );
00521 if ( new_chi_sq > chi_sq ) {
00522 restoreParameters ( plotter );
00523 }
00524 } else {
00525 restoreParameters ( plotter );
00526 }
00527 }
00528
00529 void
00530 FunctionController::
00531 fitFunctions ( PlotterBase * plotter )
00532 {
00533 if ( hasFunction ( plotter, 0 ) ) {
00534 buildComposite ( plotter );
00535 FunctionRep * frep = getFunctionRep ( plotter );
00536 fitFunction ( plotter, frep );
00537 }}
00538
00539 void
00540 FunctionController::
00541 setFitRange ( PlotterBase * plotter, const Range & range )
00542 {
00543 if ( hasFunction ( plotter, 0 ) ) {
00544 FunctionRep * frep = getFunctionRep ( plotter );
00545 frep -> setCutRange ( range );
00546 plotter -> update ();
00547 }
00548 }
00549
00550 void
00551 FunctionController::
00552 setFitRange ( PlotterBase * plotter, double low, double high )
00553 {
00554 const Range range ( low, high );
00555 setFitRange ( plotter, range );
00556 }
00557
00558 const std::vector < double >
00559 FunctionController::
00560 parameters ( const PlotterBase * plotter, unsigned int )
00561 {
00562 FunctionRep * rep = getFunctionRep ( plotter );
00563
00564 return rep -> parameters ();
00565 }
00566
00567 const std::vector < double >
00568 FunctionController::
00569 principleErrors ( const PlotterBase * plotter, unsigned int )
00570 {
00571 FunctionRep * rep = getFunctionRep ( plotter );
00572
00573 return rep -> principleErrors ();
00574 }
00575
00576 void FunctionController::saveParameters ( PlotterBase * plotter )
00577 {
00578 findFunctions ( plotter );
00579 vector< FunctionRep * >::iterator it = m_func_reps.begin ();
00580
00581 for ( ; it != m_func_reps.end (); ++it ) {
00582 FunctionRep * frep = *it;
00583 FunctionBase * function = frep->getFunction ();
00584 if ( function->isComposite () ) continue;
00585 frep->saveParameters ();
00586 }
00587 }
00588
00589 void FunctionController::restoreParameters ( PlotterBase * plotter )
00590 {
00591 findFunctions ( plotter );
00592 vector< FunctionRep * >::iterator it = m_func_reps.begin ();
00593
00594 for ( ; it != m_func_reps.end (); ++it ) {
00595 FunctionRep * frep = *it;
00596 FunctionBase * function = frep->getFunction ();
00597 if ( function->isComposite () ) continue;
00598 frep->restoreParameters ();
00599 }
00600
00601 }
00602
00603 FunctionRep *
00604 FunctionController::
00605 getFunctionRep ( const PlotterBase * plotter ) const
00606 {
00607 FunctionRep * frep = 0;
00608 DataRep * rep = 0;
00609 int index = plotter->activePlotIndex ();
00610
00611 if ( index >= 0 ) {
00612 rep = plotter -> getDataRep ( index );
00613 }
00614 else {
00615 rep = plotter -> getTarget ();
00616 }
00617
00618 FunctionRep * test = dynamic_cast < FunctionRep * > ( rep );
00619 if ( test != 0 ) {
00620 frep = test;
00621 }
00622 else {
00623 frep = getFunctionRep ( plotter, rep );
00624 }
00625
00626 return frep;
00627 }
00628
00629 FunctionRep *
00630 FunctionController::
00631 getFunctionRep ( const PlotterBase * plotter, const DataRep * datarep ) const
00632 {
00633 FunctionRep * frep = 0;
00634
00635 findFunctions ( plotter );
00636
00637 for ( unsigned int i = 0; i < m_func_reps.size(); i++ ) {
00638 FunctionRep * rep = m_func_reps[i];
00639 const DataRep * drep = rep -> getTarget ();
00640 if ( drep != datarep ) continue;
00641 frep = rep;
00642 if ( frep -> isComposite () ) break;
00643 }
00644
00645 return frep;
00646 }
00647
00648 ViewBase * FunctionController::
00649 createFuncView ( const ViewFactory * factory,
00650 PlotterBase * plotter,
00651 const std::string & name )
00652 {
00653 FunctionRep * frep = getFunctionRep ( plotter );
00654 assert ( frep != 0 );
00655
00656 DisplayController * controller = DisplayController::instance ();
00657 string nullstring ("");
00658
00659 return controller->createTextView ( factory, frep, name, nullstring );
00660 }
00661
00662 bool
00663 FunctionController::
00664 setFitter ( const PlotterBase * plotter, const std::string & name )
00665 {
00666 FunctionRep * frep = getFunctionRep ( plotter );
00667 bool ok = false;
00668 if ( frep != 0 ) {
00669 ok = setFitter ( frep, name );
00670 }
00671
00672 return ok;
00673 }
00674
00675 const string &
00676 FunctionController::
00677 getFitterName ( const PlotterBase * plotter )
00678 {
00679 FunctionRep * frep = getFunctionRep ( plotter );
00680 Fitter * fitter = frep -> getFitter ();
00681
00682 return fitter -> name ();
00683 }
00684
00685 Fitter *
00686 FunctionController::
00687 getFitter ( const PlotterBase * plotter )
00688 {
00689 FunctionRep * frep = getFunctionRep ( plotter );
00690 Fitter * fitter = frep -> getFitter ();
00691
00692 return fitter;
00693 }
00694
00695
00696 bool
00697 FunctionController::
00698 setFitter ( FunctionRep * frep, const std::string & name )
00699 {
00700 FitterFactory * factory = FitterFactory::instance ();
00701 Fitter * fitter = factory -> create ( name );
00702
00703 return setFitter ( frep, fitter );
00704 }
00705
00706 bool
00707 FunctionController::
00708 setFitter ( FunctionRep * frep, Fitter * fitter )
00709 {
00710 DataRep * drep = frep -> getTarget ();
00711 FunctionBase * function = frep -> getFunction ();
00712 StatedFCN * fcn = fitter -> getFCN ();
00713
00714 if ( fcn -> needsIntegrated () == true ) {
00715 bool yes = drep -> isAxisBinned ( Axes::X );
00716 if ( ! yes ) return false;
00717 }
00718
00719 fcn -> setFunction ( function );
00720
00721 NTupleFCN * ntfcn = dynamic_cast < NTupleFCN * > ( fcn );
00722 assert ( ntfcn != 0 );
00723
00724 const DataSource * target = drep -> getProjectedValues ();
00725 ntfcn -> setDataSource ( target );
00726 ntfcn -> setUseErrors ( );
00727
00728 frep -> setFitter ( fitter );
00729
00730 return true;
00731 }
00732
00733 double
00734 FunctionController::
00735 getObjectiveValue ( const PlotterBase * plotter, const DataRep * datarep )
00736 {
00737 FunctionRep * rep = getFunctionRep ( plotter, datarep );
00738
00739 ProjectorBase * pbase = rep->getProjector ( );
00740 FunctionProjector * projector
00741 = dynamic_cast < FunctionProjector * > ( pbase );
00742
00743 return projector -> objectiveValue ();
00744 }
00745
00746 const vector < vector < double > > &
00747 FunctionController::
00748 getCovarianceMatrix ( const PlotterBase * plotter )
00749 {
00750 FunctionRep * rep = getFunctionRep ( plotter );
00751
00752 ProjectorBase * pbase = rep->getProjector ( );
00753 FunctionProjector * projector
00754 = dynamic_cast < FunctionProjector * > ( pbase );
00755
00756 return projector -> covariance ();
00757 }
00758
00763 double
00764 FunctionController::
00765 getChiSquared ( const PlotterBase * plotter )
00766 {
00767 const DataRep * rep = plotter -> getTarget ();
00768
00769 return getObjectiveValue ( plotter, rep );
00770 }
00771
00772 int
00773 FunctionController::
00774 getDegreesOfFreedom ( const PlotterBase * plotter )
00775 {
00776 FunctionRep * rep = getFunctionRep ( plotter );
00777
00778 ProjectorBase * pbase = rep->getProjector ( );
00779 FunctionProjector * projector
00780 = dynamic_cast < FunctionProjector * > ( pbase );
00781
00782 return projector -> degreesOfFreedom ();
00783 }
00784
00785 NTuple *
00786 FunctionController::
00787 createNTuple ( PlotterBase * plotter )
00788 {
00789 int old_index = plotter -> activePlotIndex ();
00790
00791 int index = getUniqueNonFunctionIndex ( plotter );
00792 if ( index < 0 ) return 0;
00793
00794 int saved_index = plotter -> activePlotIndex ();
00795 plotter -> setActivePlot ( index, false );
00796 NTuple * ntuple = plotter -> createNTuple ();
00797 plotter -> setActivePlot ( saved_index, false );
00798
00799 FunctionRep * rep = getFunctionRep ( plotter );
00800 if ( rep == 0 ) return ntuple;
00801
00802 ProjectorBase * pbase = rep->getProjector ( );
00803 FunctionProjector * projector
00804 = dynamic_cast < FunctionProjector * > ( pbase );
00805 FunctionBase * function = projector -> function();
00806
00807 vector < double > & x = ntuple -> getColumn ( 0 );
00808 vector < double > & y = ntuple -> getColumn ( 1 );
00809 unsigned int size = ntuple -> rows ();
00810 vector < double > values ( size );
00811 vector < double > residuals ( size );
00812
00813 for ( unsigned int i = 0; i < x.size(); i++ ) {
00814 values [i] = function -> operator () ( x[i] );
00815 residuals [i] = y[i] - values [i];
00816 }
00817
00818 ntuple -> addColumn ( function->name (), values );
00819 ntuple -> addColumn ( "Residuals", residuals );
00820
00821 plotter -> setActivePlot ( old_index, true );
00822
00823 return ntuple;
00824 }
00825
00826 PlotterBase *
00827 FunctionController::
00828 createResidualsDisplay ( PlotterBase * plotter )
00829 {
00830 NTuple * ntuple = createNTuple ( plotter );
00831 ntuple -> setTitle ( plotter -> getTitle () );
00832 DataSourceController::instance () -> registerNTuple ( ntuple );
00833 vector < string > bindings ( 4 );
00834 bindings[0] = ntuple -> getLabelAt ( 0 );
00835 bindings[1] = "Residuals";
00836 bindings[2] = "nil";
00837 bindings[3] = ntuple -> getLabelAt ( 3 );
00838
00839 DisplayController * controller = DisplayController::instance ();
00840
00841
00842 PlotterBase * new_plotter = controller -> createDisplay ( "XY Plot",
00843 *ntuple,
00844 bindings );
00845 controller->setLog( new_plotter, "x",
00846 controller -> getLog( plotter, "x" ) );
00847
00848 return new_plotter;
00849 }
00850
00851 PlotterBase *
00852 FunctionController::
00853 createNewEllipsoidDisplay ( PlotterBase * masterPlot )
00854 {
00855 int n = 100;
00856 double xmin, xmax, ymin, ymax;
00857
00858
00859 NTuple* ntuple = new( NTuple );
00860 ellipsoidNTuple ( masterPlot, ntuple, n, xmin, xmax, ymin, ymax );
00861 ntuple -> setTitle ( masterPlot -> getTitle () );
00862
00863 vector < string > bindings ( 1 );
00864 bindings[0] = ntuple -> getLabelAt ( 0 );
00865
00866 DisplayController * dcontroller = DisplayController::instance ();
00867
00868
00869 PlotterBase * ellipsePlot = dcontroller ->
00870 createDisplay ( "Z Plot", *ntuple, bindings );
00871
00872
00873
00874
00875 ellipsePlot -> setBinWidth( "x", ( xmax - xmin ) / ( n - 1.0 ) );
00876 ellipsePlot -> setBinWidth( "y", ( ymax - ymin ) / ( n - 1.0 ) );
00877
00878 ellipsePlot -> setOffsets ( xmin, ymin );
00879
00880 ellipsePlot -> setRange ( string( "X" ), xmin, xmax );
00881 ellipsePlot -> setRange ( string( "Y" ), ymin, ymax );
00882
00883
00884
00885
00886 int index = dcontroller -> activeDataRepIndex( masterPlot );
00887 ellipsePlot -> setParentDataRepIndex( index );
00888 ellipsePlot -> setParentPlotter( masterPlot );
00889
00890 return ellipsePlot;
00891 }
00892
00893
00894 void
00895 FunctionController::
00896 ellipsoidNTuple ( PlotterBase* masterPlot,
00897 NTuple* nt, int n,
00898 double & xmin, double & xmax,
00899 double & ymin, double & ymax )
00900 {
00901 #ifdef SSTREAM_DEFECT
00902 ostrstream strm_text;
00903 #else
00904 ostringstream strm_text;
00905 #endif
00906 strm_text << "Confidence ellipse ";
00907 m_confid_count++;
00908 strm_text << m_confid_count;
00909 const string str_text ( strm_text.str() );
00910 nt -> setName ( str_text );
00911
00912 DataSourceController * controller = DataSourceController::instance ();
00913 controller -> registerNTuple ( nt );
00914
00915
00916 FunctionRep * frep = getFunctionRep ( masterPlot );
00917 assert( frep );
00918
00919 ProjectorBase * pbase = frep -> getProjector ( );
00920 FunctionProjector * fprojector
00921 = dynamic_cast < FunctionProjector * > ( pbase );
00922
00923
00924
00925
00926
00927 vector< vector< double > > Sigma( 2 );
00928 Sigma[0].resize( 2, 0.0 );
00929 Sigma[1].resize( 2, 0.0 );
00930
00931 const vector < vector < double > > & covariance
00932 = fprojector -> covariance ();
00933
00934 Sigma[0][0] = covariance [m_x][m_x];
00935 Sigma[0][1] = covariance [m_x][m_y];
00936 Sigma[1][0] = covariance [m_y][m_x];
00937 Sigma[1][1] = covariance [m_y][m_y];
00938
00939
00940 vector< vector< double > > SigmaInv;
00941 invertMatrix( Sigma, SigmaInv );
00942
00943
00944
00945
00946 vector< double > xbar( 2 );
00947
00948 const Fitter * fitter = getFitter ( masterPlot );
00949 vector < double > free_parms;
00950 fitter -> fillFreeParameters ( free_parms );
00951 xbar[ 0 ] = free_parms [ m_x ];
00952 xbar[ 1 ] = free_parms [ m_y ];
00953
00954
00955
00956
00957 unsigned int mu = free_parms.size();
00958 NTuple * boundingTuple = ellipse( xbar, SigmaInv, m_deltaXSq[ mu - 1 ] );
00959
00960 xmin = boundingTuple -> minElement ( 0 );
00961 xmax = boundingTuple -> maxElement ( 0 );
00962 ymin = boundingTuple -> minElement ( 1 );
00963 ymax = boundingTuple -> maxElement ( 1 );
00964
00965 delete boundingTuple;
00966
00967
00968
00969
00970 vector< double > p( n * n ), a( 2 );
00971
00972 double dx = ( xmax - xmin ) / ( n - 1.0 );
00973 double dy = ( ymax - ymin ) / ( n - 1.0 );
00974 double delta = 0.0;
00975
00976 for( int i = 0; i < n; i++ )
00977 for( int j = 0; j < n; j++ )
00978 {
00979 a[ 0 ] = xmin + i * dx - xbar[ 0 ] ;
00980 a[ 1 ] = ymin + j * dy - xbar[ 1 ];
00981 delta = quadraticProduct( SigmaInv, a );
00982 p[ n * i + j ] = 1 - gammq( mu / 2.0, delta / 2.0 );
00983 }
00984
00985 nt -> clear();
00986 nt -> addColumn( "Percent", 100 * p );
00987
00988 return;
00989 }
00990
00991 PlotterBase *
00992 FunctionController::
00993 refreshEllipsoidDisplay ( PlotterBase * plot )
00994 {
00995 int n = 100;
00996 double xmin, xmax, ymin, ymax;
00997
00998 PlotterBase* masterPlot = plot->getParentPlotter();
00999
01000
01001 NTuple* ntuple = new( NTuple );
01002 ellipsoidNTuple ( masterPlot, ntuple, n, xmin, xmax, ymin, ymax );
01003 ntuple -> setTitle ( masterPlot -> getTitle () );
01004
01005
01006
01007
01008 DataRep * drep = plot -> selectedDataRep();
01009 NTupleProjector * ntProjector =
01010 dynamic_cast < NTupleProjector * > ( drep -> getProjector() );
01011 ntProjector -> setNTuple ( ntuple );
01012
01013 NTuple * nt = const_cast < NTuple * > ( ntuple );
01014 nt -> addObserver ( ntProjector );
01015
01016
01017
01018
01019 plot -> setBinWidth( "x", ( xmax - xmin ) / ( n - 1.0 ) );
01020 plot -> setBinWidth( "y", ( ymax - ymin ) / ( n - 1.0 ) );
01021
01022 plot -> setOffsets ( xmin, ymin );
01023
01024 plot -> setRange ( string( "X" ), xmin, xmax );
01025 plot -> setRange ( string( "Y" ), ymin, ymax );
01026
01027 return plot;
01028 }
01029
01030 NTuple *
01031 FunctionController::
01032 ellipse ( const std::vector< double > & xbar,
01033 std::vector< std::vector < double > > & SigmaInv,
01034 double Csquare )
01035 {
01036
01037 assert( xbar.size() == 2 );
01038
01039
01040 assert( SigmaInv.size() == 2 );
01041 assert( SigmaInv[0].size() == 2 || SigmaInv[1].size() == 2 );
01042
01043
01044
01045
01046 double temp = ( SigmaInv[0][1] + SigmaInv[1][0] ) / 2;
01047 SigmaInv[0][1] = temp;
01048 SigmaInv[1][0] = temp;
01049
01050
01051 assert( Csquare > DBL_EPSILON );
01052
01053
01054 double b = -( SigmaInv[0][0] + SigmaInv[1][1] );
01055 double c = SigmaInv[0][0] * SigmaInv[1][1] - SigmaInv[0][1] * SigmaInv[1][0];
01056
01057 double lambda1 = ( -b + sqrt( b * b - 4 * c ) ) / 2;
01058 double lambda2 = ( -b - sqrt( b * b - 4 * c ) ) / 2;
01059
01060
01061 double alpha1 = atan( (SigmaInv[0][0] - lambda1) / SigmaInv[0][1] );
01062 double a = sqrt( Csquare / lambda1 );
01063 b = sqrt( Csquare / lambda2 );
01064
01065
01066 double Rot00 = cos( alpha1 );
01067 double Rot11 = cos( alpha1 );
01068 double Rot01 = -sin( alpha1 );
01069 double Rot10 = sin( alpha1 );
01070
01071
01072 int N = 100;
01073 vector< double > x, y;
01074
01075 x.resize( N, 0.0 );
01076 y.resize( N, 0.0 );
01077
01078 for( int i = 0; i < N; i++)
01079 {
01080
01081 double theta = ( 2 * M_PI * i ) / ( (double) (N-1) );
01082 double x0 = a * cos( theta );
01083 double x1 = b * sin( theta );
01084
01085
01086 double xrot0 = Rot00 * x0 + Rot01 * x1;
01087 double xrot1 = Rot10 * x0 + Rot11 * x1;
01088
01089
01090 x[i] = xrot0 + xbar[0];
01091 y[i] = xrot1 + xbar[1];
01092 }
01093
01094
01095 NTuple* ntuple = new( NTuple );
01096 ntuple -> addColumn( "X", x );
01097 ntuple -> addColumn( "Y", y );
01098
01099 return ntuple;
01100 }
01101
01102 int FunctionController::setEllpsoidParamIndex( hippodraw::Axes::Type axes,
01103 int index )
01104 {
01105 assert( axes == Axes::X || axes == Axes::Y );
01106
01107 if( axes == Axes::X )
01108 m_x = index;
01109
01110 if( axes == Axes::Y )
01111 m_y = index;
01112
01113 return EXIT_SUCCESS;
01114 }
01115
01116 bool
01117 FunctionController::
01118 functionExists ( const std::string & name )
01119 {
01120 FunctionFactory * factory = FunctionFactory::instance ();
01121
01122 return factory -> exists ( name );
01123 }
01124
01125 bool
01126 FunctionController::
01127 isCompatible ( const std::string & function,
01128 const std::string & fitter )
01129 {
01130 bool yes = true;
01131
01132 FunctionFactory * fun_fac = FunctionFactory::instance ();
01133 FunctionBase * fun_proto = fun_fac -> prototype ( function );
01134
01135 FitterFactory * fit_fac = FitterFactory::instance ();
01136 Fitter * fit_proto = fit_fac -> prototype ( fitter );
01137
01138 if ( fit_proto -> needsDerivatives () == true &&
01139 fun_proto -> hasDerivatives () == false ) {
01140 yes = false;
01141 }
01142
01143 return yes;
01144 }