All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PyUtils.cxx
Go to the documentation of this file.
1 #ifndef __OPT0FINDER_PYUTILS_CXX__
2 #define __OPT0FINDER_PYUTILS_CXX__
3 
4 #include "PyUtils.h"
5 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
6 //#include <numpy/ndarrayobject.h>
7 #include "numpy/arrayobject.h"
9 #include <cassert>
10 #include <iostream>
11 
12 namespace flashmatch {
13 
14  void SetPyUtil() {
15  static bool once = false;
16  if (!once) {
17  _import_array();
18  once = true;
19  }
20  }
21 
22  PyObject* as_ndarray(const QCluster_t& traj) {
23  SetPyUtil();
24  std::vector<size_t> dims(2,0);
25  dims[0] = traj.size();
26  dims[1] = 4;
27  auto pyarray = numpy_array<double>(dims);
28 
29  double **carray;
30  const int dtype = NPY_DOUBLE;
31  PyArray_Descr *descr = PyArray_DescrFromType(dtype);
32  npy_intp pydims[2];
33  if (PyArray_AsCArray(&pyarray, (void **)&carray, pydims, 2, descr) < 0) {
34  std::cerr<<"Failed to create 2D numpy array"<<std::endl;
35  throw std::exception();
36  }
37  assert(pydims[0] == ((int)(dims[0])) && pydims[1] == ((int)(dims[1])));
38 
39  for(size_t idx=0; idx<dims[0]; ++idx) {
40  carray[idx][0] = traj[idx].x;
41  carray[idx][1] = traj[idx].y;
42  carray[idx][2] = traj[idx].z;
43  carray[idx][3] = traj[idx].q;
44  }
45  PyArray_Free(pyarray, (void *)carray);
46  return pyarray;
47  }
48 
49  PyObject* as_ndarray(const ::geoalgo::Trajectory& traj) {
50  SetPyUtil();
51  std::vector<size_t> dims(2,0);
52  dims[0] = traj.size();
53  dims[1] = 3;
54  auto pyarray = numpy_array<double>(dims);
55 
56  double **carray;
57  const int dtype = NPY_DOUBLE;
58  PyArray_Descr *descr = PyArray_DescrFromType(dtype);
59  npy_intp pydims[2];
60  if (PyArray_AsCArray(&pyarray, (void **)&carray, pydims, 2, descr) < 0) {
61  std::cerr<<"Failed to create 2D numpy array"<<std::endl;
62  throw std::exception();
63  }
64  assert(pydims[0] == ((int)(dims[0])) && pydims[1] == ((int)(dims[1])));
65 
66  for(size_t idx=0; idx<dims[0]; ++idx) {
67  carray[idx][0] = traj[idx][0];
68  carray[idx][1] = traj[idx][1];
69  carray[idx][2] = traj[idx][2];
70  }
71  PyArray_Free(pyarray, (void *)carray);
72  return pyarray;
73  }
74 
75  PyObject* as_ndarray(const Flash_t& flash) {
76  SetPyUtil();
77  std::vector<size_t> dims(1);
78  dims[0] = flash.pe_v.size();
79  auto pyarray = numpy_array<double>(dims);
80 
81  double *carray;
82  const int dtype = NPY_DOUBLE;
83  PyArray_Descr *descr = PyArray_DescrFromType(dtype);
84  npy_intp pydims[1];
85  if (PyArray_AsCArray(&pyarray, (void **)&carray, pydims, 1, descr) < 0) {
86  std::cerr<<"Failed to create 2D numpy array"<<std::endl;
87  throw std::exception();
88  }
89  assert(pydims[0] == ((int)(dims[0])));
90 
91  for(size_t idx=0; idx<dims[0]; ++idx)
92  carray[idx] = flash.pe_v[idx];
93  PyArray_Free(pyarray, (void *)carray);
94  return pyarray;
95  }
96 
97  /*
98  void copy_array(PyObject *arrayin, const std::vector<float> &cvec) {
99  SetPyUtil();
100  PyArrayObject *ptr = (PyArrayObject *)(arrayin);
101 
102  //std::cout<< PyArray_NDIM(ptr) << std::endl
103  // << PyArray_DIM(ptr,0)<<std::endl
104  // << PyArray_SIZE(ptr) << std::endl;
105 
106  // Check dimension size is 1:
107  if (PyArray_NDIM(ptr) != 1){
108  throw std::exception();
109  }
110 
111  if ((long)(cvec.size()) != PyArray_SIZE(ptr))
112  throw std::exception();
113  npy_intp loc[1];
114  loc[0] = 0;
115  auto fptr = (float *)(PyArray_GetPtr(ptr, loc));
116  for (size_t i = 0; i < size_t(PyArray_SIZE(ptr)); ++i) {
117  // std::cout << fptr[i] << std::endl;
118  fptr[i] = cvec[i];
119  };
120  }
121  */
122 
123  template<class T>
124  void _copy_array(PyObject *arrayin, const std::vector<T> &cvec) {
125  SetPyUtil();
126  PyArrayObject *ptr = (PyArrayObject *)(arrayin);
127 
128  //std::cout<< PyArray_NDIM(ptr) << std::endl
129  // << PyArray_DIM(ptr,0)<<std::endl
130  // << PyArray_SIZE(ptr) << std::endl;
131 
132  // Check dimension size is 1:
133  if (PyArray_NDIM(ptr) != 1){
134  throw std::exception();
135  }
136 
137  if ((long)(cvec.size()) != PyArray_SIZE(ptr))
138  throw std::exception();
139  npy_intp loc[1];
140  loc[0] = 0;
141  auto fptr = (T *)(PyArray_GetPtr(ptr, loc));
142  for (size_t i = 0; i < size_t(PyArray_SIZE(ptr)); ++i) {
143  // std::cout << fptr[i] << std::endl;
144  fptr[i] = cvec[i];
145  };
146  }
147 
148  template void _copy_array< unsigned short >(PyObject *arrayin, const std::vector< unsigned short > &cvec);
149  template void _copy_array< unsigned int >(PyObject *arrayin, const std::vector< unsigned int > &cvec);
150  template void _copy_array< short >(PyObject *arrayin, const std::vector< short > &cvec);
151  template void _copy_array< int >(PyObject *arrayin, const std::vector< int > &cvec);
152  template void _copy_array< long long >(PyObject *arrayin, const std::vector< long long > &cvec);
153  template void _copy_array< float >(PyObject *arrayin, const std::vector< float > &cvec);
154  template void _copy_array< double >(PyObject *arrayin, const std::vector< double > &cvec);
155 
156  void copy_array(PyObject *arrayin, const std::vector< unsigned short > &cvec) { _copy_array(arrayin, cvec); }
157  void copy_array(PyObject *arrayin, const std::vector< unsigned int > &cvec) { _copy_array(arrayin, cvec); }
158  void copy_array(PyObject *arrayin, const std::vector< short > &cvec) { _copy_array(arrayin, cvec); }
159  void copy_array(PyObject *arrayin, const std::vector< int > &cvec) { _copy_array(arrayin, cvec); }
160  void copy_array(PyObject *arrayin, const std::vector< long long > &cvec) { _copy_array(arrayin, cvec); }
161  void copy_array(PyObject *arrayin, const std::vector< float > &cvec) { _copy_array(arrayin, cvec); }
162  void copy_array(PyObject *arrayin, const std::vector< double > &cvec) { _copy_array(arrayin, cvec); }
163 
164  template<> int ctype_to_numpy<short>() { SetPyUtil(); SetPyUtil(); return NPY_INT16; }
165  template<> int ctype_to_numpy<unsigned short>() { SetPyUtil(); return NPY_UINT16; }
166  template<> int ctype_to_numpy<int>() { SetPyUtil(); return NPY_INT32; }
167  template<> int ctype_to_numpy<unsigned int>() { SetPyUtil(); return NPY_UINT32; }
168  template<> int ctype_to_numpy<long long>() { SetPyUtil(); return NPY_INT64; }
169  template<> int ctype_to_numpy<unsigned long long>() { SetPyUtil(); return NPY_UINT64; }
170  template<> int ctype_to_numpy<float>() { SetPyUtil(); return NPY_FLOAT32; }
171  template<> int ctype_to_numpy<double>() { SetPyUtil(); return NPY_FLOAT64; }
172 
173  /*
174  PyObject *as_ndarray(const std::vector<float> &vec) {
175  SetPyUtil();
176 
177  if (vec.size() >= INT_MAX) {
178  LARCV_CRITICAL() << "Length of data vector too long to specify ndarray. "
179  "Use by batch call."
180  << std::endl;
181  throw larbys();
182  }
183  int nd = 1;
184  npy_intp dims[1];
185  dims[0] = (int)vec.size();
186  PyArrayObject *array = (PyArrayObject *)PyArray_SimpleNewFromData(
187  nd, dims, NPY_FLOAT, (char *)&(vec[0]));
188  return PyArray_Return(array);
189  }
190  */
191 
192  template <class T>
193  PyObject *_as_ndarray(const std::vector<T> &vec) {
194  SetPyUtil();
195 
196  if (vec.size() >= INT_MAX) {
197  std::cerr << "Length of data vector too long to specify ndarray. " << std::endl;
198  throw std::exception();
199  }
200  int nd = 1;
201  npy_intp dims[1];
202  dims[0] = (int)vec.size();
203  PyArrayObject *array = (PyArrayObject *)PyArray_SimpleNewFromData(
204  nd, dims, ctype_to_numpy<T>(), (char *)&(vec[0]));
205  return PyArray_Return(array);
206  }
207 
208  template PyObject* _as_ndarray< short > (const std::vector< short >& vec);
209  template PyObject* _as_ndarray< unsigned short > (const std::vector< unsigned short >& vec);
210  template PyObject* _as_ndarray< int > (const std::vector< int >& vec);
211  template PyObject* _as_ndarray< unsigned int > (const std::vector< unsigned int >& vec);
212  template PyObject* _as_ndarray< long long > (const std::vector< long long >& vec);
213  template PyObject* _as_ndarray< unsigned long long > (const std::vector< unsigned long long >& vec);
214  template PyObject* _as_ndarray< float > (const std::vector< float >& vec);
215  template PyObject* _as_ndarray< double > (const std::vector< double >& vec);
216 
217  PyObject* as_ndarray(const std::vector< short >& vec) { return _as_ndarray< short >(vec); }
218  PyObject* as_ndarray(const std::vector< unsigned short >& vec) { return _as_ndarray< unsigned short >(vec); }
219  PyObject* as_ndarray(const std::vector< int >& vec) { return _as_ndarray< int >(vec); }
220  PyObject* as_ndarray(const std::vector< unsigned int >& vec) { return _as_ndarray< unsigned int >(vec); }
221  PyObject* as_ndarray(const std::vector< long long >& vec) { return _as_ndarray< long long >(vec); }
222  PyObject* as_ndarray(const std::vector< unsigned long long >& vec) { return _as_ndarray< unsigned long long >(vec); }
223  PyObject* as_ndarray(const std::vector< float >& vec) { return _as_ndarray< float >(vec); }
224  PyObject* as_ndarray(const std::vector< double >& vec) { return _as_ndarray< double >(vec); }
225 
226  template<class T>
227  PyObject* numpy_array(std::vector<size_t> dims)
228  {
229  SetPyUtil();
230  int nd_ = dims.size();
231  npy_intp dims_[nd_];
232  for(size_t i=0; i<dims.size(); ++i) dims_[i] = dims[i];
233  /*
234  std::cout<<"NUMPY TYPE " << ctype_to_numpy<T>() << std::endl;
235  std::cout<<"DIMS " << dims.size() << std::endl;
236  std::cout<<"ND " << nd_ << std::endl;
237  std::cout<<"Shape ";
238  for(size_t i=0; i<dims.size(); ++i) std::cout<< " " << dims_[i];
239  std::cout<<std::endl;
240  */
241  //PyObject* res = PyArray_SimpleNew(nd_,dims_,ctype_to_numpy<T>());
242  PyObject* res = PyArray_ZEROS(nd_,dims_,ctype_to_numpy<T>(),0);
243  //Py_INCREF(res);
244  /*
245  std::cout<<PyArray_NDIM((PyArrayObject*)res) << std::endl;
246  std::cout<<PyArray_SIZE((PyArrayObject*)res) << std::endl;
247  */
248  PyArrayObject *ptr = (PyArrayObject*)(res);
249  // Check dimension size is 1:
250  //std::cout<<"ndim " << PyArray_NDIM(ptr) << std::endl;
251  //size_t len = PyArray_SIZE(ptr);
252  //std::cout<<"len " << len <<std::endl;
253  //npy_intp loc[1];
254  //loc[0] = 0;
255  //auto fptr = (T *)(PyArray_GetPtr(ptr, loc));
256  /*
257  std::cout<<"fptr " << fptr << std::endl;
258  for (size_t i = 0; i < len; ++i) {
259  std::cout << fptr[i] << std::endl;
260  fptr[i] = T(1);
261  }
262  */
263  PyArray_INCREF(ptr);
264 
265  return res;
266  }
267 
268  template PyObject* numpy_array<float>(std::vector<size_t>dims);
269 
270 }
271 #endif
272 
void SetPyUtil()
Utility function: call one-time-only numpy module initialization (you don&#39;t have to call) ...
Definition: PyUtils.cxx:14
_object PyObject
Definition: PyUtils.h:4
BEGIN_PROLOG could also be cerr
template void _copy_array< unsigned short >(PyObject *arrayin, const std::vector< unsigned short > &cvec)
PyObject * _as_ndarray(const std::vector< T > &vec)
convert vectors into np array
Definition: PyUtils.cxx:193
template PyObject * _as_ndarray< long long >(const std::vector< long long > &vec)
template void _copy_array< int >(PyObject *arrayin, const std::vector< int > &cvec)
int ctype_to_numpy< short >()
Definition: PyUtils.cxx:164
template PyObject * _as_ndarray< float >(const std::vector< float > &vec)
template PyObject * _as_ndarray< double >(const std::vector< double > &vec)
template PyObject * _as_ndarray< short >(const std::vector< short > &vec)
Struct to represent an optical flash.
template void _copy_array< unsigned int >(PyObject *arrayin, const std::vector< unsigned int > &cvec)
template PyObject * numpy_array< float >(std::vector< size_t >dims)
int ctype_to_numpy< float >()
Definition: PyUtils.cxx:170
void copy_array(PyObject *arrayin, const std::vector< unsigned short > &cvec)
Definition: PyUtils.cxx:156
then echo ***************************************echo array
Definition: find_fhicl.sh:28
int ctype_to_numpy< unsigned long long >()
Definition: PyUtils.cxx:169
std::vector< double > pe_v
PE distribution over photo-detectors.
PyObject * as_ndarray(const QCluster_t &traj)
Definition: PyUtils.cxx:22
template PyObject * _as_ndarray< unsigned short >(const std::vector< unsigned short > &vec)
int ctype_to_numpy< unsigned int >()
Definition: PyUtils.cxx:167
int ctype_to_numpy< long long >()
Definition: PyUtils.cxx:168
Collection of charge deposition 3D point (cluster)
template void _copy_array< long long >(PyObject *arrayin, const std::vector< long long > &cvec)
template PyObject * _as_ndarray< unsigned int >(const std::vector< unsigned int > &vec)
int ctype_to_numpy< double >()
Definition: PyUtils.cxx:171
void _copy_array(PyObject *arrayin, const std::vector< T > &cvec)
copy array
Definition: PyUtils.cxx:124
PyObject * numpy_array(std::vector< size_t > dims)
Definition: PyUtils.cxx:227
template void _copy_array< float >(PyObject *arrayin, const std::vector< float > &cvec)
template void _copy_array< short >(PyObject *arrayin, const std::vector< short > &cvec)
template void _copy_array< double >(PyObject *arrayin, const std::vector< double > &cvec)
int ctype_to_numpy< unsigned short >()
Definition: PyUtils.cxx:165
int ctype_to_numpy< int >()
Definition: PyUtils.cxx:166
template PyObject * _as_ndarray< unsigned long long >(const std::vector< unsigned long long > &vec)
template PyObject * _as_ndarray< int >(const std::vector< int > &vec)