QtDisplay.cxx
Go to the documentation of this file.
00001 
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h" // for have_root and have_numarray
00015 #endif
00016 
00017 // include first to avoid _POSIX_C_SOURCE warning.
00018 #include <boost/python.hpp>
00019 
00020 // For truncation warning
00021 #ifdef _MSC_VER
00022 #include "msdevstudio/MSconfig.h"
00023 #endif
00024 
00025 #include "QtDisplay.h"
00026 
00027 #include "ListTuple.h"
00028 #include "PyFunctionRep.h"
00029 #include "PyApp.h"
00030 #include "PyDataRep.h"
00031 #include "PyDataSource.h"
00032 #include "PyNTuple.h"
00033 #include "FunctionWrap.h"
00034 
00035 #include "controllers/CutController.h"
00036 #include "controllers/DisplayController.h"
00037 #include "controllers/FunctionController.h"
00038 
00039 #include "pattern/FactoryException.h"
00040 #include "plotters/PlotterBase.h"
00041 #include "plotters/PlotterException.h"
00042 #include "projectors/ProjectorBase.h"
00043 
00044 #include "datareps/DataRepException.h"
00045 #include "datareps/DataRep.h"
00046 
00047 #include "datasrcs/DataSourceController.h"
00048 
00049 #include "reps/RepBase.h"
00050 #include "reps/ContourPointRep.h"
00051 #include "colorreps/BinToColorFactory.h"
00052 #include "colorreps/BinToColor.h"
00053 
00054 #ifdef HAVE_ROOT
00055 #include "root/QtRootNTuple.h"
00056 #endif
00057 
00058 #include <algorithm>
00059 #include <sstream>
00060 #include <utility>
00061 
00062 
00063 using std::runtime_error;
00064 using std::string;
00065 using std::vector;
00066 
00067 using namespace boost::python;
00068 
00069 namespace hippodraw {
00070 namespace Python {
00071 
00072 void
00073 export_QtDisplay()
00074 {
00075   class_< QtDisplay > 
00076     ( "Display",
00077       "A wrapper for the HippoDraw PlotterBase C++ class.\n "
00078       "  See HippoDraw's QtDisplay documentation for more details.",
00079       init < const std::string & >
00080       (
00081 #if __GNUC__ < 3
00082        "Display ( string, DataSource, tuple ) -> Display\n"
00083        "\n"
00084        "Constructor for a Display."
00085 #else // gcc 2.95.3 crashes on the following...
00086        "Display ( string ) -> Display\n"
00087        "Display ( string, DataSource, tuple ) -> Display\n"
00088        "Display ( string, DataArray, tuple ) - > Display\n"
00089        "Display ( string, tuple, tuple ) -> Display\n"
00090        "Display ( string, list, tuple ) -> Display\n"
00091        "Display ( string, RootNTuple, tuple ) -> Display\n"
00092        "Display ( string, RootNTuple, tuple, tuple ) -> Display\n"
00093        "\n"
00094        "This method is used to create a Display object.\n"
00095        "The first method is used for creating static version of\n"
00096        "Histogram, etc., where the string is the type of DataRep.\n"
00097        "The remaining methods are for dynamic versions.\n"
00098        "The string argument is the type.   The second argument\n"
00099        "is the DataSource and the third argument is tuple of\n"
00100        "string for the binding to the DataSource.\n"
00101        "For the last method, the fourth argument is a tuple\n"
00102        "of integers to access a RootNTuple array variable.\n\n"
00103        "For the names of the types of DataRep classes available\n"
00104        "call DataRep.names()."
00105 #endif
00106         ) )
00107 
00108     .def ( init < PyFunctionRep * > () )
00109 
00110     .def ( init < const std::string &,
00111            const DataSource &,
00112            const std::vector< std::string > & > () )
00113 
00114     .def ( init < const std::string &,
00115            const PyDataSource &,
00116            const std::vector< std::string > & > () )
00117 
00118     .def ( init < const std::string &,
00119            boost::python::tuple,
00120            const std::vector< std::string > & > () )
00121 
00122     .def ( init < const std::string &,
00123             boost::python::list,
00124            const std::vector< std::string > & > () )
00125 
00126 #ifdef HAVE_ROOT
00127     .def ( init < const std::string &,
00128             const QtRootNTuple &,
00129            const std::vector< std::string > & > () )
00130 
00131     .def ( init < const std::string &,
00132            const QtRootNTuple &,
00133            const std::vector< std::string > &,
00134            boost::python::list > () )
00135 #endif
00136 
00137     .def ( "applyCut", &QtDisplay::applyCut,
00138            "applyCut ( Cut ) -> None\n"
00139            "\n"
00140            "Apply a Cut to the Display" )
00141 
00142     .def ( "applyCuts", &QtDisplay::applyCuts,
00143            "applyCuts ( sequence ) -> None\n"
00144            "\n"
00145            "Apply each Cut in the sequence to the Display" )
00146 
00147     .def ( "createNTuple", &QtDisplay::createNTuple,
00148            return_value_policy < manage_new_object > (),
00149            "createNTuple ( ) -> NTuple\n"
00150            "\n"
00151            "Returns a NTuple representation of the Display's contents." )
00152 
00153     .def ( "createDataArray", &QtDisplay::createDataArray,
00154            return_value_policy < manage_new_object > (),
00155            "createDataArray ( ) -> DataArray\n"
00156            "\n"
00157            "Returns a DataArray representation of the Display's contents\n"
00158            "(This method available if configured with numarray)" )
00159 
00160     .def ( "setNumberOfBins", &QtDisplay::setNumberOfBins,
00161            "setNumberOfBins ( string, value ) -> None\n"
00162            "\n"
00163            "Sets the number of bins on named axis, e.g. 'x' to the given \n"
00164            "value." )
00165           
00166     .def ( "setBinWidth", 
00167            ( void (QtDisplay::*) ( const std::string &,
00168                                    double, 
00169                                    bool ) )
00170             &QtDisplay::setBinWidth,
00171             "Set the bin width, explicitly saving the value or not." )
00172 
00173     .def ( "getBinWidth", 
00174            ( double (QtDisplay::*) ( const std::string & ) )
00175             &QtDisplay::getBinWidth,
00176            "getBinWidth ( string ) -> value\n"
00177            "\n"
00178            "Returns the bin width on axis specified as a string,\n"
00179            "e.g., 'x'." )
00180 
00181     .def ( "setBinWidth", 
00182            ( void (QtDisplay::*) ( const std::string &,
00183                                    double ) )
00184             &QtDisplay::setBinWidth,
00185            "setBinWidth ( string, value ) -> None\n"
00186            "\n"
00187             "Set the bin width to value  on axis specified as a string,\n"
00188            "e.g., 'x'." )
00189 
00190     .def ( "reset", &QtDisplay::reset,
00191            "reset () -> None\n"
00192            "\n"
00193            "Resets the contents of all bins.   Only applicable to static\n"
00194            "histograms." )
00195 
00196     .def ( "setOffset", &QtDisplay::setOffset,
00197            "setOffset ( string, value ) -> None\n"
00198            "\n"
00199            "Sets the offset of the bins relative to their current width on\n"
00200            "specified axis." )
00201           
00202     .def ( "setRange", 
00203            ( void (QtDisplay::*) (const std::string &, 
00204                                   double, double) )
00205            &QtDisplay::setRange )
00206 
00207     .def ( "setRange", 
00208            ( void (QtDisplay::*) (const std::string &, 
00209                                   double, double, bool) )
00210            &QtDisplay::setRange,
00211            "setRange ( string, value, value ) -> None\n"
00212            "setRange ( string, value, value, Boolean ) -> None\n"
00213            "\n"
00214            "Set the upper and lower bounds for the specified axis.  For the\n"
00215            "second form, also save them if the Boolean argument is true." )
00216 
00217 
00218     .def ( "getRange", &QtDisplay::getRange,
00219            "getRange ( string ) -> tuple\n"
00220            "\n"
00221            "Returns the tuple representing the range for the axis specified\n"
00222            "as a string, e.g., 'x'." )
00223 
00224      .def ( "saveView", &QtDisplay::saveView,
00225             "saveView ( ) -> int\n"
00226             "\n"
00227             "Saves the current set of x and y ranges and "
00228             "returns the index of the saved view." )
00229 
00230      .def ( "setView", &QtDisplay::setView,
00231             "setView ( int ) -> None\n"
00232             "\n"
00233             "Set the view by its index." )
00234 
00235      .def ( "nextView", &QtDisplay::nextView,
00236             "nextView ( bool ) -> int\n"
00237             "\n"
00238             "Cycle to the next view in the view buffer. "
00239             "Set the argument to True to cycle for wards, "
00240             "False to cycle back wards.\n"
00241             "Returns the index of the new view." )
00242 
00243      .def ( "numViews", &QtDisplay::numViews,
00244             "numViews ( ) -> int\n"
00245             "\n"
00246             "Return the number of stored views." )
00247 
00248      .def ( "deleteView", &QtDisplay::deleteView,
00249             "deleteView ( int ) -> None\n"
00250             "\n"
00251             "Delete a view by index." )
00252 
00253      .def ( "currentView", &QtDisplay::currentView,
00254             "currentView ( ) -> int\n"
00255             "\n"
00256             "Index of the current view." )
00257 
00258     .def ( "setTitle", &QtDisplay::setTitle,
00259            "setTitle ( string ) -> None\n"
00260            "\n"
00261            "Sets the title of the display." )
00262 
00263     .def ( "getTitle", &QtDisplay::getTitle,
00264             return_value_policy < copy_const_reference > (),
00265            "getTitle () -> string\n"
00266            "\n"
00267            "Returns the current title.   The title will be the title of\n"
00268            "the DataSource unless it has been explicitly changed." )
00269 
00270     .def ( "setLabel", &QtDisplay::setLabel,
00271            "setLabel ( string, string ) -> None\n"
00272            "\n"
00273            "Sets the label for the axis specified by first argument to value\n"
00274            "of the second argument." )
00275 
00276     .def ( "getLabel", &QtDisplay::getLabel,
00277             return_value_policy< copy_const_reference > (),
00278            "getLabel ( string ) -> string\n"
00279            "\n"
00280             "Returns the label of the axis specified as a string,\n"
00281            "e.g., 'x'." )
00282 
00283     .def ( "getDataRep", &QtDisplay::getDataRep,
00284            return_value_policy < manage_new_object > (),
00285            "getDataRep ( ) -> DataRep\n"
00286            "\n"
00287            "Returns a reference to the active DataRep or if all DataRep objects are\n"
00288            "active, returns a reference to the first one." )
00289 
00290     .def ( "getDataReps", &QtDisplay::getDataReps,
00291             return_value_policy < copy_const_reference > (),
00292            "getDataReps ( ) -> list\n"
00293            "\n"
00294            "Returns a list of DataRep objects contained by the Display.." )
00295     
00296     .def ( "addDataRep", 
00297            ( void (QtDisplay::*) (PyDataRep *) )
00298            &QtDisplay::addDataRep,
00299            "addDataRep ( DataRep ) -> Display\n"
00300            "addDataRep ( Function ) -> Display\n"
00301            "addDataRep ( string, DataSource, tuple ) -> Display\n"
00302            "\n"
00303            "Adds a DataRep to the display sharing the same Y axis range\n"
00304            "The first two methods adds existing DataRep or Function to the\n"
00305            "Display.  The third method creates and adds DataRep to the\n"
00306            "Display.  Arguments are same as Display constructor." )
00307 
00308     .def ( "addDataRep", 
00309            ( void (QtDisplay::*) (const std::string &, 
00310                                   const DataSource *,
00311                                   const std::vector <std::string > &) )
00312            &QtDisplay::addDataRep )
00313 
00314     .def ( "addDataRep", 
00315            ( void (QtDisplay::*) (PyFunctionRep *) )
00316            &QtDisplay::addDataRep )
00317 
00318     .def ( "addDataRepStacked", 
00319            ( void (QtDisplay::*) (const std::string &, 
00320                                   const DataSource *,
00321                                   const std::vector <std::string > &) )
00322            &QtDisplay::addDataRepStacked,
00323            "addDataRepStacked ( string, DataSource, tuple ) -> Display\n"
00324            "\n"
00325            "Creates and adds a DataRep with independent Y axis ranges.\n"
00326            "The arguments are the same as Display constructor." ) 
00327 
00328 #ifndef BOOST_DEFECT
00329     .def ( "addFunction", 
00330            ( void (QtDisplay::*) (FunctionBase *) )
00331            &QtDisplay::addFunction,
00332            "addFunction ( FunctionBase ) -> None\n"
00333            "\n"
00334            "Adds a FunctionBase object to the display by appropriately\n"
00335            "wrapping it with a Function." )
00336 #endif // BOOST_DEFECT
00337 
00338     .def ( "setAutoRanging",
00339             ( void (QtDisplay::*) (const std::string &,
00340                                    bool flag ) )
00341             &QtDisplay::setAutoRanging,
00342            "setAutoRanging ( string, Boolean ) -> None\n"
00343            "\n"
00344            "Sets auto-ranging on axis specified as a string, e.g. 'x',n"
00345            "on or off." )
00346 
00347     .def ( "setLog", &QtDisplay::setLog,
00348            "setLog ( string, Boolean ) -> None\n"
00349            "\n"
00350            "Sets the axis specified by the first argument on log scale." )
00351 
00352     .def ( "getLog", &QtDisplay::getLog,
00353            "getLog ( string ) -> value\n"
00354            "\n"
00355            "Returns True if axis specified as a string, e.g. 'x', is being\n"
00356            "displayed on a logarithmic scale." )
00357 
00358     .def ( "setTransform", &QtDisplay::setTransform,
00359            "setTransform ( string ) -> None\n"
00360            "\n"
00361            "Sets the transform object." )
00362 
00363     .def ( "addValues", &QtDisplay::addValues,
00364            "addValue ( tuple ) -> None\n"
00365            "\n"
00366            "For static histograms, adds a value to the accumulation.\n"
00367            "For 1D histogram, the tuple should contain one or two values,\n"
00368            "the second used as a weight.  For 2D histogram, the tuple should\n"
00369            "contain two or three elements, the third being the weight.\n"
00370            "non static Displays do nothing." )
00371 
00372     .def ( "setPointRep", &QtDisplay::setPointRep,
00373            "setPointRep ( RepBase ) -> None\n"
00374            "\n"
00375            "Sets the point representation to be used." )
00376 
00377     .def ( "setContourLevels", &QtDisplay::setContourLevels,
00378            "setContourLevels ( sequence ) -> None\n"
00379            "\n"
00380            "Sets the contour levels if the Display is using contour point\n"
00381            "representation from the values in the sequence." )
00382 
00383     .def ( "setAspectRatio", &QtDisplay::setAspectRatio,
00384            "setAspectRatio ( value ) -> None\n"
00385            "\n"
00386            "Sets the required aspect ratio of the Display to value, the\n"
00387            "ratio of the width to the height." )
00388 
00389      .def ( "numberOfEntries", &QtDisplay::numberOfEntries,
00390             "numberOfEntries ( ) -> value\n"
00391             "\n"
00392             "Returns the number of entries in the Display." )
00393 
00394      .def ( "resize", &QtDisplay::resize,
00395             "resize () -> None\n"
00396             "\n"
00397             "Resizes the Display to its saved values." )
00398 
00399      .def ( "plotterId", &QtDisplay::plotterId,
00400             "plotterId () -> value\n"
00401             "\n"
00402             "Returns a unique identifier for the Display." )
00403 
00404      .def ( "setColorMap", &QtDisplay::setColorMap,
00405             "setColorMap ( string ) -> None\n"
00406             "\n"
00407             "Set the value-to-color map to one named by the argument.")
00408 
00409     .def ( "update", &QtDisplay::update,
00410            "update () -> None\n"
00411            "\n"
00412            "Updates the display." )
00413 
00414     .def ( "addObserver", &QtDisplay::addObserver,
00415            "addObserver ( Observer ) -> None\n"
00416            "\n"
00417            "Adds an Observer to the Display object." )
00418 
00419     .def ( "setAutoTicks", &QtDisplay::setAutoTicks,
00420            "setAutoTicks ( Boolean ) -> None\n"
00421            "\n"
00422            "Set the ticks generation to be automatic (the default) or\n"
00423            "manually." )
00424 
00425     .def ( "setTicks", &QtDisplay::setTicks,
00426            "setTicks ( string, sequence, sequence ) -> None\n"
00427            "\n"
00428            "Sets the tick locations and labels.   The first argument is the\n"
00429            " axis, the second argument is a sequence containing the\n"
00430            "locations, and the third argument is a sequence of tick labels." )
00431 
00432     .def ( "unlock", &QtDisplay::unlock,
00433            "unlock () -> None\n"
00434            "\n"
00435            "Unlock the application thread." )
00436 
00437     ;
00438 }
00439 
00440 } // namespace Python
00441 } // namespace hippodraw
00442 
00443 using namespace hippodraw;
00444 
00447 void QtDisplay::createDisplay ( const std::string & type, 
00448                                 const DataSource & nt, 
00449                                 const std::vector < std::string > & bindings )
00450 {
00451   PyApp::lock();
00452   DisplayController * controller = DisplayController::instance ();
00453   try {
00454     m_plotter = controller->createDisplay ( type, nt, bindings );
00455     PyApp::unlock ();
00456   }
00457   catch ( const FactoryException & e ) {
00458     PyApp::unlock ();
00459     throw e;
00460   }
00461   catch ( const DataRepException & e ) {
00462     PyApp::unlock ();
00463     throw e;
00464   }
00465   catch ( const runtime_error & e ) {
00466     PyApp::unlock ();
00467     throw e;
00468   }
00469 }
00470 
00471 QtDisplay::
00472 QtDisplay ( const std::string & type,
00473             boost::python::tuple seq,
00474             const std::vector < std::string > & labels )
00475 {
00476   PyApp::lock();
00477 
00478   object obj = seq.attr ( "__len__" ) ();
00479 
00480   ListTuple * ntuple = new ListTuple ( );
00481 
00482   try {
00483     unsigned int size = extract < unsigned int > ( obj );
00484 
00485     if ( size > labels.size () ) {
00486       string what ( "Display: Too few labels" );
00487       throw runtime_error ( what );
00488     }
00489       
00490     for ( unsigned int i = 0, j = 0; i < size; i++, j++ ) {
00491       boost::python::list l = extract < boost::python::list > ( seq[i] );
00492 
00493       while ( labels[j] == "nil" ) {
00494         j++; // skip such labels
00495         if ( ! ( j < labels.size () ) ) {
00496           string what ( "Display: Too few non 'nil' labels" );
00497           throw runtime_error ( what );
00498         }
00499 
00500       }
00501       ntuple -> addColumn ( labels[j], l );
00502     }
00503   }
00504   catch ( const runtime_error & e ) {
00505     delete ntuple;
00506     PyApp::unlock ();
00507     throw e;
00508   }
00509 
00510   // Do not call createDisplay() as exceptions wouldn't print nicely
00511   try { 
00512     DisplayController * dc = DisplayController::instance ();
00513     m_plotter = dc -> createDisplay ( type, *ntuple, labels );
00514   }
00515   catch ( const FactoryException & e ) {
00516     delete ntuple;
00517     PyApp::unlock ();
00518     throw e;
00519   }
00520   catch ( const DataRepException & e ) {
00521     delete ntuple;
00522     PyApp::unlock ();
00523     throw e;
00524   }
00525   catch ( const runtime_error & e ) {
00526     delete ntuple;
00527     PyApp::unlock ();
00528     throw e;
00529   }
00530 
00531   // No use telling controller about it until we are sure to accept it.
00532   DataSourceController * dsc = DataSourceController::instance ();
00533   dsc -> registerNTuple ( ntuple );
00534 
00535   PyApp::unlock ();
00536 }
00537 
00538 QtDisplay::
00539 QtDisplay ( const std::string & type,
00540             boost::python::list seq,
00541             const std::vector < std::string > & labels )
00542 {
00543   PyApp::lock();
00544 
00545   object obj = seq.attr ( "__len__" ) ();
00546 
00547   ListTuple * ntuple = new ListTuple ( );
00548 
00549   try {
00550     unsigned int size = extract < unsigned int > ( obj );
00551 
00552     if ( size > labels.size () ) {
00553       string what ( "Display: Too few labels" );
00554       throw runtime_error ( what );
00555     }
00556       
00557     // gcc 2.95.3 needs full scoping
00558     for ( unsigned int i = 0, j = 0; i < size; i++, j++ ) {
00559       boost::python::list l = extract < boost::python::list > ( seq[i] );
00560 
00561       while ( labels[j] == "nil" ) {
00562         j++; // skip such labels
00563         if ( ! ( j < labels.size () ) ) {
00564           string what ( "Display: Too few non 'nil' labels" );
00565           throw runtime_error ( what );
00566         }
00567 
00568       }
00569       ntuple -> addColumn ( labels[j], l );
00570     }
00571   }
00572   catch ( const runtime_error & e ) {
00573     delete ntuple;
00574     PyApp::unlock ();
00575     throw e;
00576   }
00577 
00578   // Do not call createDisplay() as exceptions wouldn't print nicely
00579   try { 
00580     DisplayController * dc = DisplayController::instance ();
00581     m_plotter = dc -> createDisplay ( type, *ntuple, labels );
00582   }
00583   catch ( const FactoryException & e ) {
00584     delete ntuple;
00585     PyApp::unlock ();
00586     throw e;
00587   }
00588   catch ( const DataRepException & e ) {
00589     delete ntuple;
00590     PyApp::unlock ();
00591     throw e;
00592   }
00593   catch ( const runtime_error & e ) {
00594     delete ntuple;
00595     PyApp::unlock ();
00596     throw e;
00597   }
00598 
00599   // No use telling controller about it until we are sure to accept it.
00600   DataSourceController * dsc = DataSourceController::instance ();
00601   dsc -> registerNTuple ( ntuple );
00602 
00603   PyApp::unlock ();
00604 }
00605 
00606 QtDisplay::QtDisplay ()
00607   : m_plotter ( 0 )
00608 {
00609 }
00610 
00611 QtDisplay::
00612 QtDisplay ( PyFunctionRep * rep )
00613 {
00614   PyApp::lock();
00615   DisplayController * controller = DisplayController::instance ();
00616   try {
00617     DataRep * dr = rep -> getRep ();
00618     m_plotter = controller -> createDisplay ( dr );
00619     PyApp::unlock ();
00620   }
00621   catch ( const FactoryException & e ) {
00622     PyApp::unlock ();
00623     throw e;
00624   }
00625   catch ( const DataRepException & e ) {
00626     PyApp::unlock ();
00627     throw e;
00628   }
00629 }
00630 
00631 QtDisplay::
00632 QtDisplay ( const std::string & type )
00633 {
00634 //   PyApp::lock();
00635   DisplayController * controller = DisplayController::instance ();
00636   try {
00637     m_plotter = controller -> createDisplay ( type );
00638     PyApp::unlock ();
00639   }
00640   catch ( const FactoryException & e ) {
00641     PyApp::unlock ();
00642     throw e;
00643   }
00644   catch ( const DataRepException & e ) {
00645     PyApp::unlock ();
00646     throw e;
00647   }
00648 //   PyApp::unlock ();
00649 }
00650 
00651 
00652 QtDisplay::QtDisplay( const std::string & type,
00653                       const DataSource & nt,
00654                       const std::vector< std::string > & bindings )
00655 {
00656    createDisplay ( type, nt, bindings );
00657 }
00658 
00659 QtDisplay::QtDisplay( const std::string & type,
00660                       const PyDataSource & nt,
00661                       const std::vector< std::string > & bindings )
00662 {
00663    createDisplay ( type, nt.dataSource(), bindings );
00664 }
00665 
00666 #ifdef HAVE_ROOT
00667 QtDisplay::
00668 QtDisplay ( const std::string & type,
00669             const QtRootNTuple & nt,
00670             const std::vector < std::string > & bindings )
00671 {
00672   createDisplay ( type, nt, bindings );
00673 }
00674 
00675 QtDisplay::
00676 QtDisplay ( const std::string & type,
00677             const QtRootNTuple & nt,
00678             const std::vector < std::string > & variables,
00679             boost::python::list indices )
00680 {
00681   object obj = indices.attr ( "__len__" ) ();
00682   unsigned int size = extract < unsigned int > ( obj );
00683 
00684   if ( size != variables.size() ) {
00685     const string what ( "Display: bindings and indexes not the same size." );
00686     PyApp::unlock ();
00687     throw runtime_error ( what );
00688   }
00689 
00690   vector < vector < int > > vec ( size );
00691   for ( unsigned int i = 0; i < size; i++ ) {
00692     boost::python::list l = extract < boost::python::list > ( indices[i] );
00693     object o = l.attr ( "__len__" ) ();
00694     unsigned int len = extract < unsigned int > ( o );
00695     for ( unsigned int j = 0; j < len; j++ ) {
00696       unsigned int k = extract < unsigned int > ( l[j] );
00697       vec[i].push_back ( k );
00698     }
00699   }
00700 
00701   vector < string > bindings ( size );
00702 
00703   for ( unsigned int i = 0; i < size; i++ ) {
00704     const string & label = variables [ i ];
00705     const vector < int > & indexes = vec [ i ];
00706     const string name = nt.createBinding ( label, indexes );
00707     bindings [ i ] = name;
00708   }
00709 
00710   createDisplay ( type, nt, bindings );
00711 }
00712 
00713 #endif // have_root
00714 
00715 QtDisplay::
00716 QtDisplay ( PlotterBase * plotter) : m_plotter(plotter) {}
00717 
00718 QtDisplay::~QtDisplay () 
00719 { 
00720 //     delete m_plotter; 
00721 }
00722 
00723 PlotterBase * QtDisplay::display()
00724 {
00725   return m_plotter;
00726 }
00727 
00730 void QtDisplay::addDataRep ( const std::string & type, 
00731                              const DataSource * ntuple,
00732                              const std::vector < std::string > & bindings )
00733 {
00734   PyApp::lock();
00735 
00736   DisplayController * controller = DisplayController::instance ();
00737   controller->addDataRep ( m_plotter, type, ntuple, bindings );
00738 
00739   PyApp::unlock ();
00740 }
00741 
00742 void
00743 QtDisplay::
00744 addDataRepStacked ( const std::string & type, 
00745                   const DataSource * ntuple,
00746                   const std::vector < std::string > & bindings )
00747 {
00748   PyApp::lock();
00749 
00750   DisplayController * controller = DisplayController::instance ();
00751   controller->addDataRepStacked ( m_plotter, type, ntuple, bindings );
00752 
00753   PyApp::unlock ();
00754 }
00755 
00756 void QtDisplay::addDataRep ( PyDataRep * pyRep )
00757 {
00758   PyApp::lock();
00759 
00760    DisplayController * controller = DisplayController::instance ();
00761    controller->addDataRep ( m_plotter, pyRep->getDataRep() );
00762 
00763   PyApp::unlock ();
00764 }
00765 
00766 void QtDisplay::addDataRep ( PyFunctionRep * pyFuncRep )
00767 {
00768   PyApp::lock();
00769 
00770    DisplayController * controller = DisplayController::instance ();
00771    
00772    controller->addDataRep ( m_plotter, pyFuncRep->getRep() );
00773 
00774   PyApp::unlock ();
00775 }
00776 
00777 #ifndef BOOST_DEFECT
00778 void
00779 QtDisplay::
00780 addFunction ( FunctionBase * function )
00781 {
00782    PyApp::lock();
00783    FunctionController * funcController = FunctionController::instance();
00784    DataRep * dataRep = m_plotter->getDataRep( 0 );
00785 
00786 // The following datarep will be deleted by the CompositePlotter.
00787    FunctionRep * funcRep = 
00788       funcController->createFunctionRep(function, dataRep);
00789 
00790    DisplayController * controller = DisplayController::instance();
00791    dataRep = reinterpret_cast<DataRep *>(funcRep);
00792    controller->addDataRep(m_plotter, dataRep);
00793 
00794    PyApp::unlock ();
00795 }
00796 #endif // BOOST_DEFECT
00797 
00798 void
00799 QtDisplay::
00800 setRange ( const std::string & axis, double low, double high,
00801            bool save)
00802 {
00803   PyApp::lock();
00804 
00805   if (save) {
00806      if (axis == "x" || axis == "X") 
00807         m_ranges["x"] = std::make_pair(low, high);
00808      if (axis == "y" || axis == "Y") 
00809         m_ranges["y"] = std::make_pair(low, high);
00810   }
00811      
00812   m_plotter->setRange ( axis, low, high );
00813 
00814   PyApp::unlock ();
00815 }
00816 
00817 void
00818 QtDisplay::
00819 setRange ( const std::string & axis, double low, double high )
00820 {
00821   PyApp::lock();
00822   setRange( axis, low, high, false );
00823   PyApp::unlock();
00824 }
00825 
00826 std::vector<double>
00827 QtDisplay::
00828 getRange ( const std::string & axis )
00829 {
00830   PyApp::lock ();
00831 
00832   std::vector<double> myRange;
00833   try { 
00834     Axes::Type type = Axes::convert ( axis );
00835     const Range & axisRange = m_plotter->getRange( type, true );
00836     myRange.push_back(axisRange.low());
00837     myRange.push_back(axisRange.high());
00838     
00839     PyApp::unlock ();
00840   }
00841   catch ( const PlotterException & e ) {
00842     PyApp::unlock ();
00843     throw e;
00844   }
00845 
00846   return myRange;
00847 }
00848 
00849 int QtDisplay::saveView ()
00850 {
00851    std::vector<double> range_values;
00852    std::vector<double> range = getRange("x");
00853    range_values.push_back(range[0]);
00854    range_values.push_back(range[1]);
00855    m_ranges["x"] = std::make_pair(range[0], range[1]);
00856 
00857    range = getRange("y");
00858    range_values.push_back(range[0]);
00859    range_values.push_back(range[1]);
00860    m_ranges["y"] = std::make_pair(range[0], range[1]);
00861 
00862    return m_plotter->saveView(range_values);
00863 }
00864 
00865 void QtDisplay::setView ( int index )
00866 {
00867   PyApp::lock();
00868   try {
00869      m_plotter->setView( index );
00870   } catch (...) {
00871     PyApp::unlock ();
00872      throw;
00873   }
00874   PyApp::unlock ();
00875 }
00876 
00877 int QtDisplay::nextView( bool stepForward )
00878 {
00879   int index(-1);
00880   PyApp::lock();
00881    try {
00882       index = m_plotter->nextView(stepForward);
00883    } catch (...) {
00884      PyApp::unlock ();
00885       throw;
00886    }
00887    PyApp::unlock ();
00888    return index;
00889 }
00890 
00891 int QtDisplay::numViews () {
00892    return m_plotter->numViews();
00893 }
00894 
00895 void QtDisplay::deleteView (int index) {
00896   PyApp::lock();
00897    try {
00898       m_plotter->deleteView(index);
00899    } catch (...) {
00900      PyApp::unlock ();
00901       throw;
00902    }
00903    PyApp::unlock ();
00904 }
00905 
00906 int QtDisplay::currentView () {
00907    return m_plotter->currentView();
00908 }
00909 
00910 void QtDisplay::setTitle ( const std::string & title )
00911 {
00912   PyApp::lock();
00913   m_plotter->setTitle ( title );
00914   PyApp::unlock ();
00915 }
00916 
00917 const std::string & QtDisplay::getTitle() const {
00918    return m_plotter->getTitle();
00919 }
00920 
00921 void
00922 QtDisplay::
00923 setPointRep ( RepBase * rep )
00924 {
00925   PyApp::lock();
00926   try {
00927      m_plotter->setRepresentation ( rep );
00928   } catch ( const std::runtime_error & e ) {
00929     PyApp::unlock ();
00930     throw e;
00931   }
00932   PyApp::unlock ();
00933 }
00934 
00935 void
00936 QtDisplay::
00937 setContourLevels ( const std::vector<double> &levels ) 
00938 {
00939    PyApp::lock();
00940    RepBase * rep = m_plotter->representation();
00941    
00942    if ( rep->name() == std::string("Contour") ) {
00943       DataRep * datarep 
00944          = m_plotter->getDataRep ( m_plotter->activePlotIndex() );
00945 
00946       dynamic_cast<ContourPointRep *>(rep)
00947          ->setContourValues( const_cast<std::vector<double>&>(levels), 
00948                              datarep->getProjector() );
00949 
00950       datarep->notifyObservers();
00951 
00952    } else {
00953       // do nothing
00954    }
00955    PyApp::unlock ();
00956 }
00957 
00958 void QtDisplay::setLabel ( const std::string & axis,
00959                            const std::string & label )
00960 {
00961   PyApp::lock();
00962 
00963   Axes::Type at = Axes::convert ( axis );
00964   m_plotter->setLabel ( at, label );
00965 
00966   PyApp::unlock ();
00967 }
00968 
00969 const std::string &
00970 QtDisplay::
00971 getLabel ( const std::string & axis ) const
00972 {
00973   PyApp::lock ();
00974   Axes::Type at = Axes::convert ( axis );
00975   const std::string & label = m_plotter -> getLabel( at );
00976   PyApp::unlock ();
00977 
00978   return label;
00979 }
00980 
00981 void
00982 QtDisplay::
00983 setNumberOfBins ( const std::string & axis, unsigned int number )
00984 {
00985   PyApp::lock();
00986   m_plotter->setNumberOfBins ( axis, number );
00987   PyApp::unlock();
00988 }
00989 
00990 void 
00991 QtDisplay::
00992 reset()
00993 {
00994   PyApp::lock();
00995   m_plotter -> reset ();
00996   PyApp::unlock ();
00997 }
00998 
00999 void QtDisplay::setBinWidth ( const std::string & axis, double width,
01000                               bool save )
01001 {
01002   PyApp::lock();
01003 
01004   if (save) {
01005      if (axis == "x" || axis == "X") 
01006         m_binWidths["x"] = width;
01007      if (axis == "y" || axis == "Y") 
01008         m_binWidths["y"] = width;
01009   }     
01010 
01011   m_plotter->setBinWidth ( axis, width );
01012 
01013   PyApp::unlock ();
01014 }
01015 
01016 double
01017 QtDisplay::
01018 getBinWidth ( const std::string & axis ) const
01019 {
01020   return m_plotter->getBinWidth ( axis);
01021 }
01022 
01023 void
01024 QtDisplay::
01025 setBinWidth ( const std::string & axis, double width )
01026 {
01027     PyApp::lock();
01028    setBinWidth( axis, width, false );
01029    PyApp::unlock ();
01030 }
01031 
01032 void QtDisplay::setOffset ( const std::string & axis, double offset )
01033 {
01034   PyApp::lock();
01035   DisplayController * controller = DisplayController::instance ();
01036   Axes::Type type = Axes::convert ( axis );
01037 
01038   controller->setOffset ( m_plotter, type, offset );
01039   PyApp::unlock();
01040 }
01041 
01044 void QtDisplay::setTransform ( const std::string & name )
01045 {
01046   PyApp::lock();
01047 
01048   DisplayController * controller = DisplayController::instance ();
01049   try {
01050      controller->setTransform ( m_plotter, name );
01051      PyApp::unlock ();
01052   } catch (PlotterException & eObj) {
01053     PyApp::unlock ();
01054      throw eObj;
01055   } catch (FactoryException & eObj) {
01056     PyApp::unlock ();
01057      throw eObj;
01058   }
01059 }
01060 
01061 void QtDisplay::unlock() {
01062   PyApp::unlock ();
01063 }
01064 
01065 void QtDisplay::setLog ( const std::string & axis, int flag )
01066 {
01067   PyApp::lock();
01068   Axes::Type type = Axes::convert ( axis );
01069   DisplayController * controller = DisplayController::instance ();
01070   bool yes = flag != 0;
01071 
01072   controller->setLog ( m_plotter, type, yes );
01073   PyApp::unlock ();
01074 }
01075 
01076 int QtDisplay::getLog ( const std::string & axis )
01077 {
01078   DisplayController * controller = DisplayController::instance ();
01079   if ( controller->getLog ( m_plotter, axis) ) {
01080      return 1;
01081   } else {
01082      return 0;
01083   }
01084 }
01085 
01086 void QtDisplay::setAutoRanging ( const std::string & axis, bool flag )
01087 {
01088   PyApp::lock();
01089   Axes::Type type = Axes::convert ( axis );
01090   m_plotter->setAutoRanging ( type, flag );
01091   PyApp::unlock ();
01092 }
01093 
01094 PyDataRep *
01095 QtDisplay::
01096 getDataRep ()
01097 {
01098   PyApp::lock ();
01099 
01100   int index = m_plotter->activePlotIndex();
01101   if ( index < 0 ) index = 0;
01102   DataRep * rep = m_plotter->getDataRep ( index );
01103   PyDataRep * pyrep = new PyDataRep ( rep );
01104 
01105   PyApp::unlock ();
01106 
01107   return pyrep;
01108 }
01109 
01110 const std::vector<PyDataRep *> &
01111 QtDisplay::
01112 getDataReps () const
01113 {
01114   PyApp::lock ();
01115 
01116    m_pyDataReps.clear();
01117    int nReps = m_plotter->getNumDataReps();
01118    for (int i = 0; i < nReps; i++) {
01119       m_pyDataReps.push_back( new PyDataRep ( m_plotter->getDataRep( i ) ) );
01120    }
01121    PyApp::unlock ();
01122 
01123    return m_pyDataReps;
01124 }
01125 
01126 void
01127 QtDisplay::
01128 setAspectRatio ( double ratio )
01129 {
01130   PyApp::lock();
01131   m_plotter->setAspectRatio ( ratio );
01132   PyApp::unlock ();
01133 }
01134 
01135 void
01136 QtDisplay::
01137 addValues ( const std::vector < double > & v )
01138 {
01139   PyApp::lock();
01140   m_plotter -> addValues ( v );
01141   PyApp::unlock ();
01142 }
01143 
01144 PyNTuple *
01145 QtDisplay::
01146 createNTuple () const
01147 {
01148   // Need to lock else could create NTuple not yet displayed
01149   PyApp::lock();
01150   FunctionController * controller = FunctionController::instance();
01151   const NTuple * ntuple = controller -> createNTuple ( m_plotter, 0 );
01152 
01153   PyNTuple * pytuple = new PyNTuple ( *ntuple );
01154   delete ntuple;
01155 
01156   PyApp::unlock ();
01157 
01158   return pytuple;
01159 }
01160 
01161 double
01162 QtDisplay::
01163 numberOfEntries() const
01164 {
01165    ProjectorBase * projector = m_plotter->activeProjector();
01166    return projector->getNumberOfEntries();
01167 }
01168 
01169 void
01170 QtDisplay::
01171 resize() 
01172 {
01173    PyApp::lock();
01174 
01175    if (m_binWidths.count("x")) {
01176       m_plotter->setBinWidth("x", m_binWidths["x"]);
01177    } else {
01178 // set and unset log-scale to get decent bin sizes
01179       DisplayController * controller = DisplayController::instance();
01180       if ( controller->getLog( m_plotter, "x" ) ) {
01181          setLog( "x", 0 );
01182          setLog( "x", 1 );
01183       } else { 
01184          setLog( "x", 1 );
01185          setLog( "x", 0 );
01186       }
01187    }
01188 
01189    if (m_binWidths.count("y")) {
01190       m_plotter->setBinWidth("y", m_binWidths["y"]);
01191    } else {
01192      // set and unset log-scale to get decent bin sizes
01193       DisplayController * controller = DisplayController::instance();
01194       if ( controller->getLog( m_plotter, "y" ) ) {
01195          setLog( "y", 0 );
01196          setLog( "y", 1 );
01197       } else { 
01198          setLog( "y", 1 );
01199          setLog( "y", 0 );
01200       }
01201    }
01202 
01203    if (m_ranges.count("x")) {
01204       m_plotter->setRange("x", m_ranges["x"].first, m_ranges["x"].second);
01205    } else {
01206       m_plotter->setAutoRanging("x", true);
01207    }
01208 
01209    if (m_ranges.count("y")) {
01210       m_plotter->setRange("y", m_ranges["y"].first, m_ranges["y"].second);
01211    } else {
01212       m_plotter->setAutoRanging("y", true);
01213    }
01214 
01215    PyApp::unlock ();
01216 }
01217 
01218 int QtDisplay::plotterId() const
01219 {
01220    return m_plotter->plotterId();
01221 }
01222 
01226 void QtDisplay::
01227 setColorMap ( const std::string & name ) {
01228    PyApp::lock();
01229    BinToColorFactory * factory = BinToColorFactory::instance();
01230    const vector< std::string > & names = factory -> names();
01231    if ( std::find(names.begin(), names.end(), name) != names.end() ) {
01232       BinToColor * rep = factory -> create ( name );
01233       m_plotter -> setValueRep( rep );
01234       PyApp::unlock ();
01235    } else {
01236      PyApp::unlock();
01237      std::ostringstream message;
01238       message << "QtDisplay::setColorMap:\n"
01239               << "BinToColor rep '" << name << "' does not exist.\n"
01240               << "Valid rep names are \n\n";
01241       for (unsigned int i = 0; i < names.size() ; i++) {
01242          message << "'" << names[i] << "'\n";
01243       }
01244       throw std::runtime_error(message.str());
01245    }
01246 }
01247 
01248 void
01249 QtDisplay::
01250 update ()
01251 {
01252   PyApp::lock();
01253 
01254   m_plotter -> update ();
01255 
01256   PyApp::unlock ();
01257 }
01258 
01259 void
01260 QtDisplay::
01261 addObserver ( Observer * observer )
01262 {
01263   m_plotter -> addObserver ( observer );
01264 }
01265 
01266 void
01267 QtDisplay::
01268 setTicks ( const std::string & axis,
01269            const std::vector < double > & values,
01270            const std::vector < std::string > & labels )
01271 {
01272   PyApp::lock();
01273   m_plotter -> setTicks ( axis, values, labels );
01274   PyApp::unlock ();
01275 }
01276 
01277 void
01278 QtDisplay::
01279 setAutoTicks ( const std::string & axis, bool yes )
01280 {
01281   PyApp::lock();
01282   m_plotter -> setAutoTicks ( axis, yes );
01283   PyApp::unlock ();
01284 }
01285 
01286 PyDataSource *
01287 QtDisplay::
01288 createDataArray () const
01289 {
01290   // Need to lock else could create NTuple not yet displayed
01291 #ifdef HAVE_NUMARRAY
01292   PyApp::lock();
01293 
01294   FunctionController * controller = FunctionController::instance();
01295   NTuple * ntuple = controller -> createNTuple ( m_plotter, 0 );
01296   PyDataSource * ds = new PyDataSource ( "NTuple", ntuple );
01297 
01298   PyApp::unlock ();
01299 
01300   return ds;
01301 #else
01302    runtime_error e ( "HippoDraw was not built with numeric Python support" );
01303    throw e;
01304 #endif
01305 }
01306 
01307 void
01308 QtDisplay::
01309 applyCut ( QtDisplay * cut )
01310 {
01311    PyApp::lock();
01312 
01313    PlotterBase * cut_plotter = cut -> display();
01314    PlotterBase * target_plotter = display ();
01315 
01316    CutController * controller = CutController::instance();
01317    controller -> addCut ( cut_plotter, target_plotter );
01318 
01319    PyApp::unlock ();
01320 }
01321 
01322 void
01323 QtDisplay::
01324 applyCuts ( const std::vector < QtDisplay * > & cuts )
01325 {
01326    PyApp::lock();
01327 
01328    vector < PlotterBase * > cut_plotters;
01329    unsigned int size = cuts.size ();
01330    for ( unsigned int i = 0; i < size; i++ ) {
01331      QtDisplay * cut_display = cuts[i];
01332      PlotterBase * plotter = cut_display -> display();
01333      cut_plotters.push_back ( plotter );
01334    }
01335 
01336    PlotterBase * target_plotter = display ();
01337    CutController * controller = CutController::instance();
01338    controller -> addCuts ( cut_plotters, target_plotter );
01339 
01340    PyApp::unlock ();
01341 }

Generated for HippoDraw Class Library by doxygen