QtDisplay.cxx
Go to the documentation of this file.
1 
13 #ifdef HAVE_CONFIG_H
14 #include "config.h" // for have_root and have_numarray
15 #endif
16 
17 // include first to avoid _POSIX_C_SOURCE warning.
18 #include <boost/python.hpp>
19 
20 // For truncation warning
21 #ifdef _MSC_VER
22 #include "msdevstudio/MSconfig.h"
23 #endif
24 
25 #include "QtDisplay.h"
26 
27 #include "ListTuple.h"
28 #include "PyFunctionRep.h"
29 #include "PyApp.h"
30 #include "PyDataRep.h"
31 #include "PyDataSource.h"
32 #include "PyNTuple.h"
33 #include "FunctionWrap.h"
34 
38 
40 #include "plotters/PlotterBase.h"
43 
45 #include "datareps/DataRep.h"
46 
48 
49 #include "reps/RepBase.h"
50 #include "reps/ContourPointRep.h"
52 #include "colorreps/BinToColor.h"
53 
54 #ifdef HAVE_ROOT
55 #include "root/QtRootNTuple.h"
56 #endif
57 
58 #include <algorithm>
59 #include <sstream>
60 #include <utility>
61 
62 
63 using std::runtime_error;
64 using std::string;
65 using std::vector;
66 
67 using namespace boost::python;
68 
69 namespace hippodraw {
70 namespace Python {
71 
72 void
74 {
75  class_< QtDisplay >
76  ( "Display",
77  "A wrapper for the HippoDraw PlotterBase C++ class.\n "
78  " See HippoDraw's QtDisplay documentation for more details.",
79  init < const std::string & >
80  (
81 #if __GNUC__ < 3
82  "Display ( string, DataSource, tuple ) -> Display\n"
83  "\n"
84  "Constructor for a Display."
85 #else // gcc 2.95.3 crashes on the following...
86  "Display ( string ) -> Display\n"
87  "Display ( string, DataSource, tuple ) -> Display\n"
88  "Display ( string, DataArray, tuple ) - > Display\n"
89  "Display ( string, tuple, tuple ) -> Display\n"
90  "Display ( string, list, tuple ) -> Display\n"
91  "Display ( string, RootNTuple, tuple ) -> Display\n"
92  "Display ( string, RootNTuple, tuple, tuple ) -> Display\n"
93  "\n"
94  "This method is used to create a Display object.\n"
95  "The first method is used for creating static version of\n"
96  "Histogram, etc., where the string is the type of DataRep.\n"
97  "The remaining methods are for dynamic versions.\n"
98  "The string argument is the type. The second argument\n"
99  "is the DataSource and the third argument is tuple of\n"
100  "string for the binding to the DataSource.\n"
101  "For the last method, the fourth argument is a tuple\n"
102  "of integers to access a RootNTuple array variable.\n\n"
103  "For the names of the types of DataRep classes available\n"
104  "call DataRep.names()."
105 #endif
106  ) )
107 
108  .def ( init < PyFunctionRep * > () )
109 
110  .def ( init < const std::string &,
111  const DataSource &,
112  const std::vector< std::string > & > () )
113 
114  .def ( init < const std::string &,
115  const PyDataSource &,
116  const std::vector< std::string > & > () )
117 
118  .def ( init < const std::string &,
120  const std::vector< std::string > & > () )
121 
122  .def ( init < const std::string &,
124  const std::vector< std::string > & > () )
125 
126 #ifdef HAVE_ROOT
127  .def ( init < const std::string &,
128  const QtRootNTuple &,
129  const std::vector< std::string > & > () )
130 
131  .def ( init < const std::string &,
132  const QtRootNTuple &,
133  const std::vector< std::string > &,
134  boost::python::list > () )
135 #endif
136 
137  .def ( "applyCut", &QtDisplay::applyCut,
138  "applyCut ( Cut ) -> None\n"
139  "\n"
140  "Apply a Cut to the Display" )
141 
142  .def ( "applyCuts", &QtDisplay::applyCuts,
143  "applyCuts ( sequence ) -> None\n"
144  "\n"
145  "Apply each Cut in the sequence to the Display" )
146 
147  .def ( "createNTuple", &QtDisplay::createNTuple,
148  return_value_policy < manage_new_object > (),
149  "createNTuple ( ) -> NTuple\n"
150  "\n"
151  "Returns a NTuple representation of the Display's contents." )
152 
153  .def ( "createDataArray", &QtDisplay::createDataArray,
154  return_value_policy < manage_new_object > (),
155  "createDataArray ( ) -> DataArray\n"
156  "\n"
157  "Returns a DataArray representation of the Display's contents\n"
158  "(This method available if configured with numarray)" )
159 
160  .def ( "setNumberOfBins", &QtDisplay::setNumberOfBins,
161  "setNumberOfBins ( string, value ) -> None\n"
162  "\n"
163  "Sets the number of bins on named axis, e.g. 'x' to the given \n"
164  "value." )
165 
166  .def ( "setBinWidth",
167  ( void (QtDisplay::*) ( const std::string &,
168  double,
169  bool ) )
170  &QtDisplay::setBinWidth,
171  "Set the bin width, explicitly saving the value or not." )
172 
173  .def ( "getBinWidth",
174  ( double (QtDisplay::*) ( const std::string & ) )
175  &QtDisplay::getBinWidth,
176  "getBinWidth ( string ) -> value\n"
177  "\n"
178  "Returns the bin width on axis specified as a string,\n"
179  "e.g., 'x'." )
180 
181  .def ( "setBinWidth",
182  ( void (QtDisplay::*) ( const std::string &,
183  double ) )
184  &QtDisplay::setBinWidth,
185  "setBinWidth ( string, value ) -> None\n"
186  "\n"
187  "Set the bin width to value on axis specified as a string,\n"
188  "e.g., 'x'." )
189 
190  .def ( "reset", &QtDisplay::reset,
191  "reset () -> None\n"
192  "\n"
193  "Resets the contents of all bins. Only applicable to static\n"
194  "histograms." )
195 
196  .def ( "setOffset", &QtDisplay::setOffset,
197  "setOffset ( string, value ) -> None\n"
198  "\n"
199  "Sets the offset of the bins relative to their current width on\n"
200  "specified axis." )
201 
202  .def ( "setRange",
203  ( void (QtDisplay::*) (const std::string &,
204  double, double) )
205  &QtDisplay::setRange )
206 
207  .def ( "setRange",
208  ( void (QtDisplay::*) (const std::string &,
209  double, double, bool) )
210  &QtDisplay::setRange,
211  "setRange ( string, value, value ) -> None\n"
212  "setRange ( string, value, value, Boolean ) -> None\n"
213  "\n"
214  "Set the upper and lower bounds for the specified axis. For the\n"
215  "second form, also save them if the Boolean argument is true." )
216 
217 
218  .def ( "getRange", &QtDisplay::getRange,
219  "getRange ( string ) -> tuple\n"
220  "\n"
221  "Returns the tuple representing the range for the axis specified\n"
222  "as a string, e.g., 'x'." )
223 
224  .def ( "saveView", &QtDisplay::saveView,
225  "saveView ( ) -> int\n"
226  "\n"
227  "Saves the current set of x and y ranges and "
228  "returns the index of the saved view." )
229 
230  .def ( "setView", &QtDisplay::setView,
231  "setView ( int ) -> None\n"
232  "\n"
233  "Set the view by its index." )
234 
235  .def ( "nextView", &QtDisplay::nextView,
236  "nextView ( bool ) -> int\n"
237  "\n"
238  "Cycle to the next view in the view buffer. "
239  "Set the argument to True to cycle for wards, "
240  "False to cycle back wards.\n"
241  "Returns the index of the new view." )
242 
243  .def ( "numViews", &QtDisplay::numViews,
244  "numViews ( ) -> int\n"
245  "\n"
246  "Return the number of stored views." )
247 
248  .def ( "deleteView", &QtDisplay::deleteView,
249  "deleteView ( int ) -> None\n"
250  "\n"
251  "Delete a view by index." )
252 
253  .def ( "currentView", &QtDisplay::currentView,
254  "currentView ( ) -> int\n"
255  "\n"
256  "Index of the current view." )
257 
258  .def ( "setTitle", &QtDisplay::setTitle,
259  "setTitle ( string ) -> None\n"
260  "\n"
261  "Sets the title of the display." )
262 
263  .def ( "getTitle", &QtDisplay::getTitle,
264  return_value_policy < copy_const_reference > (),
265  "getTitle () -> string\n"
266  "\n"
267  "Returns the current title. The title will be the title of\n"
268  "the DataSource unless it has been explicitly changed." )
269 
270  .def ( "setLabel", &QtDisplay::setLabel,
271  "setLabel ( string, string ) -> None\n"
272  "\n"
273  "Sets the label for the axis specified by first argument to value\n"
274  "of the second argument." )
275 
276  .def ( "getLabel", &QtDisplay::getLabel,
277  return_value_policy< copy_const_reference > (),
278  "getLabel ( string ) -> string\n"
279  "\n"
280  "Returns the label of the axis specified as a string,\n"
281  "e.g., 'x'." )
282 
283  .def ( "getDataRep", &QtDisplay::getDataRep,
284  return_value_policy < manage_new_object > (),
285  "getDataRep ( ) -> DataRep\n"
286  "\n"
287  "Returns a reference to the active DataRep or if all DataRep objects are\n"
288  "active, returns a reference to the first one." )
289 
290  .def ( "getDataReps", &QtDisplay::getDataReps,
291  return_value_policy < copy_const_reference > (),
292  "getDataReps ( ) -> list\n"
293  "\n"
294  "Returns a list of DataRep objects contained by the Display.." )
295 
296  .def ( "addDataRep",
297  ( void (QtDisplay::*) (PyDataRep *) )
298  &QtDisplay::addDataRep,
299  "addDataRep ( DataRep ) -> Display\n"
300  "addDataRep ( Function ) -> Display\n"
301  "addDataRep ( string, DataSource, tuple ) -> Display\n"
302  "\n"
303  "Adds a DataRep to the display sharing the same Y axis range\n"
304  "The first two methods adds existing DataRep or Function to the\n"
305  "Display. The third method creates and adds DataRep to the\n"
306  "Display. Arguments are same as Display constructor." )
307 
308  .def ( "addDataRep",
309  ( void (QtDisplay::*) (const std::string &,
310  const DataSource *,
311  const std::vector <std::string > &) )
312  &QtDisplay::addDataRep )
313 
314  .def ( "addDataRep",
315  ( void (QtDisplay::*) (PyFunctionRep *) )
316  &QtDisplay::addDataRep )
317 
318  .def ( "addDataRepStacked",
319  ( void (QtDisplay::*) (const std::string &,
320  const DataSource *,
321  const std::vector <std::string > &) )
322  &QtDisplay::addDataRepStacked,
323  "addDataRepStacked ( string, DataSource, tuple ) -> Display\n"
324  "\n"
325  "Creates and adds a DataRep with independent Y axis ranges.\n"
326  "The arguments are the same as Display constructor." )
327 
328 #ifndef BOOST_DEFECT
329  .def ( "addFunction",
330  ( void (QtDisplay::*) (FunctionBase *) )
331  &QtDisplay::addFunction,
332  "addFunction ( FunctionBase ) -> None\n"
333  "\n"
334  "Adds a FunctionBase object to the display by appropriately\n"
335  "wrapping it with a Function." )
336 #endif // BOOST_DEFECT
337 
338  .def ( "setAutoRanging",
339  ( void (QtDisplay::*) (const std::string &,
340  bool flag ) )
341  &QtDisplay::setAutoRanging,
342  "setAutoRanging ( string, Boolean ) -> None\n"
343  "\n"
344  "Sets auto-ranging on axis specified as a string, e.g. 'x',n"
345  "on or off." )
346 
347  .def ( "setLog", &QtDisplay::setLog,
348  "setLog ( string, Boolean ) -> None\n"
349  "\n"
350  "Sets the axis specified by the first argument on log scale." )
351 
352  .def ( "getLog", &QtDisplay::getLog,
353  "getLog ( string ) -> value\n"
354  "\n"
355  "Returns True if axis specified as a string, e.g. 'x', is being\n"
356  "displayed on a logarithmic scale." )
357 
358  .def ( "setTransform", &QtDisplay::setTransform,
359  "setTransform ( string ) -> None\n"
360  "\n"
361  "Sets the transform object." )
362 
363  .def ( "addValues", &QtDisplay::addValues,
364  "addValue ( tuple ) -> None\n"
365  "\n"
366  "For static histograms, adds a value to the accumulation.\n"
367  "For 1D histogram, the tuple should contain one or two values,\n"
368  "the second used as a weight. For 2D histogram, the tuple should\n"
369  "contain two or three elements, the third being the weight.\n"
370  "non static Displays do nothing." )
371 
372  .def ( "setPointRep", &QtDisplay::setPointRep,
373  "setPointRep ( RepBase ) -> None\n"
374  "\n"
375  "Sets the point representation to be used." )
376 
377  .def ( "setContourLevels", &QtDisplay::setContourLevels,
378  "setContourLevels ( sequence ) -> None\n"
379  "\n"
380  "Sets the contour levels if the Display is using contour point\n"
381  "representation from the values in the sequence." )
382 
383  .def ( "setAspectRatio", &QtDisplay::setAspectRatio,
384  "setAspectRatio ( value ) -> None\n"
385  "\n"
386  "Sets the required aspect ratio of the Display to value, the\n"
387  "ratio of the width to the height." )
388 
389  .def ( "numberOfEntries", &QtDisplay::numberOfEntries,
390  "numberOfEntries ( ) -> value\n"
391  "\n"
392  "Returns the number of entries in the Display." )
393 
394  .def ( "resize", &QtDisplay::resize,
395  "resize () -> None\n"
396  "\n"
397  "Resizes the Display to its saved values." )
398 
399  .def ( "plotterId", &QtDisplay::plotterId,
400  "plotterId () -> value\n"
401  "\n"
402  "Returns a unique identifier for the Display." )
403 
404  .def ( "setColorMap", &QtDisplay::setColorMap,
405  "setColorMap ( string ) -> None\n"
406  "\n"
407  "Set the value-to-color map to one named by the argument.")
408 
409  .def ( "update", &QtDisplay::update,
410  "update () -> None\n"
411  "\n"
412  "Updates the display." )
413 
414  .def ( "addObserver", &QtDisplay::addObserver,
415  "addObserver ( Observer ) -> None\n"
416  "\n"
417  "Adds an Observer to the Display object." )
418 
419  .def ( "setAutoTicks", &QtDisplay::setAutoTicks,
420  "setAutoTicks ( Boolean ) -> None\n"
421  "\n"
422  "Set the ticks generation to be automatic (the default) or\n"
423  "manually." )
424 
425  .def ( "setTicks", &QtDisplay::setTicks,
426  "setTicks ( string, sequence, sequence ) -> None\n"
427  "\n"
428  "Sets the tick locations and labels. The first argument is the\n"
429  " axis, the second argument is a sequence containing the\n"
430  "locations, and the third argument is a sequence of tick labels." )
431 
432  .def ( "unlock", &QtDisplay::unlock,
433  "unlock () -> None\n"
434  "\n"
435  "Unlock the application thread." )
436 
437  ;
438 }
439 
440 } // namespace Python
441 } // namespace hippodraw
442 
443 using namespace hippodraw;
444 
447 void QtDisplay::createDisplay ( const std::string & type,
448  const DataSource & nt,
449  const std::vector < std::string > & bindings )
450 {
451  PyApp::lock();
452  DisplayController * controller = DisplayController::instance ();
453  try {
454  m_plotter = controller->createDisplay ( type, nt, bindings );
455  PyApp::unlock ();
456  }
457  catch ( const FactoryException & e ) {
458  PyApp::unlock ();
459  throw e;
460  }
461  catch ( const DataRepException & e ) {
462  PyApp::unlock ();
463  throw e;
464  }
465  catch ( const runtime_error & e ) {
466  PyApp::unlock ();
467  throw e;
468  }
469 }
470 
471 QtDisplay::
472 QtDisplay ( const std::string & type,
474  const std::vector < std::string > & labels )
475 {
476  PyApp::lock();
477 
478  object obj = seq.attr ( "__len__" ) ();
479 
480  ListTuple * ntuple = new ListTuple ( );
481 
482  try {
483  unsigned int size = extract < unsigned int > ( obj );
484 
485  if ( size > labels.size () ) {
486  string what ( "Display: Too few labels" );
487  throw runtime_error ( what );
488  }
489 
490  for ( unsigned int i = 0, j = 0; i < size; i++, j++ ) {
491  boost::python::list l = extract < boost::python::list > ( seq[i] );
492 
493  while ( labels[j] == "nil" ) {
494  j++; // skip such labels
495  if ( ! ( j < labels.size () ) ) {
496  string what ( "Display: Too few non 'nil' labels" );
497  throw runtime_error ( what );
498  }
499 
500  }
501  ntuple -> addColumn ( labels[j], l );
502  }
503  }
504  catch ( const runtime_error & e ) {
505  delete ntuple;
506  PyApp::unlock ();
507  throw e;
508  }
509 
510  // Do not call createDisplay() as exceptions wouldn't print nicely
511  try {
512  DisplayController * dc = DisplayController::instance ();
513  m_plotter = dc -> createDisplay ( type, *ntuple, labels );
514  }
515  catch ( const FactoryException & e ) {
516  delete ntuple;
517  PyApp::unlock ();
518  throw e;
519  }
520  catch ( const DataRepException & e ) {
521  delete ntuple;
522  PyApp::unlock ();
523  throw e;
524  }
525  catch ( const runtime_error & e ) {
526  delete ntuple;
527  PyApp::unlock ();
528  throw e;
529  }
530 
531  // No use telling controller about it until we are sure to accept it.
532  DataSourceController * dsc = DataSourceController::instance ();
533  dsc -> registerNTuple ( ntuple );
534 
535  PyApp::unlock ();
536 }
537 
538 QtDisplay::
539 QtDisplay ( const std::string & type,
541  const std::vector < std::string > & labels )
542 {
543  PyApp::lock();
544 
545  object obj = seq.attr ( "__len__" ) ();
546 
547  ListTuple * ntuple = new ListTuple ( );
548 
549  try {
550  unsigned int size = extract < unsigned int > ( obj );
551 
552  if ( size > labels.size () ) {
553  string what ( "Display: Too few labels" );
554  throw runtime_error ( what );
555  }
556 
557  // gcc 2.95.3 needs full scoping
558  for ( unsigned int i = 0, j = 0; i < size; i++, j++ ) {
559  boost::python::list l = extract < boost::python::list > ( seq[i] );
560 
561  while ( labels[j] == "nil" ) {
562  j++; // skip such labels
563  if ( ! ( j < labels.size () ) ) {
564  string what ( "Display: Too few non 'nil' labels" );
565  throw runtime_error ( what );
566  }
567 
568  }
569  ntuple -> addColumn ( labels[j], l );
570  }
571  }
572  catch ( const runtime_error & e ) {
573  delete ntuple;
574  PyApp::unlock ();
575  throw e;
576  }
577 
578  // Do not call createDisplay() as exceptions wouldn't print nicely
579  try {
580  DisplayController * dc = DisplayController::instance ();
581  m_plotter = dc -> createDisplay ( type, *ntuple, labels );
582  }
583  catch ( const FactoryException & e ) {
584  delete ntuple;
585  PyApp::unlock ();
586  throw e;
587  }
588  catch ( const DataRepException & e ) {
589  delete ntuple;
590  PyApp::unlock ();
591  throw e;
592  }
593  catch ( const runtime_error & e ) {
594  delete ntuple;
595  PyApp::unlock ();
596  throw e;
597  }
598 
599  // No use telling controller about it until we are sure to accept it.
600  DataSourceController * dsc = DataSourceController::instance ();
601  dsc -> registerNTuple ( ntuple );
602 
603  PyApp::unlock ();
604 }
605 
606 QtDisplay::QtDisplay ()
607  : m_plotter ( 0 )
608 {
609 }
610 
613 {
614  PyApp::lock();
616  try {
617  DataRep * dr = rep -> getRep ();
618  m_plotter = controller -> createDisplay ( dr );
619  PyApp::unlock ();
620  }
621  catch ( const FactoryException & e ) {
622  PyApp::unlock ();
623  throw e;
624  }
625  catch ( const DataRepException & e ) {
626  PyApp::unlock ();
627  throw e;
628  }
629 }
630 
632 QtDisplay ( const std::string & type )
633 {
634 // PyApp::lock();
636  try {
637  m_plotter = controller -> createDisplay ( type );
638  PyApp::unlock ();
639  }
640  catch ( const FactoryException & e ) {
641  PyApp::unlock ();
642  throw e;
643  }
644  catch ( const DataRepException & e ) {
645  PyApp::unlock ();
646  throw e;
647  }
648 // PyApp::unlock ();
649 }
650 
651 
652 QtDisplay::QtDisplay( const std::string & type,
653  const DataSource & nt,
654  const std::vector< std::string > & bindings )
655 {
656  createDisplay ( type, nt, bindings );
657 }
658 
659 QtDisplay::QtDisplay( const std::string & type,
660  const PyDataSource & nt,
661  const std::vector< std::string > & bindings )
662 {
663  createDisplay ( type, nt.dataSource(), bindings );
664 }
665 
666 #ifdef HAVE_ROOT
668 QtDisplay ( const std::string & type,
669  const QtRootNTuple & nt,
670  const std::vector < std::string > & bindings )
671 {
672  createDisplay ( type, nt, bindings );
673 }
674 
676 QtDisplay ( const std::string & type,
677  const QtRootNTuple & nt,
678  const std::vector < std::string > & variables,
679  boost::python::list indices )
680 {
681  object obj = indices.attr ( "__len__" ) ();
682  unsigned int size = extract < unsigned int > ( obj );
683 
684  if ( size != variables.size() ) {
685  const string what ( "Display: bindings and indexes not the same size." );
686  PyApp::unlock ();
687  throw runtime_error ( what );
688  }
689 
690  vector < vector < int > > vec ( size );
691  for ( unsigned int i = 0; i < size; i++ ) {
692  boost::python::list l = extract < boost::python::list > ( indices[i] );
693  object o = l.attr ( "__len__" ) ();
694  unsigned int len = extract < unsigned int > ( o );
695  for ( unsigned int j = 0; j < len; j++ ) {
696  unsigned int k = extract < unsigned int > ( l[j] );
697  vec[i].push_back ( k );
698  }
699  }
700 
701  vector < string > bindings ( size );
702 
703  for ( unsigned int i = 0; i < size; i++ ) {
704  const string & label = variables [ i ];
705  const vector < int > & indexes = vec [ i ];
706  const string name = nt.createBinding ( label, indexes );
707  bindings [ i ] = name;
708  }
709 
710  createDisplay ( type, nt, bindings );
711 }
712 
713 #endif // have_root
714 
716 QtDisplay ( PlotterBase * plotter) : m_plotter(plotter) {}
717 
719 {
720 // delete m_plotter;
721 }
722 
724 {
725  return m_plotter;
726 }
727 
730 void QtDisplay::addDataRep ( const std::string & type,
731  const DataSource * ntuple,
732  const std::vector < std::string > & bindings )
733 {
734  PyApp::lock();
735 
737  controller->addDataRep ( m_plotter, type, ntuple, bindings );
738 
739  PyApp::unlock ();
740 }
741 
742 void
744 addDataRepStacked ( const std::string & type,
745  const DataSource * ntuple,
746  const std::vector < std::string > & bindings )
747 {
748  PyApp::lock();
749 
751  controller->addDataRepStacked ( m_plotter, type, ntuple, bindings );
752 
753  PyApp::unlock ();
754 }
755 
757 {
758  PyApp::lock();
759 
761  controller->addDataRep ( m_plotter, pyRep->getDataRep() );
762 
763  PyApp::unlock ();
764 }
765 
767 {
768  PyApp::lock();
769 
771 
772  controller->addDataRep ( m_plotter, pyFuncRep->getRep() );
773 
774  PyApp::unlock ();
775 }
776 
777 #ifndef BOOST_DEFECT
778 void
780 addFunction ( FunctionBase * function )
781 {
782  PyApp::lock();
784  DataRep * dataRep = m_plotter->getDataRep( 0 );
785 
786 // The following datarep will be deleted by the CompositePlotter.
787  FunctionRep * funcRep =
788  funcController->createFunctionRep(function, dataRep);
789 
791  dataRep = reinterpret_cast<DataRep *>(funcRep);
792  controller->addDataRep(m_plotter, dataRep);
793 
794  PyApp::unlock ();
795 }
796 #endif // BOOST_DEFECT
797 
798 void
800 setRange ( const std::string & axis, double low, double high,
801  bool save)
802 {
803  PyApp::lock();
804 
805  if (save) {
806  if (axis == "x" || axis == "X")
807  m_ranges["x"] = std::make_pair(low, high);
808  if (axis == "y" || axis == "Y")
809  m_ranges["y"] = std::make_pair(low, high);
810  }
811 
812  m_plotter->setRange ( axis, low, high );
813 
814  PyApp::unlock ();
815 }
816 
817 void
819 setRange ( const std::string & axis, double low, double high )
820 {
821  PyApp::lock();
822  setRange( axis, low, high, false );
823  PyApp::unlock();
824 }
825 
826 std::vector<double>
828 getRange ( const std::string & axis )
829 {
830  PyApp::lock ();
831 
832  std::vector<double> myRange;
833  try {
834  Axes::Type type = Axes::convert ( axis );
835  const Range & axisRange = m_plotter->getRange( type, true );
836  myRange.push_back(axisRange.low());
837  myRange.push_back(axisRange.high());
838 
839  PyApp::unlock ();
840  }
841  catch ( const PlotterException & e ) {
842  PyApp::unlock ();
843  throw e;
844  }
845 
846  return myRange;
847 }
848 
850 {
851  std::vector<double> range_values;
852  std::vector<double> range = getRange("x");
853  range_values.push_back(range[0]);
854  range_values.push_back(range[1]);
855  m_ranges["x"] = std::make_pair(range[0], range[1]);
856 
857  range = getRange("y");
858  range_values.push_back(range[0]);
859  range_values.push_back(range[1]);
860  m_ranges["y"] = std::make_pair(range[0], range[1]);
861 
862  return m_plotter->saveView(range_values);
863 }
864 
865 void QtDisplay::setView ( int index )
866 {
867  PyApp::lock();
868  try {
869  m_plotter->setView( index );
870  } catch (...) {
871  PyApp::unlock ();
872  throw;
873  }
874  PyApp::unlock ();
875 }
876 
877 int QtDisplay::nextView( bool stepForward )
878 {
879  int index(-1);
880  PyApp::lock();
881  try {
882  index = m_plotter->nextView(stepForward);
883  } catch (...) {
884  PyApp::unlock ();
885  throw;
886  }
887  PyApp::unlock ();
888  return index;
889 }
890 
892  return m_plotter->numViews();
893 }
894 
895 void QtDisplay::deleteView (int index) {
896  PyApp::lock();
897  try {
898  m_plotter->deleteView(index);
899  } catch (...) {
900  PyApp::unlock ();
901  throw;
902  }
903  PyApp::unlock ();
904 }
905 
907  return m_plotter->currentView();
908 }
909 
910 void QtDisplay::setTitle ( const std::string & title )
911 {
912  PyApp::lock();
913  m_plotter->setTitle ( title );
914  PyApp::unlock ();
915 }
916 
917 const std::string & QtDisplay::getTitle() const {
918  return m_plotter->getTitle();
919 }
920 
921 void
924 {
925  PyApp::lock();
926  try {
927  m_plotter->setRepresentation ( rep );
928  } catch ( const std::runtime_error & e ) {
929  PyApp::unlock ();
930  throw e;
931  }
932  PyApp::unlock ();
933 }
934 
935 void
937 setContourLevels ( const std::vector<double> &levels )
938 {
939  PyApp::lock();
940  RepBase * rep = m_plotter->representation();
941 
942  if ( rep->name() == std::string("Contour") ) {
943  DataRep * datarep
945 
946  dynamic_cast<ContourPointRep *>(rep)
947  ->setContourValues( const_cast<std::vector<double>&>(levels),
948  datarep->getProjector() );
949 
950  datarep->notifyObservers();
951 
952  } else {
953  // do nothing
954  }
955  PyApp::unlock ();
956 }
957 
958 void QtDisplay::setLabel ( const std::string & axis,
959  const std::string & label )
960 {
961  PyApp::lock();
962 
963  Axes::Type at = Axes::convert ( axis );
964  m_plotter->setLabel ( at, label );
965 
966  PyApp::unlock ();
967 }
968 
969 const std::string &
971 getLabel ( const std::string & axis ) const
972 {
973  PyApp::lock ();
974  Axes::Type at = Axes::convert ( axis );
975  const std::string & label = m_plotter -> getLabel( at );
976  PyApp::unlock ();
977 
978  return label;
979 }
980 
981 void
983 setNumberOfBins ( const std::string & axis, unsigned int number )
984 {
985  PyApp::lock();
986  m_plotter->setNumberOfBins ( axis, number );
987  PyApp::unlock();
988 }
989 
990 void
993 {
994  PyApp::lock();
995  m_plotter -> reset ();
996  PyApp::unlock ();
997 }
998 
999 void QtDisplay::setBinWidth ( const std::string & axis, double width,
1000  bool save )
1001 {
1002  PyApp::lock();
1003 
1004  if (save) {
1005  if (axis == "x" || axis == "X")
1006  m_binWidths["x"] = width;
1007  if (axis == "y" || axis == "Y")
1008  m_binWidths["y"] = width;
1009  }
1010 
1011  m_plotter->setBinWidth ( axis, width );
1012 
1013  PyApp::unlock ();
1014 }
1015 
1016 double
1018 getBinWidth ( const std::string & axis ) const
1019 {
1020  return m_plotter->getBinWidth ( axis);
1021 }
1022 
1023 void
1025 setBinWidth ( const std::string & axis, double width )
1026 {
1027  PyApp::lock();
1028  setBinWidth( axis, width, false );
1029  PyApp::unlock ();
1030 }
1031 
1032 void QtDisplay::setOffset ( const std::string & axis, double offset )
1033 {
1034  PyApp::lock();
1036  Axes::Type type = Axes::convert ( axis );
1037 
1038  controller->setOffset ( m_plotter, type, offset );
1039  PyApp::unlock();
1040 }
1041 
1044 void QtDisplay::setTransform ( const std::string & name )
1045 {
1046  PyApp::lock();
1047 
1049  try {
1050  controller->setTransform ( m_plotter, name );
1051  PyApp::unlock ();
1052  } catch (PlotterException & eObj) {
1053  PyApp::unlock ();
1054  throw eObj;
1055  } catch (FactoryException & eObj) {
1056  PyApp::unlock ();
1057  throw eObj;
1058  }
1059 }
1060 
1062  PyApp::unlock ();
1063 }
1064 
1065 void QtDisplay::setLog ( const std::string & axis, int flag )
1066 {
1067  PyApp::lock();
1068  Axes::Type type = Axes::convert ( axis );
1070  bool yes = flag != 0;
1071 
1072  controller->setLog ( m_plotter, type, yes );
1073  PyApp::unlock ();
1074 }
1075 
1076 int QtDisplay::getLog ( const std::string & axis )
1077 {
1079  if ( controller->getLog ( m_plotter, axis) ) {
1080  return 1;
1081  } else {
1082  return 0;
1083  }
1084 }
1085 
1086 void QtDisplay::setAutoRanging ( const std::string & axis, bool flag )
1087 {
1088  PyApp::lock();
1089  Axes::Type type = Axes::convert ( axis );
1090  m_plotter->setAutoRanging ( type, flag );
1091  PyApp::unlock ();
1092 }
1093 
1094 PyDataRep *
1097 {
1098  PyApp::lock ();
1099 
1100  int index = m_plotter->activePlotIndex();
1101  if ( index < 0 ) index = 0;
1102  DataRep * rep = m_plotter->getDataRep ( index );
1103  PyDataRep * pyrep = new PyDataRep ( rep );
1104 
1105  PyApp::unlock ();
1106 
1107  return pyrep;
1108 }
1109 
1110 const std::vector<PyDataRep *> &
1112 getDataReps () const
1113 {
1114  PyApp::lock ();
1115 
1116  m_pyDataReps.clear();
1117  int nReps = m_plotter->getNumDataReps();
1118  for (int i = 0; i < nReps; i++) {
1119  m_pyDataReps.push_back( new PyDataRep ( m_plotter->getDataRep( i ) ) );
1120  }
1121  PyApp::unlock ();
1122 
1123  return m_pyDataReps;
1124 }
1125 
1126 void
1128 setAspectRatio ( double ratio )
1129 {
1130  PyApp::lock();
1131  m_plotter->setAspectRatio ( ratio );
1132  PyApp::unlock ();
1133 }
1134 
1135 void
1137 addValues ( const std::vector < double > & v )
1138 {
1139  PyApp::lock();
1140  m_plotter -> addValues ( v );
1141  PyApp::unlock ();
1142 }
1143 
1144 PyNTuple *
1147 {
1148  // Need to lock else could create NTuple not yet displayed
1149  PyApp::lock();
1151  const NTuple * ntuple = controller -> createNTuple ( m_plotter, 0 );
1152 
1153  PyNTuple * pytuple = new PyNTuple ( *ntuple );
1154  delete ntuple;
1155 
1156  PyApp::unlock ();
1157 
1158  return pytuple;
1159 }
1160 
1161 double
1164 {
1165  ProjectorBase * projector = m_plotter->activeProjector();
1166  return projector->getNumberOfEntries();
1167 }
1168 
1169 void
1172 {
1173  PyApp::lock();
1174 
1175  if (m_binWidths.count("x")) {
1176  m_plotter->setBinWidth("x", m_binWidths["x"]);
1177  } else {
1178 // set and unset log-scale to get decent bin sizes
1180  if ( controller->getLog( m_plotter, "x" ) ) {
1181  setLog( "x", 0 );
1182  setLog( "x", 1 );
1183  } else {
1184  setLog( "x", 1 );
1185  setLog( "x", 0 );
1186  }
1187  }
1188 
1189  if (m_binWidths.count("y")) {
1190  m_plotter->setBinWidth("y", m_binWidths["y"]);
1191  } else {
1192  // set and unset log-scale to get decent bin sizes
1194  if ( controller->getLog( m_plotter, "y" ) ) {
1195  setLog( "y", 0 );
1196  setLog( "y", 1 );
1197  } else {
1198  setLog( "y", 1 );
1199  setLog( "y", 0 );
1200  }
1201  }
1202 
1203  if (m_ranges.count("x")) {
1204  m_plotter->setRange("x", m_ranges["x"].first, m_ranges["x"].second);
1205  } else {
1206  m_plotter->setAutoRanging("x", true);
1207  }
1208 
1209  if (m_ranges.count("y")) {
1210  m_plotter->setRange("y", m_ranges["y"].first, m_ranges["y"].second);
1211  } else {
1212  m_plotter->setAutoRanging("y", true);
1213  }
1214 
1215  PyApp::unlock ();
1216 }
1217 
1219 {
1220  return m_plotter->plotterId();
1221 }
1222 
1226 void QtDisplay::
1227 setColorMap ( const std::string & name ) {
1228  PyApp::lock();
1230  const vector< std::string > & names = factory -> names();
1231  if ( std::find(names.begin(), names.end(), name) != names.end() ) {
1232  BinToColor * rep = factory -> create ( name );
1233  m_plotter -> setValueRep( rep );
1234  PyApp::unlock ();
1235  } else {
1236  PyApp::unlock();
1237  std::ostringstream message;
1238  message << "QtDisplay::setColorMap:\n"
1239  << "BinToColor rep '" << name << "' does not exist.\n"
1240  << "Valid rep names are \n\n";
1241  for (unsigned int i = 0; i < names.size() ; i++) {
1242  message << "'" << names[i] << "'\n";
1243  }
1244  throw std::runtime_error(message.str());
1245  }
1246 }
1247 
1248 void
1251 {
1252  PyApp::lock();
1253 
1254  m_plotter -> update ();
1255 
1256  PyApp::unlock ();
1257 }
1258 
1259 void
1261 addObserver ( Observer * observer )
1262 {
1263  m_plotter -> addObserver ( observer );
1264 }
1265 
1266 void
1268 setTicks ( const std::string & axis,
1269  const std::vector < double > & values,
1270  const std::vector < std::string > & labels )
1271 {
1272  PyApp::lock();
1273  m_plotter -> setTicks ( axis, values, labels );
1274  PyApp::unlock ();
1275 }
1276 
1277 void
1279 setAutoTicks ( const std::string & axis, bool yes )
1280 {
1281  PyApp::lock();
1282  m_plotter -> setAutoTicks ( axis, yes );
1283  PyApp::unlock ();
1284 }
1285 
1286 PyDataSource *
1289 {
1290  // Need to lock else could create NTuple not yet displayed
1291 #ifdef HAVE_NUMARRAY
1292  PyApp::lock();
1293 
1295  NTuple * ntuple = controller -> createNTuple ( m_plotter, 0 );
1296  PyDataSource * ds = new PyDataSource ( "NTuple", ntuple );
1297 
1298  PyApp::unlock ();
1299 
1300  return ds;
1301 #else
1302  runtime_error e ( "HippoDraw was not built with numeric Python support" );
1303  throw e;
1304 #endif
1305 }
1306 
1307 void
1310 {
1311  PyApp::lock();
1312 
1313  PlotterBase * cut_plotter = cut -> display();
1314  PlotterBase * target_plotter = display ();
1315 
1316  CutController * controller = CutController::instance();
1317  controller -> addCut ( cut_plotter, target_plotter );
1318 
1319  PyApp::unlock ();
1320 }
1321 
1322 void
1324 applyCuts ( const std::vector < QtDisplay * > & cuts )
1325 {
1326  PyApp::lock();
1327 
1328  vector < PlotterBase * > cut_plotters;
1329  unsigned int size = cuts.size ();
1330  for ( unsigned int i = 0; i < size; i++ ) {
1331  QtDisplay * cut_display = cuts[i];
1332  PlotterBase * plotter = cut_display -> display();
1333  cut_plotters.push_back ( plotter );
1334  }
1335 
1336  PlotterBase * target_plotter = display ();
1337  CutController * controller = CutController::instance();
1338  controller -> addCuts ( cut_plotters, target_plotter );
1339 
1340  PyApp::unlock ();
1341 }

Generated for HippoDraw Class Library by doxygen