~durga/maus/rel709

« back to all changes in this revision

Viewing changes to src/py_cpp/optics/PyPhaseSpaceVector.hh

  • Committer: Durga Rajaram
  • Date: 2013-10-01 00:19:57 UTC
  • mfrom: (659.1.74 rc)
  • Revision ID: durga@fnal.gov-20131001001957-iswih60vis9rodw0
Tags: MAUS-v0.7.1
MAUS-v0.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus
 
2
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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/>.
 
15
 *
 
16
 */
 
17
 
 
18
#ifndef _SRC_PY_CPP_PYPHASESPACEVECTOR_HH_
 
19
#define _SRC_PY_CPP_PYPHASESPACEVECTOR_HH_
 
20
 
 
21
// These ifdefs are required to avoid cpp compiler warning
 
22
#ifdef _POSIX_C_SOURCE
 
23
#undef _POSIX_C_SOURCE
 
24
#endif
 
25
 
 
26
#ifdef _XOPEN_SOURCE
 
27
#undef _XOPEN_SOURCE
 
28
#endif
 
29
 
 
30
#include <Python.h>
 
31
 
 
32
#ifdef MAUS_PYPHASESPACEVECTOR_CC
 
33
 
 
34
namespace MAUS {
 
35
 
 
36
class PhaseSpaceVector; // note this is just in MAUS namespace
 
37
 
 
38
/** Methods for the PyPhaseSpaceVector object
 
39
 */
 
40
namespace PyPhaseSpaceVector {
 
41
 
 
42
/** PyPhaseSpaceVector is the python implementation of the C++ PhaseSpaceVector
 
43
 */
 
44
typedef struct {
 
45
    PyObject_HEAD;
 
46
    PhaseSpaceVector* psv;
 
47
} PyPhaseSpaceVector;
 
48
 
 
49
/** @namespace C_API defines functions that can be accessed by other C libraries
 
50
 *
 
51
 *  To access these functions, you must call import_PyPhaseSpaceVector()
 
52
 *  (otherwise you will get segmentation fault)
 
53
 */
 
54
namespace C_API {
 
55
 
 
56
/** Create a new empty PyPhaseSpaceVector (psv is NULL)
 
57
 *
 
58
 *  \returns NULL on failure or the object on success. Caller owns the returned
 
59
 *           object
 
60
 */
 
61
 
 
62
static PyObject* create_empty_vector();
 
63
 
 
64
/** Return the C++ PhaseSpaceVector associated with a PyPhaseSpaceVector
 
65
 *
 
66
 *  \param py_psv PyPhaseSpaceVector* cast as a PyObject*. Python representation
 
67
 *         of the phase space vector.
 
68
 *
 
69
 *  \returns NULL on failure or the object on success. PyPhaseSpaceVector still
 
70
 *          owns the memory allocated to PhaseSpaceVector.
 
71
 */
 
72
static PhaseSpaceVector* get_phase_space_vector(PyObject* py_psv);
 
73
 
 
74
/** Set the C++ phase space vector associated with a PyPhaseSpaceVector
 
75
 *
 
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
 
80
 *
 
81
 *  \returns 0 on failure, 1 on success
 
82
 */
 
83
static int set_phase_space_vector(PyObject* py_psv, PhaseSpaceVector* psv);
 
84
}
 
85
 
 
86
// ~~~~~~~~~~~~~~~~~~~~ PyPhaseSpaceVector private methods ~~~~~~~~~~~~~~~~~~~~~
 
87
// most are available as native python functions
 
88
 
 
89
/** _alloc allocates memory for PyPhaseSpaceVector
 
90
 *
 
91
 *  @param type - pointer to a PyPhaseSpaceVectorType object, as defined in
 
92
 *         PyPhaseSpaceVectorType.cc
 
93
 *
 
94
 *  returns a PyPhaseSpaceVector* (cast as a PyObject*); caller owns this memory
 
95
 */
 
96
static PyObject *_alloc(PyTypeObject *type, Py_ssize_t nitems);
 
97
 
 
98
/** _init initialises an allocated PyPhaseSpaceVector object
 
99
 *
 
100
 *  @param self an initialised PyPhaseSpaceVector* cast as a PyObject*; caller
 
101
 *         owns this memory
 
102
 *  @param args not used
 
103
 *  @param kwds accepts t, energy, x, px, y, py keywords; see python docstring
 
104
 *
 
105
 *  @returns 0 on success; -1 on failure
 
106
 */
 
107
static int _init(PyObject* self, PyObject *args, PyObject *kwds);
 
108
 
 
109
/** deallocate memory
 
110
 *
 
111
 *  @params self an initialised PyPhaseSpaceVector*; memory will be freed by
 
112
 *          this function
 
113
 */
 
114
static void _free(PyPhaseSpaceVector * self);
 
115
 
 
116
/** Initialise phase_space_vector module
 
117
 *
 
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
 
121
 */
 
122
PyMODINIT_FUNC initphase_space_vector(void);
 
123
 
 
124
/** get time t [ns]
 
125
 *
 
126
 *  @params self a PyPhaseSpaceVector
 
127
 *  @params args not used
 
128
 *  @params kwds not used
 
129
 *
 
130
 *  @returns a PyObject float containing time t
 
131
 */
 
132
static PyObject* get_t(PyObject* self, PyObject *args, PyObject *kwds);
 
133
 
 
134
/** get energy E [MeV]
 
135
 *
 
136
 *  @params self a PyPhaseSpaceVector
 
137
 *  @params args not used
 
138
 *  @params kwds not used
 
139
 *
 
140
 *  @returns a PyObject float containing energy E
 
141
 */
 
142
static PyObject* get_energy(PyObject* self, PyObject *args, PyObject *kwds);
 
143
 
 
144
/** get x (horizontal) position [mm]
 
145
 *
 
146
 *  @params self a PyPhaseSpaceVector
 
147
 *  @params args not used
 
148
 *  @params kwds not used
 
149
 *
 
150
 *  @returns a PyObject float containing position x
 
151
 */
 
152
static PyObject* get_x(PyObject* self, PyObject *args, PyObject *kwds);
 
153
 
 
154
/** get px (horizontal component of momentum) [MeV/c]
 
155
 *
 
156
 *  @params self a PyPhaseSpaceVector
 
157
 *  @params args not used
 
158
 *  @params kwds not used
 
159
 *
 
160
 *  @returns a PyObject float containing momentum px
 
161
 */
 
162
static PyObject* get_px(PyObject* self, PyObject *args, PyObject *kwds);
 
163
 
 
164
/** get y (vertical position) [mm]
 
165
 *
 
166
 *  @params self a PyPhaseSpaceVector
 
167
 *  @params args not used
 
168
 *  @params kwds not used
 
169
 *
 
170
 *  @returns a PyObject float containing position y
 
171
 */
 
172
static PyObject* get_y(PyObject* self, PyObject *args, PyObject *kwds);
 
173
 
 
174
/** get py (vertical component of momentum) [MeV/c]
 
175
 *
 
176
 *  @params self a PyPhaseSpaceVector
 
177
 *  @params args not used
 
178
 *  @params kwds not used
 
179
 *
 
180
 *  @returns a PyObject float containing momentum py
 
181
 */
 
182
static PyObject* get_py(PyObject* self, PyObject *args, PyObject *kwds);
 
183
 
 
184
/** set t (time) [ns]
 
185
 *
 
186
 *  @params self a PyPhaseSpaceVector
 
187
 *  @params args not used
 
188
 *  @params kwds accepts keyword value (float)
 
189
 *
 
190
 *  @returns None
 
191
 */
 
192
static PyObject* set_t(PyObject* self, PyObject *args, PyObject *kwds);
 
193
 
 
194
/** set E (energy) [MeV/c]
 
195
 *
 
196
 *  @params self a PyPhaseSpaceVector
 
197
 *  @params args not used
 
198
 *  @params kwds accepts keyword value (float)
 
199
 *
 
200
 *  @returns None
 
201
 */
 
202
static PyObject* set_energy(PyObject* self, PyObject *args, PyObject *kwds);
 
203
 
 
204
/** set x (horizontal position) [mm]
 
205
 *
 
206
 *  @params self a PyPhaseSpaceVector
 
207
 *  @params args not used
 
208
 *  @params kwds accepts keyword value (float)
 
209
 *
 
210
 *  @returns None
 
211
 */
 
212
static PyObject* set_x(PyObject* self, PyObject *args, PyObject *kwds);
 
213
 
 
214
/** set px (horizontal component of momentum) [MeV/c]
 
215
 *
 
216
 *  @params self a PyPhaseSpaceVector
 
217
 *  @params args not used
 
218
 *  @params kwds accepts keyword value (float)
 
219
 *
 
220
 *  @returns None
 
221
 */
 
222
static PyObject* set_px(PyObject* self, PyObject *args, PyObject *kwds);
 
223
 
 
224
/** set y (vertical position) [mm]
 
225
 *
 
226
 *  @params self a PyPhaseSpaceVector
 
227
 *  @params args not used
 
228
 *  @params kwds accepts keyword value (float)
 
229
 *
 
230
 *  @returns None
 
231
 */
 
232
static PyObject* set_y(PyObject* self, PyObject *args, PyObject *kwds);
 
233
 
 
234
/** set py (vertical component of momentum) [MeV/c]
 
235
 *
 
236
 *  @params self a PyPhaseSpaceVector
 
237
 *  @params args not used
 
238
 *  @params kwds accepts keyword value (float)
 
239
 *
 
240
 *  @returns None
 
241
 */
 
242
static PyObject* set_py(PyObject* self, PyObject *args, PyObject *kwds);
 
243
 
 
244
/** Template for get functions */
 
245
static PyObject* get(PyObject* self,
 
246
                     double (PhaseSpaceVector::*get_function)() const);
 
247
 
 
248
/** Template for set functions */
 
249
static PyObject* set(PyObject* self,
 
250
                     PyObject *args,
 
251
                     PyObject *kwds,
 
252
                     void (PhaseSpaceVector::*set_function)(double value));
 
253
 
 
254
/** Return a python string describing the phase space vector
 
255
 *
 
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]
 
258
 */
 
259
static PyObject* _str(PyObject * self);
 
260
}
 
261
}
 
262
 
 
263
#else // ifdef MAUS_PYPHASESPACEVECTOR_CC
 
264
 
 
265
/** MAUS::PyOpticsModel::PyPhaseSpaceVector C API objects
 
266
 *
 
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
 
270
 *  there.
 
271
 *
 
272
 *  Hacky implementation of public keyword in C++
 
273
 */
 
274
namespace MAUS {
 
275
namespace PyPhaseSpaceVector {
 
276
/** import the PyPhaseSpaceVector C_API
 
277
 *
 
278
 *  Make the functions in C_API namespace available to other C modules.
 
279
 *  Functions will be in namespace MAUS::PyPhaseSpaceVector.
 
280
 *
 
281
 *  @returns 0 if the import fails; return 1 if it is a success
 
282
 */
 
283
int import_PyPhaseSpaceVector();
 
284
 
 
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;
 
288
}
 
289
}
 
290
 
 
291
int MAUS::PyPhaseSpaceVector::import_PyPhaseSpaceVector() {
 
292
  PyObject* psv_module = PyImport_ImportModule("maus_cpp.phase_space_vector");
 
293
  if (psv_module == NULL) {
 
294
      return 0;
 
295
  } else {
 
296
    PyObject *psv_dict  = PyModule_GetDict(psv_module);
 
297
 
 
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);
 
303
 
 
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);
 
309
 
 
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);
 
315
 
 
316
    if ((create_empty_vector == NULL) ||
 
317
        (set_phase_space_vector == NULL) ||
 
318
        (get_phase_space_vector == NULL))
 
319
        return 0;
 
320
  }
 
321
  return 1;
 
322
}
 
323
#endif  // #ifdef MAUS_PYPHASESPACEVECTOR_CC
 
324
#endif  // _SRC_PY_CPP_PYPHASESPACEVECTOR_HH_
 
325