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

Generated for HippoDraw Class Library by doxygen