00001
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016
00017
00018 #include <boost/python.hpp>
00019
00020
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 }
00441 }
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++;
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
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
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
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++;
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
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
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
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
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
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
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
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
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
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
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
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 }