QtRootNTuple.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 #include "config.h"
00017 #endif
00018 
00019 // For truncation warning
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   // doesn't call ROOT, so no need for lock
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   // doesn't call ROOT, so no lock needed
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++ ) { // skip first dimension
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; // have to return something for VC++
00375 #else
00376   throw std::runtime_error ( "HippoDraw was not built with "
00377                              "numeric Python support" );
00378 #endif
00379 }
00380 

Generated for HippoDraw Class Library by doxygen