00001
00012
00013 #include <boost/python.hpp>
00014
00015 #ifdef HAVE_CONFIG_H
00016
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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 using namespace hippodraw;
00066
00067 ListTuple::ListTuple ()
00068 : DataSource ()
00069 {
00070 }
00071
00072 ListTuple::~ListTuple()
00073 {
00074 }
00075
00076 unsigned int
00077 ListTuple::
00078 getSize ( const boost::python::list & sequence )
00079 {
00080 #ifdef HAVE_QT4
00081 #ifdef HAVE_SMP
00082 PyGILState_STATE gstate;
00083 gstate = PyGILState_Ensure ();
00084 #endif
00085 #endif
00086
00087 object obj = sequence.attr ( "__len__" ) ();
00088 unsigned int size = extract < unsigned int > ( obj );
00089
00090 #ifdef HAVE_QT4
00091 #ifdef HAVE_SMP
00092 PyGILState_Release ( gstate );
00093 #endif
00094 #endif
00095
00096 return size;
00097 }
00098
00099 void
00100 ListTuple::
00101 copy ( const DataSource & )
00102 {
00103 assert ( false );
00104 }
00105
00106 void
00107 ListTuple::
00108 notifyObservers ( ) const
00109 {
00110 Observable::notifyObservers ();
00111 }
00112
00113 unsigned int
00114 ListTuple::
00115 rows() const
00116 {
00117 unsigned int size = 0;
00118 if ( m_data.empty () == false ) {
00119 const boost::python::list & seq = m_data[0];
00120
00121 size = getSize ( seq );
00122 }
00123
00124 return size;
00125 }
00126
00127 bool
00128 ListTuple::
00129 empty () const
00130 {
00131 return rows () == 0;
00132 }
00133
00134 double
00135 ListTuple::
00136 valueAt( unsigned int row, unsigned int column ) const
00137 {
00138 assert ( column < m_data.size () );
00139 double value = 0;
00140
00141 const boost::python::list & seq = m_data[column];
00142
00143 unsigned int size = getSize ( seq );
00144
00145 assert ( row < size );
00146
00147 object result = seq[row];
00148 value = extract < double > ( result );
00149
00150 return value;
00151 }
00152
00156 const std::vector < double > &
00157 ListTuple::
00158 getRow ( unsigned int row ) const
00159 {
00160 unsigned int size = m_data.size();
00161 m_row.resize ( size );
00162 for ( unsigned int column = 0; column < size; column++ ) {
00163 m_row [ column ] = valueAt ( row, column );
00164 }
00165
00166 return m_row;
00167 }
00168
00169 bool
00170 ListTuple::
00171 isAcceptable ( const boost::python::list & array )
00172 {
00173 bool yes = true;
00174 unsigned int size = getSize ( array );
00175 for ( unsigned int i = 0; i < size; i++ ) {
00176 object obj = array[i];
00177 extract < double > check ( obj );
00178 if ( check.check() == false ) {
00179 yes = false;
00180 break;
00181 }
00182 }
00183 return yes;
00184 }
00185
00188 int
00189 ListTuple::
00190 addColumn ( const std::string & label,
00191 boost::python::list array )
00192 {
00193
00194 int index = indexOf ( label );
00195 if ( index >= 0 ) {
00196 string what ( "ListTuple Attempt to add a column whose label"
00197 " is same as other column." );
00198 throw runtime_error ( what );
00199 }
00200
00201 unsigned int new_size = getSize ( array );
00202
00203 if ( m_data.empty () == false ) {
00204 unsigned int old_size = rows ();
00205
00206 if ( old_size != 0 && old_size != new_size ) {
00207 string what ( "ListTuple Attempt to add a column whose size"
00208 " is not equal to other columns." );
00209 throw runtime_error ( what );
00210 }
00211 }
00212 if ( isAcceptable ( array ) == false ) {
00213 string what ( "ListTuple: Attempt to add a column with one or more"
00214 " elements not convertable to float" );
00215 throw runtime_error ( what );
00216 }
00217
00218 m_data.push_back ( array );
00219 addLabel ( label );
00220
00221 return m_data.size() - 1;
00222 }
00223
00224 void
00225 ListTuple::
00226 replaceColumn ( unsigned int col,
00227 boost::python::list array )
00228 {
00229 unsigned int size = columns ();
00230 if ( col >= size ) {
00231 const string what ( "NunArrayTuple: column doesn't exist" );
00232 throw runtime_error ( what );
00233 }
00234
00235 const boost::python::list & old_array = m_data[col];
00236 int old_size = getSize ( old_array );
00237 int new_size = getSize ( array );
00238
00239 if ( old_size != 0 && old_size != new_size ) {
00240 const string what ( "ListTuple: Attempt to replace column with one "
00241 "whose size is not equal to other columns." );
00242 throw runtime_error ( what );
00243 }
00244 m_data[col] = array;
00245
00246 notifyObservers ();
00247 }
00248
00249 void
00250 ListTuple::
00251 replaceColumn ( const std::string & column,
00252 boost::python::list array )
00253 {
00254 unsigned int index = indexOf ( column );
00255
00256 replaceColumn ( index, array );
00257 }
00258
00259 void
00260 ListTuple::
00261 setShape ( std::vector < unsigned int > & shape )
00262 {
00263 m_shape = shape;
00264 }
00265
00266 const vector < unsigned int > &
00267 ListTuple::
00268 getShape () const
00269 {
00270 return m_shape;
00271 }
00272 void
00273 ListTuple::
00274 clear ()
00275 {
00276 assert ( false );
00277 }
00278
00279 void
00280 ListTuple::
00281 reserve ( unsigned int )
00282 {
00283 assert ( false );
00284 }
00285
00286 double
00287 ListTuple::
00288 operator [] ( std::vector < unsigned int > & ) const
00289 {
00290 assert ( false );
00291 return 0.0;
00292 }