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

Generated for HippoDraw Class Library by doxygen