Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:45

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIPYTHON_HELPERS_H
0012 #define GAUDIPYTHON_HELPERS_H
0013 
0014 #include "Python.h"
0015 
0016 // Python 3 compatibility
0017 #if PY_MAJOR_VERSION >= 3
0018 
0019 #  define PyInt_FromLong PyLong_FromLong
0020 
0021 #  define PyBuffer_Type PyMemoryView_Type
0022 
0023 #endif
0024 
0025 #include "GaudiKernel/DataObject.h"
0026 #include "GaudiKernel/IAlgManager.h"
0027 #include "GaudiKernel/IAlgTool.h"
0028 #include "GaudiKernel/IAlgorithm.h"
0029 #include "GaudiKernel/IDataProviderSvc.h"
0030 #include "GaudiKernel/IHistogramSvc.h"
0031 #include "GaudiKernel/ISvcLocator.h"
0032 #include "GaudiKernel/IToolSvc.h"
0033 #include <Gaudi/Property.h>
0034 
0035 // FIXME: (MCl) workaround for ROOT-5850
0036 namespace AIDA {
0037   class IHistogram1D;
0038   class IHistogram2D;
0039   class IHistogram3D;
0040   class IProfile1D;
0041   class IProfile2D;
0042 } // namespace AIDA
0043 
0044 #if PY_VERSION_HEX < 0x02050000
0045 // Note (MCl):
0046 // In Python 2.5, all the functions working with lenghts use the type PySsize_t
0047 // instead of int. The also changed the name of the typedefs for those functions.
0048 // Here we use:
0049 //  intargfunc -> ssizeargfunc
0050 //  inquiry    -> lenfunc
0051 //
0052 /// For compatibility with Python 2.4 and 2.5
0053 typedef int Py_ssize_t;
0054 #endif
0055 
0056 // the following is done instead of including Python.h becuase there is
0057 // a clash with codecs.h defined in Python and the one in VC++ 7.1
0058 // struct _object;
0059 // typedef _object PyObject;
0060 // extern "C" {
0061 //  PyObject* PyBuffer_FromMemory( void *ptr, int size);
0062 //}
0063 
0064 /** Namespace for all classes interfacing Gaudi to Python.
0065  */
0066 
0067 namespace GaudiPython {
0068 
0069   struct Helper {
0070     // Python 3 compatibility
0071 #if PY_MAJOR_VERSION >= 3
0072     // Taken from ROOT's TPyBufferFactory
0073     static PyObject* PyBuffer_FromReadWriteMemory( void* ptr, int size ) {
0074 #  if PY_VERSION_HEX > 0x03000000
0075       // Python 3 will set an exception if nullptr, just rely on size == 0
0076       if ( !ptr ) {
0077         static long dummy[1];
0078         ptr  = dummy;
0079         size = 0;
0080       }
0081 #  endif
0082       Py_buffer bufinfo = {
0083         ptr,
0084         NULL,
0085         size,
0086         1,
0087         0,
0088         1,
0089         NULL,
0090         NULL,
0091         NULL,
0092         NULL,
0093 #  if PY_VERSION_HEX < 0x03030000
0094         { 0, 0 },
0095 #  endif
0096         NULL
0097       };
0098       return PyMemoryView_FromBuffer( &bufinfo );
0099     }
0100 #endif
0101     // This is a number of static functions to overcome the current problem with PyLCGDict that
0102     // does not allow to return instances of complex objects by calling arguments
0103     // (reference to pointers)
0104     Helper() {}
0105     // Provided for backward compatibility
0106     static IService* service( ISvcLocator* svcloc, const std::string& name, bool createif = false ) {
0107       return svcloc->service( name, createif ).get();
0108     }
0109     // Provided for backward compatibility
0110     static IAlgorithm* algorithm( IAlgManager* algmgr, const std::string& name, const bool createIf = false ) {
0111       return algmgr->algorithm( name, createIf ).get();
0112     }
0113     // ==========================================================================
0114     static DataObject* dataobject( IDataProviderSvc* dpsvc, const std::string& path ) {
0115       DataObject* o;
0116       return dpsvc->retrieveObject( path, o ).isSuccess() ? o : nullptr;
0117     }
0118     // ==========================================================================
0119     static StatusCode registerObject( IDataProviderSvc* dpsvc, const std::string& path, DataObject* pObject ) {
0120       return dpsvc->registerObject( path, pObject );
0121     }
0122     // ==========================================================================
0123     static StatusCode unregisterObject( IDataProviderSvc* dpsvc, const std::string& path ) {
0124       return dpsvc->unregisterObject( path );
0125     }
0126     // ==========================================================================
0127     /** simple wrapper for IDataProviderSvc::findObject
0128      *  The methdod does NOT trigger the loading the object from tape or Data-On-Demand action
0129      *  @see IDataProviderSvc
0130      *  @see IDataProviderSvc::findObject
0131      *  @param psvc (INPUT) pointer to Data ProviderService
0132      *  @param path the full path in TES
0133      *  @return the object
0134      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0135      *  @date 2009-10-09
0136      */
0137     static GAUDI_API DataObject* findobject( IDataProviderSvc* dpsvc, const std::string& path );
0138     // ==========================================================================
0139     /** the generic function to get object from TES
0140      *  @see IDataProviderSvc
0141      *  @see IDataProviderSvc::findObject
0142      *  @see IDataProviderSvc::retriveObject
0143      *  @param psvc       (INPUT) pointer to Data ProviderService
0144      *  @param path the full path in TES
0145      *  @param rerieve    (INPUT) retrieve or find object ?
0146      *  @param disableDoD (INPUT) disable 'on-demand-actions' ?
0147      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0148      *  @date 2009-10-09
0149      */
0150     static GAUDI_API DataObject* getobject( IDataProviderSvc* dpsvc, const std::string& path,
0151                                             const bool retrieve = true, const bool disableDoD = false );
0152     // ==========================================================================
0153     static IAlgTool* tool( IToolSvc* toolsvc, const std::string& type, const std::string& name, IInterface* p,
0154                            bool cif ) {
0155       IAlgTool* o;
0156       return toolsvc->retrieve( type, name, IAlgTool::interfaceID(), o, p, cif ).isSuccess() ? o : nullptr;
0157     }
0158     static long loadDynamicLib( const std::string& name ) {
0159       void* h;
0160       return System::loadDynamicLib( name, &h );
0161     }
0162     static IHistogram1D* histo1D( IHistogramSvc* hsvc, const std::string& path ) {
0163       IHistogram1D* h;
0164       return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
0165     }
0166     static IHistogram2D* histo2D( IHistogramSvc* hsvc, const std::string& path ) {
0167       IHistogram2D* h;
0168       return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
0169     }
0170     static IHistogram3D* histo3D( IHistogramSvc* hsvc, const std::string& path ) {
0171       IHistogram3D* h;
0172       return ( hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
0173     }
0174     static IProfile1D* profile1D( IHistogramSvc* hsvc, const std::string& path ) {
0175       IProfile1D* h = 0;
0176       return ( hsvc && hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
0177     }
0178     static IProfile2D* profile2D( IHistogramSvc* hsvc, const std::string& path ) {
0179       IProfile2D* h = 0;
0180       return ( hsvc && hsvc->findObject( path, h ).isSuccess() ) ? h : nullptr;
0181     }
0182 
0183     // Array support
0184   private:
0185     template <class T>
0186     static Py_ssize_t Array_length( PyObject* self ) {
0187 #if PY_MAJOR_VERSION >= 3
0188       Py_buffer bufinfo;
0189       ( *( self->ob_type->tp_as_buffer->bf_getbuffer ) )( self, &bufinfo, PyBUF_SIMPLE );
0190       Py_ssize_t size = bufinfo.len;
0191 #else
0192 #  if PY_VERSION_HEX < 0x02050000
0193       const
0194 #  endif
0195           char*  buf  = 0;
0196       Py_ssize_t size = ( *( self->ob_type->tp_as_buffer->bf_getcharbuffer ) )( self, 0, &buf );
0197 #endif
0198       return size / sizeof( T );
0199     }
0200 
0201     template <class T>
0202     static PyObject* toPython( T* /*o*/ ) {
0203       return 0;
0204     }
0205     static PyObject* toPython( int* o ) { return PyInt_FromLong( (long)*o ); }
0206     static PyObject* toPython( short* o ) { return PyInt_FromLong( (long)*o ); }
0207     static PyObject* toPython( char* o ) { return PyInt_FromLong( (long)*o ); }
0208     static PyObject* toPython( long* o ) { return PyInt_FromLong( *o ); }
0209     static PyObject* toPython( float* o ) { return PyFloat_FromDouble( (double)*o ); }
0210     static PyObject* toPython( double* o ) { return PyFloat_FromDouble( *o ); }
0211 
0212     template <class T>
0213     static PyObject* Array_item( PyObject* self, Py_ssize_t idx ) {
0214 #if PY_VERSION_HEX < 0x02050000
0215       const
0216 #endif
0217           char* buf = nullptr;
0218 #if PY_MAJOR_VERSION >= 3
0219       Py_buffer bufinfo;
0220       ( *( self->ob_type->tp_as_buffer->bf_getbuffer ) )( self, &bufinfo, PyBUF_SIMPLE );
0221       Py_ssize_t size = bufinfo.len;
0222 #else
0223       Py_ssize_t size = ( *( self->ob_type->tp_as_buffer->bf_getcharbuffer ) )( self, 0, &buf );
0224 #endif
0225       if ( idx < 0 || idx >= size / int( sizeof( T ) ) ) {
0226         PyErr_SetString( PyExc_IndexError, "buffer index out of range" );
0227         return nullptr;
0228       }
0229       return toPython( (T*)buf + idx );
0230     }
0231 
0232   public:
0233     template <class T>
0234     static PyObject* toArray( T* ptr, Py_ssize_t size ) {
0235       static PyTypeObject      type = PyBuffer_Type;
0236       static PySequenceMethods meth = *( PyBuffer_Type.tp_as_sequence );
0237 #if PY_VERSION_HEX < 0x02050000
0238       meth.sq_item   = (intargfunc)&Array_item<T>;
0239       meth.sq_length = (inquiry)&Array_length<T>;
0240 #else
0241       meth.sq_item    = (ssizeargfunc)&Array_item<T>;
0242       meth.sq_length  = (lenfunc)&Array_length<T>;
0243 #endif
0244       type.tp_as_sequence = &meth;
0245       PyObject* buf       = PyBuffer_FromReadWriteMemory( ptr, size * sizeof( T ) );
0246       buf->ob_type        = &type;
0247       Py_INCREF( buf->ob_type );
0248       return buf;
0249     }
0250     static PyObject* toIntArray( void* ptr, Py_ssize_t size ) { return toArray( (int*)ptr, size ); }
0251     static PyObject* toShortArray( void* ptr, Py_ssize_t size ) { return toArray( (short*)ptr, size ); }
0252     static PyObject* toFloatArray( void* ptr, Py_ssize_t size ) { return toArray( (float*)ptr, size ); }
0253     static PyObject* toDoubleArray( void* ptr, Py_ssize_t size ) { return toArray( (double*)ptr, size ); }
0254 
0255     template <class T>
0256     static T* toAddress( std::vector<T>& v ) {
0257       return v.data();
0258     }
0259     template <class T>
0260     static T* toAddress( void* a ) {
0261       return (T*)a;
0262     }
0263   };
0264 
0265   template PyObject* Helper::toArray( int*, Py_ssize_t );
0266   template PyObject* Helper::toArray( char*, Py_ssize_t );
0267   template PyObject* Helper::toArray( short*, Py_ssize_t );
0268   template PyObject* Helper::toArray( float*, Py_ssize_t );
0269   template PyObject* Helper::toArray( double*, Py_ssize_t );
0270   template int*      Helper::toAddress( std::vector<int>& );
0271   template float*    Helper::toAddress( std::vector<float>& );
0272   template double*   Helper::toAddress( std::vector<double>& );
0273   template int*      Helper::toAddress<int>( void* );
0274   template float*    Helper::toAddress<float>( void* );
0275   template double*   Helper::toAddress<double>( void* );
0276 
0277 } // namespace GaudiPython
0278 
0279 #endif // !GAUDIPYTHON_HELPERS_H