The Gaudi Framework  v33r0 (d5ea422b)
Helpers.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #ifndef GAUDIPYTHON_HELPERS_H
12 #define GAUDIPYTHON_HELPERS_H
13 
14 #include "Python.h"
15 
16 // Python 3 compatibility
17 #if PY_MAJOR_VERSION >= 3
18 
19 # define PyInt_FromLong PyLong_FromLong
20 
21 # define PyBuffer_Type PyMemoryView_Type
22 
23 // Taken from ROOT's TPyBufferFactory
24 static PyObject* PyBuffer_FromReadWriteMemory( void* ptr, int size ) {
25 # if PY_VERSION_HEX > 0x03000000
26  // Python 3 will set an exception if nullptr, just rely on size == 0
27  if ( !ptr ) {
28  static long dummy[1];
29  ptr = dummy;
30  size = 0;
31  }
32 # endif
33  Py_buffer bufinfo = {
34  ptr,
35  NULL,
36  size,
37  1,
38  0,
39  1,
40  NULL,
41  NULL,
42  NULL,
43  NULL,
44 # if PY_VERSION_HEX < 0x03030000
45  {0, 0},
46 # endif
47  NULL
48  };
49  return PyMemoryView_FromBuffer( &bufinfo );
50 }
51 #endif
52 
53 #include "GaudiKernel/DataObject.h"
55 #include "GaudiKernel/IAlgTool.h"
56 #include "GaudiKernel/IAlgorithm.h"
60 #include "GaudiKernel/IToolSvc.h"
61 #include "GaudiKernel/Property.h"
62 
63 // FIXME: (MCl) workaround for ROOT-5850
64 namespace AIDA {
65  class IHistogram1D;
66  class IHistogram2D;
67  class IHistogram3D;
68  class IProfile1D;
69  class IProfile2D;
70 } // namespace AIDA
71 
72 #if PY_VERSION_HEX < 0x02050000
73 // Note (MCl):
74 // In Python 2.5, all the functions working with lenghts use the type PySsize_t
75 // instead of int. The also changed the name of the typedefs for those functions.
76 // Here we use:
77 // intargfunc -> ssizeargfunc
78 // inquiry -> lenfunc
79 //
81 typedef int Py_ssize_t;
82 #endif
83 
84 // the following is done instead of including Python.h becuase there is
85 // a clash with codecs.h defined in Python and the one in VC++ 7.1
86 // struct _object;
87 // typedef _object PyObject;
88 // extern "C" {
89 // PyObject* PyBuffer_FromMemory( void *ptr, int size);
90 //}
91 
95 namespace GaudiPython {
96 
97  struct Helper {
98  // This is a number of static functions to overcome the current problem with PyLCGDict that
99  // does not allow to return instances of complex objects by calling arguments
100  // (reference to pointers)
101  Helper() {}
102  // Provided for backward compatibility
103  static IService* service( ISvcLocator* svcloc, const std::string& name, bool createif = false ) {
104  return svcloc->service( name, createif ).get();
105  }
106  // Provided for backward compatibility
107  static IAlgorithm* algorithm( IAlgManager* algmgr, const std::string& name, const bool createIf = false ) {
108  return algmgr->algorithm( name, createIf ).get();
109  }
110  // ==========================================================================
112  DataObject* o;
113  return dpsvc->retrieveObject( path, o ).isSuccess() ? o : nullptr;
114  }
115  // ==========================================================================
117  return dpsvc->registerObject( path, pObject );
118  }
119  // ==========================================================================
121  return dpsvc->unregisterObject( path );
122  }
123  // ==========================================================================
135  // ==========================================================================
148  const bool retrieve = true, const bool disableDoD = false );
149  // ==========================================================================
150  static IAlgTool* tool( IToolSvc* toolsvc, const std::string& type, const std::string& name, IInterface* p,
151  bool cif ) {
152  IAlgTool* o;
153  return toolsvc->retrieve( type, name, IAlgTool::interfaceID(), o, p, cif ).isSuccess() ? o : nullptr;
154  }
155  static long loadDynamicLib( const std::string& name ) {
156  void* h;
157  return System::loadDynamicLib( name, &h );
158  }
159  static IHistogram1D* histo1D( IHistogramSvc* hsvc, const std::string& path ) {
160  IHistogram1D* h;
161  return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
162  }
163  static IHistogram2D* histo2D( IHistogramSvc* hsvc, const std::string& path ) {
164  IHistogram2D* h;
165  return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
166  }
167  static IHistogram3D* histo3D( IHistogramSvc* hsvc, const std::string& path ) {
168  IHistogram3D* h;
169  return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
170  }
171  static IProfile1D* profile1D( IHistogramSvc* hsvc, const std::string& path ) {
172  IProfile1D* h = 0;
173  return ( hsvc && hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
174  }
175  static IProfile2D* profile2D( IHistogramSvc* hsvc, const std::string& path ) {
176  IProfile2D* h = 0;
177  return ( hsvc && hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
178  }
179 
180  // Array support
181  private:
182  template <class T>
183  static Py_ssize_t Array_length( PyObject* self ) {
184 #if PY_MAJOR_VERSION >= 3
185  Py_buffer bufinfo;
186  ( *( self->ob_type->tp_as_buffer->bf_getbuffer ) )( self, &bufinfo, PyBUF_SIMPLE );
187  Py_ssize_t size = bufinfo.len;
188 #else
189 # if PY_VERSION_HEX < 0x02050000
190  const
191 # endif
192  char* buf = 0;
193  Py_ssize_t size = ( *( self->ob_type->tp_as_buffer->bf_getcharbuffer ) )( self, 0, &buf );
194 #endif
195  return size / sizeof( T );
196  }
197 
198  template <class T>
199  static PyObject* toPython( T* /*o*/ ) {
200  return 0;
201  }
202  static PyObject* toPython( int* o ) { return PyInt_FromLong( (long)*o ); }
203  static PyObject* toPython( short* o ) { return PyInt_FromLong( (long)*o ); }
204  static PyObject* toPython( char* o ) { return PyInt_FromLong( (long)*o ); }
205  static PyObject* toPython( long* o ) { return PyInt_FromLong( *o ); }
206  static PyObject* toPython( float* o ) { return PyFloat_FromDouble( (double)*o ); }
207  static PyObject* toPython( double* o ) { return PyFloat_FromDouble( *o ); }
208 
209  template <class T>
210  static PyObject* Array_item( PyObject* self, Py_ssize_t idx ) {
211 #if PY_VERSION_HEX < 0x02050000
212  const
213 #endif
214  char* buf = nullptr;
215 #if PY_MAJOR_VERSION >= 3
216  Py_buffer bufinfo;
217  ( *( self->ob_type->tp_as_buffer->bf_getbuffer ) )( self, &bufinfo, PyBUF_SIMPLE );
218  Py_ssize_t size = bufinfo.len;
219 #else
220  Py_ssize_t size = ( *( self->ob_type->tp_as_buffer->bf_getcharbuffer ) )( self, 0, &buf );
221 #endif
222  if ( idx < 0 || idx >= size / int( sizeof( T ) ) ) {
223  PyErr_SetString( PyExc_IndexError, "buffer index out of range" );
224  return nullptr;
225  }
226  return toPython( (T*)buf + idx );
227  }
228 
229  public:
230  template <class T>
231  static PyObject* toArray( T* ptr, Py_ssize_t size ) {
232  static PyTypeObject type = PyBuffer_Type;
233  static PySequenceMethods meth = *( PyBuffer_Type.tp_as_sequence );
234 #if PY_VERSION_HEX < 0x02050000
235  meth.sq_item = (intargfunc)&Array_item<T>;
236  meth.sq_length = (inquiry)&Array_length<T>;
237 #else
238  meth.sq_item = (ssizeargfunc)&Array_item<T>;
239  meth.sq_length = (lenfunc)&Array_length<T>;
240 #endif
241  type.tp_as_sequence = &meth;
242  PyObject* buf = PyBuffer_FromReadWriteMemory( ptr, size * sizeof( T ) );
243  buf->ob_type = &type;
244  Py_INCREF( buf->ob_type );
245  return buf;
246  }
247  static PyObject* toIntArray( void* ptr, Py_ssize_t size ) { return toArray( (int*)ptr, size ); }
248  static PyObject* toShortArray( void* ptr, Py_ssize_t size ) { return toArray( (short*)ptr, size ); }
249  static PyObject* toFloatArray( void* ptr, Py_ssize_t size ) { return toArray( (float*)ptr, size ); }
250  static PyObject* toDoubleArray( void* ptr, Py_ssize_t size ) { return toArray( (double*)ptr, size ); }
251 
252  template <class T>
253  static T* toAddress( std::vector<T>& v ) {
254  return v.data();
255  }
256  template <class T>
257  static T* toAddress( void* a ) {
258  return (T*)a;
259  }
260 
261  // FIXME: (MCl) workaround for ROOT-6028, ROOT-6054, ROOT-6073
263  return p.fromString( s );
264  }
265  };
266 
267  template PyObject* Helper::toArray( int*, Py_ssize_t );
268  template PyObject* Helper::toArray( char*, Py_ssize_t );
269  template PyObject* Helper::toArray( short*, Py_ssize_t );
270  template PyObject* Helper::toArray( float*, Py_ssize_t );
271  template PyObject* Helper::toArray( double*, Py_ssize_t );
272  template int* Helper::toAddress( std::vector<int>& );
273  template float* Helper::toAddress( std::vector<float>& );
274  template double* Helper::toAddress( std::vector<double>& );
275  template int* Helper::toAddress<int>( void* );
276  template float* Helper::toAddress<float>( void* );
277  template double* Helper::toAddress<double>( void* );
278 
279 } // namespace GaudiPython
280 
281 #endif // !GAUDIPYTHON_HELPERS_H
virtual SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
The interface implemented by the IToolSvc base class.
Definition: IToolSvc.h:29
constexpr auto size(const T &, Args &&...) noexcept
static PyObject * toPython(long *o)
Definition: Helpers.h:205
virtual StatusCode retrieve(const std::string &type, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent=0, bool createIf=true)=0
Retrieve tool with tool dependent part of the name automatically assigned.
static IAlgTool * tool(IToolSvc *toolsvc, const std::string &type, const std::string &name, IInterface *p, bool cif)
Definition: Helpers.h:150
static PyObject * toDoubleArray(void *ptr, Py_ssize_t size)
Definition: Helpers.h:250
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:35
static PyObject * toIntArray(void *ptr, Py_ssize_t size)
Definition: Helpers.h:247
static PyObject * toPython(double *o)
Definition: Helpers.h:207
static PyObject * toPython(int *o)
Definition: Helpers.h:202
static GAUDI_API DataObject * findobject(IDataProviderSvc *dpsvc, const std::string &path)
simple wrapper for IDataProviderSvc::findObject The methdod does NOT trigger the loading the object f...
Definition: Helpers.cpp:51
static PyObject * toArray(T *ptr, Py_ssize_t size)
Definition: Helpers.h:231
static IProfile2D * profile2D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:175
static PyObject * toPython(T *)
Definition: Helpers.h:199
The IAlgManager is the interface implemented by the Algorithm Factory in the Application Manager to s...
Definition: IAlgManager.h:37
static PyObject * Array_item(PyObject *self, Py_ssize_t idx)
Definition: Helpers.h:210
static PyObject * toPython(float *o)
Definition: Helpers.h:206
int Py_ssize_t
For compatibility with Python 2.4 and 2.5.
Definition: Helpers.h:81
Data provider interface definition.
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:86
static PyObject * toFloatArray(void *ptr, Py_ssize_t size)
Definition: Helpers.h:249
GaudiKernel.
Definition: Fill.h:20
virtual StatusCode fromString(const std::string &value)=0
string -> value
STL class.
virtual StatusCode unregisterObject(std::string_view fullPath)=0
Unregister object from the data store.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:86
static StatusCode setPropertyFromString(Gaudi::Details::PropertyBase &p, const std::string &s)
Definition: Helpers.h:262
T data(T... args)
static IHistogram3D * histo3D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:167
static long loadDynamicLib(const std::string &name)
Definition: Helpers.h:155
static T * toAddress(void *a)
Definition: Helpers.h:257
General service interface definition.
Definition: IService.h:28
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
Definition of the basic interface.
Definition: IInterface.h:254
static IAlgorithm * algorithm(IAlgManager *algmgr, const std::string &name, const bool createIf=false)
Definition: Helpers.h:107
Definition of the IHistogramSvc interface class.
Definition: IHistogramSvc.h:56
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:42
static GAUDI_API DataObject * getobject(IDataProviderSvc *dpsvc, const std::string &path, const bool retrieve=true, const bool disableDoD=false)
the generic function to get object from TES
Definition: Helpers.cpp:119
bool isSuccess() const
Definition: StatusCode.h:361
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:38
GaudiPython.h GaudiPython/GaudiPython.h.
Definition: AlgDecorators.h:47
static IHistogram2D * histo2D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:163
static StatusCode unregisterObject(IDataProviderSvc *dpsvc, const std::string &path)
Definition: Helpers.h:120
static IService * service(ISvcLocator *svcloc, const std::string &name, bool createif=false)
Definition: Helpers.h:103
STL class.
virtual StatusCode retrieveObject(IRegistry *pDirectory, std::string_view path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
static PyObject * toShortArray(void *ptr, Py_ssize_t size)
Definition: Helpers.h:248
static DataObject * dataobject(IDataProviderSvc *dpsvc, const std::string &path)
Definition: Helpers.h:111
StatusCode registerObject(std::string_view fullPath, DataObject *pObject)
Register object with the data store.
virtual StatusCode findObject(const std::string &fullPath, AIDA::IHistogram1D *&h1dObj)=0
static Py_ssize_t Array_length(PyObject *self)
Definition: Helpers.h:183
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:33
string s
Definition: gaudirun.py:328
static T * toAddress(std::vector< T > &v)
Definition: Helpers.h:253
static IProfile1D * profile1D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:171
#define GAUDI_API
Definition: Kernel.h:81
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:40
static IHistogram1D * histo1D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:159
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:263
static PyObject * toPython(char *o)
Definition: Helpers.h:204
static PyObject * toPython(short *o)
Definition: Helpers.h:203
static StatusCode registerObject(IDataProviderSvc *dpsvc, const std::string &path, DataObject *pObject)
Definition: Helpers.h:116
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
Definition: System.cpp:145