00001
00013 #ifdef HAVE_CONFIG_H
00014
00015 #include "config.h"
00016 #endif
00017
00018
00019 #ifdef _MSC_VER
00020 #include "msdevstudio/MSconfig.h"
00021 #endif
00022
00023
00024 #include <boost/python.hpp>
00025
00026 #include "PyDataSource.h"
00027
00028 #include "ListTuple.h"
00029 #include "PyApp.h"
00030
00031 #include "datasrcs/DataSourceController.h"
00032 #include "datasrcs/NTuple.h"
00033 #include "pattern/string_convert.h"
00034
00035 #ifdef HAVE_NUMARRAY
00036 #include "numarray/NumArrayTuple.h"
00037 #include "numarray/num_util.h"
00038 #endif
00039
00040 #ifdef HAVE_CFITSIO
00041 #include "fits/FitsNTuple.h"
00042 #endif
00043
00044 #ifdef HAVE_ROOT
00045 #include "root/QtRootNTuple.h"
00046 #endif
00047
00048 using namespace boost::python;
00049
00050 #ifdef HAVE_NUMARRAY
00051 namespace {
00052
00056 template < typename T >
00057 void copy_direct ( boost::python::numeric::array array,
00058 std::vector<double > & col )
00059 {
00060 T * data = reinterpret_cast < T * > ( num_util::data ( array ) );
00061 int size = num_util::size ( array );
00062 std::copy ( data, data+ size, back_inserter( col ) );
00063 }
00064
00070 void extractVector ( boost::python::numeric::array array,
00071 std::vector<double> & col )
00072 {
00073 PyArray_TYPES type = num_util::type ( array );
00074
00075 if ( num_util::iscontiguous ( array ) &&
00076 type != PyArray_NOTYPE ) {
00077 switch ( type )
00078 {
00079 #ifdef HAVE_NUMPY
00080 case PyArray_BOOL:
00081 copy_direct < bool > ( array, col );
00082 break;
00083 #endif
00084 case PyArray_CHAR:
00085 copy_direct < char > ( array, col );
00086 break;
00087
00088 case PyArray_SHORT :
00089 copy_direct < short > ( array, col );
00090 break;
00091
00092 case PyArray_INT :
00093 copy_direct < int > ( array, col );
00094 break;
00095
00096 case PyArray_UINT :
00097 copy_direct < unsigned int > ( array, col );
00098 break;
00099 case PyArray_FLOAT :
00100 copy_direct < float > ( array, col );
00101 break;
00102 case PyArray_DOUBLE :
00103 copy_direct < double > ( array, col );
00104 break;
00105
00106 default:
00107 std::string what ( "DataArray: Array type `" );
00108 what += num_util::type2string ( type );
00109 what += "' not supported.";
00110 throw std::runtime_error ( what );
00111 break;
00112 }
00113 }
00114 else {
00115 const numeric::array & my_array = array;
00116 int rank = num_util::rank ( my_array );
00117 if ( rank < 2 ) {
00118 int size = num_util::size( my_array );
00119 col.clear();
00120 col.reserve(size);
00121 for (int i = 0; i < size; i++) {
00122 boost::python::object result = my_array[i];
00123 col.push_back( boost::python::extract<double>(result) );
00124 }
00125 }
00126 else {
00127 boost::python::object tarray = array.getflat();
00128 int size = num_util::size ( array );
00129 for ( int i = 0; i < size; i++ ) {
00130 boost::python::object result = tarray[i];
00131 col.push_back ( boost::python::extract < double > ( result ) );
00132 }
00133 }
00134 }
00135
00136 }
00137 }
00138 #endif
00139
00140 namespace hippodraw {
00141 namespace Python {
00142
00143 void PyDataSourceExceptionTranslator( const PyDataSource::StopIteration & e ) {
00144 PyErr_SetString ( PyExc_StopIteration, e.what() );
00145 }
00146
00147 void
00148 export_DataArray()
00149 {
00150 class_ < PyDataSource >
00151 ( "DataArray",
00152 "A DataArray wraps a DataSource object so that numerical Python\n"
00153 "arrays can be used as both input and output. The numerical array\n"
00154 "can be either a numarray.array or Numeric.array depending on\n"
00155 "how the hippo module was configured.\n"
00156 "\n"
00157 "Access to the array is done like a Python list or dictionary.\n"
00158 "\tarray = my_data_array [ index ] # list form\n"
00159 "\tarray = my_data_array [ 'my_label' ] # dict form\n"
00160 "\n"
00161 "Storage to the array is also done like a Python list or dictionary.\n"
00162 "\tmy_data_array [ index ] = ... # list form\n"
00163 "\tmy_data_array [ 'my_label' ] = ... # dict form\n" )
00164
00165 .def ( init < const std::string & > (
00166 "DataArray ( string ) -> DataArray\n"
00167 "\n"
00168 "Creates a DataArray. The string can be one of\n"
00169 "\tListTuple\n"
00170 "\tNTuple\n"
00171 "\tNumArrayTuple" ) )
00172
00173 .add_property ( "columns",
00174 &PyDataSource::columns )
00175
00176 .add_property ( "rows",
00177 &PyDataSource::rows )
00178
00179 .def ( "getCurrent",
00180 &PyDataSource::getCurrentDataSource,
00181 return_value_policy < reference_existing_object > (),
00182 "getCurrent () -> DataArray\n"
00183 "\n"
00184 "Returns a DataArray that wraps the current DataSource." )
00185
00186 .staticmethod ( "getCurrent" )
00187
00188 .def ( "dataSource",
00189 &PyDataSource::dataSource,
00190 return_value_policy < reference_existing_object > (),
00191 "dataSource () -> DataSource\n"
00192 "\n"
00193 "Returns reference to underlying DataSource" )
00194
00195 .def ( "getTitle",
00196 &PyDataSource::getTitle,
00197 return_value_policy < copy_const_reference > (),
00198 "getTitle () -> string\n"
00199 "\n"
00200 "Returns title of the DataSource." )
00201
00202 .def ( "setName",
00203 &PyDataSource::setName,
00204 "setName ( string ) -> None\n"
00205 "\n"
00206 "Sets the name of the DataSource. The name should be unique\n"
00207 "with one application and may appear in the Inspector panel." )
00208
00209 .def ( "setTitle",
00210 &PyDataSource::setTitle,
00211 "setTitle ( string ) -> None\n"
00212 "\n"
00213 "Sets the title of the DataSource. The title is what appears,\n"
00214 "by default, at the top of a Display." )
00215
00216 .def ( "getLabels",
00217 &PyDataSource::getLabels,
00218 return_value_policy < copy_const_reference > (),
00219 "getLabels () -> list\n"
00220 "\n"
00221 "Returns the list of string objects of column labels." )
00222
00223 .def ( "addColumn",
00224 ( int (PyDataSource:: * )
00225 (const std::string &, const std::vector<double> &) )
00226 &PyDataSource::addColumn,
00227 "addColumn ( string, list ) -> value\n"
00228 "addColumn ( string, array ) -> value\n"
00229 "\n"
00230 "Adds a column. The string will be the label of the column.\n"
00231 "A copy of the list or array values will be the contents.\n"
00232 "The second form is only available if HippoDraw was configured\n"
00233 "with numerical Python support. Returns the new column's index." )
00234
00235 #ifdef HAVE_NUMARRAY
00236 .def ( "addColumn",
00237 ( int (PyDataSource:: * )
00238 (const std::string &, boost::python::numeric::array) )
00239 &PyDataSource::addColumn )
00240 #endif
00241
00242 .def ( "getColumn",
00243 ( const std::vector < double > & (PyDataSource:: * )
00244 ( unsigned int ) const)
00245 &PyDataSource::getColumn,
00246 return_value_policy < copy_const_reference> (),
00247 "getColumn ( value ) -> list\n"
00248 "\n"
00249 "Returns a column as list of floats. 'value' maybe either\n"
00250 "the column label or its index." )
00251
00252 .def ( "getColumn",
00253 ( const std::vector < double > & (PyDataSource:: * )
00254 ( const std::string & ) const)
00255 &PyDataSource::getColumn,
00256 return_value_policy < copy_const_reference> () )
00257
00258 .def ( "replaceColumn",
00259 ( void (PyDataSource:: * )
00260 ( const std::string &, const std::vector<double> & ) )
00261 &PyDataSource::replaceColumn,
00262 "replaceColumn ( value, list ) -> None\n"
00263 "replaceColumn ( value, array ) -> None\n"
00264 "\n"
00265 "Replace column by its label or index. The second form is \n"
00266 "only available if HippoDraw was configure with numerical\n"
00267 "arrays." )
00268
00269 .def ( "replaceColumn",
00270 ( void (PyDataSource:: * )
00271 ( unsigned int index, const std::vector<double> & ) )
00272 &PyDataSource::replaceColumn )
00273
00274 #ifdef HAVE_NUMARRAY
00275 .def ( "replaceColumn",
00276 ( void (PyDataSource:: * )
00277 ( const std::string &, numeric::array ) )
00278 &PyDataSource::replaceColumn )
00279
00280 .def ( "replaceColumn",
00281 ( void (PyDataSource:: * )
00282 ( unsigned int index, numeric::array ) )
00283 &PyDataSource::replaceColumn )
00284 #endif
00285
00286
00287
00288
00289
00290
00291 .def ("has_key",
00292 &PyDataSource::hasColumn,
00293 "has_key ( string ) -> Boolean\n"
00294 "\n"
00295 "Returns True if column with label exists.")
00296
00297 .def ( "keys",
00298 &PyDataSource::getLabels,
00299 return_value_policy < copy_const_reference > (),
00300 "keys () -> list\n"
00301 "\n"
00302 "Returns the list of column labels." )
00303
00304 .def ( "register",
00305 ( void (PyDataSource:: * ) ( const std::string & ) )
00306 &PyDataSource::registerNTuple,
00307 "register ( string ) -> None\n"
00308 "register ( ) -> string\n"
00309 "\n"
00310 "Register the underlying DataSource with the\n"
00311 "DataSourceController. The first form registers it with the\n"
00312 "given name, while the second from returns a unique name\n"
00313 "generated by the controller." )
00314
00315 .def ( "register",
00316 ( std::string (PyDataSource:: * ) () )
00317 &PyDataSource::registerNTuple )
00318
00319
00320
00321
00322
00323 .def ( "__setitem__",
00324 &PyDataSource::saveColumnFrom,
00325 "__setitem__ ( label, sequence ) -> None\n"
00326 "\n"
00327 "Copies the contensts of the sequence. If column with label\n"
00328 "already exists, replaces it, otherwise add a new column." )
00329
00330 .def ( "addRow",
00331 &PyDataSource::addRow,
00332 "addRow ( sequence ) -> None\n"
00333 "\n"
00334 "Adds a row to the held DataSource object if supported, otherwise"
00335 " throws Runtime exception." )
00336
00337 .def ( "append",
00338 ( void ( PyDataSource:: * )
00339 ( const DataSource * ) )
00340 &PyDataSource::append,
00341 "append ( DataArray ) -> None\n"
00342 "append ( DataSource ) -> None\n"
00343 "\n"
00344 "Appends contents of DataSource or DataArray to the DataArray." )
00345
00346 .def ( "append",
00347 ( void ( PyDataSource:: * )
00348 ( const PyDataSource * ) )
00349 &PyDataSource::append )
00350
00351
00352 .def ( "__getitem__",
00353 ( numeric::array ( PyDataSource:: * )
00354 ( const std::string & ) const )
00355 &PyDataSource::columnAsNumArray,
00356 return_value_policy < return_by_value > (),
00357 "__getitem__ ( value ) -> array\n"
00358 "\n"
00359 "Returns a copy of the column as numerical array. 'value' can\n"
00360 "be either the column label or its index." )
00361
00362 .def ( "__getitem__",
00363 ( numeric::array ( PyDataSource:: * )
00364 ( unsigned int ) const )
00365 &PyDataSource::columnAsNumArray,
00366 return_value_policy < return_by_value > () )
00367
00368 .def ( "__setitem__",
00369 ( void ( PyDataSource:: * )
00370 ( const std::string &,
00371 numeric::array ) )
00372 &PyDataSource::saveColumnFromNumArray,
00373 return_value_policy < return_by_value > (),
00374 "__setitem__ ( value, array ) -> None\n"
00375 "\n"
00376 "Copies the contents of array. If `'value' is an index, then\n"
00377 "replaces the contents of the existing column. If 'value' is\n"
00378 "a label then either replaces existing column with that label\n"
00379 "or adds a new column." )
00380
00381 .def ( "__setitem__",
00382 ( void ( PyDataSource:: * )
00383 ( unsigned int,
00384 numeric::array ) )
00385 &PyDataSource::saveColumnFromNumArray,
00386 return_value_policy < return_by_value > () )
00387
00388 ;
00389 register_exception_translator<PyDataSource::StopIteration>
00390 (&PyDataSourceExceptionTranslator);
00391 }
00392
00393 }
00394 }
00395
00396 using namespace hippodraw;
00397
00398 PyDataSource::PyDataSource() {
00399 m_type = "NTuple";
00400 m_dataSource = new NTuple();
00401 }
00402
00403 PyDataSource::
00404 PyDataSource ( const std::string & name, DataSource * source )
00405 : m_type ( name ),
00406 m_dataSource ( source )
00407 {
00408 }
00409
00413 PyDataSource::
00414 PyDataSource(const std::string & dataSource)
00415 : m_type(dataSource) {
00416 if (dataSource == "ListTuple") {
00417 m_dataSource = new ListTuple();
00418 } else if (dataSource == "NTuple") {
00419 m_dataSource = new NTuple();
00420 #ifdef HAVE_NUMARRAY
00421 } else if (dataSource == "NumArrayTuple") {
00422 m_dataSource = new NumArrayTuple();
00423 #else
00424 } else if (dataSource == "NumArrayTuple") {
00425 throw std::runtime_error ("HippoDraw was not built with "
00426 "numeric Python soupport" );
00427 #endif
00428 } else {
00429 throw std::runtime_error("Invalid DataSource: " + dataSource);
00430 }
00431 }
00432
00433 PyDataSource::
00434 ~PyDataSource()
00435 {
00436 delete m_dataSource;
00437 }
00438
00439 PyDataSource *
00440 PyDataSource::
00441 getCurrentDataSource ()
00442 {
00443 PyDataSource * array = 0;
00444
00445 DataSourceController * controller = DataSourceController::instance ();
00446 DataSource * source = controller -> getCurrent ();
00447
00448 if ( source != 0 ) {
00449 NTuple * ntuple = dynamic_cast < NTuple * > ( source );
00450 if ( ntuple != 0 ) {
00451 array = new PyDataSource ( "NTuple", source );
00452 }
00453
00454 ListTuple * ltuple = dynamic_cast < ListTuple * > ( source );
00455 if ( ltuple != 0 ) {
00456 array = new PyDataSource ( "ListTuple", source );
00457 }
00458
00459 #ifdef HAVE_NUMARRAY
00460 NumArrayTuple * natuple = dynamic_cast < NumArrayTuple * > ( source );
00461 if ( natuple != 0 ) {
00462 array = new PyDataSource ( "NumArrayTuple", source );
00463 }
00464 #endif
00465
00466 #ifdef HAVE_CFITSIO
00467 FitsNTuple * fntuple = dynamic_cast < FitsNTuple * > ( source );
00468 if ( fntuple != 0 ) {
00469 array = new PyDataSource ( "FitsNTuple", source );
00470 }
00471 #endif
00472
00473 #ifdef HAVE_ROOT
00474 RootNTuple * rntuple = dynamic_cast < RootNTuple * > ( source );
00475 if ( rntuple != 0 ) {
00476 array = new PyDataSource ( "RootNTuple", source );
00477 }
00478 #endif
00479 }
00480
00481
00482 return array;
00483 }
00484
00485 unsigned int PyDataSource::columns() const {
00486 return m_dataSource->columns();
00487 }
00488
00489 unsigned int PyDataSource::rows() const {
00490 return m_dataSource->rows();
00491 }
00492
00493 const std::string & PyDataSource::getTitle() const {
00494 return m_dataSource->title();
00495 }
00496
00497 void PyDataSource::setTitle(const std::string & title) {
00498 m_dataSource->setTitle(title);
00499 }
00500
00501 void PyDataSource::setName(const std::string & name) {
00502 m_dataSource->setName(name);
00503 }
00504
00505 const std::vector<std::string> & PyDataSource::getLabels() const {
00506 return m_dataSource->getLabels();
00507 }
00508
00509 const std::vector<double> &
00510 PyDataSource::getColumn(const std::string & name) const {
00511 return m_dataSource->getColumn(name);
00512 }
00513
00514 const std::vector<double> &
00515 PyDataSource::getColumn(unsigned int index) const {
00516 return m_dataSource->getColumn(index);
00517 }
00518
00519 void
00520 PyDataSource::
00521 replaceColumn (const std::string & label,
00522 const std::vector < double > & col )
00523 {
00524 if ( m_type == "NTuple" ||
00525 m_type == "FitsNTuple" ||
00526 m_type == "RootNTuple" ) {
00527 m_dataSource -> replaceColumn ( label, col );
00528 } else if (m_type == "ListTuple") {
00529 ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
00530 boost::python::list seq(col);
00531 nt->replaceColumn(label, seq);
00532 } else {
00533 std::string what("Cannot replace a column of this type in a " + m_type);
00534 throw std::runtime_error(what);
00535 }
00536 }
00537
00538 void
00539 PyDataSource::
00540 replaceColumn ( unsigned int index,
00541 const std::vector < double > & col)
00542 {
00543 const std::vector<std::string> & names = m_dataSource->getLabels();
00544 if ( index < names.size() ) {
00545 replaceColumn(names[index], col);
00546 } else {
00547 std::string what ( "Invalid column index: " );
00548 what += hippodraw::String::convert ( index );
00549 throw std::runtime_error ( what );
00550 }
00551 }
00552
00553 void
00554 PyDataSource::
00555 replaceColumn ( const std::string & label,
00556 boost::python::numeric::array array)
00557 {
00558 #ifdef HAVE_NUMARRAY
00559 NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00560 if (!nt) {
00561 std::string what("Cannot replace a column of this type in a " + m_type);
00562 throw std::runtime_error(what);
00563 }
00564 nt->replaceColumn(label, array);
00565 #else
00566 throw std::runtime_error ( "HippoDraw was not built with "
00567 "numeric Python suppport" );
00568 #endif
00569 }
00570
00571 void
00572 PyDataSource::
00573 replaceColumn ( unsigned int index,
00574 boost::python::numeric::array array )
00575 {
00576 #ifdef HAVE_NUMARRAY
00577 NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00578 if (!nt) {
00579 std::string what("Cannot replace a column of this type in a " + m_type);
00580 throw std::runtime_error(what);
00581 }
00582 nt->replaceColumn(index, array);
00583 #else
00584 throw std::runtime_error ( "HippoDraw was not built with "
00585 "numeric Python suppport" );
00586 #endif
00587 }
00588
00589 int PyDataSource::addColumn( const std::string & label,
00590 const std::vector<double> & col ) {
00591 if (m_type == "NTuple") {
00592 NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
00593 return nt->addColumn(label, col);
00594 } else if (m_type == "ListTuple") {
00595 ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
00596 boost::python::list seq(col);
00597 return nt->addColumn(label, seq);
00598 } else {
00599 std::string what("Cannot add a column of this type to a " + m_type);
00600 throw std::runtime_error(what);
00601 }
00602 return m_dataSource->columns();
00603 }
00604
00605 int PyDataSource::addColumn( const std::string & label,
00606 boost::python::numeric::array array ) {
00607 #ifdef HAVE_NUMARRAY
00608 NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00609 if (!nt) {
00610 std::string what("Cannot add a column of this type to a " + m_type);
00611 throw std::runtime_error(what);
00612 }
00613 return nt->addColumn(label, array);
00614 #else
00615 throw std::runtime_error ( "HippoDraw was not built with "
00616 "numeric Python support" );
00617 #endif
00618 }
00619
00620 void PyDataSource::clear() {
00621 m_dataSource->clear();
00622 }
00623
00624 bool PyDataSource::hasColumn(const std::string & colname) const {
00625 const std::vector<std::string> & names = getLabels();
00626 return std::find(names.begin(), names.end(), colname) != names.end();
00627 }
00628
00629 void PyDataSource::registerNTuple( const std::string & name ) {
00630 m_dataSource->setName(name);
00631 DataSourceController * controller = DataSourceController::instance();
00632 controller->registerNTuple(name, m_dataSource);
00633 }
00634
00635 std::string PyDataSource::registerNTuple() {
00636 DataSourceController * controller = DataSourceController::instance();
00637 return controller->registerNTuple(m_dataSource);
00638 }
00639
00640 boost::python::numeric::array
00641 PyDataSource::
00642 columnAsNumArray( const std::string & colname ) const
00643 {
00644 #ifdef HAVE_NUMARRAY
00645 if (m_type == "NumArrayTuple") {
00646 NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00647 boost::python::numeric::array a = nt->getNumArray(colname);
00648 return a;
00649 }
00650
00651 #ifdef HAVE_ROOT
00652 if ( m_type == "RootNTuple" ) {
00653 QtRootNTuple * tuple = dynamic_cast < QtRootNTuple *> ( m_dataSource );
00654 boost::python::numeric::array a = tuple -> getColumnAsArray ( colname );
00655 return a;
00656 }
00657 #endif
00658
00659 typedef std::vector<double> vec;
00660 const vec & array = m_dataSource->getColumn(colname);
00661 std::vector < int > shape;
00662 m_dataSource -> fillShape ( shape, colname );
00663 numeric::array na
00664 = num_util::makeNum ( &const_cast<vec &>( array )[0], shape );
00665 return na;
00666 #else
00667 throw std::runtime_error ("HippoDraw was not built with "
00668 "numeric Python support" );
00669 #endif // HAVE_NUMARRAY
00670 }
00671
00672 boost::python::numeric::array
00673 PyDataSource::
00674 columnAsNumArray ( unsigned int index ) const {
00675 #ifdef HAVE_NUMARRAY
00676 if ( index < columns() ) {
00677 if (m_type == "NumArrayTuple") {
00678 NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00679 return nt->getNumArray(index);
00680 }
00681 typedef std::vector<double> vec;
00682 const vec & array = m_dataSource->getColumn(index);
00683 std::vector < int > shape;
00684 m_dataSource -> fillShape ( shape, index );
00685 numeric::array na =
00686 num_util::makeNum ( &const_cast <vec &> ( array )[0], shape );
00687 return na;
00688 } else {
00689 throw StopIteration("index out-of-range");
00690 }
00691 #else
00692 throw std::runtime_error ( "HippoDraw was not built with "
00693 "numeric Python support" );
00694 #endif
00695 }
00696
00697 void
00698 PyDataSource::
00699 checkRank ( boost::python::numeric::array array )
00700 {
00701 #ifdef HAVE_NUMARRAY
00702 int rank = num_util::rank ( array );
00703 if ( rank > 1 ) {
00704 std::string what ( "DataArray: Can not add " );
00705 what += hippodraw::String::convert ( rank );
00706 what += " dimensional array\n to ";
00707 what += m_type;
00708 throw std::runtime_error ( what );
00709 }
00710 #endif
00711 }
00712
00713 void
00714 PyDataSource::
00715 saveColumn ( const std::string & label,
00716 const std::vector < double > & v,
00717 const std::vector < intptr_t > & shape )
00718 {
00719 if ( hasColumn ( label ) ) {
00720 m_dataSource -> replaceColumn ( label, v, shape );
00721 } else {
00722 m_dataSource -> addColumn ( label, v, shape );
00723 }
00724 }
00725
00726 void
00727 PyDataSource::
00728 saveColumnFromNumArray ( const std::string & label,
00729 boost::python::numeric::array array )
00730 {
00731 #ifdef HAVE_NUMARRAY
00732 PyApp::lock ();
00733 if (m_type == "NumArrayTuple") {
00734 if (hasColumn(label)) {
00735 replaceColumn(label, array);
00736 } else {
00737 addColumn(label, array);
00738 }
00739 PyApp::unlock();
00740 return;
00741 }
00742
00743 #ifdef HAVE_CFITSIO
00744 FitsNTuple * fnt = dynamic_cast < FitsNTuple * > ( m_dataSource );
00745 if ( fnt != 0 ) {
00746 std::vector < double > vec;
00747 ::extractVector ( array, vec );
00748
00749 const std::vector < intptr_t > shape = num_util::shape ( array );
00750 saveColumn ( label, vec, shape );
00751
00752 PyApp::unlock();
00753 return;
00754 }
00755 #endif // cfitsio
00756
00757 if (m_type == "ListTuple") {
00758 boost::python::list seq(array);
00759 ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
00760 if (hasColumn(label)) {
00761 nt->replaceColumn(label, seq);
00762 } else {
00763 nt->addColumn(label, seq);
00764 }
00765 PyApp::unlock();
00766 return;
00767 }
00768
00769 checkRank ( array );
00770 std::vector<double> col;
00771 ::extractVector(array, col);
00772
00773 if (m_type == "NTuple") {
00774 NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
00775 if (hasColumn(label)) {
00776 m_dataSource ->replaceColumn ( label, col );
00777 } else {
00778 nt->addColumn(label, col);
00779 }
00780 PyApp::unlock();
00781 return;
00782 }
00783
00784
00785 #ifdef HAVE_ROOT
00786 RootNTuple * rnt = dynamic_cast < RootNTuple * > ( m_dataSource );
00787 if ( rnt != 0 ) {
00788 if ( hasColumn ( label ) ) {
00789 m_dataSource -> replaceColumn ( label, col );
00790 } else {
00791 rnt -> addColumn ( label, col );
00792 }
00793 PyApp::unlock();
00794 return;
00795 }
00796 #endif // root
00797 PyApp::unlock();
00798
00799 throw std::runtime_error("__setitem__ not supported for " + m_type);
00800 #else
00801 throw std::runtime_error ("HippoDraw was not built with "
00802 "numeric Python support" );
00803 #endif
00804 }
00805
00808 void PyDataSource::
00809 saveColumnFromNumArray( unsigned int index,
00810 boost::python::numeric::array array )
00811 {
00812 #ifdef HAVE_NUMARRAY
00813 if ( index < columns()) {
00814
00815 if (m_type == "NumArrayTuple") {
00816 replaceColumn(index, array);
00817 return;
00818
00819 } else if (m_type == "NTuple") {
00820 checkRank ( array );
00821 std::vector<double> col;
00822 ::extractVector(array, col);
00823 NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
00824 nt->replaceColumn(index, col);
00825 return;
00826
00827 } else if (m_type == "ListTuple") {
00828 boost::python::list seq(array);
00829 ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
00830 nt->replaceColumn(index, seq);
00831 return;
00832 }
00833 #ifdef HAVE_CFITSIO
00834 else {
00835 FitsNTuple * fnt = dynamic_cast < FitsNTuple * > ( m_dataSource );
00836 if ( fnt != 0 ) {
00837 std::vector<double> col;
00838 ::extractVector ( array, col );
00839 const std::vector < intptr_t > shape = num_util::shape ( array );
00840 fnt -> replaceColumn ( index, col, shape );
00841 return;
00842 }
00843 }
00844 #endif
00845 throw std::runtime_error
00846 ("__setitem__ by index is not supported for " + m_type);
00847 } else {
00848 std::string what ( "DataArray:: Attempt to save column " );
00849 what += hippodraw::String::convert ( index );
00850 what += " with ";
00851 what += hippodraw::String::convert ( columns () );
00852 what += " columns in data source";
00853 throw std::runtime_error ( what );
00854 }
00855 #else
00856 throw std::runtime_error ( "HippoDraw was not built with "
00857 "numeric Python support" );
00858 #endif
00859 }
00860
00861
00862 void
00863 PyDataSource::
00864 saveColumnFrom ( const std::string & label,
00865 const std::vector < double > & array )
00866 {
00867 if ( hasColumn ( label ) ) {
00868 m_dataSource -> replaceColumn ( label, array );
00869 }
00870 else {
00871 m_dataSource -> addColumn ( label, array );
00872 }
00873 }
00874
00875 void
00876 PyDataSource::
00877 addRow ( const std::vector < double > & row )
00878 {
00879 PyApp::lock ();
00880 try {
00881 m_dataSource -> addRow ( row );
00882 }
00883 catch ( const std::runtime_error & e ) {
00884 PyApp::unlock ();
00885 throw e;
00886 }
00887 PyApp::unlock ();
00888 }
00889
00890 void
00891 PyDataSource::
00892 append ( const DataSource * source )
00893 {
00894 PyApp::lock ();
00895 m_dataSource -> append ( source );
00896 PyApp::unlock ();
00897 }
00898 void
00899 PyDataSource::
00900 append ( const PyDataSource * source )
00901 {
00902 m_dataSource -> append ( & source -> dataSource() );
00903 }