ListTuple.cxx
Go to the documentation of this file.
00001 
00012 // include first to avoid _POSIX_C_SOURCE warning.
00013 #include <boost/python.hpp>
00014 
00015 #ifdef HAVE_CONFIG_H
00016 // for have smp and qt4
00017 #include "config.h"
00018 #endif
00019 
00020 #include "ListTuple.h"
00021 
00022 #include "axes/Range.h"
00023 
00024 #include <stdexcept>
00025 
00026 using namespace boost::python;
00027 
00028 using std::runtime_error;
00029 using std::string;
00030 using std::vector;
00031 
00032 namespace
00033 {
00043   unsigned int getSize ( const boost::python::list & sequence )
00044   {
00045 #ifdef HAVE_QT4
00046 #ifdef HAVE_SMP
00047     PyGILState_STATE gstate;
00048     gstate = PyGILState_Ensure ();
00049 #endif
00050 #endif
00051 
00052     object obj = sequence.attr ( "__len__" ) ();
00053     unsigned int size = extract < unsigned int > ( obj );
00054 
00055 #ifdef HAVE_QT4
00056 #ifdef HAVE_SMP
00057     PyGILState_Release ( gstate );
00058 #endif
00059 #endif
00060 
00061     return size;
00062   }
00063 }
00064 
00065 using namespace hippodraw;
00066 
00067 ListTuple::ListTuple ()
00068   : DataSource ()
00069 {
00070 }
00071 
00072 ListTuple::~ListTuple()
00073 {
00074 }
00075 
00076 void
00077 ListTuple::
00078 copy ( const DataSource & )
00079 {
00080   assert ( false );
00081 }
00082 
00083 void
00084 ListTuple::
00085 notifyObservers ( ) const
00086 {
00087   Observable::notifyObservers ();
00088 }
00089 
00090 unsigned int
00091 ListTuple::
00092 rows() const
00093 {
00094   unsigned int size = 0;
00095   if ( m_data.empty () == false ) {
00096     const boost::python::list & seq = m_data[0];
00097 
00098     size = getSize ( seq );
00099   }
00100 
00101   return size;
00102 }
00103 
00104 bool
00105 ListTuple::
00106 empty () const
00107 {
00108   return rows () == 0;
00109 }
00110 
00111 double
00112 ListTuple::
00113 valueAt( unsigned int row, unsigned int column ) const
00114 {
00115   assert ( column < m_data.size () );
00116   double value = 0; 
00117 
00118   const boost::python::list & seq = m_data[column];
00119 
00120   unsigned int size = getSize ( seq );
00121 
00122   assert ( row < size );
00123 
00124   object result = seq[row];
00125   value = extract < double > ( result );
00126 
00127   return value;
00128 }
00129 
00133 const std::vector < double > &
00134 ListTuple::
00135 getRow ( unsigned int row ) const
00136 {
00137   unsigned int size = m_data.size();
00138   m_row.resize ( size );
00139   for ( unsigned int column = 0; column < size; column++ ) {
00140     m_row [ column ] = valueAt ( row, column );
00141   }
00142 
00143   return m_row;
00144 }
00145 
00146 bool
00147 ListTuple::
00148 isAcceptable ( const  boost::python::list & array )
00149 {
00150   bool yes = true;
00151   unsigned int size = getSize ( array );
00152   for ( unsigned int i = 0; i < size; i++ ) {
00153     object obj = array[i];
00154     extract < double > check ( obj );
00155     if ( check.check() == false ) {
00156       yes = false;
00157       break;
00158     }
00159   }
00160   return yes;
00161 }
00162 
00165 int
00166 ListTuple::
00167 addColumn ( const std::string & label,
00168             boost::python::list array )
00169 {
00170   // Check if label already exists.
00171   int index = indexOf ( label );
00172   if ( index >= 0 ) {
00173     string what ( "ListTuple Attempt to add a column whose label"
00174                   " is same as other column." );
00175     throw runtime_error ( what );
00176   }
00177 
00178   unsigned int new_size = getSize ( array );
00179   // Check if column has right size.
00180   if ( m_data.empty () == false ) {
00181     unsigned int old_size = rows ();
00182 
00183     if ( old_size != 0 && old_size != new_size ) {
00184       string what ( "ListTuple Attempt to add a column whose size"
00185                     " is not equal to other columns." );
00186       throw runtime_error ( what );
00187     }
00188   }
00189   if ( isAcceptable ( array ) == false ) {
00190     string what ( "ListTuple: Attempt to add a column with one or more"
00191                   " elements not convertable to float" );
00192     throw runtime_error ( what );
00193   }
00194 
00195   m_data.push_back ( array );
00196   addLabel ( label );
00197 
00198   return m_data.size() - 1;
00199 }
00200 
00201 void
00202 ListTuple::
00203 replaceColumn ( unsigned int col, 
00204                 boost::python::list array )
00205 {
00206   unsigned int size = columns ();
00207   if ( col >= size ) {
00208     const string what ( "NunArrayTuple: column doesn't exist" );
00209     throw runtime_error ( what );
00210   }
00211 
00212   const boost::python::list & old_array = m_data[col];
00213   int old_size = getSize ( old_array );
00214   int new_size = getSize ( array );
00215 
00216   if ( old_size != 0 && old_size != new_size ) {
00217     const string what ( "ListTuple: Attempt to replace column with one "
00218                         "whose size is not equal to other columns." );
00219     throw runtime_error ( what );
00220   }
00221   m_data[col] = array;
00222 
00223   notifyObservers ();
00224 }
00225 
00226 void
00227 ListTuple::
00228 replaceColumn ( const std::string & column,
00229                 boost::python::list array )
00230 {
00231   unsigned int index = indexOf ( column );
00232 
00233   replaceColumn ( index, array );
00234 }
00235 
00236 void
00237 ListTuple::
00238 setShape ( std::vector < unsigned int > & shape )
00239 {
00240   m_shape = shape;
00241 }
00242 
00243 const vector < unsigned int > &
00244 ListTuple::
00245 getShape () const
00246 {
00247   return m_shape;
00248 }
00249 void
00250 ListTuple::
00251 clear ()
00252 {
00253   assert ( false );
00254 }
00255 
00256 void
00257 ListTuple::
00258 reserve ( unsigned int )
00259 {
00260   assert ( false );
00261 }
00262 
00263 double 
00264 ListTuple::
00265 operator [] (  std::vector < unsigned int > & /* indices */ ) const
00266 {
00267   assert ( false );
00268   return 0.0;
00269 }

Generated for HippoDraw Class Library by doxygen