00001
00012
00013 #ifdef _MSC_VER
00014 #include "msdevstudio/MSconfig.h"
00015 #endif
00016
00017
00018 #include <boost/python.hpp>
00019
00020 #include "PyDataRep.h"
00021
00022 #include "PyApp.h"
00023 #include "PyDataSource.h"
00024 #include "QtCut.h"
00025
00026 #include "controllers/DisplayController.h"
00027 #include "controllers/DataRepController.h"
00028 #include "controllers/CutController.h"
00029 #include "projectors/ProjectorBase.h"
00030 #include "reps/RepBase.h"
00031 #include "datareps/DyHistogram.h"
00032 #include "datasrcs/NTuple.h"
00033 #include "plotters/Cut1DPlotter.h"
00034
00035 #include <stdexcept>
00036 #include <sstream>
00037
00038 using std::runtime_error;
00039 using std::string;
00040
00041 using namespace boost::python;
00042
00043 namespace hippodraw {
00044 namespace Python {
00045
00046 void
00047 export_DataRep()
00048 {
00049 class_ < PyDataRep >
00050 ( "DataRep",
00051 "A base class for representing data in various ways. For example, a\n"
00052 "a histogram is a way to represent a column of data." )
00053
00054 .def ( init < const std::string &,
00055 const DataSource *,
00056 const std::vector< std::string > & >
00057 (
00058 "DataRep ( string ) -> DataRep\n"
00059 "DataRep ( string, DataSource, sequence ) -> DataRep\n"
00060 "DataRep ( DataRep ) -> DataRep\n"
00061 "\n"
00062 "Constructors for DataRep objects. The first form creates a\n"
00063 "static version. The second form creates a dynamic version\n"
00064 "bound to a DataSource with bindings taken from the strings in\n"
00065 "the sequence. The final version makes a copy of existing\n"
00066 "DataRep.\n\n"
00067 "For the names of the types of DataRep classes available\n"
00068 "see names().") )
00069
00070 .def ( init < const std::string &,
00071 const PyDataSource *,
00072 const std::vector< std::string > & > () )
00073
00074 .def ( init < PyDataRep * > () )
00075
00076 .def ( "names", &PyDataRep::names,
00077 return_value_policy < copy_const_reference > (),
00078 "names () -> tuple\n"
00079 "\n"
00080 "Returns a tuple containing the names of the types of DataRep\n"
00081 "that are available." )
00082
00083 .staticmethod ( "names" )
00084
00085 .def ( "setPointRep", &PyDataRep::setPointRep,
00086 "setPointRep ( RepBase ) -> None\n"
00087 "\n"
00088 "Sets the point representation." )
00089
00090 .def ( "setAxisBinding", &PyDataRep::setAxisBinding,
00091 "setAxisBinding ( string, string ) -> None\n"
00092 "\n"
00093 "Sets an axis binding. The first argument is the axis and the\n"
00094 "second is a label of a column in the DataSource." )
00095
00096 .def ( "setAxisBindings", &PyDataRep::setAxisBindings,
00097 "setAxisBindings ( string, sequence ) -> None\n"
00098 "\n"
00099 "Sets all the axes bindings. The first argument is the axis and\n"
00100 "the sequence contains labels of columns in the DataSource." )
00101
00102 .def ( "setWeight", &PyDataRep::setWeight,
00103 "setWeight ( string ) -> None\n"
00104 "\n"
00105 "Sets the weight option if DataRep is a type of histogram.\n"
00106 "The string is a label of a column in the DataSource." )
00107
00108 .def ( "name", &PyDataRep::name,
00109 return_value_policy < copy_const_reference > (),
00110 "name ( ) -> string\n"
00111 "\n"
00112 "Returns the type of DataRep." )
00113
00114 .def ( "getBinWidth", &PyDataRep::getBinWidth,
00115 "getBinWidth ( string ) -> value\n"
00116 ""
00117 "Returns the bin width on specified axis. Only meaningful if\n"
00118 "object is histogram type." )
00119
00120 .def ( "getMean", &PyDataRep::getMean,
00121 "getMean ( string ) -> value\n"
00122 "\n"
00123 "Returns the mean of the data along specified axis" )
00124
00125 .def ( "getRMS", &PyDataRep::getRMS,
00126 "getRMS ( string ) -> value\n"
00127 "\n"
00128 "Returns root mean squared of data along specified axis" )
00129
00130 .def ( "numberOfEntries", &PyDataRep::numberOfEntries,
00131 "numberOfEntries ( ) -> value\n"
00132 "\n"
00133 "Returns the number of entries." )
00134
00135 .def ( "applyCut", &PyDataRep::applyCut,
00136 "applyCut ( Cut ) -> None\n"
00137 "\n"
00138 "Applies a Cut to limit the rows of the DataSource used by\n"
00139 "the Display." )
00140
00141 .def ( "applyCuts", &PyDataRep::applyCuts,
00142 "applyCuts ( sequence ) -> None\n"
00143 "\n"
00144 "Applies a sequence of Cut object to limit the rows of\n"
00145 "the DataSource used by the Display." )
00146
00147 .def ( "colorNames", &PyDataRep::colorNames,
00148 return_value_policy < copy_const_reference > (),
00149 "colorNames () -> tuple\n"
00150 "\n"
00151 "Returns a list of available color names." )
00152
00153 .def ( "set",
00154 ( void ( PyDataRep:: * )
00155 ( Color::Value ) )
00156 &PyDataRep::set,
00157 "set ( ColorValue ) -> None\n"
00158 "set ( Line ) -> None\n"
00159 "set ( Symbol ) -> None\n"
00160 "\n"
00161 "Sets the color, line style or Symbol of the RepBase object.\n"
00162 "Use ColorValue.values, Line.values, or Symbol.values to see\n"
00163 "available values." )
00164
00165 .def ( "set",
00166 ( void ( PyDataRep:: * )
00167 ( Line::Style ) )
00168 &PyDataRep::set )
00169
00170 .def ( "set",
00171 ( void ( PyDataRep:: * )
00172 ( Symbol::Type ) )
00173 &PyDataRep::set )
00174
00175 .def ( "setColor", &PyDataRep::setColor,
00176 "setColor ( string ) -> None\n"
00177 "\n"
00178 "Sets the color of the point representation.\n"
00179 "See DataRep.colorNames() for list of available colors." )
00180
00181 .def ( "setErrorDisplay", &PyDataRep::setErrorDisplay,
00182 "setErrorDisplay ( string, boolean ) -> None\n"
00183 "\n"
00184 "Turns on or off display of error bars, if available, on\n"
00185 "specified axis." )
00186
00187 .def ( "createNTuple", &PyDataRep::createNTuple,
00188 return_value_policy < manage_new_object > (),
00189 "createNTuple () -> NTuple\n"
00190 "\n"
00191 "Creates and returns an NTuple representation of the object." )
00192
00193 .def ( "getNTupleWithCuts", &PyDataRep::getNTupleWithCuts,
00194 return_value_policy < manage_new_object > (),
00195 "getNTupleWithCuts () -> NTuple\n"
00196 "\n"
00197 "Creates and returns to NTuple being used, with cuts applied." )
00198
00199 .def ( "getColumnWithCuts",
00200 ( const std::vector<double> & (PyDataRep:: *)
00201 ( const std::string & ) const )
00202 &PyDataRep::getColumnWithCuts,
00203 return_value_policy < copy_const_reference > (),
00204 "getColumnWithCuts ( column ) -> tuple\n"
00205 "\n"
00206 "Creates and returns the named column, with cuts applied." )
00207
00208 .def ( "createNTupleUnderRegion", &PyDataRep::createNTupleUnderRegion,
00209 return_value_policy < manage_new_object > (),
00210 "createNTupleUnderRegion () -> NTuple\n"
00211 "\n"
00212 "Creates and returns a NTuple contain only rows that pass the\n"
00213 "region cuts." )
00214
00215 .def ( "addCut", &PyDataRep::addCut,
00216 "addCut ( ) -> None\n"
00217 "\n"
00218 "Adds a cut to limit the region given to a fitter." )
00219
00220 .def ( "setCutRange", &PyDataRep::setCutRange,
00221 "setCutRange ( low, high ) -> None\n"
00222 "\n"
00223 "Sets the low and high end of the region highlight" )
00224
00225 .def ( "setSize", & PyDataRep::setSize,
00226 "setSize ( value ) -> None\n"
00227 "\n"
00228 "Sets the size of the point representation." )
00229
00230 .def ( "setSymbol", &PyDataRep::setSymbol,
00231 "setSymbol ( string, value ) -> None\n"
00232 "\n"
00233 "Sets the point symbol and size. This method is deprecated, use\n"
00234 "DataRep.set(Symbol) and DataRep.setSize() instead." )
00235
00236 .def ( "setLineStyle", &PyDataRep::setLineStyle,
00237 "setLineStyle ( string ) -> None\n"
00238 "\n"
00239 "Sets the line style.\n"
00240 "This method is deprecated, use DataRep.set(Line) instead." )
00241
00242 .def ( "normalizeTo", &PyDataRep::normalizeTo,
00243 "normalizeTo ( DataRep ) -> None\n"
00244 "\n"
00245 "Sets the object to normalize itself to a target one" )
00246
00247 .def ( "setBinWidth", &PyDataRep::setBinWidth,
00248 "setBinWidth ( string, value ) -> None\n"
00249 "\n"
00250 "Sets the width of the bins, if data representation is binned.\n" )
00251 ;
00252 }
00253
00254 }
00255 }
00256
00257 using namespace hippodraw;
00258
00259 std::map< std::string, hippodraw::Symbol::Type > PyDataRep::s_symbols;
00260 std::map< std::string, hippodraw::Line::Style > PyDataRep::s_lineStyles;
00261 bool PyDataRep::s_have_static_members(false);
00262
00263 PyDataRep::PyDataRep ( DataRep * rep )
00264 {
00265 m_datarep = rep;
00266 init();
00267 }
00268
00269 PyDataRep::PyDataRep ( const std::string & type,
00270 const DataSource * ntuple,
00271 const std::vector< std::string > & bindings )
00272 {
00273 DataRepController * controller = DataRepController::instance ();
00274 m_datarep = controller->createDataRep ( type, ntuple, bindings );
00275 init();
00276 }
00277
00278 PyDataRep::PyDataRep ( const std::string & type,
00279 const PyDataSource * nt,
00280 const std::vector< std::string > & bindings )
00281 {
00282 DataRepController * controller = DataRepController::instance ();
00283 m_datarep = controller->createDataRep ( type, &(nt->dataSource()),
00284 bindings );
00285 init();
00286 }
00287
00288 PyDataRep::PyDataRep ()
00289 {
00290 m_datarep = 0;
00291 init();
00292 }
00293
00294 PyDataRep::PyDataRep( PyDataRep * pyRep )
00295 {
00296 m_datarep = pyRep->getDataRep()->clone();
00297 }
00298
00299 const vector < string > &
00300 PyDataRep::
00301 names ()
00302 {
00303 DataRepController * controller = DataRepController::instance ();
00304
00305 return controller -> names ();
00306 }
00307
00308 DataRep * PyDataRep::getDataRep()
00309 {
00310 return m_datarep;
00311 }
00312
00318 void PyDataRep::setPointRep ( RepBase * pointRep )
00319 {
00320 PyApp::lock();
00321 m_datarep->setPointRep ( pointRep );
00322 PyApp::unlock ();
00323 }
00324
00325 void PyDataRep::setAxisBinding ( const std::string & axis,
00326 const std::string & label )
00327 {
00328 PyApp::lock();
00329 try {
00330 m_datarep->setAxisBinding ( axis, label );
00331 }
00332 catch ( runtime_error & e ) {
00333 PyApp::unlock ();
00334 throw e;
00335 }
00336 PyApp::unlock ();
00337 }
00338
00339 void PyDataRep::setAxisBindings ( const std::vector< std::string > & bindings)
00340 {
00341 PyApp::lock();
00342 try {
00343 m_datarep->setAxisBindings ( bindings );
00344 }
00345 catch ( runtime_error & e ) {
00346 PyApp::unlock ();
00347 throw e;
00348 }
00349 PyApp::unlock ();
00350 }
00351
00352 void PyDataRep::setWeight ( const std::string &label )
00353 {
00354 PyApp::lock();
00355 if ( m_datarep->name() == "Histogram"
00356 || m_datarep->name() == "Color Plot"
00357 || m_datarep->name() == "Contour Plot") {
00358 m_datarep->setAxisBinding( std::string("Weight (optional)"),
00359 label );
00360 } else {
00361
00362 }
00363 PyApp::unlock ();
00364 }
00365
00366 const std::string & PyDataRep::name () const
00367 {
00368 return m_datarep->name();
00369 }
00370
00371 double PyDataRep::getBinWidth ( const std::string &axis )
00372 {
00373 PyApp::lock();
00374 Axes::Type at = Axes::convert ( axis );
00375 ProjectorBase * projector = m_datarep->getProjector ();
00376 PyApp::unlock ();
00377
00378 return projector->getBinWidth ( at );
00379 }
00380
00381 double
00382 PyDataRep::
00383 getMean ( const std::string & axis )
00384 {
00385 PyApp::lock();
00386 double mean = m_datarep -> getMean ( axis );
00387 PyApp::unlock ();
00388
00389 return mean;
00390 }
00391
00392 double
00393 PyDataRep::
00394 getRMS ( const std::string & axis )
00395 {
00396 PyApp::lock();
00397 double rms = m_datarep -> getRMS ( axis );
00398 PyApp::unlock ();
00399
00400 return rms;
00401 }
00402
00403 double PyDataRep::numberOfEntries() const
00404 {
00405 ProjectorBase * projector = m_datarep->getProjector();
00406 return projector -> getNumberOfEntries();
00407 }
00408
00409 void PyDataRep::applyCut ( QtCut * cut )
00410 {
00411 PyApp::lock();
00412 CutController * controller = CutController::instance();
00413 CutPlotter * cp = dynamic_cast < CutPlotter * > ( cut -> display() );
00414 controller -> linkCutAndRep( cp, m_datarep );
00415 PyApp::unlock ();
00416 }
00417
00418 void PyDataRep::applyCuts ( const std::vector < QtCut * > & cuts )
00419 {
00420 PyApp::lock();
00421 CutController * controller = CutController::instance();
00422 unsigned int size = cuts.size();
00423 for ( unsigned int i = 0; i < size; i++ ) {
00424 CutPlotter * cp = dynamic_cast < CutPlotter * > ( cuts[i] -> display() );
00425 controller -> linkCutAndRep( cp, m_datarep );
00426 }
00427
00428 PyApp::unlock ();
00429 }
00430
00431 const vector < string > &
00432 PyDataRep::
00433 colorNames ()
00434 {
00435 return Color::colorNames ();
00436 }
00437
00438 void
00439 PyDataRep::
00440 set ( Color::Value value )
00441 {
00442 PyApp::lock();
00443 const RepBase * rep = m_datarep -> getRepresentation ();
00444 if ( rep -> uses ( value ) ) {
00445 m_datarep -> set ( value );
00446 }
00447 else {
00448 PyApp::unlock ();
00449 const string what ( "This DataRep does not use ColorValue." );
00450 throw std::runtime_error ( what );
00451 }
00452 PyApp::unlock ();
00453 }
00454
00455 void
00456 PyDataRep::
00457 setColor ( const std::string & color )
00458 {
00459 PyApp::lock();
00460
00461 if ( Color::isValid ( color ) ) {
00462 Color colorObj ( color );
00463 m_datarep -> setRepColor ( colorObj );
00464 } else {
00465 PyApp::unlock ();
00466 std::string what ( "DataRep.setColor: color" );
00467 what += " `";
00468 what += color;
00469 what += "' not available.";
00470 throw runtime_error( what );
00471 }
00472 PyApp::unlock ();
00473 }
00474
00475 void
00476 PyDataRep::
00477 setErrorDisplay ( const std::string &axis, bool flag )
00478 {
00479 PyApp::lock();
00480
00481 Axes::Type at = Axes::convert ( axis );
00482 m_datarep->setErrorDisplay( at, flag );
00483
00484 PyApp::unlock ();
00485 }
00486
00487 const NTuple *
00488 PyDataRep::
00489 createNTuple () const
00490 {
00491 PyApp::lock();
00492
00493 const NTuple * ntuple = m_datarep -> createNTuple ();
00494
00495 PyApp::unlock ();
00496
00497 return ntuple;
00498 }
00499
00500 NTuple * PyDataRep::getNTupleWithCuts () const {
00501 PyApp::lock();
00502 NTuple * ntuple = m_datarep->getNTupleAfterCuts();
00503 PyApp::unlock ();
00504
00505 return ntuple;
00506 }
00507
00508 const std::vector<double> &
00509 PyDataRep::
00510 getColumnWithCuts( const std::string & column ) {
00511 PyApp::unlock ();
00512
00513 m_columnData.clear();
00514 m_datarep->fillColumnAfterCuts(column, m_columnData);
00515
00516 PyApp::unlock ();
00517
00518 return m_columnData;
00519 }
00520
00521 NTuple *
00522 PyDataRep::
00523 createNTupleUnderRegion () const
00524 {
00525 PyApp::lock ();
00526
00527 NTuple * nt = m_datarep -> createNTupleUnderRegion ();
00528
00529 PyApp::unlock ();
00530
00531 return nt;
00532 }
00533
00534 void
00535 PyDataRep::
00536 addCut ( )
00537 {
00538 PyApp::lock();
00539 m_datarep -> addCut ( );
00540 PyApp::unlock ();
00541 }
00542
00543 void
00544 PyDataRep::
00545 setCutRange ( double low, double high )
00546 {
00547 PyApp::lock();
00548
00549 const Range range ( low, high );
00550 m_datarep -> setCutRangeAt ( range, 0 );
00551
00552 PyApp::unlock ();
00553 }
00554
00555 void PyDataRep::makeSymbolMap() {
00556 s_symbols["square"] = hippodraw::Symbol::SQUARE;
00557 s_symbols["filled_square"] = hippodraw::Symbol::SOLIDSQUARE;
00558 s_symbols["plus"] = hippodraw::Symbol::PLUS;
00559 s_symbols["times"] = hippodraw::Symbol::TIMES;
00560 s_symbols["triangle"] = hippodraw::Symbol::TRIANGLE;
00561 s_symbols["filled_triangle"] = hippodraw::Symbol::FILLED_TRIANGLE;
00562 s_symbols["circle"] = hippodraw::Symbol::CIRCLE;
00563 s_symbols["filled_circle"] = hippodraw::Symbol::FILLED_CIRCLE;
00564 }
00565
00566 void
00567 PyDataRep::
00568 set ( Symbol::Type type )
00569 {
00570 PyApp::lock();
00571 const RepBase * rep = m_datarep -> getRepresentation ();
00572 if ( rep -> uses ( type ) ) {
00573 m_datarep -> setRepStyle ( type );
00574 }
00575 else {
00576 PyApp::unlock ();
00577 const string what ( "This DataRep does not use Symbol type." );
00578 throw std::runtime_error ( what );
00579 }
00580 PyApp::unlock ();
00581 }
00582
00583 void
00584 PyDataRep::
00585 setSize ( double size )
00586 {
00587 PyApp::lock();
00588 m_datarep -> setRepSize ( size );
00589 PyApp::unlock ();
00590 }
00591
00592 void PyDataRep::setSymbol( const std::string &symbolName, float size) {
00593 PyApp::lock();
00594 if ( s_symbols.count( symbolName ) ) {
00595 m_datarep -> setRepStyle ( s_symbols[symbolName] );
00596 m_datarep -> setRepSize ( size );
00597 } else {
00598 PyApp::unlock ();
00599 std::ostringstream what;
00600 what << "PyDataRep::setSymbol: symbol "
00601 << symbolName << " is not available.\n"
00602 << "Valid symbol names:\n";
00603 std::map< std::string, hippodraw::Symbol::Type >
00604 ::const_iterator it = s_symbols.begin();
00605 for ( ; it != s_symbols.end(); it++) {
00606 what << " " << it->first << "\n";
00607 }
00608 throw runtime_error( what.str() );
00609 }
00610 PyApp::unlock ();
00611 }
00612
00613 void PyDataRep::makeLineStyleMap() {
00614 s_lineStyles["Solid"] = hippodraw::Line::Solid;
00615 s_lineStyles["Dash"] = hippodraw::Line::Dash;
00616 s_lineStyles["Dot"] = hippodraw::Line::Dot;
00617 s_lineStyles["DashDot"] = hippodraw::Line::DashDot;
00618 s_lineStyles["DashDotDot"] = hippodraw::Line::DashDotDot;
00619 s_lineStyles["Invisible"] = hippodraw::Line::Invisible;
00620 }
00621
00622 void
00623 PyDataRep::
00624 set ( Line::Style style )
00625 {
00626 PyApp::lock();
00627 const RepBase * rep = m_datarep -> getRepresentation ();
00628 if ( rep -> uses ( style ) ) {
00629 m_datarep -> setRepStyle ( style );
00630 }
00631 else {
00632 PyApp::unlock ();
00633 const string what ( "This DataRep does not use Line style." );
00634 throw std::runtime_error ( what );
00635 }
00636
00637 PyApp::unlock ();
00638 }
00639
00640 void
00641 PyDataRep::
00642 setLineStyle( const std::string &lineStyleName )
00643 {
00644 PyApp::lock();
00645 if ( s_lineStyles.count( lineStyleName ) ) {
00646 m_datarep->setRepStyle( s_lineStyles[lineStyleName] );
00647 } else {
00648 PyApp::unlock ();
00649 std::ostringstream what;
00650 what << "PyDataRep::setLineStyle: lineStyle "
00651 << lineStyleName << " is not available.\n"
00652 << "Valid lineStyle names:\n";
00653 std::map< std::string, hippodraw::Line::Style >
00654 ::const_iterator it = s_lineStyles.begin();
00655 for ( ; it != s_lineStyles.end(); it++) {
00656 what << " " << it->first << "\n";
00657 }
00658 throw runtime_error( what.str() );
00659 }
00660 PyApp::unlock ();
00661 }
00662
00663 void PyDataRep::init() {
00664 if (!s_have_static_members) {
00665 makeSymbolMap();
00666 makeLineStyleMap();
00667
00668 s_have_static_members = true;
00669 }
00670 }
00671
00672 void
00673 PyDataRep::
00674 normalizeTo ( const PyDataRep * rep )
00675 {
00676 PyApp::lock();
00677
00678 const DataRep * datarep = rep -> m_datarep;
00679 m_datarep -> normalizeTo ( datarep );
00680
00681 PyApp::unlock ();
00682 }
00683
00684 void
00685 PyDataRep::
00686 setBinWidth ( const std::string & axis, double width )
00687 {
00688 PyApp::lock();
00689
00690 Axes::Type type = Axes::convert ( axis );
00691 DisplayController * controller = DisplayController::instance ();
00692 controller -> setBinWidth ( m_datarep, type, width );
00693 PyApp::unlock ();
00694 }