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 {
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 { // not contiguous
00115       const numeric::array & my_array = array;
00116       int rank = num_util::rank ( my_array );
00117       if ( rank < 2 ) { // rank 1
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 { // rank > 1
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 } // namespace
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:: * ) // fptr
00244                ( unsigned int ) const) // function signature
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:: * ) // fptr
00254                ( const std::string & ) const) // function signature
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:: * ) // fptr
00271                ( unsigned int index, const std::vector<double> & ) )
00272              &PyDataSource::replaceColumn )
00273 
00274 #ifdef HAVE_NUMARRAY      
00275       .def ( "replaceColumn", 
00276              ( void (PyDataSource:: * ) // fptr
00277                ( const std::string &, numeric::array ) ) // function signature
00278              &PyDataSource::replaceColumn )
00279       
00280       .def ( "replaceColumn", 
00281              ( void (PyDataSource:: * ) // fptr
00282                ( unsigned int index, numeric::array ) ) // function signature
00283              &PyDataSource::replaceColumn )
00284 #endif
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    
00393 } // namespace Python
00394 } // namespace hippodraw
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 }

Generated for HippoDraw Class Library by doxygen