QtRootNTuple.cxx
Go to the documentation of this file.
1 
12 // include first to avoid _POSIX_C_SOURCE warning.
13 #include <boost/python.hpp>
14 
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18 
19 // For truncation warning
20 #ifdef _MSC_VER
21 #include "msdevstudio/MSconfig.h"
22 #endif
23 
24 #include "QtRootNTuple.h"
25 
26 #include "python/PyApp.h"
27 
28 #ifdef HAVE_NUMARRAY
29 #include "numarray/num_util.h"
30 #endif
31 
32 #include <stdexcept>
33 #include <utility>
34 
35 using std::runtime_error;
36 using std::string;
37 using std::vector;
38 
39 using namespace hippodraw;
40 
42 QtRootNTuple ( TTree * tree )
43  : RootNTuple ( tree )
44 {
45 }
46 
49  : RootNTuple ( )
50 {
51 }
52 
53 unsigned int
55 rows () const
56 {
57  PyApp::lock();
58  unsigned int rows = RootNTuple::rows ();
59  PyApp::unlock ();
60 
61  return rows;
62 }
63 
64 unsigned int
66 columns () const
67 {
68  // doesn't call ROOT, so no need for lock
69  return RootNTuple::columns ();
70 }
71 
72 const vector < double > &
74 getColumn ( const std::string & name ) const
75 {
76  static vector < double > temp;
77  PyApp::lock();
78  try {
79  const vector < double > & column = RootNTuple::getColumn ( name );
80  PyApp::unlock ();
81  return column;
82  }
83  catch ( const runtime_error & e ) {
84  PyApp::unlock ();
85  throw e;
86  }
87  return temp;
88 }
89 
90 const vector < double > &
92 getColumn ( const std::string & name,
93  const std::vector < int > & indexes ) const
94 {
95  static vector < double > temp;
96  PyApp::lock();
97  try {
98  const vector < double > & column
99  = RootNTuple::getColumn ( name, indexes );
100  PyApp::unlock ();
101  return column;
102  }
103  catch ( const runtime_error & e ) {
104  PyApp::unlock ();
105  throw e;
106  }
107  return temp;
108 }
109 
110 const vector < double > &
112 getColumn ( unsigned int index ) const
113 {
114  static vector < double > temp;
115  PyApp::lock();
116  try {
117  const vector < double > & column = RootNTuple::getColumn ( index );
118  PyApp::unlock ();
119  return column;
120  }
121  catch ( const runtime_error & e ) {
122  PyApp::unlock ();
123  throw e;
124  }
125 
126  return temp;
127 }
128 
129 const vector < double > &
131 getRow ( unsigned int index ) const
132 {
133  static vector < double > temp;
134  PyApp::lock();
135  try {
136  const vector < double > & row = RootNTuple::getRow ( index );
137  PyApp::unlock ();
138  return row;
139  }
140  catch ( const runtime_error & e ) {
141  PyApp::unlock ();
142  throw e;
143  }
144 
145  return temp;
146 }
147 
148 int
150 addColumn ( const std::string & label,
151  const std::vector < double > & column )
152 {
153  return RootNTuple::addColumn ( label, column );
154 }
155 
156 const std::vector < std::string > &
158 getLabels () const
159 {
160  // doesn't call ROOT, so no lock needed
161  return RootNTuple::getLabels ();
162 }
163 
164 bool
166 isMultiDimensional ( const std::string & column ) const
167 {
168  PyApp::lock();
169  try {
170  bool yes = RootNTuple::isMultiDimensional ( column );
171  PyApp::unlock ();
172  return yes;
173  }
174  catch ( const runtime_error & e ) {
175  PyApp::unlock ();
176  throw e;
177  }
178 }
179 
180 void
182 sliceRowDimension ( std::vector < int > & shape )
183 {
184  unsigned int rank = shape.size ();
185  for ( unsigned int i = 0; i < rank -1; i++ ) {
186  shape[i] = shape[i+1];
187  }
188  shape.pop_back ();
189 }
190 
191 const std::vector < int >
193 getColumnShape ( const std::string & label ) {
194  PyApp::lock();
195  try {
196  int column = indexOf ( label );
197  if ( column < 0 ) {
198  string what ( "RootNTuple: No column with named `" );
199  what += label;
200  what += "'.";
201  throw std::runtime_error ( what );
202  }
203  vector < int > shape;
204  fillShape ( shape, column );
205  sliceRowDimension ( shape );
206 
207  PyApp::unlock ();
208 
209  return shape;
210  }
211  catch ( const runtime_error & e ) {
212  PyApp::unlock ();
213  throw e;
214  }
215 }
216 
217 void
219 expandIfNeeded ( const std::vector < std::string > & labels ) const
220 {
221  PyApp::lock ();
222  RootNTuple::expandIfNeeded ( labels );
223  PyApp::unlock ();
224 }
225 
226 std::string
228 createBinding ( const std::string & name,
229  const std::vector < int > & indices ) const
230 {
231  return RootNTuple::createBinding ( name, indices );
232 }
233 
234 using namespace boost::python;
235 
236 numeric::array
238 valueAt ( unsigned int row, const std::string & variable )
239 {
240 #ifdef HAVE_NUMARRAY
241  RootNTuple::throwIfInvalidLabel ( variable );
242  int column = RootNTuple::indexOf ( variable );
243  vector < int > shape;
244  fillShape ( shape, column );
245  sliceRowDimension ( shape );
247  switch ( type ) {
248  case RootData::Double:
249  {
250  double * array = RootNTuple::doubleArrayAt ( row, column );
251  numeric::array na = num_util::makeNum ( array, shape );
252  return na;
253  }
254  break;
255  case RootData::Float:
256  {
257  float * array = RootNTuple::floatArrayAt ( row, column );
258  numeric::array na = num_util::makeNum ( array, shape );
259  return na;
260  }
261  break;
262  case RootData::Int:
263  {
264  int * array = RootNTuple::intArrayAt ( row, column );
265  numeric::array na = num_util::makeNum ( array, shape );
266  return na;
267  }
268  break;
269  default:
270  assert ( false );
271  break;
272  }
273  return num_util::makeNum ( 1, PyArray_DOUBLE );
274 #else
275  throw std::runtime_error ( "HippoDraw was not built with "
276  "numeric Python support" );
277 #endif
278 }
279 
280 numeric::array
282 getColumnAsArray ( const std::string & name )
283 {
284 #ifdef HAVE_NUMARRAY
285  throwIfInvalidLabel ( name );
286  unsigned int length = rows ();
287  unsigned int column = indexOf ( name );
288 
289  if ( isMultiDimensional ( name ) == false ) {
290  vector < int > shape;
291  shape.push_back ( length );
292  const vector < double > & col_vec = getColumn ( column );
293  double * array = const_cast < double * > ( &col_vec[0] );
294  numeric::array na = num_util::makeNum ( array, shape );
295 
296  return na;
297  }
298 
299  int size = 1;
300  vector < int > shape;
301  fillShape ( shape, column );
302  unsigned int rank = shape.size();
303  for ( unsigned int i = 1; i < rank; i++ ) { // skip first dimension
304  size *= shape[i];
305  }
306  int total_size = size * shape [ 0 ];
307 
308  RootData::Type type = getType ( column );
309 
310  switch ( type ) {
311  case RootData::Double:
312  {
313  vector < double > array_vec;
314  array_vec.reserve ( total_size );
315  for ( unsigned int row = 0; row < length; row++ ) {
316  double * array =RootNTuple::doubleArrayAt ( row, column );
317  array_vec.insert ( array_vec.end(), array, array + size );
318  }
319  numeric::array na = num_util::makeNum ( &array_vec[0], shape );
320 
321  return na;
322  }
323  break;
324 
325  case RootData::Float:
326  {
327  vector < float > array_vec;
328  array_vec.reserve ( total_size );
329  for ( unsigned int row = 0; row < length; row++ ) {
330  float * array = RootNTuple::floatArrayAt ( row, column );
331  array_vec.insert ( array_vec.end(), array, array + size );
332  }
333  numeric::array na = num_util::makeNum ( &array_vec[0], shape );
334 
335  return na;
336  }
337  break;
338 
339  case RootData::Int:
340  {
341  vector < int > array_vec;
342  array_vec.reserve ( total_size );
343  for ( unsigned int row = 0; row < length; row++ ) {
344  int * array = RootNTuple::intArrayAt ( row, column );
345  array_vec.insert ( array_vec.end(), array, array + size );
346  }
347  numeric::array na = num_util::makeNum ( &array_vec[0], shape );
348 
349  return na;
350  }
351  break;
352 
353  case RootData::UInt:
354  {
355  vector < unsigned int > array_vec;
356  array_vec.reserve ( total_size );
357  for ( unsigned int row = 0; row < length; row++ ) {
358  unsigned int * array = RootNTuple::uintArrayAt ( row, column );
359  array_vec.insert ( array_vec.end(), array, array + size );
360  }
361  numeric::array na = num_util::makeNum ( &array_vec[0], shape );
362 
363  return na;
364  }
365  break;
366 
367  default:
368  assert ( false );
369  break;
370  }
371  vector < double > array_vec;
372  numeric::array na = num_util::makeNum ( & array_vec[0], shape );
373 
374  return na; // have to return something for VC++
375 #else
376  throw std::runtime_error ( "HippoDraw was not built with "
377  "numeric Python support" );
378 #endif
379 }
380 

Generated for HippoDraw Class Library by doxygen