1
/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus
3
* MAUS is free software: you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation, either version 3 of the License, or
6
* (at your option) any later version.
8
* MAUS is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with MAUS. If not, see <http://www.gnu.org/licenses/>.
18
#ifndef _SRC_PY_CPP_PYPHASESPACEVECTOR_HH_
19
#define _SRC_PY_CPP_PYPHASESPACEVECTOR_HH_
21
// These ifdefs are required to avoid cpp compiler warning
22
#ifdef _POSIX_C_SOURCE
23
#undef _POSIX_C_SOURCE
32
#ifdef MAUS_PYPHASESPACEVECTOR_CC
36
class PhaseSpaceVector; // note this is just in MAUS namespace
38
/** Methods for the PyPhaseSpaceVector object
40
namespace PyPhaseSpaceVector {
42
/** PyPhaseSpaceVector is the python implementation of the C++ PhaseSpaceVector
46
PhaseSpaceVector* psv;
49
/** @namespace C_API defines functions that can be accessed by other C libraries
51
* To access these functions, you must call import_PyPhaseSpaceVector()
52
* (otherwise you will get segmentation fault)
56
/** Create a new empty PyPhaseSpaceVector (psv is NULL)
58
* \returns NULL on failure or the object on success. Caller owns the returned
62
static PyObject* create_empty_vector();
64
/** Return the C++ PhaseSpaceVector associated with a PyPhaseSpaceVector
66
* \param py_psv PyPhaseSpaceVector* cast as a PyObject*. Python representation
67
* of the phase space vector.
69
* \returns NULL on failure or the object on success. PyPhaseSpaceVector still
70
* owns the memory allocated to PhaseSpaceVector.
72
static PhaseSpaceVector* get_phase_space_vector(PyObject* py_psv);
74
/** Set the C++ phase space vector associated with a PyPhaseSpaceVector
76
* \param py_psv PyPhaseSpaceVector* cast as a PyObject*. Python representation
77
* of the phase space vector
78
* \param psv C++ representation of the phase space vector. PyPhaseSpaceVector
79
* takes ownership of the memory allocated to psv
81
* \returns 0 on failure, 1 on success
83
static int set_phase_space_vector(PyObject* py_psv, PhaseSpaceVector* psv);
86
// ~~~~~~~~~~~~~~~~~~~~ PyPhaseSpaceVector private methods ~~~~~~~~~~~~~~~~~~~~~
87
// most are available as native python functions
89
/** _alloc allocates memory for PyPhaseSpaceVector
91
* @param type - pointer to a PyPhaseSpaceVectorType object, as defined in
92
* PyPhaseSpaceVectorType.cc
94
* returns a PyPhaseSpaceVector* (cast as a PyObject*); caller owns this memory
96
static PyObject *_alloc(PyTypeObject *type, Py_ssize_t nitems);
98
/** _init initialises an allocated PyPhaseSpaceVector object
100
* @param self an initialised PyPhaseSpaceVector* cast as a PyObject*; caller
102
* @param args not used
103
* @param kwds accepts t, energy, x, px, y, py keywords; see python docstring
105
* @returns 0 on success; -1 on failure
107
static int _init(PyObject* self, PyObject *args, PyObject *kwds);
109
/** deallocate memory
111
* @params self an initialised PyPhaseSpaceVector*; memory will be freed by
114
static void _free(PyPhaseSpaceVector * self);
116
/** Initialise phase_space_vector module
118
* This is called by import phase_space_vector; it initialises the
119
* PhaseSpaceVector type allowing user to construct and call methods on
120
* PhaseSpaceVector objects
122
PyMODINIT_FUNC initphase_space_vector(void);
126
* @params self a PyPhaseSpaceVector
127
* @params args not used
128
* @params kwds not used
130
* @returns a PyObject float containing time t
132
static PyObject* get_t(PyObject* self, PyObject *args, PyObject *kwds);
134
/** get energy E [MeV]
136
* @params self a PyPhaseSpaceVector
137
* @params args not used
138
* @params kwds not used
140
* @returns a PyObject float containing energy E
142
static PyObject* get_energy(PyObject* self, PyObject *args, PyObject *kwds);
144
/** get x (horizontal) position [mm]
146
* @params self a PyPhaseSpaceVector
147
* @params args not used
148
* @params kwds not used
150
* @returns a PyObject float containing position x
152
static PyObject* get_x(PyObject* self, PyObject *args, PyObject *kwds);
154
/** get px (horizontal component of momentum) [MeV/c]
156
* @params self a PyPhaseSpaceVector
157
* @params args not used
158
* @params kwds not used
160
* @returns a PyObject float containing momentum px
162
static PyObject* get_px(PyObject* self, PyObject *args, PyObject *kwds);
164
/** get y (vertical position) [mm]
166
* @params self a PyPhaseSpaceVector
167
* @params args not used
168
* @params kwds not used
170
* @returns a PyObject float containing position y
172
static PyObject* get_y(PyObject* self, PyObject *args, PyObject *kwds);
174
/** get py (vertical component of momentum) [MeV/c]
176
* @params self a PyPhaseSpaceVector
177
* @params args not used
178
* @params kwds not used
180
* @returns a PyObject float containing momentum py
182
static PyObject* get_py(PyObject* self, PyObject *args, PyObject *kwds);
184
/** set t (time) [ns]
186
* @params self a PyPhaseSpaceVector
187
* @params args not used
188
* @params kwds accepts keyword value (float)
192
static PyObject* set_t(PyObject* self, PyObject *args, PyObject *kwds);
194
/** set E (energy) [MeV/c]
196
* @params self a PyPhaseSpaceVector
197
* @params args not used
198
* @params kwds accepts keyword value (float)
202
static PyObject* set_energy(PyObject* self, PyObject *args, PyObject *kwds);
204
/** set x (horizontal position) [mm]
206
* @params self a PyPhaseSpaceVector
207
* @params args not used
208
* @params kwds accepts keyword value (float)
212
static PyObject* set_x(PyObject* self, PyObject *args, PyObject *kwds);
214
/** set px (horizontal component of momentum) [MeV/c]
216
* @params self a PyPhaseSpaceVector
217
* @params args not used
218
* @params kwds accepts keyword value (float)
222
static PyObject* set_px(PyObject* self, PyObject *args, PyObject *kwds);
224
/** set y (vertical position) [mm]
226
* @params self a PyPhaseSpaceVector
227
* @params args not used
228
* @params kwds accepts keyword value (float)
232
static PyObject* set_y(PyObject* self, PyObject *args, PyObject *kwds);
234
/** set py (vertical component of momentum) [MeV/c]
236
* @params self a PyPhaseSpaceVector
237
* @params args not used
238
* @params kwds accepts keyword value (float)
242
static PyObject* set_py(PyObject* self, PyObject *args, PyObject *kwds);
244
/** Template for get functions */
245
static PyObject* get(PyObject* self,
246
double (PhaseSpaceVector::*get_function)() const);
248
/** Template for set functions */
249
static PyObject* set(PyObject* self,
252
void (PhaseSpaceVector::*set_function)(double value));
254
/** Return a python string describing the phase space vector
256
* Returns string formatted like a python list with contents:
257
* time [ns], energy [MeV], x [mm], px [MeV/c], y [mm], py [MeV/c]
259
static PyObject* _str(PyObject * self);
263
#else // ifdef MAUS_PYPHASESPACEVECTOR_CC
265
/** MAUS::PyOpticsModel::PyPhaseSpaceVector C API objects
267
* Because of the way python does share libraries, we have to explicitly import
268
* C functions via the Python API, which is done at import time. This mimics
269
* the functions in MAUS::PyPhaseSpaceVector. Full documentation is found
272
* Hacky implementation of public keyword in C++
275
namespace PyPhaseSpaceVector {
276
/** import the PyPhaseSpaceVector C_API
278
* Make the functions in C_API namespace available to other C modules.
279
* Functions will be in namespace MAUS::PyPhaseSpaceVector.
281
* @returns 0 if the import fails; return 1 if it is a success
283
int import_PyPhaseSpaceVector();
285
int (*set_phase_space_vector)(PyObject* py_psv, PhaseSpaceVector* psv) = NULL;
286
PhaseSpaceVector* (*get_phase_space_vector)(PyObject* py_psv) = NULL;
287
PyObject* (*create_empty_vector)() = NULL;
291
int MAUS::PyPhaseSpaceVector::import_PyPhaseSpaceVector() {
292
PyObject* psv_module = PyImport_ImportModule("maus_cpp.phase_space_vector");
293
if (psv_module == NULL) {
296
PyObject *psv_dict = PyModule_GetDict(psv_module);
298
PyObject* gpsv_c_api = PyDict_GetItemString(psv_dict,
299
"C_API_GET_PHASE_SPACE_VECTOR");
300
void* gpsv_void = reinterpret_cast<void*>(PyCObject_AsVoidPtr(gpsv_c_api));
301
PyPhaseSpaceVector::get_phase_space_vector =
302
reinterpret_cast<PhaseSpaceVector* (*)(PyObject*)>(gpsv_void);
304
PyObject* spsv_c_api = PyDict_GetItemString(psv_dict,
305
"C_API_SET_PHASE_SPACE_VECTOR");
306
void* spsv_void = reinterpret_cast<void*>(PyCObject_AsVoidPtr(spsv_c_api));
307
PyPhaseSpaceVector::set_phase_space_vector =
308
reinterpret_cast<int (*)(PyObject*, PhaseSpaceVector*)>(spsv_void);
310
PyObject* cev_c_api = PyDict_GetItemString(psv_dict,
311
"C_API_CREATE_EMPTY_VECTOR");
312
void* cev_void = reinterpret_cast<void*>(PyCObject_AsVoidPtr(cev_c_api));
313
PyPhaseSpaceVector::create_empty_vector =
314
reinterpret_cast<PyObject* (*)()>(cev_void);
316
if ((create_empty_vector == NULL) ||
317
(set_phase_space_vector == NULL) ||
318
(get_phase_space_vector == NULL))
323
#endif // #ifdef MAUS_PYPHASESPACEVECTOR_CC
324
#endif // _SRC_PY_CPP_PYPHASESPACEVECTOR_HH_