00001
00012
00013 #include <boost/python.hpp>
00014
00015 #ifdef HAVE_CONFIG_H
00016 #include "config.h"
00017 #endif
00018
00019
00020 #ifdef _MSC_VER
00021 #include "msdevstudio/MSconfig.h"
00022 #endif
00023
00024 #include "QtRootNTuple.h"
00025
00026 #include "python/PyApp.h"
00027
00028 #ifdef HAVE_NUMARRAY
00029 #include "numarray/num_util.h"
00030 #endif
00031
00032 #include <stdexcept>
00033 #include <utility>
00034
00035 using std::runtime_error;
00036 using std::string;
00037 using std::vector;
00038
00039 using namespace hippodraw;
00040
00041 QtRootNTuple::
00042 QtRootNTuple ( TTree * tree )
00043 : RootNTuple ( tree )
00044 {
00045 }
00046
00047 QtRootNTuple::
00048 QtRootNTuple ( )
00049 : RootNTuple ( )
00050 {
00051 }
00052
00053 unsigned int
00054 QtRootNTuple::
00055 rows () const
00056 {
00057 PyApp::lock();
00058 unsigned int rows = RootNTuple::rows ();
00059 PyApp::unlock ();
00060
00061 return rows;
00062 }
00063
00064 unsigned int
00065 QtRootNTuple::
00066 columns () const
00067 {
00068
00069 return RootNTuple::columns ();
00070 }
00071
00072 const vector < double > &
00073 QtRootNTuple::
00074 getColumn ( const std::string & name ) const
00075 {
00076 static vector < double > temp;
00077 PyApp::lock();
00078 try {
00079 const vector < double > & column = RootNTuple::getColumn ( name );
00080 PyApp::unlock ();
00081 return column;
00082 }
00083 catch ( const runtime_error & e ) {
00084 PyApp::unlock ();
00085 throw e;
00086 }
00087 return temp;
00088 }
00089
00090 const vector < double > &
00091 QtRootNTuple::
00092 getColumn ( const std::string & name,
00093 const std::vector < int > & indexes ) const
00094 {
00095 static vector < double > temp;
00096 PyApp::lock();
00097 try {
00098 const vector < double > & column
00099 = RootNTuple::getColumn ( name, indexes );
00100 PyApp::unlock ();
00101 return column;
00102 }
00103 catch ( const runtime_error & e ) {
00104 PyApp::unlock ();
00105 throw e;
00106 }
00107 return temp;
00108 }
00109
00110 const vector < double > &
00111 QtRootNTuple::
00112 getColumn ( unsigned int index ) const
00113 {
00114 static vector < double > temp;
00115 PyApp::lock();
00116 try {
00117 const vector < double > & column = RootNTuple::getColumn ( index );
00118 PyApp::unlock ();
00119 return column;
00120 }
00121 catch ( const runtime_error & e ) {
00122 PyApp::unlock ();
00123 throw e;
00124 }
00125
00126 return temp;
00127 }
00128
00129 const vector < double > &
00130 QtRootNTuple::
00131 getRow ( unsigned int index ) const
00132 {
00133 static vector < double > temp;
00134 PyApp::lock();
00135 try {
00136 const vector < double > & row = RootNTuple::getRow ( index );
00137 PyApp::unlock ();
00138 return row;
00139 }
00140 catch ( const runtime_error & e ) {
00141 PyApp::unlock ();
00142 throw e;
00143 }
00144
00145 return temp;
00146 }
00147
00148 int
00149 QtRootNTuple::
00150 addColumn ( const std::string & label,
00151 const std::vector < double > & column )
00152 {
00153 return RootNTuple::addColumn ( label, column );
00154 }
00155
00156 const std::vector < std::string > &
00157 QtRootNTuple::
00158 getLabels () const
00159 {
00160
00161 return RootNTuple::getLabels ();
00162 }
00163
00164 bool
00165 QtRootNTuple::
00166 isMultiDimensional ( const std::string & column ) const
00167 {
00168 PyApp::lock();
00169 try {
00170 bool yes = RootNTuple::isMultiDimensional ( column );
00171 PyApp::unlock ();
00172 return yes;
00173 }
00174 catch ( const runtime_error & e ) {
00175 PyApp::unlock ();
00176 throw e;
00177 }
00178 }
00179
00180 void
00181 QtRootNTuple::
00182 sliceRowDimension ( std::vector < int > & shape )
00183 {
00184 unsigned int rank = shape.size ();
00185 for ( unsigned int i = 0; i < rank -1; i++ ) {
00186 shape[i] = shape[i+1];
00187 }
00188 shape.pop_back ();
00189 }
00190
00191 const std::vector < int >
00192 QtRootNTuple::
00193 getColumnShape ( const std::string & label ) {
00194 PyApp::lock();
00195 try {
00196 int column = indexOf ( label );
00197 if ( column < 0 ) {
00198 string what ( "RootNTuple: No column with named `" );
00199 what += label;
00200 what += "'.";
00201 throw std::runtime_error ( what );
00202 }
00203 vector < int > shape;
00204 fillShape ( shape, column );
00205 sliceRowDimension ( shape );
00206
00207 PyApp::unlock ();
00208
00209 return shape;
00210 }
00211 catch ( const runtime_error & e ) {
00212 PyApp::unlock ();
00213 throw e;
00214 }
00215 }
00216
00217 void
00218 QtRootNTuple::
00219 expandIfNeeded ( const std::vector < std::string > & labels ) const
00220 {
00221 PyApp::lock ();
00222 RootNTuple::expandIfNeeded ( labels );
00223 PyApp::unlock ();
00224 }
00225
00226 std::string
00227 QtRootNTuple::
00228 createBinding ( const std::string & name,
00229 const std::vector < int > & indices ) const
00230 {
00231 return RootNTuple::createBinding ( name, indices );
00232 }
00233
00234 using namespace boost::python;
00235
00236 numeric::array
00237 QtRootNTuple::
00238 valueAt ( unsigned int row, const std::string & variable )
00239 {
00240 #ifdef HAVE_NUMARRAY
00241 RootNTuple::throwIfInvalidLabel ( variable );
00242 int column = RootNTuple::indexOf ( variable );
00243 vector < int > shape;
00244 fillShape ( shape, column );
00245 sliceRowDimension ( shape );
00246 RootData::Type type = RootNTuple::getType ( column );
00247 switch ( type ) {
00248 case RootData::Double:
00249 {
00250 double * array = RootNTuple::doubleArrayAt ( row, column );
00251 numeric::array na = num_util::makeNum ( array, shape );
00252 return na;
00253 }
00254 break;
00255 case RootData::Float:
00256 {
00257 float * array = RootNTuple::floatArrayAt ( row, column );
00258 numeric::array na = num_util::makeNum ( array, shape );
00259 return na;
00260 }
00261 break;
00262 case RootData::Int:
00263 {
00264 int * array = RootNTuple::intArrayAt ( row, column );
00265 numeric::array na = num_util::makeNum ( array, shape );
00266 return na;
00267 }
00268 break;
00269 default:
00270 assert ( false );
00271 break;
00272 }
00273 return num_util::makeNum ( 1, PyArray_DOUBLE );
00274 #else
00275 throw std::runtime_error ( "HippoDraw was not built with "
00276 "numeric Python support" );
00277 #endif
00278 }
00279
00280 numeric::array
00281 QtRootNTuple::
00282 getColumnAsArray ( const std::string & name )
00283 {
00284 #ifdef HAVE_NUMARRAY
00285 throwIfInvalidLabel ( name );
00286 unsigned int length = rows ();
00287 unsigned int column = indexOf ( name );
00288
00289 if ( isMultiDimensional ( name ) == false ) {
00290 vector < int > shape;
00291 shape.push_back ( length );
00292 const vector < double > & col_vec = getColumn ( column );
00293 double * array = const_cast < double * > ( &col_vec[0] );
00294 numeric::array na = num_util::makeNum ( array, shape );
00295
00296 return na;
00297 }
00298
00299 int size = 1;
00300 vector < int > shape;
00301 fillShape ( shape, column );
00302 unsigned int rank = shape.size();
00303 for ( unsigned int i = 1; i < rank; i++ ) {
00304 size *= shape[i];
00305 }
00306 int total_size = size * shape [ 0 ];
00307
00308 RootData::Type type = getType ( column );
00309
00310 switch ( type ) {
00311 case RootData::Double:
00312 {
00313 vector < double > array_vec;
00314 array_vec.reserve ( total_size );
00315 for ( unsigned int row = 0; row < length; row++ ) {
00316 double * array =RootNTuple::doubleArrayAt ( row, column );
00317 array_vec.insert ( array_vec.end(), array, array + size );
00318 }
00319 numeric::array na = num_util::makeNum ( &array_vec[0], shape );
00320
00321 return na;
00322 }
00323 break;
00324
00325 case RootData::Float:
00326 {
00327 vector < float > array_vec;
00328 array_vec.reserve ( total_size );
00329 for ( unsigned int row = 0; row < length; row++ ) {
00330 float * array = RootNTuple::floatArrayAt ( row, column );
00331 array_vec.insert ( array_vec.end(), array, array + size );
00332 }
00333 numeric::array na = num_util::makeNum ( &array_vec[0], shape );
00334
00335 return na;
00336 }
00337 break;
00338
00339 case RootData::Int:
00340 {
00341 vector < int > array_vec;
00342 array_vec.reserve ( total_size );
00343 for ( unsigned int row = 0; row < length; row++ ) {
00344 int * array = RootNTuple::intArrayAt ( row, column );
00345 array_vec.insert ( array_vec.end(), array, array + size );
00346 }
00347 numeric::array na = num_util::makeNum ( &array_vec[0], shape );
00348
00349 return na;
00350 }
00351 break;
00352
00353 case RootData::UInt:
00354 {
00355 vector < unsigned int > array_vec;
00356 array_vec.reserve ( total_size );
00357 for ( unsigned int row = 0; row < length; row++ ) {
00358 unsigned int * array = RootNTuple::uintArrayAt ( row, column );
00359 array_vec.insert ( array_vec.end(), array, array + size );
00360 }
00361 numeric::array na = num_util::makeNum ( &array_vec[0], shape );
00362
00363 return na;
00364 }
00365 break;
00366
00367 default:
00368 assert ( false );
00369 break;
00370 }
00371 vector < double > array_vec;
00372 numeric::array na = num_util::makeNum ( & array_vec[0], shape );
00373
00374 return na;
00375 #else
00376 throw std::runtime_error ( "HippoDraw was not built with "
00377 "numeric Python support" );
00378 #endif
00379 }
00380