~ajdobbs/maus/event-selection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/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 <http://www.gnu.org/licenses/>.
 *
 */

#ifndef _SRC_PY_CPP_PYMICEMODULE_HH_
#define _SRC_PY_CPP_PYMICEMODULE_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 <Python.h>

#include <string>

#ifdef MAUS_PYMICEMODULE_CC

class MiceModule;

namespace MAUS {

namespace PyMiceModule {

/** PyMiceModule is the python implementation of the C++ MiceModule
 *
 *  Note about memory management: In order to keep the memory usage self
 *  consistent all functions that access (get) the MiceModule tree deep copy the
 *  associated MiceModule and Python owns the memory. All functions that update
 *  (set) the MiceModule tree deep copy the associated MiceModule and MAUS owns
 *  the memory.
 */
typedef struct {
    PyObject_HEAD;
    MiceModule* mod;
} PyMiceModule;

/** @namespace C_API defines functions that can be accessed by other C libraries
 *
 *  To access these functions, first call int import_PyMiceModule(). This will
 *  also set up and put C_API objects into the MAUS::PyMiceModule namespace
 */
namespace C_API {

/** Allocate a new PyMiceModule
 *
 *  \returns PyMiceModule* cast as a PyObject* with mod pointer set to NULL
 */
static PyObject *create_empty_module();

/** Return the C++ MiceModule associated with a PyMiceModule
 *
 *  \param py_mod PyMiceModule* cast as a PyObject*. Python representation
 *         of the mice module
 *
 *  PyMiceModule still owns the memory allocated to MiceModule
 */
static MiceModule* get_mice_module(PyObject* py_mod);

/** Set the C++ mice module associated with a PyMiceModule
 *
 *  \param py_mod PyMiceModule* cast as a PyObject*. Python representation
 *               of the mice module
 *  \param mod  C++ representation of the mice module. PyMiceModule
 *             takes ownership of the memory allocated to mod. Always sets
 *             mod->mother() as NULL to avoid memory problems.
 *  Returns 1 on success, 0 on failure.
 */
static int set_mice_module(PyObject* py_mod, MiceModule* mod);
}

/** get name of this PyMiceModule
 *   - self a PyObject of type PyMiceModule
 *   - args not used
 *   - kwds not used
 *  Returns a python string with the name of this MiceModule 
 */
static PyObject *get_children(PyObject* self, PyObject *args, PyObject *kwds);


/** get child modules of this PyMiceModule
 *   - self a PyObject of type PyMiceModule
 *   - args not used
 *   - kwds not used
 *  Returns a python list of PyObjects each of which is a PyMiceModule 
 */
static PyObject *get_children(PyObject* self, PyObject *args, PyObject *kwds);

/** get child modules of this PyMiceModule
 *   - self a PyObject of type PyMiceModule
 *   - args not used
 *   - kwds takes one argument, children, which should be a python list whose
 *     members are all of type PyMiceModule
 *  Returns a python list of PyObjects each of which is a PyMiceModule 
 */
static PyObject *set_children(PyObject* self, PyObject *args, PyObject *kwds);

/** get the value of a property of the PyMiceModule
 *    - self a PyObject of type PyMiceModule
 *    - args not used
 *    - kwds takes two arguments, name (PyString name of the property) and type
 *      (PyString type of the property)
 *  Returns PyNone
 */
static PyObject *get_property(PyObject* self, PyObject *args, PyObject *kwds);

/** set the value of a property of the PyMiceModule
 *    - self a PyObject of type PyMiceModule
 *    - kwds takes three arguments, name (PyString name of the property),
 *      type (PyString type of the property), value (PyString value to set the
 *      property to)
 *  Returns PyNone
 */
static PyObject *set_property(PyObject* self, PyObject *args, PyObject *kwds);

/** _alloc allocates memory for PyMiceModule
 *
 *  @param type - pointer to a PyMiceModuleType object, as defined in
 *         PyMiceModule.cc
 *
 *  returns a PyMiceModule* (cast as a PyObject*); caller owns this memory
 */
static PyObject *_alloc(PyTypeObject *type, Py_ssize_t nitems);

/** _init initialises an allocated PyMiceModule object
 *
 *  @param self an initialised PyMiceModule* 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 PyMiceModule*; memory will be freed by
 *          this function
 */
static void _free(PyMiceModule * self);

/** Return a Python string representation of the PyMiceModule */
static PyObject* _str(PyObject * self);

/** Initialise mice_module module
 *
 *  This is called by import mice_module; it initialises the MiceModule type 
 *  allowing user to construct and call methods on MiceModule objects
 */
PyMODINIT_FUNC initmice_module(void);

/** Return a PyObject boolean with given name from module mod */
static PyObject* get_bool(MiceModule* mod, std::string name);

/** Return a PyObject string with given name from module mod */
static PyObject* get_string(MiceModule* mod, std::string name);

/** Return a PyObject double with given name from module mod */
static PyObject* get_double(MiceModule* mod, std::string name);

/** Return a PyObject int with given name from module mod */
static PyObject* get_int(MiceModule* mod, std::string name);

/** Return a PyObject Hep3Vector with given name from module mod
 *
 *  Returns like {"x":v.x(), "y":v.y(), "z":v.z()}
 */
static PyObject* get_hep3vector(MiceModule* mod, std::string name);

/** Set a MiceModule Hep3Vector with a dict like {"x":1., "y":2., "z":3.} */
static PyObject* set_property_hep3vector
                        (MiceModule* mod, std::string name, PyObject* py_value);

/** Helper function to extract data from Hep3Vector dict */
bool set_property_hep3vector_one
                              (PyObject* py_dict, std::string dim, double* value);


}  // namespace PyMiceModule
}  // namespace MAUS
#else // MAUS_PYMICEMODULE_CC

namespace MAUS {
namespace PyMiceModule {

/** import the PyMiceModule C_API
 *
 *  Makes the functions in C_API available in the MAUS::PyMiceModule
 *  namespace, for other python/C code
 *
 *  @returns 0 if the import fails; return 1 if it is a success
 */
int import_PyMiceModule();

PyObject* (*create_empty_module)() = NULL;
int (*set_mice_module)(PyObject* py_mod, MiceModule* mod) = NULL;
MiceModule* (*get_mice_module)(PyObject* py_mod) = NULL;
}  // namespace PyMiceModule
}  // namespace MAUS

int MAUS::PyMiceModule::import_PyMiceModule() {
  PyObject* mod_module = PyImport_ImportModule("maus_cpp.mice_module");
  if (mod_module == NULL) {
      return 0;
  } else {
    PyObject *mod_dict  = PyModule_GetDict(mod_module);

    PyObject* cem_c_api = PyDict_GetItemString(mod_dict,
                                                 "C_API_CREATE_EMPTY_MODULE");
    void* cem_void = reinterpret_cast<void*>(PyCObject_AsVoidPtr(cem_c_api));
    PyMiceModule::create_empty_module =
                                    reinterpret_cast<PyObject* (*)()>(cem_void);

    PyObject* gmm_c_api = PyDict_GetItemString(mod_dict,
                                               "C_API_GET_MICE_MODULE");
    void* gmm_void = reinterpret_cast<void*>(PyCObject_AsVoidPtr(gmm_c_api));
    PyMiceModule::get_mice_module =
                   reinterpret_cast<MiceModule* (*)(PyObject*)>(gmm_void);

    PyObject* smm_c_api = PyDict_GetItemString(mod_dict,
                                               "C_API_SET_MICE_MODULE");
    void* smm_void = reinterpret_cast<void*>(PyCObject_AsVoidPtr(smm_c_api));
    PyMiceModule::set_mice_module =
             reinterpret_cast<int (*)(PyObject*, MiceModule*)>(smm_void);
    if ((create_empty_module == NULL) ||
        (set_mice_module == NULL) ||
        (get_mice_module == NULL))
        return 0;
  }
  return 1;
}


#endif // MAUS_PYMICEMODULE_CC
#endif // _SRC_PY_CPP_PYMICEMODULE_HH_