/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . * */ #ifndef _SRC_PY_CPP_PYCOVARIANCEMATRIX_HH_ #define _SRC_PY_CPP_PYCOVARIANCEMATRIX_HH_ // These ifdefs are required to avoid cpp compiler warning #ifdef _POSIX_C_SOURCE #undef _POSIX_C_SOURCE #endif #ifdef _XOPEN_SOURCE #undef _XOPEN_SOURCE #endif #include #ifdef MAUS_PYCOVARIANCEMATRIX_CC namespace MAUS { class CovarianceMatrix; // note this is just in MAUS namespace namespace PyCovarianceMatrix { /** PyCovarianceMatrix is the python implementation of the C++ CovarianceMatrix */ typedef struct { PyObject_HEAD; CovarianceMatrix* cov_mat; } PyCovarianceMatrix; /** @namespace C_API defines functions that can be accessed by other C libraries * * To access these functions call int import_PyCovarianceMatrix() otherwise you * will get a segmentation fault. The import will place the C_API functions in * the MAUS::PyCovarianceMatrix namespace. */ namespace C_API { /** Allocate a new PyCovarianceMatrix * * \returns PyCovarianceMatrix* cast as a PyObject* with cm pointer set to * NULL. Caller owns the memory allocated to PyCovarianceMatrix* */ static PyObject *create_empty_matrix(); /** Return the C++ covariance matrix associated with a PyCovarianceMatrix * * \param py_cm PyCovarianceMatrix* cast as a PyObject*. Python representation * of the covariance matrix * * \returns NULL on failure and raises a TypeError. On success returns the * CovarianceMatrix. PyCovarianceMatrix still owns the memory allocated to * CovarianceMatrix. */ static CovarianceMatrix* get_covariance_matrix(PyObject* py_cm); /** Set the C++ covariance matrix associated with a PyCovarianceMatrix * * \param py_cm PyCovarianceMatrix* cast as a PyObject*. Python representation * of the covariance matrix * \param cm C++ representation of the covariance matrix. PyCovarianceMatrix * takes ownership of the memory allocated to cm * * \returns 1 on success, 0 on failure and raises a TypeError */ static int set_covariance_matrix(PyObject* py_cm, CovarianceMatrix* cm); } /** _alloc allocates memory for PyCovarianceMatrix * * @param type - pointer to a PyCovarianceMatrixType object, as defined in * PyCovarianceMatrix.cc * * returns a PyCovarianceMatrix* (cast as a PyObject*); caller owns this memory */ static PyObject *_alloc(PyTypeObject *type, Py_ssize_t nitems); /** _init initialises an allocated PyCovarianceMatrix object * * @param self an initialised PyCovarianceMatrix* cast as a PyObject*; caller * owns this memory * @param args not used * @param kwds not used * * @returns 0 on success; -1 on failure */ static int _init(PyObject* self, PyObject *args, PyObject *kwds); /** deallocate memory * * @params self an initialised PyCovarianceMatrix*; memory will be freed by * this function */ static void _free(PyCovarianceMatrix * self); /** Return a Python string representation of the PyCovarianceMatrix */ static PyObject* _str(PyObject * self); /** Initialise covariance_matrix module * * This is called by import covariance_matrix; it initialises the * CovarianceMatrix type allowing user to construct and call methods on * CovarianceMatrix objects */ PyMODINIT_FUNC initcovariance_matrix(void); /** Get the value of an element * * \param self - not used * \param args - not used * \param kwds - keyword arguments; row, column for matrix row, column * */ static PyObject* get_element(PyObject* self, PyObject *args, PyObject *kwds); /** Create a PyCovarianceMatrix from penn parameters * * \param self - not used * \param args - value arguments * \param kwds - keyword arguments * * \returns PyCovarianceMatrix cast to a PyObject - caller owns this memory */ static PyObject* create_from_penn_parameters (PyObject *self, PyObject *args, PyObject *kwds); /** Create a PyCovarianceMatrix from twiss parameters * * \param self - not used * \param args - value arguments * \param kwds - keyword arguments * * \returns PyCovarianceMatrix cast to a PyObject - caller owns this memory */ static PyObject* create_from_twiss_parameters (PyObject *self, PyObject *args, PyObject *kwds); /** Create a PyCovarianceMatrix from a numpy matrix * * \param self - not used * \param args - value arguments * \param kwds - keyword arguments; takes one keywd, matrix which is a 6x6 * numpy matrix * * \returns PyCovarianceMatrix cast to a PyObject - caller owns this memory */ static PyObject* create_from_matrix (PyObject* self, PyObject *args, PyObject *kwds); /** Create a PyCovarianceMatrix from a numpy matrix * * \param numpy_array borrowed reference to a numpy array. Should be 6x6 * matrix, assumed to be symmetric. Borrowed reference means caller * still owns the array. * * \returns new CovarianceMatrix; caller owns the memory * * \throws MAUS::Exception if array has wrong shape or is not a numpy_array */ static CovarianceMatrix* create_from_numpy_matrix(PyObject *numpy_array); } } #else /** MAUS::PyOpticsModel::PyCovarianceMatrix C API objects * * Because of the way python does share libraries, we have to explicitly import * C functions via the Python API, which is done at import time. This mimics * the functions in MAUS::PyCovarianceMatrix. Full documentation is found * there. */ namespace MAUS { namespace PyCovarianceMatrix { /** import the PyCovarianceMatrix C_API * * Makes the functions in C_API available in the MAUS::PyCovarianceMatrix * namespace, for other python/C code * * @returns 0 if the import fails; return 1 if it is a success */ int import_PyCovarianceMatrix(); PyObject* (*create_empty_matrix)() = NULL; int (*set_covariance_matrix)(PyObject* py_cm, CovarianceMatrix* cm) = NULL; CovarianceMatrix* (*get_covariance_matrix)(PyObject* py_cm) = NULL; } } int MAUS::PyCovarianceMatrix::import_PyCovarianceMatrix() { PyObject* cm_module = PyImport_ImportModule("maus_cpp.covariance_matrix"); if (cm_module == NULL) { return 0; } else { PyObject *cm_dict = PyModule_GetDict(cm_module); PyObject* cem_c_api = PyDict_GetItemString(cm_dict, "C_API_CREATE_EMPTY_MATRIX"); void* cem_void = reinterpret_cast(PyCObject_AsVoidPtr(cem_c_api)); PyCovarianceMatrix::create_empty_matrix = reinterpret_cast(cem_void); PyObject* gcm_c_api = PyDict_GetItemString(cm_dict, "C_API_GET_COVARIANCE_MATRIX"); void* gcm_void = reinterpret_cast(PyCObject_AsVoidPtr(gcm_c_api)); PyCovarianceMatrix::get_covariance_matrix = reinterpret_cast(gcm_void); PyObject* scm_c_api = PyDict_GetItemString(cm_dict, "C_API_SET_COVARIANCE_MATRIX"); void* scm_void = reinterpret_cast(PyCObject_AsVoidPtr(scm_c_api)); PyCovarianceMatrix::set_covariance_matrix = reinterpret_cast(scm_void); if ((create_empty_matrix == NULL) || (set_covariance_matrix == NULL) || (get_covariance_matrix == NULL)) return 0; } return 1; } #endif // MAUS_PYCOVARIANCEMATRIX_CC #endif // _SRC_PY_CPP_PYCOVARIANCEMATRIX_HH_