00001 #include <psana_python/python_converter.h>
00002
00003
00004 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
00005 #define PY_ARRAY_UNIQUE_SYMBOL PSALG_NUMPY_NDARRAY_CONVERTER
00006 #include <numpy/arrayobject.h>
00007
00008 #include <boost/preprocessor/seq/for_each_product.hpp>
00009 #include <boost/preprocessor/seq/elem.hpp>
00010 #include <boost/preprocessor/seq/for_each.hpp>
00011
00012 #include <pytools/PyDataType.h>
00013
00014 #include <PSEvt/Event.h>
00015 #include <psana_python/Event.h>
00016
00017 #include <PSEnv/Env.h>
00018 #include <psana_python/Env.h>
00019
00020 #include <PSEvt/Source.h>
00021 #include <psana_python/Source.h>
00022
00023
00024 #include <string>
00025 #include <iostream>
00026 #include "MsgLogger/MsgLogger.h"
00027
00028
00029
00030 #define ND_RANKS (1)(2)(3)(4)(5)(6)
00031 #define ND_TYPES (int8_t)(uint8_t)(int16_t)(uint16_t)(int32_t)(uint32_t)(int64_t)(uint64_t)(float)(double)
00032 #define CONST_ND_TYPES (const int8_t)(const uint8_t)(const int16_t)(const uint16_t)(const int32_t)(const uint32_t)(const int64_t)(const uint64_t)(const float)(const double)
00033
00034
00035 namespace psana_python {
00036
00037
00038 const char *pyConverterlogger = "Python_Converter";
00039
00040 void createConverters() {
00041
00042
00043 import_array();
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #define REGISTER_NDARRAY_TO_NUMPY_CONVERTER(r,PRODUCT) \
00065 psana_python::NDArrayToNumpy<BOOST_PP_SEQ_ELEM(0,PRODUCT),BOOST_PP_SEQ_ELEM(1,PRODUCT)>().register_ndarray_to_numpy_cvt();
00066
00067
00068
00069 #define REGISTER_NUMPY_TO_NDARRAY_CONVERTER(r,PRODUCT) \
00070 psana_python::NumpyToNDArray<BOOST_PP_SEQ_ELEM(0,PRODUCT),BOOST_PP_SEQ_ELEM(1,PRODUCT)>().from_python();
00071
00072
00073
00074
00075 BOOST_PP_SEQ_FOR_EACH_PRODUCT(REGISTER_NDARRAY_TO_NUMPY_CONVERTER,(ND_TYPES)(ND_RANKS))
00076 BOOST_PP_SEQ_FOR_EACH_PRODUCT(REGISTER_NDARRAY_TO_NUMPY_CONVERTER,(CONST_ND_TYPES)(ND_RANKS))
00077
00078 BOOST_PP_SEQ_FOR_EACH_PRODUCT(REGISTER_NUMPY_TO_NDARRAY_CONVERTER,(ND_TYPES)(ND_RANKS))
00079 BOOST_PP_SEQ_FOR_EACH_PRODUCT(REGISTER_NUMPY_TO_NDARRAY_CONVERTER,(CONST_ND_TYPES)(ND_RANKS))
00080
00081
00082
00083 #define REGISTER_STLLIST_TO_NUMPY_CONVERTER(r,data, ELEMENT) \
00084 psana_python::StlListToNumpy< ELEMENT >().register_stllist_to_numpy_cvt();
00085
00086 BOOST_PP_SEQ_FOR_EACH(REGISTER_STLLIST_TO_NUMPY_CONVERTER,BOOST_PP_EMPTY(),ND_TYPES)
00087
00088
00089 psana_python::PyEvtToEvt().from_python();
00090
00091
00092 psana_python::PyEnvToEnv().from_python();
00093
00094
00095 psana_python::PySourceToSource().from_python();
00096
00097 return;
00098 }
00099
00100
00101 namespace {
00102
00103
00104
00105 template <typename T> struct Traits {};
00106
00107
00108
00109
00110 template <> struct Traits<int8_t> {
00111 static const char* typeName() { return "int8"; }
00112 static int numpyType() { return NPY_INT8; }
00113 };
00114 template <> struct Traits<uint8_t> {
00115 static const char* typeName() { return "uint8"; }
00116 static int numpyType() { return NPY_UINT8; }
00117 };
00118 template <> struct Traits<int16_t> {
00119 static const char* typeName() { return "int16"; }
00120 static int numpyType() { return NPY_INT16; }
00121 };
00122 template <> struct Traits<uint16_t> {
00123 static const char* typeName() { return "uint16"; }
00124 static int numpyType() { return NPY_UINT16; }
00125 };
00126 template <> struct Traits<int32_t> {
00127 static const char* typeName() { return "int32"; }
00128 static int numpyType() { return NPY_INT32; }
00129 };
00130 template <> struct Traits<uint32_t> {
00131 static const char* typeName() { return "uint32"; }
00132 static int numpyType() { return NPY_UINT32; }
00133 };
00134 template <> struct Traits<int64_t> {
00135 static const char* typeName() { return "int64"; }
00136 static int numpyType() { return NPY_INT64; }
00137 };
00138 template <> struct Traits<uint64_t> {
00139 static const char* typeName() { return "uint64"; }
00140 static int numpyType() { return NPY_UINT64; }
00141 };
00142 template <> struct Traits<float> {
00143 static const char* typeName() { return "float32"; }
00144 static int numpyType() { return NPY_FLOAT32; }
00145 };
00146 template <> struct Traits<double> {
00147 static const char* typeName() { return "float64"; }
00148 static int numpyType() { return NPY_FLOAT64; }
00149 };
00150
00151
00152
00153 template <> struct Traits<const int8_t> {
00154 static const char* typeName() { return "int8"; }
00155 static int numpyType() { return NPY_INT8; }
00156 };
00157 template <> struct Traits<const uint8_t> {
00158 static const char* typeName() { return "uint8"; }
00159 static int numpyType() { return NPY_UINT8; }
00160 };
00161 template <> struct Traits<const int16_t> {
00162 static const char* typeName() { return "int16"; }
00163 static int numpyType() { return NPY_INT16; }
00164 };
00165 template <> struct Traits<const uint16_t> {
00166 static const char* typeName() { return "uint16"; }
00167 static int numpyType() { return NPY_UINT16; }
00168 };
00169 template <> struct Traits<const int32_t> {
00170 static const char* typeName() { return "int32"; }
00171 static int numpyType() { return NPY_INT32; }
00172 };
00173 template <> struct Traits<const uint32_t> {
00174 static const char* typeName() { return "uint32"; }
00175 static int numpyType() { return NPY_UINT32; }
00176 };
00177 template <> struct Traits<const int64_t> {
00178 static const char* typeName() { return "int64"; }
00179 static int numpyType() { return NPY_INT64; }
00180 };
00181 template <> struct Traits<const uint64_t> {
00182 static const char* typeName() { return "uint64"; }
00183 static int numpyType() { return NPY_UINT64; }
00184 };
00185 template <> struct Traits<const float> {
00186 static const char* typeName() { return "float32"; }
00187 static int numpyType() { return NPY_FLOAT32; }
00188 };
00189 template <> struct Traits<const double> {
00190 static const char* typeName() { return "float64"; }
00191 static int numpyType() { return NPY_FLOAT64; }
00192 };
00193
00194
00195
00196 template <unsigned Rank>
00197 bool isCArray(const unsigned shape[], const int strides[]) {
00198 int stride = 1;
00199 for (int i = Rank; i > 0; -- i) {
00200 if (strides[i-1] != stride) return false;
00201 stride *= shape[i-1];
00202 }
00203 return true;
00204 }
00205
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 namespace {
00217
00218 template <typename T, unsigned Rank>
00219 class NDarrayWrapper :
00220 public pytools::PyDataType<NDarrayWrapper<T, Rank>, ndarray<T, Rank> > { };
00221 }
00222
00223
00224 template <typename T, unsigned Rank>
00225 PyObject* NDArrayToNumpy<T,Rank>::convert(ndarray<T, Rank> const& array)
00226 {
00227 MsgLog(pyConverterlogger, debug, "Calling converter from ndarray<"
00228 << Traits<T>::typeName() << "," << Rank << "> to python object");
00229
00230
00231 const size_t itemsize = sizeof(T);
00232
00233
00234
00235 const int typenum = Traits<T>::numpyType();
00236
00237
00238 npy_intp dims[Rank], strides[Rank];
00239
00240
00241
00242 for (unsigned i=0; i<Rank; i++) {
00243 dims[i] = array.shape()[i];
00244 strides[i] = array.strides()[i] * itemsize;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 const void* data = array.data();
00259
00260
00261
00262 int flags = 0;
00263
00264
00265 flags |= NPY_ARRAY_WRITEABLE;
00266
00267
00268
00269 if (psana_python::isCArray<Rank>(array.shape(),array.strides())) {
00270 flags |= NPY_ARRAY_C_CONTIGUOUS;
00271 }
00272
00273
00274 if (reinterpret_cast<size_t>(array.data()) % itemsize == 0) {
00275 flags |= NPY_ARRAY_ALIGNED;
00276 }
00277
00278
00279
00280 PyObject* outgoing_numpy_array = PyArray_New(&PyArray_Type,
00281 Rank,
00282 dims,
00283 typenum,
00284 strides,
00285 const_cast<void*>(data),
00286 itemsize,
00287 flags,
00288 0);
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 PyObject* numpy_array_tracking_object =
00327 NDarrayWrapper<T,Rank>::PyObject_FromCpp(array);
00328
00329
00330
00331
00332
00333 PyArrayObject* aoptr_outgoing_numpy_array =
00334 reinterpret_cast<PyArrayObject*>(outgoing_numpy_array);
00335 PyArray_SetBaseObject(aoptr_outgoing_numpy_array,
00336 numpy_array_tracking_object);
00337
00338
00339
00340 return outgoing_numpy_array;
00341 }
00342
00343
00344
00345 template <typename T, unsigned Rank>
00346 void NDArrayToNumpy<T,Rank>::register_ndarray_to_numpy_cvt()
00347 {
00348
00349 boost::python::type_info tinfo = boost::python::type_id<ndarray<T, Rank> >();
00350 boost::python::converter::registration const* reg = boost::python::converter::registry::query(tinfo);
00351
00352 if (reg == NULL) {
00353 MsgLog(pyConverterlogger, debug,
00354 "REGISTER NDARRAY<" << Traits<T>::typeName() << "," << Rank << ">"
00355 << "TO NUMPY CONVERTER");
00356 boost::python::to_python_converter<ndarray<T,Rank>,NDArrayToNumpy<T,Rank> >();
00357
00358 } else if ( (*reg).m_to_python == NULL) {
00359 MsgLog(pyConverterlogger, debug,
00360 "REGISTER NDARRAY<" << Traits<T>::typeName() << "," << Rank << ">"
00361 << "TO NUMPY CONVERTER");
00362 boost::python::to_python_converter<ndarray<T,Rank>,NDArrayToNumpy<T,Rank> >();
00363
00364 } else {
00365 MsgLog(pyConverterlogger, debug,
00366 "NDARRAY<" << Traits<T>::typeName() << "," << Rank << ">"
00367 << "TO NUMPY CONVERTER ALREADY REGISTERED");
00368 }
00369
00370 return;
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 template <typename T, unsigned Rank>
00393 NumpyToNDArray<T,Rank>& NumpyToNDArray<T,Rank>::from_python()
00394 {
00395
00396 boost::python::type_info tinfo = boost::python::type_id<ndarray<T, Rank> >();
00397 boost::python::converter::registration const* reg = boost::python::converter::registry::query(tinfo);
00398
00399
00400 MsgLog(pyConverterlogger, debug,"reg:" << reg);
00401 MsgLog(pyConverterlogger, debug,"reg.m_to_python:" << (*reg).m_to_python);
00402 MsgLog(pyConverterlogger, debug,"reg.m_class_object:" << (*reg).m_class_object);
00403 MsgLog(pyConverterlogger, debug,"reg.lvalue_chain:" << (*reg).lvalue_chain);
00404 MsgLog(pyConverterlogger, debug,"reg.rvalue_chain:" << (*reg).rvalue_chain);
00405
00406 if (reg == NULL) {
00407 boost::python::converter::registry::push_back(&NumpyToNDArray::convertible,
00408 &NumpyToNDArray::construct,
00409 boost::python::type_id< ndarray<T, Rank> >() );
00410 MsgLog(pyConverterlogger, debug,
00411 "REGISTER BOOST PYTHON converter for NUMPY to NDARRAY"
00412 << "<" << Traits<T>::typeName() << "," << Rank << ">");
00413
00414 } else if ((*reg).rvalue_chain == NULL && (*reg).lvalue_chain == NULL) {
00415 boost::python::converter::registry::push_back(&NumpyToNDArray::convertible,
00416 &NumpyToNDArray::construct,
00417 boost::python::type_id< ndarray<T, Rank> >() );
00418 MsgLog(pyConverterlogger, debug,
00419 "REGISTER BOOST PYTHON converter for NUMPY to NDARRAY"
00420 << "<" << Traits<T>::typeName() << "," << Rank << ">");
00421
00422
00423
00424 } else {
00425 MsgLog(pyConverterlogger, debug,
00426 "BOOST PYTHON converter for NUMPY to NDARRAY"
00427 << "<" << Traits<T>::typeName() << "," << Rank << "> ALREADY REGISTERED");
00428 }
00429
00430 return *this;
00431 }
00432
00433
00434
00435 template <typename T, unsigned Rank>
00436 void* NumpyToNDArray<T,Rank>::convertible(PyObject* obj)
00437 {
00438 MsgLog(pyConverterlogger, debug,"CHECKING PYTHON OBJECT IS A NUMPY ARRAY");
00439 MsgLog(pyConverterlogger, debug,
00440 "Value from PyArray_Check " << PyArray_Check(obj) );
00441
00442 if ( !PyArray_Check(obj) ) {
00443 MsgLog(pyConverterlogger, debug,"PYTHON OBJECT IS NOT A NUMPY ARRAY");
00444 return NULL;
00445 }
00446
00447 PyArrayObject* arrayPtr = reinterpret_cast<PyArrayObject*>(obj);
00448 const int rank = PyArray_NDIM(arrayPtr);
00449 if (rank != Rank) {
00450 MsgLog(pyConverterlogger, debug,
00451 "INCORRECT NUMBER OF DIMENSIONS. Expected:" << Rank << " Got:" << rank);
00452 return NULL;
00453 }
00454
00455 if (Traits<T>::numpyType() != PyArray_TYPE(arrayPtr)) {
00456 MsgLog(pyConverterlogger, debug,
00457 "INCORRECT TYPE. Expected " << Traits<T>::typeName()
00458 << " Got:" << PyArray_TYPE(arrayPtr));
00459 return NULL;
00460 }
00461
00462 MsgLog(pyConverterlogger, debug,"PYTHON OBJECT IS A NUMPY ARRAY");
00463 MsgLog(pyConverterlogger, debug,"Leaving convertible");
00464 return obj;
00465 }
00466
00467
00468
00469
00470
00471
00472 template <typename T, unsigned Rank>
00473 void NumpyToNDArray<T,Rank>::construct(PyObject* obj, BoostData* boostData)
00474 {
00475
00476
00477 PyArrayObject* arrayPtr = reinterpret_cast<PyArrayObject*>(obj);
00478
00479 const int itemsize = PyArray_ITEMSIZE(arrayPtr);
00480
00481
00482
00483 T* array = reinterpret_cast<T*>(PyArray_DATA(arrayPtr));
00484
00485
00486 unsigned shape[Rank];
00487 int strides[Rank];
00488 for (unsigned i=0; i<Rank; i++) {
00489 shape[i] = PyArray_DIM(arrayPtr,i);
00490
00491 strides[i] = PyArray_STRIDE(arrayPtr,i)/itemsize;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500 typedef boost::python::converter::rvalue_from_python_storage<ndarray<T,Rank> > storagetype;
00501
00502
00503 void* storage = reinterpret_cast<storagetype*> (boostData)->storage.bytes;
00504
00505
00506 MsgLog(pyConverterlogger, debug,"Creating outgoing ndarray");
00507 boostData->convertible = new(storage) ndarray<T,Rank>(array,shape);
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 ndarray<T,Rank>* outgoingArray = reinterpret_cast<ndarray<T,Rank>*>(boostData->convertible);
00528 outgoingArray->strides(strides);
00529
00530 MsgLog(pyConverterlogger, debug,
00531 "Address of orignal Numpy data " << array);
00532 return;
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 template <typename T>
00554 PyObject* StlListToNumpy<T>::convert( std::list<T> const& list )
00555 {
00556 MsgLog(pyConverterlogger, debug,
00557 "Calling converter from stl::list<"
00558 << Traits<T>::typeName() << "> to python object");
00559
00560
00561 const int typenum = Traits<T>::numpyType();
00562
00563
00564 npy_intp dims[1];
00565 dims[0] = list.size();
00566
00567
00568 PyObject* outgoing_numpy_array = PyArray_SimpleNew(1,dims,typenum);
00569
00570
00571 PyArrayObject* aoptr_outgoing_numpy_array =
00572 reinterpret_cast<PyArrayObject*>(outgoing_numpy_array);
00573
00574
00575 T* arrayData = reinterpret_cast<T*>(PyArray_DATA(aoptr_outgoing_numpy_array));
00576
00577
00578
00579 typename std::list<T>::const_iterator listIter;
00580 for(listIter = list.begin(); listIter != list.end(); listIter++,arrayData++)
00581 {
00582 MsgLog(pyConverterlogger, debug, *listIter);
00583 *arrayData = *listIter;
00584 }
00585
00586
00587
00588 return outgoing_numpy_array;
00589 }
00590
00591
00592
00593
00594 template <typename T>
00595 void StlListToNumpy<T>::register_stllist_to_numpy_cvt()
00596 {
00597
00598 boost::python::type_info tinfo = boost::python::type_id< std::list<T> >();
00599 boost::python::converter::registration const* reg = boost::python::converter::registry::query(tinfo);
00600
00601 if (reg == NULL) {
00602 MsgLog(pyConverterlogger, debug,
00603 "REGISTER STL LIST<" << Traits<T>::typeName() << ">"
00604 << "TO NUMPY CONVERTER");
00605 boost::python::to_python_converter< std::list<T>, StlListToNumpy<T> >();
00606
00607 } else if ( (*reg).m_to_python == NULL) {
00608 MsgLog(pyConverterlogger, debug,
00609 "REGISTER STL LIST<" << Traits<T>::typeName() << ">"
00610 << "TO NUMPY CONVERTER");
00611 boost::python::to_python_converter< std::list<T>, StlListToNumpy<T> >();
00612
00613 } else {
00614 MsgLog(pyConverterlogger, debug,
00615 "STL LIST<" << Traits<T>::typeName() << ">"
00616 << "TO NUMPY CONVERTER ALREADY REGISTERED");
00617 }
00618
00619 return;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 PyEvtToEvt& PyEvtToEvt::from_python()
00640 {
00641
00642 boost::python::type_info tinfo = boost::python::type_id< boost::shared_ptr<PSEvt::Event> >();
00643 boost::python::converter::registration const* reg = boost::python::converter::registry::query(tinfo);
00644
00645
00646 MsgLog(pyConverterlogger, debug,"reg:" << reg);
00647 if (reg == NULL) {
00648 boost::python::converter::registry::push_back(&PyEvtToEvt::convertible,
00649 &PyEvtToEvt::construct,
00650 boost::python::type_id<boost::shared_ptr<PSEvt::Event> >());
00651
00652 MsgLog(pyConverterlogger, debug,"REGISTER BOOST PYTHON converter for Event");
00653
00654 } else if ((*reg).rvalue_chain == NULL && (*reg).lvalue_chain == NULL) {
00655 boost::python::converter::registry::push_back(&PyEvtToEvt::convertible,
00656 &PyEvtToEvt::construct,
00657 boost::python::type_id<boost::shared_ptr<PSEvt::Event> >());
00658 MsgLog(pyConverterlogger, debug,"REGISTER BOOST PYTHON converter for Event");
00659
00660
00661
00662 } else {
00663 MsgLog(pyConverterlogger, debug,"BOOST PYTHON converter for Event ALREADY REGISTERED");
00664 }
00665
00666 return *this;
00667 }
00668
00669
00670
00671 void* PyEvtToEvt::convertible(PyObject* obj)
00672 {
00673 MsgLog(pyConverterlogger, debug,"CHECKING PYTHON OBJECT IS A PYTHON-EVENT");
00674 MsgLog(pyConverterlogger, debug,"Pyobject type " << obj->ob_type->tp_name );
00675
00676 if (!psana_python::Event::Object_TypeCheck(obj)) {
00677 MsgLog(pyConverterlogger, debug,"PYTHON OBJECT IS NOT A PSANA EVENT");
00678 return NULL;
00679 }
00680
00681 MsgLog(pyConverterlogger, debug,"PYTHON OBJECT IS A PSANA EVENT");
00682 MsgLog(pyConverterlogger, debug,"Leaving convertible");
00683 return obj;
00684 }
00685
00686
00687
00688
00689
00690
00691 void PyEvtToEvt::construct(PyObject* obj, BoostData* boostData)
00692 {
00693
00694
00695
00696
00697 MsgLog(pyConverterlogger, debug,"Pointing back to original PSANA Event Object");
00698
00699
00700
00701
00702
00703
00704
00705 MsgLog(pyConverterlogger, debug,
00706 " WE ARE GIVING BOOST A REFERENCE TO A SMART POINTER")
00707 psana_python::Event* py_this = static_cast<psana_python::Event*>(obj);
00708 boostData->convertible = static_cast<void*> (&(py_this->m_obj));
00709
00710 return;
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 PyEnvToEnv& PyEnvToEnv::from_python()
00730 {
00731
00732 boost::python::type_info tinfo = boost::python::type_id< boost::shared_ptr<PSEnv::Env> >();
00733 boost::python::converter::registration const* reg = boost::python::converter::registry::query(tinfo);
00734
00735
00736 MsgLog(pyConverterlogger, debug,"reg:" << reg);
00737 if (reg == NULL) {
00738 boost::python::converter::registry::push_back(&PyEnvToEnv::convertible,
00739 &PyEnvToEnv::construct,
00740 boost::python::type_id<boost::shared_ptr<PSEnv::Env> >());
00741
00742 MsgLog(pyConverterlogger, debug,"REGISTER BOOST PYTHON converter for Env");
00743
00744 } else if ((*reg).rvalue_chain == NULL && (*reg).lvalue_chain == NULL) {
00745 boost::python::converter::registry::push_back(&PyEnvToEnv::convertible,
00746 &PyEnvToEnv::construct,
00747 boost::python::type_id<boost::shared_ptr<PSEnv::Env> >());
00748 MsgLog(pyConverterlogger, debug,"REGISTER BOOST PYTHON converter for Env");
00749
00750
00751
00752 } else {
00753 MsgLog(pyConverterlogger, debug,"BOOST PYTHON converter for Env ALREADY REGISTERED");
00754 }
00755
00756 return *this;
00757 }
00758
00759
00760
00761 void* PyEnvToEnv::convertible(PyObject* obj)
00762 {
00763 MsgLog(pyConverterlogger, debug,"CHECKING PYTHON OBJECT IS A PYTHON-ENV");
00764 MsgLog(pyConverterlogger, debug,"Pyobject type " << obj->ob_type->tp_name );
00765
00766 if (!psana_python::Env::Object_TypeCheck(obj)) {
00767 MsgLog(pyConverterlogger, debug,"PYTHON OBJECT IS NOT A PSANA ENV");
00768 return NULL;
00769 }
00770
00771 MsgLog(pyConverterlogger, debug,"PYTHON OBJECT IS A PSANA ENV");
00772 MsgLog(pyConverterlogger, debug,"Leaving convertible");
00773 return obj;
00774 }
00775
00776
00777
00778
00779
00780
00781 void PyEnvToEnv::construct(PyObject* obj, BoostData* boostData)
00782 {
00783
00784
00785
00786
00787 MsgLog(pyConverterlogger, debug,"Pointing back to original PSANA Env Object");
00788
00789
00790
00791
00792
00793
00794
00795 MsgLog(pyConverterlogger, debug,
00796 " WE ARE GIVING BOOST A REFERENCE TO A SMART POINTER")
00797 psana_python::Env* py_this = static_cast<psana_python::Env*>(obj);
00798 boostData->convertible = static_cast<void*> (&(py_this->m_obj));
00799
00800 return;
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819 PySourceToSource& PySourceToSource::from_python()
00820 {
00821
00822 boost::python::type_info tinfo = boost::python::type_id<PSEvt::Source>();
00823 boost::python::converter::registration const* reg = boost::python::converter::registry::query(tinfo);
00824
00825
00826 MsgLog(pyConverterlogger, debug,"reg:" << reg);
00827 if (reg == NULL) {
00828 boost::python::converter::registry::push_back(&PySourceToSource::convertible,
00829 &PySourceToSource::construct,
00830 boost::python::type_id<PSEvt::Source>());
00831
00832 MsgLog(pyConverterlogger, debug,"REGISTER BOOST PYTHON converter for Source");
00833
00834 } else if ((*reg).rvalue_chain == NULL && (*reg).lvalue_chain == NULL) {
00835 boost::python::converter::registry::push_back(&PySourceToSource::convertible,
00836 &PySourceToSource::construct,
00837 boost::python::type_id<PSEvt::Source>());
00838 MsgLog(pyConverterlogger, debug,"REGISTER BOOST PYTHON converter for Source");
00839
00840
00841
00842 } else {
00843 MsgLog(pyConverterlogger, debug,"BOOST PYTHON converter for Source ALREADY REGISTERED");
00844 }
00845
00846 return *this;
00847 }
00848
00849
00850
00851 void* PySourceToSource::convertible(PyObject* obj)
00852 {
00853 MsgLog(pyConverterlogger, debug,"CHECKING PYTHON OBJECT IS A PYTHON-SOURCE");
00854
00855 if (!psana_python::Source::Object_TypeCheck(obj) ) {
00856 MsgLog(pyConverterlogger, debug,"PYTHON OBJECT IS NOT A PSANA SOURCE");
00857 return NULL;
00858 }
00859
00860 MsgLog(pyConverterlogger, debug,"PYTHON OBJECT IS A PSANA SOURCE");
00861 MsgLog(pyConverterlogger, debug,"Leaving convertible");
00862 return obj;
00863 }
00864
00865
00866
00867
00868
00869
00870 void PySourceToSource::construct(PyObject* obj, BoostData* boostData)
00871 {
00872
00873
00874
00875
00876 MsgLog(pyConverterlogger, debug,"Pointing back to original PSANA Source Object");
00877
00878 psana_python::Source* py_this = static_cast<psana_python::Source*>(obj);
00879
00880
00881
00882
00883
00884 typedef boost::python::converter::rvalue_from_python_storage<PSEvt::Source> storagetype;
00885
00886
00887 void* storage = reinterpret_cast<storagetype*> (boostData)->storage.bytes;
00888
00889
00890 MsgLog(pyConverterlogger, debug,"Creating outgoing CPP-SOURCE");
00891 boostData->convertible = new(storage) PSEvt::Source(py_this->m_obj);
00892
00893 return;
00894 }
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 }
00906