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 [ 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 }
00442 }
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++;
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
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
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
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++;
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
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
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
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
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
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
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
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
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
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
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
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 }