20 #include "msdevstudio/MSconfig.h"
24 #include <boost/python.hpp>
48 using namespace boost::python;
142 namespace hippodraw {
146 PyErr_SetString ( PyExc_StopIteration, e.
what() );
152 class_ < PyDataSource >
154 "A DataArray wraps a DataSource object so that numerical Python\n"
155 "arrays can be used as both input and output. The numerical array\n"
156 "can be either a numarray.array or Numeric.array depending on\n"
157 "how the hippo module was configured.\n"
159 "Access to the array is done like a Python list or dictionary.\n"
160 "\tarray = my_data_array [ index ] # list form\n"
161 "\tarray = my_data_array [ 'my_label' ] # dict form\n"
163 "Storage to the array is also done like a Python list or dictionary.\n"
164 "\tmy_data_array [ index ] = ... # list form\n"
165 "\tmy_data_array [ 'my_label' ] = ... # dict form\n" )
167 .def ( init < const std::string & > (
168 "DataArray ( string ) -> DataArray\n"
170 "Creates a DataArray. The string can be one of\n"
173 "\tNumArrayTuple" ) )
175 .add_property (
"columns",
176 &PyDataSource::columns )
178 .add_property (
"rows",
179 &PyDataSource::rows )
182 &PyDataSource::getCurrentDataSource,
183 return_value_policy < reference_existing_object > (),
184 "getCurrent () -> DataArray\n"
186 "Returns a DataArray that wraps the current DataSource." )
188 .staticmethod (
"getCurrent" )
191 &PyDataSource::dataSource,
192 return_value_policy < reference_existing_object > (),
193 "dataSource () -> DataSource\n"
195 "Returns reference to underlying DataSource" )
198 &PyDataSource::getTitle,
199 return_value_policy < copy_const_reference > (),
200 "getTitle () -> string\n"
202 "Returns title of the DataSource." )
205 &PyDataSource::setName,
206 "setName ( string ) -> None\n"
208 "Sets the name of the DataSource. The name should be unique\n"
209 "with one application and may appear in the Inspector panel." )
212 &PyDataSource::setTitle,
213 "setTitle ( string ) -> None\n"
215 "Sets the title of the DataSource. The title is what appears,\n"
216 "by default, at the top of a Display." )
219 &PyDataSource::getLabels,
220 return_value_policy < copy_const_reference > (),
221 "getLabels () -> list\n"
223 "Returns the list of string objects of column labels." )
227 (
const std::string &,
const std::vector<double> &) )
228 &PyDataSource::addColumn,
229 "addColumn ( string, list ) -> value\n"
230 "addColumn ( string, array ) -> value\n"
232 "Adds a column. The string will be the label of the column.\n"
233 "A copy of the list or array values will be the contents.\n"
234 "The second form is only available if HippoDraw was configured\n"
235 "with numerical Python support. Returns the new column's index." )
240 (
const std::string &, boost::python::numeric::array) )
241 &PyDataSource::addColumn )
246 (
unsigned int )
const)
247 &PyDataSource::getColumn,
248 return_value_policy < copy_const_reference> (),
249 "getColumn ( value ) -> list\n"
251 "Returns a column as list of floats. 'value' maybe either\n"
252 "the column label or its index." )
256 (
const std::string & )
const)
257 &PyDataSource::getColumn,
258 return_value_policy < copy_const_reference> () )
260 .def (
"replaceColumn",
262 (
const std::string &,
const std::vector<double> & ) )
263 &PyDataSource::replaceColumn,
264 "replaceColumn ( value, list ) -> None\n"
265 "replaceColumn ( value, array ) -> None\n"
267 "Replace column by its label or index. The second form is \n"
268 "only available if HippoDraw was configure with numerical\n"
271 .def (
"replaceColumn",
273 (
unsigned int index,
const std::vector<double> & ) )
274 &PyDataSource::replaceColumn )
276 .def (
"replaceColumn",
278 (
const std::string &, numeric::array ) )
279 &PyDataSource::replaceColumn )
281 .def (
"replaceColumn",
283 (
unsigned int index, numeric::array ) )
284 &PyDataSource::replaceColumn )
292 &PyDataSource::hasColumn,
293 "has_key ( string ) -> Boolean\n"
295 "Returns True if column with label exists.")
298 &PyDataSource::getLabels,
299 return_value_policy < copy_const_reference > (),
302 "Returns the list of column labels." )
306 &PyDataSource::registerNTuple,
307 "register ( string ) -> None\n"
308 "register ( ) -> string\n"
310 "Register the underlying DataSource with the\n"
311 "DataSourceController. The first form registers it with the\n"
312 "given name, while the second from returns a unique name\n"
313 "generated by the controller." )
317 &PyDataSource::registerNTuple )
323 .def (
"__setitem__",
324 &PyDataSource::saveColumnFrom,
325 "__setitem__ ( label, sequence ) -> None\n"
327 "Copies the contensts of the sequence. If column with label\n"
328 "already exists, replaces it, otherwise add a new column." )
331 &PyDataSource::addRow,
332 "addRow ( sequence ) -> None\n"
334 "Adds a row to the held DataSource object if supported, otherwise"
335 " throws Runtime exception." )
340 &PyDataSource::append,
341 "append ( DataArray ) -> None\n"
342 "append ( DataSource ) -> None\n"
344 "Appends contents of DataSource or DataArray to the DataArray." )
349 &PyDataSource::append )
352 .def (
"__getitem__",
354 (
const std::string & )
const )
355 &PyDataSource::columnAsNumArray,
356 return_value_policy < return_by_value > (),
357 "__getitem__ ( value ) -> array\n"
359 "Returns a copy of the column as numerical array. 'value' can\n"
360 "be either the column label or its index." )
362 .def (
"__getitem__",
364 (
unsigned int )
const )
365 &PyDataSource::columnAsNumArray,
366 return_value_policy < return_by_value > () )
368 .def (
"__setitem__",
370 (
const std::string &,
372 &PyDataSource::saveColumnFromNumArray,
373 return_value_policy < return_by_value > (),
374 "__setitem__ ( value, array ) -> None\n"
376 "Copies the contents of array. If `'value' is an index, then\n"
377 "replaces the contents of the existing column. If 'value' is\n"
378 "a label then either replaces existing column with that label\n"
379 "or adds a new column." )
381 .def (
"__setitem__",
385 &PyDataSource::saveColumnFromNumArray,
386 return_value_policy < return_by_value > () )
389 register_exception_translator<PyDataSource::StopIteration>
395 using namespace hippodraw;
397 PyDataSource::PyDataSource() {
399 m_dataSource =
new NTuple();
403 PyDataSource (
const std::string & name,
DataSource * source )
405 m_dataSource ( source )
414 : m_type(dataSource) {
415 if (dataSource ==
"ListTuple") {
417 }
else if (dataSource ==
"NTuple") {
420 }
else if (dataSource ==
"NumArrayTuple") {
423 }
else if (dataSource ==
"NumArrayTuple") {
424 throw std::runtime_error (
"HippoDraw was not built with "
425 "numeric Python soupport" );
428 throw std::runtime_error(
"Invalid DataSource: " + dataSource);
438 template <
typename T >
442 std::vector<double > & col )
447 std::copy ( data, data+ size, back_inserter( col ) );
449 throw std::runtime_error (
"HippoDraw was not built with "
457 std::vector<double> & col )
463 type != PyArray_NOTYPE ) {
468 copy_direct < bool > ( array, col );
472 copy_direct < char > ( array, col );
476 copy_direct < short > ( array, col );
480 copy_direct < int > ( array, col );
484 copy_direct < unsigned int > ( array, col );
487 copy_direct < float > ( array, col );
489 case PyArray_DOUBLE :
490 copy_direct < double > ( array, col );
494 std::string what (
"DataArray: Array type `" );
496 what +=
"' not supported.";
497 throw std::runtime_error ( what );
502 const numeric::array & my_array = array;
508 for (
int i = 0;
i <
size;
i++) {
509 boost::python::object result = my_array[
i];
510 col.push_back( boost::python::extract<double>(result) );
514 boost::python::object tarray = array.getflat();
516 for (
int i = 0;
i <
size;
i++ ) {
517 boost::python::object result = tarray[
i];
518 col.push_back ( boost::python::extract < double > ( result ) );
523 throw std::runtime_error (
"HippoDraw was not built with "
535 DataSource * source = controller -> getCurrent ();
550 if ( natuple != 0 ) {
557 if ( fntuple != 0 ) {
564 if ( rntuple != 0 ) {
598 const std::vector<double> &
603 const std::vector<double> &
611 const std::vector < double > & col )
613 if (
m_type ==
"NTuple" ||
615 m_type ==
"RootNTuple" ) {
617 }
else if (
m_type ==
"ListTuple") {
622 std::string what(
"Cannot replace a column of this type in a " +
m_type);
623 throw std::runtime_error(what);
630 const std::vector < double > & col)
633 if ( index < names.size() ) {
636 std::string what (
"Invalid column index: " );
638 throw std::runtime_error ( what );
645 boost::python::numeric::array array)
650 std::string what(
"Cannot replace a column of this type in a " +
m_type);
651 throw std::runtime_error(what);
655 throw std::runtime_error (
"HippoDraw was not built with "
656 "numeric Python suppport" );
663 boost::python::numeric::array array )
668 std::string what(
"Cannot replace a column of this type in a " +
m_type);
669 throw std::runtime_error(what);
673 throw std::runtime_error (
"HippoDraw was not built with "
674 "numeric Python suppport" );
679 const std::vector<double> & col ) {
683 }
else if (
m_type ==
"ListTuple") {
688 std::string what(
"Cannot add a column of this type to a " +
m_type);
689 throw std::runtime_error(what);
695 boost::python::numeric::array array ) {
699 std::string what(
"Cannot add a column of this type to a " +
m_type);
700 throw std::runtime_error(what);
704 throw std::runtime_error (
"HippoDraw was not built with "
705 "numeric Python support" );
714 const std::vector<std::string> & names =
getLabels();
715 return std::find(names.begin(), names.end(), colname) != names.end();
729 boost::python::numeric::array
734 if (
m_type ==
"NumArrayTuple") {
736 boost::python::numeric::array a = nt->
getNumArray(colname);
741 if (
m_type ==
"RootNTuple" ) {
743 boost::python::numeric::array a = tuple -> getColumnAsArray ( colname );
748 typedef std::vector<double>
vec;
750 std::vector < int >
shape;
756 throw std::runtime_error (
"HippoDraw was not built with "
757 "numeric Python support" );
758 #endif // HAVE_NUMARRAY
761 boost::python::numeric::array
766 if (
m_type ==
"NumArrayTuple") {
770 typedef std::vector<double>
vec;
772 std::vector < int >
shape;
781 throw std::runtime_error (
"HippoDraw was not built with "
782 "numeric Python support" );
793 std::string what (
"DataArray: Can not add " );
795 what +=
" dimensional array\n to ";
797 throw std::runtime_error ( what );
805 const std::vector < double > &
v,
806 const std::vector < intptr_t > &
shape )
818 boost::python::numeric::array array )
822 if (
m_type ==
"NumArrayTuple") {
835 std::vector < double >
vec;
846 if (
m_type ==
"ListTuple") {
859 std::vector<double> col;
888 throw std::runtime_error(
"__setitem__ not supported for " +
m_type);
890 throw std::runtime_error (
"HippoDraw was not built with "
891 "numeric Python support" );
899 boost::python::numeric::array array )
904 if (
m_type ==
"NumArrayTuple") {
908 }
else if (
m_type ==
"NTuple") {
910 std::vector<double> col;
916 }
else if (
m_type ==
"ListTuple") {
926 std::vector<double> col;
934 throw std::runtime_error
935 (
"__setitem__ by index is not supported for " +
m_type);
937 std::string what (
"DataArray:: Attempt to save column " );
941 what +=
" columns in data source";
942 throw std::runtime_error ( what );
945 throw std::runtime_error (
"HippoDraw was not built with "
946 "numeric Python support" );
954 const std::vector < double > & array )
966 addRow (
const std::vector < double > & row )
972 catch (
const std::runtime_error & e ) {
virtual void setTitle(const std::string &title)
Sets the title of the data source to title.
unsigned int columns() const
void replaceColumn(const std::string &, const std::vector< double > &col)
Replace a column by its label.
numeric::array makeNum(object x)
void setTitle(const std::string &title)
virtual void replaceColumn(const std::string &label, const std::vector< double > &array)
Replaces data in column label with contents of array.
A wrapper class for Python tuple objects.
hippodraw::QtRootNTuple class interface.
const std::vector< std::string > & getLabels() const
Get the column names.
void PyDataSourceExceptionTranslator(const PyDataSource::StopIteration &e)
std::string registerNTuple()
Register this DataSource, returning a unique name.
void clear()
Clear the data elements of the DataSource.
A DataSource class implemented with a ROOT TBranch objects from a ROOT TTree to store the column data...
PyDataSource()
Default constructor wraps an ordinary NTuple.
hippodraw::FitsNTuple class interface.
virtual void replaceColumn(unsigned int index, const std::vector< double > &data)
Replaces the data in column col.
A DataSource class implemented with a Python numarray array to store the column data.
static void lock()
Obtains a lock on the application's mutex.
void * data(numeric::array arr)
void addRow(const std::vector< double > &array)
Adds a row to the DataSource.
void export_DataArray()
Export PyDataSourceWrapper.
static PyDataSource * getCurrentDataSource()
Returns a new PyDataSource that wraps the current DataSource in the DataSourceController.
std::string type2string(PyArray_TYPES t_type)
Converts a PyArray_TYPE to its name in string.
const std::string & title() const
Returns a const reference to the title of the data source.
unsigned int rows() const
std::vector< intptr_t > shape(numeric::array arr)
const std::string & getTitle() const
The title of the DataSource.
The namespace for conversion to string.
A wrapper for RootNTuple, so that when RootNTuple is used in Qt based application, the application object can be locked and unlocked before calling any ROOT functions.
virtual const std::vector< double > & getColumn(const std::string &name) const
Returns the data in the column with label name.
hippodraw::PyDataSource class interface
hippodraw::NTuple class interface.
static void extractVector(boost::python::numeric::array array, std::vector< double > &col)
Extracts a vector from the numarray object.
boost::python::numeric::array columnAsNumArray(const std::string &label) const
Return a column from the DataSource as a numarray object, indexing by column label.
void append(const DataSource *source)
Adds all the rows of source to the DataArray.
PyArray_TYPES type(numeric::array arr)
virtual const std::vector< std::string > & getLabels() const
Returns the list of available labels.
DataSource * m_dataSource
The actual DataSource object.
hippodraw::PyApp class interface.
void saveColumnFrom(const std::string &label, const std::vector< double > &array)
Replace or add a column from vector.
void saveColumnFromNumArray(const std::string &label, boost::python::numeric::array array)
Replace or add a column from a numarray object, indexing by column label.
hippodraw::ListTuple class interface.
const std::vector< double > & getColumn(const std::string &name) const
Get a column as a tuple of floats by column name.
intp size(numeric::array arr)
int rank(numeric::array arr)
void replaceColumn(unsigned int index, boost::python::list array)
Replaces the column indexed by index with the array.
string convert(int i)
Converts an integer to a string.
void checkRank(boost::python::numeric::array array)
Checks the rank of the array.
bool iscontiguous(numeric::array arr)
This class is the public interface to a DataSource object that the user sees as the DataArray object ...
void setName(const std::string &name)
Set the name of the DataSource.
virtual int addColumn(const std::string &, const std::vector< double > &column)
Adds a column to the end of the ntuple and returns the index to the added column. ...
void replaceColumn(unsigned int index, boost::python::numeric::array array)
Replaces the column indexed by index with the array.
void saveColumn(const std::string &label, const std::vector< double > &v, const std::vector< intptr_t > &shape)
Replaces or add column vector.
A singleton class that is the interface between GUI and the DataSource objects.
boost::python::numeric::array getNumArray(const std::string &label) const
Return the reference to the desired numarray by column label.
int addColumn(const std::string &label, boost::python::list seq)
Adds a column to the end of the ListTuple.
A DataSource class implemented with std::vector<double> to store the column data. ...
hippodraw::NumArrayTuple class interface.
virtual void clear()=0
Clears the data source.
virtual unsigned int rows() const =0
Returns the number of rows.
std::string registerNTuple(DataSource *nt)
Register a DataSource.
const char * what() const
static void unlock()
Releases the lock on the application's mutex.
const DataSource & dataSource() const
Return a reference to the underlying DataSource.
unsigned int columns() const
Returns the number of columns or data arrays available from this DataSource.
A DataSource class implemented with a vector < DataColumn * > objects.
bool hasColumn(const std::string &name) const
Return true if column with label name exists in DataSource.
int addColumn(const std::string &label, boost::python::numeric::array array)
Adds a column to the end of the NumArrayTuple.
std::string m_type
The type of data source.
static void copy_direct(boost::python::numeric::array array, std::vector< double > &col)
Copies and converts to double, if needed, data of type T from array to fill the std::vector col...
DataSourceController class interface.
void setName(const std::string &name)
Sets the name of the data source.
A wrapper class for Python list objects.
A DataSource class implemented with a Python list to store the column data.
int addColumn(const std::string &label, const std::vector< double > &col)
Add a column to an NTuple or ListTuple.
static DataSourceController * instance()
Returns the pointer to the singleton instance.
Base class for DataSource.