The Gaudi Framework  master (d98a2936)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Helpers.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 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 #pragma once
12 
13 #include <Python.h>
14 
15 // Python 3 compatibility
16 #if PY_MAJOR_VERSION >= 3
17 
18 # define PyInt_FromLong PyLong_FromLong
19 
20 # define PyBuffer_Type PyMemoryView_Type
21 
22 #endif
23 
24 #include <Gaudi/Property.h>
25 #include <GaudiKernel/DataObject.h>
27 #include <GaudiKernel/IAlgTool.h>
28 #include <GaudiKernel/IAlgorithm.h>
32 #include <GaudiKernel/IToolSvc.h>
33 
34 // FIXME: (MCl) workaround for ROOT-5850
35 namespace AIDA {
36  class IHistogram1D;
37  class IHistogram2D;
38  class IHistogram3D;
39  class IProfile1D;
40  class IProfile2D;
41 } // namespace AIDA
42 
43 #if PY_VERSION_HEX < 0x02050000
44 // Note (MCl):
45 // In Python 2.5, all the functions working with lenghts use the type PySsize_t
46 // instead of int. The also changed the name of the typedefs for those functions.
47 // Here we use:
48 // intargfunc -> ssizeargfunc
49 // inquiry -> lenfunc
50 //
52 typedef int Py_ssize_t;
53 #endif
54 
55 // the following is done instead of including Python.h becuase there is
56 // a clash with codecs.h defined in Python and the one in VC++ 7.1
57 // struct _object;
58 // typedef _object PyObject;
59 // extern "C" {
60 // PyObject* PyBuffer_FromMemory( void *ptr, int size);
61 //}
62 
66 namespace GaudiPython {
67 
68  struct Helper {
69  // Python 3 compatibility
70 #if PY_MAJOR_VERSION >= 3
71  // Taken from ROOT's TPyBufferFactory
72  static PyObject* PyBuffer_FromReadWriteMemory( void* ptr, int size ) {
73 # if PY_VERSION_HEX > 0x03000000
74  // Python 3 will set an exception if nullptr, just rely on size == 0
75  if ( !ptr ) {
76  static long dummy[1];
77  ptr = dummy;
78  size = 0;
79  }
80 # endif
81  Py_buffer bufinfo = {
82  ptr,
83  NULL,
84  size,
85  1,
86  0,
87  1,
88  NULL,
89  NULL,
90  NULL,
91  NULL,
92 # if PY_VERSION_HEX < 0x03030000
93  { 0, 0 },
94 # endif
95  NULL
96  };
97  return PyMemoryView_FromBuffer( &bufinfo );
98  }
99 #endif
100  // This is a number of static functions to overcome the current problem with PyLCGDict that
101  // does not allow to return instances of complex objects by calling arguments
102  // (reference to pointers)
103  Helper() {}
104  // Provided for backward compatibility
105  static IService* service( ISvcLocator* svcloc, const std::string& name, bool createif = false ) {
106  return svcloc->service( name, createif ).get();
107  }
108  // Provided for backward compatibility
109  static IAlgorithm* algorithm( IAlgManager* algmgr, const std::string& name, const bool createIf = false ) {
110  return algmgr->algorithm( name, createIf ).get();
111  }
112  // ==========================================================================
113  static DataObject* dataobject( IDataProviderSvc* dpsvc, const std::string& path ) {
114  DataObject* o;
115  return dpsvc->retrieveObject( path, o ).isSuccess() ? o : nullptr;
116  }
117  // ==========================================================================
118  static StatusCode registerObject( IDataProviderSvc* dpsvc, const std::string& path, DataObject* pObject ) {
119  return dpsvc->registerObject( path, pObject );
120  }
121  // ==========================================================================
122  static StatusCode unregisterObject( IDataProviderSvc* dpsvc, const std::string& path ) {
123  return dpsvc->unregisterObject( path );
124  }
125  // ==========================================================================
136  static GAUDI_API DataObject* findobject( IDataProviderSvc* dpsvc, const std::string& path );
137  // ==========================================================================
149  static GAUDI_API DataObject* getobject( IDataProviderSvc* dpsvc, const std::string& path,
150  const bool retrieve = true, const bool disableDoD = false );
151  // ==========================================================================
152  static IAlgTool* tool( IToolSvc* toolsvc, const std::string& type, const std::string& name, IInterface* p,
153  bool cif ) {
154  IAlgTool* o;
155  return toolsvc->retrieve( type, name, IAlgTool::interfaceID(), o, p, cif ).isSuccess() ? o : nullptr;
156  }
157  static long loadDynamicLib( const std::string& name ) {
158  void* h;
159  return System::loadDynamicLib( name, &h );
160  }
161  static IHistogram1D* histo1D( IHistogramSvc* hsvc, const std::string& path ) {
162  IHistogram1D* h;
163  return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
164  }
165  static IHistogram2D* histo2D( IHistogramSvc* hsvc, const std::string& path ) {
166  IHistogram2D* h;
167  return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
168  }
169  static IHistogram3D* histo3D( IHistogramSvc* hsvc, const std::string& path ) {
170  IHistogram3D* h;
171  return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
172  }
173  static IProfile1D* profile1D( IHistogramSvc* hsvc, const std::string& path ) {
174  IProfile1D* h = 0;
175  return ( hsvc && hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
176  }
177  static IProfile2D* profile2D( IHistogramSvc* hsvc, const std::string& path ) {
178  IProfile2D* h = 0;
179  return ( hsvc && hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
180  }
181 
182  // Array support
183  private:
184  template <class T>
185  static Py_ssize_t Array_length( PyObject* self ) {
186 #if PY_MAJOR_VERSION >= 3
187  Py_buffer bufinfo;
188  ( *( self->ob_type->tp_as_buffer->bf_getbuffer ) )( self, &bufinfo, PyBUF_SIMPLE );
189  Py_ssize_t size = bufinfo.len;
190 #else
191 # if PY_VERSION_HEX < 0x02050000
192  const
193 # endif
194  char* buf = 0;
195  Py_ssize_t size = ( *( self->ob_type->tp_as_buffer->bf_getcharbuffer ) )( self, 0, &buf );
196 #endif
197  return size / sizeof( T );
198  }
199 
200  template <class T>
201  static PyObject* toPython( T* /*o*/ ) {
202  return 0;
203  }
204  static PyObject* toPython( int* o ) { return PyInt_FromLong( (long)*o ); }
205  static PyObject* toPython( short* o ) { return PyInt_FromLong( (long)*o ); }
206  static PyObject* toPython( char* o ) { return PyInt_FromLong( (long)*o ); }
207  static PyObject* toPython( long* o ) { return PyInt_FromLong( *o ); }
208  static PyObject* toPython( float* o ) { return PyFloat_FromDouble( (double)*o ); }
209  static PyObject* toPython( double* o ) { return PyFloat_FromDouble( *o ); }
210 
211  template <class T>
212  static PyObject* Array_item( PyObject* self, Py_ssize_t idx ) {
213 #if PY_VERSION_HEX < 0x02050000
214  const
215 #endif
216  char* buf = nullptr;
217 #if PY_MAJOR_VERSION >= 3
218  Py_buffer bufinfo;
219  ( *( self->ob_type->tp_as_buffer->bf_getbuffer ) )( self, &bufinfo, PyBUF_SIMPLE );
220  Py_ssize_t size = bufinfo.len;
221 #else
222  Py_ssize_t size = ( *( self->ob_type->tp_as_buffer->bf_getcharbuffer ) )( self, 0, &buf );
223 #endif
224  if ( idx < 0 || idx >= size / int( sizeof( T ) ) ) {
225  PyErr_SetString( PyExc_IndexError, "buffer index out of range" );
226  return nullptr;
227  }
228  return toPython( (T*)buf + idx );
229  }
230 
231  public:
232  template <class T>
233  static PyObject* toArray( T* ptr, Py_ssize_t size ) {
234  static PyTypeObject type = PyBuffer_Type;
235  static PySequenceMethods meth = *( PyBuffer_Type.tp_as_sequence );
236 #if PY_VERSION_HEX < 0x02050000
237  meth.sq_item = (intargfunc)&Array_item<T>;
238  meth.sq_length = (inquiry)&Array_length<T>;
239 #else
240  meth.sq_item = (ssizeargfunc)&Array_item<T>;
241  meth.sq_length = (lenfunc)&Array_length<T>;
242 #endif
243  type.tp_as_sequence = &meth;
244  PyObject* buf = PyBuffer_FromReadWriteMemory( ptr, size * sizeof( T ) );
245  buf->ob_type = &type;
246  Py_INCREF( buf->ob_type );
247  return buf;
248  }
249  static PyObject* toIntArray( void* ptr, Py_ssize_t size ) { return toArray( (int*)ptr, size ); }
250  static PyObject* toShortArray( void* ptr, Py_ssize_t size ) { return toArray( (short*)ptr, size ); }
251  static PyObject* toFloatArray( void* ptr, Py_ssize_t size ) { return toArray( (float*)ptr, size ); }
252  static PyObject* toDoubleArray( void* ptr, Py_ssize_t size ) { return toArray( (double*)ptr, size ); }
253 
254  template <class T>
255  static T* toAddress( std::vector<T>& v ) {
256  return v.data();
257  }
258  template <class T>
259  static T* toAddress( void* a ) {
260  return (T*)a;
261  }
262  };
263 
264  template PyObject* Helper::toArray( int*, Py_ssize_t );
265  template PyObject* Helper::toArray( char*, Py_ssize_t );
266  template PyObject* Helper::toArray( short*, Py_ssize_t );
267  template PyObject* Helper::toArray( float*, Py_ssize_t );
268  template PyObject* Helper::toArray( double*, Py_ssize_t );
269  template int* Helper::toAddress( std::vector<int>& );
270  template float* Helper::toAddress( std::vector<float>& );
271  template double* Helper::toAddress( std::vector<double>& );
272  template int* Helper::toAddress<int>( void* );
273  template float* Helper::toAddress<float>( void* );
274  template double* Helper::toAddress<double>( void* );
275 
276 } // namespace GaudiPython
IService
Definition: IService.h:26
GaudiPython::Helper::toIntArray
static PyObject * toIntArray(void *ptr, Py_ssize_t size)
Definition: Helpers.h:249
GaudiPython::Helper::toPython
static PyObject * toPython(short *o)
Definition: Helpers.h:205
GaudiPython::Helper::toPython
static PyObject * toPython(float *o)
Definition: Helpers.h:208
GaudiPython::Helper::dataobject
static DataObject * dataobject(IDataProviderSvc *dpsvc, const std::string &path)
Definition: Helpers.h:113
AIDA
Definition: Annotation.h:21
System::loadDynamicLib
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
Definition: System.cpp:115
IAlgManager.h
IDataProviderSvc::unregisterObject
virtual StatusCode unregisterObject(std::string_view fullPath)=0
Unregister object from the data store.
Py_ssize_t
int Py_ssize_t
For compatibility with Python 2.4 and 2.5.
Definition: Helpers.h:52
IAlgTool
Definition: IAlgTool.h:29
details::size
constexpr auto size(const T &, Args &&...) noexcept
Definition: AnyDataWrapper.h:23
IHistogramSvc
Definition: IHistogramSvc.h:53
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:314
GaudiPython::Helper::toDoubleArray
static PyObject * toDoubleArray(void *ptr, Py_ssize_t size)
Definition: Helpers.h:252
IHistogramSvc::findObject
virtual StatusCode findObject(const std::string &fullPath, AIDA::IHistogram1D *&h1dObj)=0
GaudiPython::Helper::toPython
static PyObject * toPython(char *o)
Definition: Helpers.h:206
GaudiPython::Helper::toPython
static PyObject * toPython(T *)
Definition: Helpers.h:201
GaudiPython::Helper::tool
static IAlgTool * tool(IToolSvc *toolsvc, const std::string &type, const std::string &name, IInterface *p, bool cif)
Definition: Helpers.h:152
GaudiPython::Helper::registerObject
static StatusCode registerObject(IDataProviderSvc *dpsvc, const std::string &path, DataObject *pObject)
Definition: Helpers.h:118
ISvcLocator
Definition: ISvcLocator.h:42
GaudiPython::Helper::getobject
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
GaudiPython::Helper
Definition: Helpers.h:68
GaudiPython::Helper::toPython
static PyObject * toPython(int *o)
Definition: Helpers.h:204
GaudiPython::Helper::toArray
static PyObject * toArray(T *ptr, Py_ssize_t size)
Definition: Helpers.h:233
GaudiPython::Helper::Array_item
static PyObject * Array_item(PyObject *self, Py_ssize_t idx)
Definition: Helpers.h:212
IDataProviderSvc.h
GaudiPython::Helper::histo3D
static IHistogram3D * histo3D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:169
IDataProviderSvc::registerObject
StatusCode registerObject(std::string_view fullPath, DataObject *pObject)
Register object with the data store.
Definition: IDataProviderSvc.h:67
GaudiPython::Helper::toAddress
static T * toAddress(std::vector< T > &v)
Definition: Helpers.h:255
IToolSvc.h
GaudiPython::Helper::toAddress
static T * toAddress(void *a)
Definition: Helpers.h:259
IAlgManager
Definition: IAlgManager.h:34
ISvcLocator::service
virtual SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
IAlgManager::algorithm
virtual SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
GaudiPython::Helper::toPython
static PyObject * toPython(long *o)
Definition: Helpers.h:207
StatusCode
Definition: StatusCode.h:64
IAlgorithm
Definition: IAlgorithm.h:36
IInterface::interfaceID
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:234
IDataProviderSvc::retrieveObject
virtual StatusCode retrieveObject(IRegistry *pDirectory, std::string_view path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
IAlgTool.h
AlgSequencer.h
h
Definition: AlgSequencer.py:31
GaudiPython::Helper::histo1D
static IHistogram1D * histo1D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:161
IToolSvc::retrieve
virtual StatusCode retrieve(std::string_view 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.
GaudiPython::Helper::Helper
Helper()
Definition: Helpers.h:103
GaudiPython::Helper::loadDynamicLib
static long loadDynamicLib(const std::string &name)
Definition: Helpers.h:157
GaudiPython::Helper::toPython
static PyObject * toPython(double *o)
Definition: Helpers.h:209
SmartRefVectorImpl::PyObject
_object PyObject
Definition: SmartRefVector.h:19
GaudiPython::Helper::toShortArray
static PyObject * toShortArray(void *ptr, Py_ssize_t size)
Definition: Helpers.h:250
GaudiPython::Helper::service
static IService * service(ISvcLocator *svcloc, const std::string &name, bool createif=false)
Definition: Helpers.h:105
GaudiPython::Helper::Array_length
static Py_ssize_t Array_length(PyObject *self)
Definition: Helpers.h:185
gaudirun.type
type
Definition: gaudirun.py:160
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
DataObject.h
SmartIF::get
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:82
GaudiPython::Helper::profile2D
static IProfile2D * profile2D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:177
GaudiPython
Namespace for all classes interfacing Gaudi to Python.
Definition: Algorithm.h:29
IInterface
Definition: IInterface.h:225
DataObject
Definition: DataObject.h:37
Properties.v
v
Definition: Properties.py:122
GaudiPython::Helper::algorithm
static IAlgorithm * algorithm(IAlgManager *algmgr, const std::string &name, const bool createIf=false)
Definition: Helpers.h:109
GaudiPython::Helper::toFloatArray
static PyObject * toFloatArray(void *ptr, Py_ssize_t size)
Definition: Helpers.h:251
IDataProviderSvc
Definition: IDataProviderSvc.h:48
IAlgorithm.h
ISvcLocator.h
GaudiPython::Helper::findobject
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
IToolSvc
Definition: IToolSvc.h:28
GAUDI_API
#define GAUDI_API
Definition: Kernel.h:49
IHistogramSvc.h
GaudiPython::Helper::histo2D
static IHistogram2D * histo2D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:165
GaudiPython::Helper::profile1D
static IProfile1D * profile1D(IHistogramSvc *hsvc, const std::string &path)
Definition: Helpers.h:173
Property.h
GaudiPython::Helper::unregisterObject
static StatusCode unregisterObject(IDataProviderSvc *dpsvc, const std::string &path)
Definition: Helpers.h:122