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

Generated for HippoDraw Class Library by doxygen