PyDataSource.cxx
Go to the documentation of this file.
1 
13 #ifdef HAVE_CONFIG_H
14 // for root and cfitsio
15 #include "config.h"
16 #endif
17 
18 // For truncation warning
19 #ifdef _MSC_VER
20 #include "msdevstudio/MSconfig.h"
21 #endif
22 
23 // include first to avoid _POSIX_C_SOURCE warning.
24 #include <boost/python.hpp>
25 
26 #include "PyDataSource.h"
27 
28 #include "ListTuple.h"
29 #include "PyApp.h"
30 
32 #include "datasrcs/NTuple.h"
33 #include "pattern/string_convert.h"
34 
35 #ifdef HAVE_NUMARRAY
36 #include "numarray/NumArrayTuple.h"
37 #include "numarray/num_util.h"
38 #endif
39 
40 #ifdef HAVE_CFITSIO
41 #include "fits/FitsNTuple.h"
42 #endif
43 
44 #ifdef HAVE_ROOT
45 #include "root/QtRootNTuple.h"
46 #endif
47 
48 using namespace boost::python;
49 
50 #ifdef HAVE_NUMARRAY
51 namespace hippodraw {
52  namespace Python {
53 
57 // template < typename T >
58 // void copy_direct ( boost::python::numeric::array array,
59 // std::vector<double > & col )
60 // {
61 // T * data = reinterpret_cast < T * > ( num_util::data ( array ) );
62 // int size = num_util::size ( array );
63 // std::copy ( data, data+ size, back_inserter( col ) );
64 // }
65 
66 // /** Extracts a vector from the numarray object. Extracts a vector
67 // from the numarray object @a array and fills the vector @a col.
68 // If @a array is contiguous, copies the data directly, otherwise
69 // copies the data element by element.
70 // */
71 // void extractVector ( boost::python::numeric::array array,
72 // std::vector<double> & col )
73 // {
74 // PyArray_TYPES type = num_util::type ( array );
75 
76 // if ( num_util::iscontiguous ( array ) &&
77 // type != PyArray_NOTYPE ) {
78 // switch ( type )
79 // {
80 // #ifdef HAVE_NUMPY
81 // case PyArray_BOOL:
82 // copy_direct < bool > ( array, col );
83 // break;
84 // #endif
85 // case PyArray_CHAR:
86 // copy_direct < char > ( array, col );
87 // break;
88 
89 // case PyArray_SHORT :
90 // copy_direct < short > ( array, col );
91 // break;
92 
93 // case PyArray_INT :
94 // copy_direct < int > ( array, col );
95 // break;
96 
97 // case PyArray_UINT :
98 // copy_direct < unsigned int > ( array, col );
99 // break;
100 // case PyArray_FLOAT :
101 // copy_direct < float > ( array, col );
102 // break;
103 // case PyArray_DOUBLE :
104 // copy_direct < double > ( array, col );
105 // break;
106 
107 // default:
108 // std::string what ( "DataArray: Array type `" );
109 // what += num_util::type2string ( type );
110 // what += "' not supported.";
111 // throw std::runtime_error ( what );
112 // break;
113 // }
114 // }
115 // else { // not contiguous
116 // const numeric::array & my_array = array;
117 // int rank = num_util::rank ( my_array );
118 // if ( rank < 2 ) { // rank 1
119 // int size = num_util::size( my_array );
120 // col.clear();
121 // col.reserve(size);
122 // for (int i = 0; i < size; i++) {
123 // boost::python::object result = my_array[i];
124 // col.push_back( boost::python::extract<double>(result) );
125 // }
126 // }
127 // else { // rank > 1
128 // boost::python::object tarray = array.getflat();
129 // int size = num_util::size ( array );
130 // for ( int i = 0; i < size; i++ ) {
131 // boost::python::object result = tarray[i];
132 // col.push_back ( boost::python::extract < double > ( result ) );
133 // }
134 // }
135 // }
136 
137 // }
138 } // namespace
139 } // namespace
140 #endif
141 
142 namespace hippodraw {
143 namespace Python {
144 
146  PyErr_SetString ( PyExc_StopIteration, e.what() );
147 }
148 
149 void
151 {
152  class_ < PyDataSource >
153  ( "DataArray",
154  "A DataArray wraps a DataSource object so that numerical Python\n"
155  "arrays can be used as both input and output. The numerical array\n"
156  "can be either a numarray.array or Numeric.array depending on\n"
157  "how the hippo module was configured.\n"
158  "\n"
159  "Access to the array is done like a Python list or dictionary.\n"
160  "\tarray = my_data_array [ index ] # list form\n"
161  "\tarray = my_data_array [ 'my_label' ] # dict form\n"
162  "\n"
163  "Storage to the array is also done like a Python list or dictionary.\n"
164  "\tmy_data_array [ index ] = ... # list form\n"
165  "\tmy_data_array [ 'my_label' ] = ... # dict form\n" )
166 
167  .def ( init < const std::string & > (
168  "DataArray ( string ) -> DataArray\n"
169  "\n"
170  "Creates a DataArray. The string can be one of\n"
171  "\tListTuple\n"
172  "\tNTuple\n"
173  "\tNumArrayTuple" ) )
174 
175  .add_property ( "columns",
176  &PyDataSource::columns )
177 
178  .add_property ( "rows",
179  &PyDataSource::rows )
180 
181  .def ( "getCurrent",
182  &PyDataSource::getCurrentDataSource,
183  return_value_policy < reference_existing_object > (),
184  "getCurrent () -> DataArray\n"
185  "\n"
186  "Returns a DataArray that wraps the current DataSource." )
187 
188  .staticmethod ( "getCurrent" )
189 
190  .def ( "dataSource",
191  &PyDataSource::dataSource,
192  return_value_policy < reference_existing_object > (),
193  "dataSource () -> DataSource\n"
194  "\n"
195  "Returns reference to underlying DataSource" )
196 
197  .def ( "getTitle",
198  &PyDataSource::getTitle,
199  return_value_policy < copy_const_reference > (),
200  "getTitle () -> string\n"
201  "\n"
202  "Returns title of the DataSource." )
203 
204  .def ( "setName",
205  &PyDataSource::setName,
206  "setName ( string ) -> None\n"
207  "\n"
208  "Sets the name of the DataSource. The name should be unique\n"
209  "with one application and may appear in the Inspector panel." )
210 
211  .def ( "setTitle",
212  &PyDataSource::setTitle,
213  "setTitle ( string ) -> None\n"
214  "\n"
215  "Sets the title of the DataSource. The title is what appears,\n"
216  "by default, at the top of a Display." )
217 
218  .def ( "getLabels",
219  &PyDataSource::getLabels,
220  return_value_policy < copy_const_reference > (),
221  "getLabels () -> list\n"
222  "\n"
223  "Returns the list of string objects of column labels." )
224 
225  .def ( "addColumn",
226  ( int (PyDataSource:: * )
227  (const std::string &, const std::vector<double> &) )
228  &PyDataSource::addColumn,
229  "addColumn ( string, list ) -> value\n"
230  "addColumn ( string, array ) -> value\n"
231  "\n"
232  "Adds a column. The string will be the label of the column.\n"
233  "A copy of the list or array values will be the contents.\n"
234  "The second form is only available if HippoDraw was configured\n"
235  "with numerical Python support. Returns the new column's index." )
236 
237 #ifdef HAVE_NUMARRAY
238  .def ( "addColumn",
239  ( int (PyDataSource:: * )
240  (const std::string &, boost::python::numeric::array) )
241  &PyDataSource::addColumn )
242 #endif
243 
244  .def ( "getColumn",
245  ( const std::vector < double > & (PyDataSource:: * ) // fptr
246  ( unsigned int ) const) // function signature
247  &PyDataSource::getColumn,
248  return_value_policy < copy_const_reference> (),
249  "getColumn ( value ) -> list\n"
250  "\n"
251  "Returns a column as list of floats. 'value' maybe either\n"
252  "the column label or its index." )
253 
254  .def ( "getColumn",
255  ( const std::vector < double > & (PyDataSource:: * ) // fptr
256  ( const std::string & ) const) // function signature
257  &PyDataSource::getColumn,
258  return_value_policy < copy_const_reference> () )
259 
260  .def ( "replaceColumn",
261  ( void (PyDataSource:: * )
262  ( const std::string &, const std::vector<double> & ) )
263  &PyDataSource::replaceColumn,
264  "replaceColumn ( value, list ) -> None\n"
265  "replaceColumn ( value, array ) -> None\n"
266  "\n"
267  "Replace column by its label or index. The second form is \n"
268  "only available if HippoDraw was configure with numerical\n"
269  "arrays." )
270 
271  .def ( "replaceColumn",
272  ( void (PyDataSource:: * ) // fptr
273  ( unsigned int index, const std::vector<double> & ) )
274  &PyDataSource::replaceColumn )
275 
276  .def ( "replaceColumn",
277  ( void (PyDataSource:: * ) // fptr
278  ( const std::string &, numeric::array ) ) // function signature
279  &PyDataSource::replaceColumn )
280 
281  .def ( "replaceColumn",
282  ( void (PyDataSource:: * ) // fptr
283  ( unsigned int index, numeric::array ) ) // function signature
284  &PyDataSource::replaceColumn )
285 
286 // comment out until implemented for ListTuple and NumArrayTuple
287 // .def ( "clear",
288 // &PyDataSource::clear,
289 // "Clears the data elements of the DataSource" )
290 
291  .def ("has_key",
292  &PyDataSource::hasColumn,
293  "has_key ( string ) -> Boolean\n"
294  "\n"
295  "Returns True if column with label exists.")
296 
297  .def ( "keys",
298  &PyDataSource::getLabels,
299  return_value_policy < copy_const_reference > (),
300  "keys () -> list\n"
301  "\n"
302  "Returns the list of column labels." )
303 
304  .def ( "register",
305  ( void (PyDataSource:: * ) ( const std::string & ) )
306  &PyDataSource::registerNTuple,
307  "register ( string ) -> None\n"
308  "register ( ) -> string\n"
309  "\n"
310  "Register the underlying DataSource with the\n"
311  "DataSourceController. The first form registers it with the\n"
312  "given name, while the second from returns a unique name\n"
313  "generated by the controller." )
314 
315  .def ( "register",
316  ( std::string (PyDataSource:: * ) () )
317  &PyDataSource::registerNTuple )
318 
319 
320  // The following must come before the other __setitem__ so that
321  // it is seen last, otherwise a numarray gets converted to
322  // vector.
323  .def ( "__setitem__",
324  &PyDataSource::saveColumnFrom,
325  "__setitem__ ( label, sequence ) -> None\n"
326  "\n"
327  "Copies the contensts of the sequence. If column with label\n"
328  "already exists, replaces it, otherwise add a new column." )
329 
330  .def ( "addRow",
331  &PyDataSource::addRow,
332  "addRow ( sequence ) -> None\n"
333  "\n"
334  "Adds a row to the held DataSource object if supported, otherwise"
335  " throws Runtime exception." )
336 
337  .def ( "append",
338  ( void ( PyDataSource:: * ) // function pointer
339  ( const DataSource * ) ) // signature
340  &PyDataSource::append,
341  "append ( DataArray ) -> None\n"
342  "append ( DataSource ) -> None\n"
343  "\n"
344  "Appends contents of DataSource or DataArray to the DataArray." )
345 
346  .def ( "append",
347  ( void ( PyDataSource:: * ) // function pointer
348  ( const PyDataSource * ) ) // signature
349  &PyDataSource::append )
350 
351 
352  .def ( "__getitem__",
353  ( numeric::array ( PyDataSource:: * )
354  ( const std::string & ) const )
355  &PyDataSource::columnAsNumArray,
356  return_value_policy < return_by_value > (),
357  "__getitem__ ( value ) -> array\n"
358  "\n"
359  "Returns a copy of the column as numerical array. 'value' can\n"
360  "be either the column label or its index." )
361 
362  .def ( "__getitem__",
363  ( numeric::array ( PyDataSource:: * )
364  ( unsigned int ) const )
365  &PyDataSource::columnAsNumArray,
366  return_value_policy < return_by_value > () )
367 
368  .def ( "__setitem__",
369  ( void ( PyDataSource:: * )
370  ( const std::string &,
371  numeric::array ) )
372  &PyDataSource::saveColumnFromNumArray,
373  return_value_policy < return_by_value > (),
374  "__setitem__ ( value, array ) -> None\n"
375  "\n"
376  "Copies the contents of array. If `'value' is an index, then\n"
377  "replaces the contents of the existing column. If 'value' is\n"
378  "a label then either replaces existing column with that label\n"
379  "or adds a new column." )
380 
381  .def ( "__setitem__",
382  ( void ( PyDataSource:: * )
383  ( unsigned int,
384  numeric::array ) )
385  &PyDataSource::saveColumnFromNumArray,
386  return_value_policy < return_by_value > () )
387 
388  ;
389  register_exception_translator<PyDataSource::StopIteration>
391 }
392 } // namespace Python
393 } // namespace hippodraw
394 
395 using namespace hippodraw;
396 
397 PyDataSource::PyDataSource() {
398  m_type = "NTuple";
399  m_dataSource = new NTuple();
400 }
401 
402 PyDataSource::
403 PyDataSource ( const std::string & name, DataSource * source )
404  : m_type ( name ),
405  m_dataSource ( source )
406 {
407 }
408 
413 PyDataSource(const std::string & dataSource)
414  : m_type(dataSource) {
415  if (dataSource == "ListTuple") {
416  m_dataSource = new ListTuple();
417  } else if (dataSource == "NTuple") {
418  m_dataSource = new NTuple();
419 #ifdef HAVE_NUMARRAY
420  } else if (dataSource == "NumArrayTuple") {
421  m_dataSource = new NumArrayTuple();
422 #else
423  } else if (dataSource == "NumArrayTuple") {
424  throw std::runtime_error ("HippoDraw was not built with "
425  "numeric Python soupport" );
426 #endif
427  } else {
428  throw std::runtime_error("Invalid DataSource: " + dataSource);
429  }
430 }
431 
434 {
435  delete m_dataSource;
436 }
437 
438 template < typename T >
439 void
441 copy_direct ( boost::python::numeric::array array,
442  std::vector<double > & col )
443 {
444 #ifdef HAVE_NUMARRAY
445  T * data = reinterpret_cast < T * > ( num_util::data ( array ) );
446  int size = num_util::size ( array );
447  std::copy ( data, data+ size, back_inserter( col ) );
448 #else
449  throw std::runtime_error ( "HippoDraw was not built with "
450  "numeric support");
451 #endif
452 }
453 
454 void
456 extractVector ( boost::python::numeric::array array,
457  std::vector<double> & col )
458 {
459 #ifdef HAVE_NUMARRAY
460  PyArray_TYPES type = num_util::type ( array );
461 
462  if ( num_util::iscontiguous ( array ) &&
463  type != PyArray_NOTYPE ) {
464  switch ( type )
465  {
466 #ifdef HAVE_NUMPY
467  case PyArray_BOOL:
468  copy_direct < bool > ( array, col );
469  break;
470 #endif
471  case PyArray_CHAR:
472  copy_direct < char > ( array, col );
473  break;
474 
475  case PyArray_SHORT :
476  copy_direct < short > ( array, col );
477  break;
478 
479  case PyArray_INT :
480  copy_direct < int > ( array, col );
481  break;
482 
483  case PyArray_UINT :
484  copy_direct < unsigned int > ( array, col );
485  break;
486  case PyArray_FLOAT :
487  copy_direct < float > ( array, col );
488  break;
489  case PyArray_DOUBLE :
490  copy_direct < double > ( array, col );
491  break;
492 
493  default:
494  std::string what ( "DataArray: Array type `" );
495  what += num_util::type2string ( type );
496  what += "' not supported.";
497  throw std::runtime_error ( what );
498  break;
499  }
500  }
501  else { // not contiguous
502  const numeric::array & my_array = array;
503  int rank = num_util::rank ( my_array );
504  if ( rank < 2 ) { // rank 1
505  int size = num_util::size( my_array );
506  col.clear();
507  col.reserve(size);
508  for (int i = 0; i < size; i++) {
509  boost::python::object result = my_array[i];
510  col.push_back( boost::python::extract<double>(result) );
511  }
512  }
513  else { // rank > 1
514  boost::python::object tarray = array.getflat();
515  int size = num_util::size ( array );
516  for ( int i = 0; i < size; i++ ) {
517  boost::python::object result = tarray[i];
518  col.push_back ( boost::python::extract < double > ( result ) );
519  }
520  }
521  }
522 #else
523  throw std::runtime_error ( "HippoDraw was not built with "
524  "numeric support.");
525 #endif
526 }
527 
528 PyDataSource *
531 {
532  PyDataSource * array = 0;
533 
535  DataSource * source = controller -> getCurrent ();
536 
537  if ( source != 0 ) {
538  NTuple * ntuple = dynamic_cast < NTuple * > ( source );
539  if ( ntuple != 0 ) {
540  array = new PyDataSource ( "NTuple", source );
541  }
542 
543  ListTuple * ltuple = dynamic_cast < ListTuple * > ( source );
544  if ( ltuple != 0 ) {
545  array = new PyDataSource ( "ListTuple", source );
546  }
547 
548 #ifdef HAVE_NUMARRAY
549  NumArrayTuple * natuple = dynamic_cast < NumArrayTuple * > ( source );
550  if ( natuple != 0 ) {
551  array = new PyDataSource ( "NumArrayTuple", source );
552  }
553 #endif
554 
555 #ifdef HAVE_CFITSIO
556  FitsNTuple * fntuple = dynamic_cast < FitsNTuple * > ( source );
557  if ( fntuple != 0 ) {
558  array = new PyDataSource ( "FitsNTuple", source );
559  }
560 #endif
561 
562 #ifdef HAVE_ROOT
563  RootNTuple * rntuple = dynamic_cast < RootNTuple * > ( source );
564  if ( rntuple != 0 ) {
565  array = new PyDataSource ( "RootNTuple", source );
566  }
567 #endif
568  }
569 
570 
571  return array;
572 }
573 
574 unsigned int PyDataSource::columns() const {
575  return m_dataSource->columns();
576 }
577 
578 unsigned int PyDataSource::rows() const {
579  return m_dataSource->rows();
580 }
581 
582 const std::string & PyDataSource::getTitle() const {
583  return m_dataSource->title();
584 }
585 
586 void PyDataSource::setTitle(const std::string & title) {
587  m_dataSource->setTitle(title);
588 }
589 
590 void PyDataSource::setName(const std::string & name) {
591  m_dataSource->setName(name);
592 }
593 
594 const std::vector<std::string> & PyDataSource::getLabels() const {
595  return m_dataSource->getLabels();
596 }
597 
598 const std::vector<double> &
599 PyDataSource::getColumn(const std::string & name) const {
600  return m_dataSource->getColumn(name);
601 }
602 
603 const std::vector<double> &
604 PyDataSource::getColumn(unsigned int index) const {
605  return m_dataSource->getColumn(index);
606 }
607 
608 void
610 replaceColumn (const std::string & label,
611  const std::vector < double > & col )
612 {
613  if ( m_type == "NTuple" ||
614  m_type == "FitsNTuple" ||
615  m_type == "RootNTuple" ) {
616  m_dataSource -> replaceColumn ( label, col );
617  } else if (m_type == "ListTuple") {
618  ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
619  boost::python::list seq(col);
620  nt->replaceColumn(label, seq);
621  } else {
622  std::string what("Cannot replace a column of this type in a " + m_type);
623  throw std::runtime_error(what);
624  }
625 }
626 
627 void
629 replaceColumn ( unsigned int index,
630  const std::vector < double > & col)
631 {
632  const std::vector<std::string> & names = m_dataSource->getLabels();
633  if ( index < names.size() ) {
634  replaceColumn(names[index], col);
635  } else {
636  std::string what ( "Invalid column index: " );
637  what += hippodraw::String::convert ( index );
638  throw std::runtime_error ( what );
639  }
640 }
641 
642 void
644 replaceColumn ( const std::string & label,
645  boost::python::numeric::array array)
646 {
647 #ifdef HAVE_NUMARRAY
648  NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
649  if (!nt) {
650  std::string what("Cannot replace a column of this type in a " + m_type);
651  throw std::runtime_error(what);
652  }
653  nt->replaceColumn(label, array);
654 #else
655  throw std::runtime_error ( "HippoDraw was not built with "
656  "numeric Python suppport" );
657 #endif
658 }
659 
660 void
662 replaceColumn ( unsigned int index,
663  boost::python::numeric::array array )
664 {
665 #ifdef HAVE_NUMARRAY
666  NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
667  if (!nt) {
668  std::string what("Cannot replace a column of this type in a " + m_type);
669  throw std::runtime_error(what);
670  }
671  nt->replaceColumn(index, array);
672 #else
673  throw std::runtime_error ( "HippoDraw was not built with "
674  "numeric Python suppport" );
675 #endif
676 }
677 
678 int PyDataSource::addColumn( const std::string & label,
679  const std::vector<double> & col ) {
680  if (m_type == "NTuple") {
681  NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
682  return nt->addColumn(label, col);
683  } else if (m_type == "ListTuple") {
684  ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
685  boost::python::list seq(col);
686  return nt->addColumn(label, seq);
687  } else {
688  std::string what("Cannot add a column of this type to a " + m_type);
689  throw std::runtime_error(what);
690  }
691  return m_dataSource->columns();
692 }
693 
694 int PyDataSource::addColumn( const std::string & label,
695  boost::python::numeric::array array ) {
696 #ifdef HAVE_NUMARRAY
697  NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
698  if (!nt) {
699  std::string what("Cannot add a column of this type to a " + m_type);
700  throw std::runtime_error(what);
701  }
702  return nt->addColumn(label, array);
703 #else
704  throw std::runtime_error ( "HippoDraw was not built with "
705  "numeric Python support" );
706 #endif
707 }
708 
710  m_dataSource->clear();
711 }
712 
713 bool PyDataSource::hasColumn(const std::string & colname) const {
714  const std::vector<std::string> & names = getLabels();
715  return std::find(names.begin(), names.end(), colname) != names.end();
716 }
717 
718 void PyDataSource::registerNTuple( const std::string & name ) {
719  m_dataSource->setName(name);
721  controller->registerNTuple(name, m_dataSource);
722 }
723 
726  return controller->registerNTuple(m_dataSource);
727 }
728 
729 boost::python::numeric::array
731 columnAsNumArray( const std::string & colname ) const
732 {
733 #ifdef HAVE_NUMARRAY
734  if (m_type == "NumArrayTuple") {
735  NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
736  boost::python::numeric::array a = nt->getNumArray(colname);
737  return a;
738  }
739 
740 #ifdef HAVE_ROOT
741  if ( m_type == "RootNTuple" ) {
742  QtRootNTuple * tuple = dynamic_cast < QtRootNTuple *> ( m_dataSource );
743  boost::python::numeric::array a = tuple -> getColumnAsArray ( colname );
744  return a;
745  }
746 #endif
747 
748  typedef std::vector<double> vec;
749  const vec & array = m_dataSource->getColumn(colname);
750  std::vector < int > shape;
751  m_dataSource -> fillShape ( shape, colname );
752  numeric::array na
753  = num_util::makeNum ( &const_cast<vec &>( array )[0], shape );
754  return na;
755 #else
756  throw std::runtime_error ("HippoDraw was not built with "
757  "numeric Python support" );
758 #endif // HAVE_NUMARRAY
759 }
760 
761 boost::python::numeric::array
763 columnAsNumArray ( unsigned int index ) const {
764 #ifdef HAVE_NUMARRAY
765  if ( index < columns() ) {
766  if (m_type == "NumArrayTuple") {
767  NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
768  return nt->getNumArray(index);
769  }
770  typedef std::vector<double> vec;
771  const vec & array = m_dataSource->getColumn(index);
772  std::vector < int > shape;
773  m_dataSource -> fillShape ( shape, index );
774  numeric::array na =
775  num_util::makeNum ( &const_cast <vec &> ( array )[0], shape );
776  return na;
777  } else {
778  throw StopIteration("index out-of-range");
779  }
780 #else
781  throw std::runtime_error ( "HippoDraw was not built with "
782  "numeric Python support" );
783 #endif
784 }
785 
786 void
788 checkRank ( boost::python::numeric::array array )
789 {
790 #ifdef HAVE_NUMARRAY
791  int rank = num_util::rank ( array );
792  if ( rank > 1 ) {
793  std::string what ( "DataArray: Can not add " );
794  what += hippodraw::String::convert ( rank );
795  what += " dimensional array\n to ";
796  what += m_type;
797  throw std::runtime_error ( what );
798  }
799 #endif
800 }
801 
802 void
804 saveColumn ( const std::string & label,
805  const std::vector < double > & v,
806  const std::vector < intptr_t > & shape )
807 {
808  if ( hasColumn ( label ) ) {
809  m_dataSource -> replaceColumn ( label, v, shape );
810  } else {
811  m_dataSource -> addColumn ( label, v, shape );
812  }
813 }
814 
815 void
817 saveColumnFromNumArray ( const std::string & label,
818  boost::python::numeric::array array )
819 {
820 #ifdef HAVE_NUMARRAY
821  PyApp::lock ();
822  if (m_type == "NumArrayTuple") {
823  if (hasColumn(label)) {
824  replaceColumn(label, array);
825  } else {
826  addColumn(label, array);
827  }
828  PyApp::unlock();
829  return;
830  }
831 
832 #ifdef HAVE_CFITSIO
833  FitsNTuple * fnt = dynamic_cast < FitsNTuple * > ( m_dataSource );
834  if ( fnt != 0 ) {
835  std::vector < double > vec;
836  extractVector ( array, vec );
837 
838  const std::vector < intptr_t > shape = num_util::shape ( array );
839  saveColumn ( label, vec, shape );
840 
841  PyApp::unlock();
842  return;
843  }
844 #endif // cfitsio
845 
846  if (m_type == "ListTuple") {
847  boost::python::list seq(array);
848  ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
849  if (hasColumn(label)) {
850  nt->replaceColumn(label, seq);
851  } else {
852  nt->addColumn(label, seq);
853  }
854  PyApp::unlock();
855  return;
856  }
857 
858  checkRank ( array );
859  std::vector<double> col;
860  extractVector(array, col);
861 
862  if (m_type == "NTuple") {
863  NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
864  if (hasColumn(label)) {
865  m_dataSource ->replaceColumn ( label, col );
866  } else {
867  nt->addColumn(label, col);
868  }
869  PyApp::unlock();
870  return;
871  }
872 
873 
874 #ifdef HAVE_ROOT
875  RootNTuple * rnt = dynamic_cast < RootNTuple * > ( m_dataSource );
876  if ( rnt != 0 ) {
877  if ( hasColumn ( label ) ) {
878  m_dataSource -> replaceColumn ( label, col );
879  } else {
880  rnt -> addColumn ( label, col );
881  }
882  PyApp::unlock();
883  return;
884  }
885 #endif // root
886  PyApp::unlock();
887 
888  throw std::runtime_error("__setitem__ not supported for " + m_type);
889 #else
890  throw std::runtime_error ("HippoDraw was not built with "
891  "numeric Python support" );
892 #endif
893 }
894 
897 void PyDataSource::
899  boost::python::numeric::array array )
900 {
901 #ifdef HAVE_NUMARRAY
902  if ( index < columns()) {
903 
904  if (m_type == "NumArrayTuple") {
905  replaceColumn(index, array);
906  return;
907 
908  } else if (m_type == "NTuple") {
909  checkRank ( array );
910  std::vector<double> col;
911  extractVector ( array, col );
912  NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
913  nt->replaceColumn(index, col);
914  return;
915 
916  } else if (m_type == "ListTuple") {
917  boost::python::list seq(array);
918  ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
919  nt->replaceColumn(index, seq);
920  return;
921  }
922 #ifdef HAVE_CFITSIO
923  else {
924  FitsNTuple * fnt = dynamic_cast < FitsNTuple * > ( m_dataSource );
925  if ( fnt != 0 ) {
926  std::vector<double> col;
927  extractVector ( array, col );
928  const std::vector < intptr_t > shape = num_util::shape ( array );
929  fnt -> replaceColumn ( index, col, shape );
930  return;
931  }
932  }
933 #endif
934  throw std::runtime_error
935  ("__setitem__ by index is not supported for " + m_type);
936  } else {
937  std::string what ( "DataArray:: Attempt to save column " );
938  what += hippodraw::String::convert ( index );
939  what += " with ";
940  what += hippodraw::String::convert ( columns () );
941  what += " columns in data source";
942  throw std::runtime_error ( what );
943  }
944 #else
945  throw std::runtime_error ( "HippoDraw was not built with "
946  "numeric Python support" );
947 #endif
948 }
949 
950 
951 void
953 saveColumnFrom ( const std::string & label,
954  const std::vector < double > & array )
955 {
956  if ( hasColumn ( label ) ) {
957  m_dataSource -> replaceColumn ( label, array );
958  }
959  else {
960  m_dataSource -> addColumn ( label, array );
961  }
962 }
963 
964 void
966 addRow ( const std::vector < double > & row )
967 {
968  PyApp::lock ();
969  try {
970  m_dataSource -> addRow ( row );
971  }
972  catch ( const std::runtime_error & e ) {
973  PyApp::unlock ();
974  throw e;
975  }
976  PyApp::unlock ();
977 }
978 
979 void
981 append ( const DataSource * source )
982 {
983  PyApp::lock ();
984  m_dataSource -> append ( source );
985  PyApp::unlock ();
986 }
987 void
989 append ( const PyDataSource * source )
990 {
991  m_dataSource -> append ( & source -> dataSource() );
992 }
virtual void setTitle(const std::string &title)
Sets the title of the data source to title.
Definition: DataSource.cxx:146
unsigned int columns() const
unsigned int i
void replaceColumn(const std::string &, const std::vector< double > &col)
Replace a column by its label.
numeric::array makeNum(object x)
Definition: num_util.cpp:219
void setTitle(const std::string &title)
virtual void replaceColumn(const std::string &label, const std::vector< double > &array)
Replaces data in column label with contents of array.
Definition: DataSource.cxx:360
A wrapper class for Python tuple objects.
Definition: python.dir:45
hippodraw::QtRootNTuple class interface.
const std::vector< std::string > & getLabels() const
Get the column names.
void PyDataSourceExceptionTranslator(const PyDataSource::StopIteration &e)
std::string registerNTuple()
Register this DataSource, returning a unique name.
void clear()
Clear the data elements of the DataSource.
A DataSource class implemented with a ROOT TBranch objects from a ROOT TTree to store the column data...
Definition: RootNTuple.h:37
PyDataSource()
Default constructor wraps an ordinary NTuple.
hippodraw::FitsNTuple class interface.
virtual void replaceColumn(unsigned int index, const std::vector< double > &data)
Replaces the data in column col.
Definition: NTuple.cxx:440
A DataSource class implemented with a Python numarray array to store the column data.
Definition: NumArrayTuple.h:54
static void lock()
Obtains a lock on the application&#39;s mutex.
Definition: PyApp.cxx:331
void * data(numeric::array arr)
Definition: num_util.cpp:389
void addRow(const std::vector< double > &array)
Adds a row to the DataSource.
void export_DataArray()
Export PyDataSourceWrapper.
static PyDataSource * getCurrentDataSource()
Returns a new PyDataSource that wraps the current DataSource in the DataSourceController.
std::string type2string(PyArray_TYPES t_type)
Converts a PyArray_TYPE to its name in string.
Definition: num_util.cpp:467
const std::string & title() const
Returns a const reference to the title of the data source.
Definition: DataSource.cxx:141
unsigned int rows() const
std::vector< intptr_t > shape(numeric::array arr)
Definition: num_util.cpp:317
const std::string & getTitle() const
The title of the DataSource.
The namespace for conversion to string.
A wrapper for RootNTuple, so that when RootNTuple is used in Qt based application, the application object can be locked and unlocked before calling any ROOT functions.
Definition: QtRootNTuple.h:37
virtual const std::vector< double > & getColumn(const std::string &name) const
Returns the data in the column with label name.
Definition: DataSource.cxx:243
hippodraw::PyDataSource class interface
hippodraw::NTuple class interface.
static void extractVector(boost::python::numeric::array array, std::vector< double > &col)
Extracts a vector from the numarray object.
boost::python::numeric::array columnAsNumArray(const std::string &label) const
Return a column from the DataSource as a numarray object, indexing by column label.
void append(const DataSource *source)
Adds all the rows of source to the DataArray.
PyArray_TYPES type(numeric::array arr)
Definition: num_util.cpp:249
virtual const std::vector< std::string > & getLabels() const
Returns the list of available labels.
Definition: DataSource.cxx:172
DataSource * m_dataSource
The actual DataSource object.
Definition: PyDataSource.h:224
hippodraw::PyApp class interface.
void saveColumnFrom(const std::string &label, const std::vector< double > &array)
Replace or add a column from vector.
void saveColumnFromNumArray(const std::string &label, boost::python::numeric::array array)
Replace or add a column from a numarray object, indexing by column label.
hippodraw::ListTuple class interface.
ViewBase * v
Definition: PlotTable.cxx:104
const std::vector< double > & getColumn(const std::string &name) const
Get a column as a tuple of floats by column name.
intp size(numeric::array arr)
Definition: num_util.cpp:296
int rank(numeric::array arr)
Definition: num_util.cpp:271
void replaceColumn(unsigned int index, boost::python::list array)
Replaces the column indexed by index with the array.
Definition: ListTuple.cxx:226
string convert(int i)
Converts an integer to a string.
void checkRank(boost::python::numeric::array array)
Checks the rank of the array.
bool iscontiguous(numeric::array arr)
Definition: num_util.cpp:374
This class is the public interface to a DataSource object that the user sees as the DataArray object ...
Definition: PyDataSource.h:43
void setName(const std::string &name)
Set the name of the DataSource.
virtual int addColumn(const std::string &, const std::vector< double > &column)
Adds a column to the end of the ntuple and returns the index to the added column. ...
Definition: NTuple.cxx:405
void replaceColumn(unsigned int index, boost::python::numeric::array array)
Replaces the column indexed by index with the array.
void saveColumn(const std::string &label, const std::vector< double > &v, const std::vector< intptr_t > &shape)
Replaces or add column vector.
A singleton class that is the interface between GUI and the DataSource objects.
boost::python::numeric::array getNumArray(const std::string &label) const
Return the reference to the desired numarray by column label.
int addColumn(const std::string &label, boost::python::list seq)
Adds a column to the end of the ListTuple.
Definition: ListTuple.cxx:190
A DataSource class implemented with std::vector&lt;double&gt; to store the column data. ...
Definition: NTuple.h:33
hippodraw::NumArrayTuple class interface.
virtual void clear()=0
Clears the data source.
virtual unsigned int rows() const =0
Returns the number of rows.
std::string registerNTuple(DataSource *nt)
Register a DataSource.
static void unlock()
Releases the lock on the application&#39;s mutex.
Definition: PyApp.cxx:357
const DataSource & dataSource() const
Return a reference to the underlying DataSource.
Definition: PyDataSource.h:89
unsigned int columns() const
Returns the number of columns or data arrays available from this DataSource.
Definition: DataSource.h:458
A DataSource class implemented with a vector &lt; DataColumn * &gt; objects.
Definition: FitsNTuple.h:31
bool hasColumn(const std::string &name) const
Return true if column with label name exists in DataSource.
return index
Definition: PickTable.cxx:182
int addColumn(const std::string &label, boost::python::numeric::array array)
Adds a column to the end of the NumArrayTuple.
std::string m_type
The type of data source.
Definition: PyDataSource.h:221
static void copy_direct(boost::python::numeric::array array, std::vector< double > &col)
Copies and converts to double, if needed, data of type T from array to fill the std::vector col...
DataSourceController class interface.
void setName(const std::string &name)
Sets the name of the data source.
Definition: DataSource.cxx:130
A wrapper class for Python list objects.
Definition: python.dir:41
A DataSource class implemented with a Python list to store the column data.
Definition: ListTuple.h:40
int addColumn(const std::string &label, const std::vector< double > &col)
Add a column to an NTuple or ListTuple.
static DataSourceController * instance()
Returns the pointer to the singleton instance.
Base class for DataSource.
Definition: DataSource.h:55

Generated for HippoDraw Class Library by doxygen