PyDataSource.cxx

Go to the documentation of this file.
00001 
00013 #ifdef HAVE_CONFIG_H
00014 // for root and cfitsio
00015 #include "config.h"
00016 #endif
00017 
00018 // For truncation warning
00019 #ifdef _MSC_VER
00020 #include "msdevstudio/MSconfig.h"
00021 #endif
00022 
00023 // include first to avoid _POSIX_C_SOURCE warning.
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 hippodraw {
00052   namespace Python {
00053 
00057 // template < typename T >
00058 // void copy_direct ( boost::python::numeric::array array,
00059 //                 std::vector<double > & col )
00060 // {
00061 //   T * data = reinterpret_cast < T * > ( num_util::data ( array ) );
00062 //   int size = num_util::size ( array );
00063 //   std::copy ( data, data+ size, back_inserter( col ) );
00064 // }
00065 
00066 //   /** Extracts a vector from the numarray object. Extracts a vector
00067 //       from the numarray object @a array and fills the vector @a col.
00068 //       If @a array is contiguous, copies the data directly, otherwise
00069 //       copies the data element by element.
00070 //    */
00071 //    void extractVector ( boost::python::numeric::array array,
00072 //                      std::vector<double> & col )
00073 // {
00074 //   PyArray_TYPES type = num_util::type ( array );
00075 
00076 //   if ( num_util::iscontiguous ( array ) &&
00077 //        type != PyArray_NOTYPE ) {
00078 //     switch ( type )
00079 //       {
00080 // #ifdef HAVE_NUMPY
00081 //       case PyArray_BOOL:
00082 //      copy_direct < bool > ( array, col );
00083 //      break;
00084 // #endif
00085 //       case PyArray_CHAR:
00086 //      copy_direct < char > ( array, col );
00087 //      break;
00088 
00089 //       case PyArray_SHORT :
00090 //      copy_direct < short > ( array, col );
00091 //      break;
00092 
00093 //       case PyArray_INT :
00094 //      copy_direct < int > ( array, col );
00095 //      break;
00096 
00097 //       case PyArray_UINT :
00098 //      copy_direct < unsigned int > ( array, col );
00099 //      break;
00100 //       case PyArray_FLOAT :
00101 //      copy_direct < float > ( array, col );
00102 //      break;
00103 //       case PyArray_DOUBLE :
00104 //      copy_direct < double > ( array, col );
00105 //      break;
00106 
00107 //       default:
00108 //      std::string what ( "DataArray: Array type `" );
00109 //      what += num_util::type2string ( type );
00110 //      what += "' not supported.";
00111 //      throw std::runtime_error ( what );
00112 //      break;
00113 //       }
00114 //   }
00115 //   else { // not contiguous
00116 //       const numeric::array & my_array = array;
00117 //       int rank = num_util::rank ( my_array );
00118 //       if ( rank < 2 ) { // rank 1
00119 //      int size = num_util::size( my_array );
00120 //      col.clear();
00121 //      col.reserve(size);
00122 //      for (int i = 0; i < size; i++) {
00123 //        boost::python::object result = my_array[i];
00124 //        col.push_back( boost::python::extract<double>(result) );
00125 //      }
00126 //       }
00127 //       else { // rank > 1
00128 //      boost::python::object tarray = array.getflat();
00129 //      int size = num_util::size ( array );
00130 //      for ( int i = 0; i < size; i++ ) {
00131 //        boost::python::object result = tarray[i];
00132 //        col.push_back ( boost::python::extract < double > ( result ) );
00133 //      }
00134 //       }
00135 //   } 
00136 
00137 // }
00138 } // namespace
00139 } // namespace
00140 #endif
00141 
00142 namespace hippodraw {
00143 namespace Python {
00144 
00145 void PyDataSourceExceptionTranslator( const PyDataSource::StopIteration & e ) {
00146    PyErr_SetString ( PyExc_StopIteration, e.what() );
00147 }
00148 
00149 void
00150 export_DataArray()
00151 {
00152    class_ < PyDataSource >
00153      ( "DataArray",
00154        "A DataArray wraps a DataSource object so that numerical Python\n"
00155        "arrays can be used as both input and output.   The numerical array\n"
00156        "can be either a numarray.array or Numeric.array depending on\n"
00157        "how the hippo module was configured.\n"
00158        "\n"
00159        "Access to the array is done like a Python list or dictionary.\n"
00160        "\tarray = my_data_array [ index ] # list form\n"
00161        "\tarray = my_data_array [ 'my_label' ] # dict form\n"
00162        "\n"
00163        "Storage to the array is also done like a Python list or dictionary.\n"
00164        "\tmy_data_array [ index ] = ... # list form\n"
00165        "\tmy_data_array [ 'my_label' ] = ... # dict form\n" )
00166 
00167       .def ( init < const std::string & > (
00168              "DataArray ( string ) -> DataArray\n"
00169              "\n"
00170              "Creates a DataArray.   The string can be one of\n"
00171              "\tListTuple\n"
00172              "\tNTuple\n"
00173              "\tNumArrayTuple" ) )
00174 
00175       .add_property ( "columns", 
00176                       &PyDataSource::columns )
00177       
00178       .add_property ( "rows",
00179                       &PyDataSource::rows )
00180 
00181      .def ( "getCurrent",
00182             &PyDataSource::getCurrentDataSource,
00183             return_value_policy < reference_existing_object > (),
00184             "getCurrent () -> DataArray\n"
00185             "\n"
00186             "Returns a DataArray that wraps the current DataSource." )
00187 
00188      .staticmethod ( "getCurrent" )
00189 
00190      .def ( "dataSource",
00191             &PyDataSource::dataSource,
00192             return_value_policy < reference_existing_object > (),
00193             "dataSource () -> DataSource\n"
00194             "\n"
00195             "Returns reference to underlying DataSource"  )
00196 
00197       .def ( "getTitle", 
00198              &PyDataSource::getTitle,
00199              return_value_policy < copy_const_reference > (),
00200              "getTitle () -> string\n"
00201              "\n"
00202              "Returns title of the DataSource." )
00203 
00204       .def ( "setName",
00205              &PyDataSource::setName,
00206              "setName ( string ) -> None\n"
00207              "\n"
00208              "Sets the name of the DataSource. The name should be unique\n"
00209              "with one application and may appear in the Inspector panel." )
00210       
00211       .def ( "setTitle",
00212              &PyDataSource::setTitle,
00213              "setTitle ( string ) -> None\n"
00214              "\n"
00215              "Sets the title of the DataSource.  The title is what appears,\n"
00216              "by default, at the top of a Display." )
00217            
00218       .def ( "getLabels",
00219              &PyDataSource::getLabels,
00220              return_value_policy < copy_const_reference > (),
00221              "getLabels () -> list\n"
00222              "\n"
00223              "Returns the list of string objects of column labels." )
00224       
00225       .def ( "addColumn", 
00226              ( int (PyDataSource:: * )
00227                (const std::string &, const std::vector<double> &) )
00228              &PyDataSource::addColumn,
00229              "addColumn ( string, list ) -> value\n"
00230              "addColumn ( string, array ) -> value\n"
00231              "\n"
00232              "Adds a column. The string will be the label of the column.\n"
00233              "A copy of the list or array values will be the contents.\n"
00234              "The second form is only available if HippoDraw was configured\n"
00235              "with numerical Python support. Returns the new column's index." )
00236              
00237 #ifdef HAVE_NUMARRAY      
00238       .def ( "addColumn", 
00239              ( int (PyDataSource:: * )
00240                (const std::string &, boost::python::numeric::array) )
00241              &PyDataSource::addColumn )
00242 #endif
00243              
00244       .def ( "getColumn", 
00245              ( const std::vector < double > & (PyDataSource:: * ) // fptr
00246                ( unsigned int ) const) // function signature
00247              &PyDataSource::getColumn,
00248              return_value_policy < copy_const_reference> (),
00249              "getColumn ( value ) -> list\n"
00250              "\n"
00251              "Returns a column as list of floats.  'value' maybe either\n"
00252              "the column label or its index." )
00253 
00254       .def ( "getColumn", 
00255              ( const std::vector < double > & (PyDataSource:: * ) // fptr
00256                ( const std::string & ) const) // function signature
00257              &PyDataSource::getColumn,
00258              return_value_policy < copy_const_reference> () )
00259       
00260       .def ( "replaceColumn", 
00261              ( void (PyDataSource:: * )
00262                ( const std::string &, const std::vector<double> & ) )
00263              &PyDataSource::replaceColumn,
00264              "replaceColumn ( value, list ) -> None\n"
00265              "replaceColumn ( value, array ) -> None\n"
00266              "\n"
00267              "Replace column by its label or index.  The second form is \n"
00268              "only available if HippoDraw was configure with numerical\n"
00269              "arrays." )
00270       
00271       .def ( "replaceColumn", 
00272              ( void (PyDataSource:: * ) // fptr
00273                ( unsigned int index, const std::vector<double> & ) )
00274              &PyDataSource::replaceColumn )
00275 
00276       .def ( "replaceColumn", 
00277              ( void (PyDataSource:: * ) // fptr
00278                ( const std::string &, numeric::array ) ) // function signature
00279              &PyDataSource::replaceColumn )
00280       
00281       .def ( "replaceColumn", 
00282              ( void (PyDataSource:: * ) // fptr
00283                ( unsigned int index, numeric::array ) ) // function signature
00284              &PyDataSource::replaceColumn )
00285 
00286 // comment out until implemented for ListTuple and NumArrayTuple
00287 //       .def ( "clear",
00288 //              &PyDataSource::clear,
00289 //              "Clears the data elements of the DataSource" )
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      // The following must come before the other __setitem__ so that
00321      // it is seen last, otherwise a numarray gets converted to
00322      // vector.
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:: * ) // function pointer
00339               ( const DataSource * ) ) // signature
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:: * ) // function pointer
00348               ( const PyDataSource * ) ) // signature
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 } // namespace Python
00393 } // namespace hippodraw
00394 
00395 using namespace hippodraw;
00396 
00397 PyDataSource::PyDataSource() {
00398    m_type = "NTuple";
00399    m_dataSource = new NTuple();
00400 }
00401 
00402 PyDataSource::
00403 PyDataSource ( const std::string & name, DataSource * source )
00404   : m_type ( name ),
00405     m_dataSource ( source )
00406 {
00407 }
00408 
00412 PyDataSource::
00413 PyDataSource(const std::string & dataSource)
00414   : m_type(dataSource) {
00415    if (dataSource == "ListTuple") {
00416       m_dataSource = new ListTuple();
00417    } else if (dataSource == "NTuple") {
00418       m_dataSource = new NTuple();
00419 #ifdef HAVE_NUMARRAY
00420    } else if (dataSource == "NumArrayTuple") {
00421       m_dataSource = new NumArrayTuple();
00422 #else
00423    } else if (dataSource == "NumArrayTuple") {
00424       throw std::runtime_error ("HippoDraw was not built with "
00425                                 "numeric Python soupport" );
00426 #endif
00427    } else {
00428       throw std::runtime_error("Invalid DataSource: " + dataSource);
00429    }
00430 }
00431 
00432 PyDataSource::
00433 ~PyDataSource()
00434 {
00435    delete m_dataSource;
00436 }
00437 
00438 template < typename T >
00439 void
00440 PyDataSource::
00441 copy_direct ( boost::python::numeric::array array,
00442               std::vector<double > & col )
00443 {
00444 #ifdef HAVE_NUMARRAY
00445   T * data = reinterpret_cast < T * > ( num_util::data ( array ) );
00446   int size = num_util::size ( array );
00447   std::copy ( data, data+ size, back_inserter( col ) );
00448 #endif
00449 }
00450 
00451 void 
00452 PyDataSource::
00453 extractVector ( boost::python::numeric::array array,
00454                 std::vector<double> & col )
00455 {
00456 #ifdef HAVE_NUMARRAY
00457   PyArray_TYPES type = num_util::type ( array );
00458 
00459   if ( num_util::iscontiguous ( array ) &&
00460        type != PyArray_NOTYPE ) {
00461     switch ( type )
00462       {
00463 #ifdef HAVE_NUMPY
00464       case PyArray_BOOL:
00465         copy_direct < bool > ( array, col );
00466         break;
00467 #endif
00468       case PyArray_CHAR:
00469         copy_direct < char > ( array, col );
00470         break;
00471 
00472       case PyArray_SHORT :
00473         copy_direct < short > ( array, col );
00474         break;
00475 
00476       case PyArray_INT :
00477         copy_direct < int > ( array, col );
00478         break;
00479 
00480       case PyArray_UINT :
00481         copy_direct < unsigned int > ( array, col );
00482         break;
00483       case PyArray_FLOAT :
00484         copy_direct < float > ( array, col );
00485         break;
00486       case PyArray_DOUBLE :
00487         copy_direct < double > ( array, col );
00488         break;
00489 
00490       default:
00491         std::string what ( "DataArray: Array type `" );
00492         what += num_util::type2string ( type );
00493         what += "' not supported.";
00494         throw std::runtime_error ( what );
00495         break;
00496       }
00497   }
00498   else { // not contiguous
00499       const numeric::array & my_array = array;
00500       int rank = num_util::rank ( my_array );
00501       if ( rank < 2 ) { // rank 1
00502         int size = num_util::size( my_array );
00503         col.clear();
00504         col.reserve(size);
00505         for (int i = 0; i < size; i++) {
00506           boost::python::object result = my_array[i];
00507           col.push_back( boost::python::extract<double>(result) );
00508         }
00509       }
00510       else { // rank > 1
00511         boost::python::object tarray = array.getflat();
00512         int size = num_util::size ( array );
00513         for ( int i = 0; i < size; i++ ) {
00514           boost::python::object result = tarray[i];
00515           col.push_back ( boost::python::extract < double > ( result ) );
00516         }
00517       }
00518   } 
00519 #endif
00520 }
00521 
00522 PyDataSource *
00523 PyDataSource::
00524 getCurrentDataSource ()
00525 {
00526   PyDataSource * array = 0;
00527 
00528   DataSourceController * controller = DataSourceController::instance ();
00529   DataSource * source = controller -> getCurrent ();
00530 
00531   if ( source != 0 ) {
00532     NTuple * ntuple = dynamic_cast < NTuple * > ( source );
00533     if ( ntuple != 0 ) {
00534       array = new PyDataSource ( "NTuple", source );
00535     }
00536 
00537     ListTuple * ltuple = dynamic_cast < ListTuple * > ( source );
00538     if ( ltuple != 0 ) {
00539       array = new PyDataSource ( "ListTuple", source );
00540     }
00541 
00542 #ifdef HAVE_NUMARRAY
00543     NumArrayTuple * natuple = dynamic_cast < NumArrayTuple * > ( source );
00544     if ( natuple != 0 ) {
00545       array = new PyDataSource ( "NumArrayTuple", source );
00546     }
00547 #endif
00548 
00549 #ifdef HAVE_CFITSIO
00550     FitsNTuple * fntuple = dynamic_cast < FitsNTuple * > ( source );
00551     if ( fntuple != 0 ) {
00552       array = new PyDataSource ( "FitsNTuple", source );
00553     }
00554 #endif
00555 
00556 #ifdef HAVE_ROOT
00557     RootNTuple * rntuple = dynamic_cast < RootNTuple * > ( source );
00558     if ( rntuple != 0 ) {
00559       array = new PyDataSource ( "RootNTuple", source );
00560     }
00561 #endif
00562   }
00563 
00564 
00565   return array;
00566 }
00567 
00568 unsigned int PyDataSource::columns() const {
00569    return m_dataSource->columns();
00570 }
00571 
00572 unsigned int PyDataSource::rows() const {
00573    return m_dataSource->rows();
00574 }
00575 
00576 const std::string & PyDataSource::getTitle() const {
00577    return m_dataSource->title();
00578 }
00579 
00580 void PyDataSource::setTitle(const std::string & title) {
00581    m_dataSource->setTitle(title);
00582 }
00583 
00584 void PyDataSource::setName(const std::string & name) {
00585    m_dataSource->setName(name);
00586 }
00587 
00588 const std::vector<std::string> & PyDataSource::getLabels() const {
00589    return m_dataSource->getLabels();
00590 }
00591 
00592 const std::vector<double> & 
00593 PyDataSource::getColumn(const std::string & name) const {
00594    return m_dataSource->getColumn(name);
00595 }
00596 
00597 const std::vector<double> & 
00598 PyDataSource::getColumn(unsigned int index) const {
00599    return m_dataSource->getColumn(index);
00600 }
00601 
00602 void
00603 PyDataSource::
00604 replaceColumn (const std::string & label,
00605                const std::vector < double > & col )
00606 {
00607    if ( m_type == "NTuple" || 
00608         m_type == "FitsNTuple" ||
00609         m_type == "RootNTuple" ) {
00610      m_dataSource -> replaceColumn ( label, col );
00611    } else if (m_type == "ListTuple") {
00612       ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
00613       boost::python::list seq(col);
00614       nt->replaceColumn(label, seq);
00615    } else {
00616       std::string what("Cannot replace a column of this type in a " + m_type);
00617       throw std::runtime_error(what);
00618    }
00619 }
00620 
00621 void
00622 PyDataSource::
00623 replaceColumn ( unsigned int index,
00624                 const std::vector < double > & col)
00625 {
00626    const std::vector<std::string> & names = m_dataSource->getLabels();
00627    if ( index < names.size() ) {
00628       replaceColumn(names[index], col);
00629    } else {
00630       std::string what ( "Invalid column index: " );
00631       what += hippodraw::String::convert ( index );
00632       throw std::runtime_error ( what );
00633    }
00634 }
00635 
00636 void
00637 PyDataSource::
00638 replaceColumn ( const std::string & label,
00639                 boost::python::numeric::array array)
00640 {
00641 #ifdef HAVE_NUMARRAY
00642    NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00643    if (!nt) {
00644       std::string what("Cannot replace a column of this type in a " + m_type);
00645       throw std::runtime_error(what);
00646    }
00647    nt->replaceColumn(label, array);
00648 #else
00649    throw std::runtime_error ( "HippoDraw was not built with "
00650                               "numeric Python suppport" );
00651 #endif
00652 }
00653 
00654 void
00655 PyDataSource::
00656 replaceColumn ( unsigned int index,
00657                 boost::python::numeric::array array )
00658 {
00659 #ifdef HAVE_NUMARRAY
00660    NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00661    if (!nt) {
00662       std::string what("Cannot replace a column of this type in a " + m_type);
00663       throw std::runtime_error(what);
00664    }
00665    nt->replaceColumn(index, array);
00666 #else
00667    throw std::runtime_error ( "HippoDraw was not built with "
00668                               "numeric Python suppport" );
00669 #endif
00670 }
00671 
00672 int PyDataSource::addColumn( const std::string & label,
00673                              const std::vector<double> & col ) {
00674    if (m_type == "NTuple") {
00675       NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
00676       return nt->addColumn(label, col);
00677    } else if (m_type == "ListTuple") {
00678       ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
00679       boost::python::list seq(col);
00680       return nt->addColumn(label, seq);
00681    } else {
00682       std::string what("Cannot add a column of this type to a " + m_type);
00683       throw std::runtime_error(what);
00684    }
00685    return m_dataSource->columns();
00686 }
00687 
00688 int PyDataSource::addColumn( const std::string & label, 
00689                              boost::python::numeric::array array ) {
00690 #ifdef HAVE_NUMARRAY
00691    NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00692    if (!nt) {
00693       std::string what("Cannot add a column of this type to a " + m_type);
00694       throw std::runtime_error(what);
00695    }
00696    return nt->addColumn(label, array);
00697 #else
00698    throw std::runtime_error ( "HippoDraw was not built with "
00699                               "numeric Python support" );
00700 #endif
00701 }
00702 
00703 void PyDataSource::clear() {
00704    m_dataSource->clear();
00705 }
00706 
00707 bool PyDataSource::hasColumn(const std::string & colname) const {
00708    const std::vector<std::string> & names = getLabels();
00709    return std::find(names.begin(), names.end(), colname) != names.end();
00710 }
00711 
00712 void PyDataSource::registerNTuple( const std::string & name ) {
00713    m_dataSource->setName(name);
00714    DataSourceController * controller  = DataSourceController::instance();
00715    controller->registerNTuple(name, m_dataSource);
00716 }
00717 
00718 std::string PyDataSource::registerNTuple() {
00719    DataSourceController * controller  = DataSourceController::instance();
00720    return controller->registerNTuple(m_dataSource);
00721 }
00722 
00723 boost::python::numeric::array
00724 PyDataSource::
00725 columnAsNumArray( const std::string & colname ) const
00726 {
00727 #ifdef HAVE_NUMARRAY
00728   if (m_type == "NumArrayTuple") {
00729       NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00730       boost::python::numeric::array a = nt->getNumArray(colname);
00731       return a;
00732    }
00733 
00734 #ifdef HAVE_ROOT
00735    if ( m_type == "RootNTuple" ) {
00736      QtRootNTuple * tuple = dynamic_cast < QtRootNTuple *> ( m_dataSource );
00737      boost::python::numeric::array a = tuple -> getColumnAsArray ( colname );
00738      return a;
00739    }
00740 #endif
00741 
00742    typedef std::vector<double> vec;
00743    const vec & array = m_dataSource->getColumn(colname);
00744    std::vector < int > shape;
00745    m_dataSource -> fillShape ( shape, colname );
00746    numeric::array na 
00747      = num_util::makeNum ( &const_cast<vec &>( array )[0], shape );
00748    return na;
00749 #else
00750    throw std::runtime_error ("HippoDraw was not built with "
00751                              "numeric Python support" );
00752 #endif // HAVE_NUMARRAY
00753 }
00754 
00755 boost::python::numeric::array
00756 PyDataSource::
00757 columnAsNumArray ( unsigned int index ) const {
00758 #ifdef HAVE_NUMARRAY
00759    if ( index < columns() ) {
00760       if (m_type == "NumArrayTuple") {
00761          NumArrayTuple * nt = dynamic_cast<NumArrayTuple *>(m_dataSource);
00762          return nt->getNumArray(index);
00763       } 
00764       typedef std::vector<double> vec;
00765       const vec & array = m_dataSource->getColumn(index);
00766       std::vector < int > shape;
00767       m_dataSource -> fillShape ( shape, index );
00768       numeric::array na = 
00769         num_util::makeNum ( &const_cast <vec &> ( array )[0], shape );
00770       return na;
00771    } else {
00772       throw StopIteration("index out-of-range");
00773    }
00774 #else
00775    throw std::runtime_error ( "HippoDraw was not built with "
00776                               "numeric Python support" );
00777 #endif
00778 }
00779 
00780 void
00781 PyDataSource::
00782 checkRank ( boost::python::numeric::array array )
00783 {
00784 #ifdef HAVE_NUMARRAY
00785   int rank = num_util::rank ( array );
00786   if ( rank > 1 ) {
00787     std::string what ( "DataArray: Can not add " );
00788     what += hippodraw::String::convert ( rank );
00789     what += " dimensional array\n to ";
00790     what += m_type;
00791     throw std::runtime_error ( what );
00792   }
00793 #endif
00794 }
00795 
00796 void
00797 PyDataSource::
00798 saveColumn ( const std::string & label,
00799              const std::vector < double > & v,
00800              const std::vector < intptr_t > & shape )
00801 {
00802   if ( hasColumn ( label ) ) {
00803     m_dataSource -> replaceColumn ( label, v, shape  );
00804   } else {
00805     m_dataSource -> addColumn ( label, v, shape );
00806   }
00807 }
00808 
00809 void
00810 PyDataSource::
00811 saveColumnFromNumArray ( const std::string & label,
00812                          boost::python::numeric::array array )
00813 {
00814 #ifdef HAVE_NUMARRAY
00815   PyApp::lock ();
00816    if (m_type == "NumArrayTuple") {
00817       if (hasColumn(label)) {
00818          replaceColumn(label, array);
00819       } else {
00820          addColumn(label, array);
00821       }
00822       PyApp::unlock();
00823       return;
00824    }
00825 
00826 #ifdef HAVE_CFITSIO
00827    FitsNTuple * fnt = dynamic_cast < FitsNTuple * > ( m_dataSource );
00828    if ( fnt != 0 ) {
00829      std::vector < double > vec;
00830      extractVector ( array, vec );
00831 
00832      const std::vector < intptr_t > shape = num_util::shape ( array );
00833      saveColumn ( label, vec, shape );
00834 
00835       PyApp::unlock();
00836      return;
00837    }
00838 #endif // cfitsio
00839 
00840    if (m_type == "ListTuple") {
00841       boost::python::list seq(array);
00842       ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
00843       if (hasColumn(label)) {
00844          nt->replaceColumn(label, seq);
00845       } else {
00846          nt->addColumn(label, seq);
00847       }
00848       PyApp::unlock();
00849       return;
00850    }
00851 
00852    checkRank ( array );
00853    std::vector<double> col;
00854    extractVector(array, col);
00855 
00856    if (m_type == "NTuple") {
00857       NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
00858       if (hasColumn(label)) {
00859          m_dataSource ->replaceColumn ( label, col );
00860       } else {
00861          nt->addColumn(label, col);
00862       }
00863       PyApp::unlock();
00864       return;
00865    }
00866 
00867 
00868 #ifdef HAVE_ROOT
00869    RootNTuple * rnt = dynamic_cast < RootNTuple * > ( m_dataSource );
00870    if ( rnt != 0 ) {
00871      if ( hasColumn ( label ) ) {
00872        m_dataSource -> replaceColumn ( label, col );
00873      } else {
00874        rnt -> addColumn ( label, col );
00875      }
00876       PyApp::unlock();
00877      return;
00878    }
00879 #endif // root
00880    PyApp::unlock();
00881 
00882    throw std::runtime_error("__setitem__ not supported for " + m_type);
00883 #else
00884    throw std::runtime_error ("HippoDraw was not built with "
00885                              "numeric Python support" );
00886 #endif
00887 }
00888 
00891 void PyDataSource::
00892 saveColumnFromNumArray( unsigned int index,
00893                         boost::python::numeric::array array )
00894 {
00895 #ifdef HAVE_NUMARRAY
00896    if ( index < columns()) {
00897 
00898       if (m_type == "NumArrayTuple") {
00899          replaceColumn(index, array);
00900          return;
00901 
00902       } else if (m_type == "NTuple") {
00903          checkRank ( array );
00904          std::vector<double> col;
00905          extractVector ( array, col );
00906          NTuple * nt = dynamic_cast<NTuple *>(m_dataSource);
00907          nt->replaceColumn(index, col);
00908          return;
00909 
00910       } else if (m_type == "ListTuple") {
00911          boost::python::list seq(array);
00912          ListTuple * nt = dynamic_cast<ListTuple *>(m_dataSource);
00913          nt->replaceColumn(index, seq);
00914          return;
00915       }
00916 #ifdef HAVE_CFITSIO
00917       else {
00918         FitsNTuple * fnt = dynamic_cast < FitsNTuple * > ( m_dataSource );
00919         if ( fnt != 0 ) {
00920           std::vector<double> col;
00921           extractVector ( array, col );
00922           const std::vector < intptr_t > shape = num_util::shape ( array );
00923           fnt -> replaceColumn ( index, col, shape );
00924           return;
00925         }
00926       }
00927 #endif
00928          throw std::runtime_error
00929             ("__setitem__ by index is not supported for " + m_type);
00930    } else {
00931      std::string what ( "DataArray:: Attempt to save column " );
00932       what += hippodraw::String::convert ( index );
00933       what += " with ";
00934       what += hippodraw::String::convert ( columns () );
00935       what += " columns in data source";
00936       throw std::runtime_error ( what );
00937    }
00938 #else
00939    throw std::runtime_error ( "HippoDraw was not built with "
00940                               "numeric Python support" );
00941 #endif
00942 }
00943 
00944 
00945 void
00946 PyDataSource::
00947 saveColumnFrom ( const std::string & label,
00948                  const std::vector < double > & array )
00949 {
00950   if ( hasColumn ( label ) ) {
00951     m_dataSource -> replaceColumn ( label, array );
00952   }
00953   else {
00954     m_dataSource -> addColumn ( label, array );
00955   }
00956 }
00957 
00958 void
00959 PyDataSource::
00960 addRow ( const std::vector < double > & row )
00961 {
00962   PyApp::lock ();
00963   try {
00964     m_dataSource -> addRow ( row );
00965   }
00966   catch ( const std::runtime_error & e ) {
00967     PyApp::unlock ();
00968     throw e;
00969   }
00970   PyApp::unlock ();
00971 }
00972 
00973 void
00974 PyDataSource::
00975 append ( const DataSource * source )
00976 {
00977   PyApp::lock ();
00978   m_dataSource -> append ( source );
00979   PyApp::unlock ();
00980 }
00981 void
00982 PyDataSource::
00983 append ( const PyDataSource * source )
00984 {
00985   m_dataSource -> append ( & source -> dataSource() );
00986 }

Generated for HippoDraw Class Library by doxygen