source: sasview/src/sas/sascalc/calculator/c_extensions/sld2i_module.c @ f4e2f22

magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249unittest-saveload
Last change on this file since f4e2f22 was a1daf86, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

hack around broken isfinite/isnan in tinycc

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/**
2  SLD2I module to perform point and I calculations
3 */
4#include <Python.h>
5#include <stdio.h>
6#include "sld2i.h"
7
8#if PY_MAJOR_VERSION < 3
9typedef void (*PyCapsule_Destructor)(PyObject *);
10typedef void (*PyCObject_Destructor)(void *);
11#define PyCapsule_New(pointer, name, destructor) (PyCObject_FromVoidPtr(pointer, (PyCObject_Destructor)destructor))
12#define PyCapsule_GetPointer(capsule, name) (PyCObject_AsVoidPtr(capsule))
13#endif
14
15
16// Utilities
17#define INVECTOR(obj,buf,len)                                                                           \
18    do { \
19        int err = PyObject_AsReadBuffer(obj, (const void **)(&buf), &len); \
20        if (err < 0) return NULL; \
21        len /= sizeof(*buf); \
22    } while (0)
23
24#define OUTVECTOR(obj,buf,len) \
25    do { \
26        int err = PyObject_AsWriteBuffer(obj, (void **)(&buf), &len); \
27        if (err < 0) return NULL; \
28        len /= sizeof(*buf); \
29    } while (0)
30
31
32/**
33 * Delete a GenI object
34 */
35void
36del_sld2i(PyObject *obj){
37#if PY_MAJOR_VERSION < 3
38        GenI* sld2i = (GenI *)obj;
39#else
40        GenI* sld2i = (GenI *)(PyCapsule_GetPointer(obj, "GenI"));
41#endif
42        PyMem_Free((void *)sld2i);
43}
44
45/**
46 * Create a GenI as a python object by supplying arrays
47 */
48PyObject * new_GenI(PyObject *self, PyObject *args) {
49        PyObject *x_val_obj;
50        PyObject *y_val_obj;
51        PyObject *z_val_obj;
52        PyObject *sldn_val_obj;
53        PyObject *mx_val_obj;
54        PyObject *my_val_obj;
55        PyObject *mz_val_obj;
56        PyObject *vol_pix_obj;
57        Py_ssize_t n_x, n_y, n_z, n_sld, n_mx, n_my, n_mz, n_vol_pix;
58        int is_avg;
59        double* x_val;
60        double* y_val;
61        double* z_val;
62        double* sldn_val;
63        double* mx_val;
64        double* my_val;
65        double* mz_val;
66        double* vol_pix;
67        double inspin;
68        double outspin;
69        double stheta;
70        PyObject *obj;
71        GenI* sld2i;
72
73        //printf("new GenI\n");
74        if (!PyArg_ParseTuple(args, "iOOOOOOOOddd", &is_avg, &x_val_obj, &y_val_obj, &z_val_obj, &sldn_val_obj, &mx_val_obj, &my_val_obj, &mz_val_obj, &vol_pix_obj, &inspin, &outspin, &stheta)) return NULL;
75        INVECTOR(x_val_obj, x_val, n_x);
76        INVECTOR(y_val_obj, y_val, n_y);
77        INVECTOR(z_val_obj, z_val, n_z);
78        INVECTOR(sldn_val_obj, sldn_val, n_sld);
79        INVECTOR(mx_val_obj, mx_val, n_mx);
80        INVECTOR(my_val_obj, my_val, n_my);
81        INVECTOR(mz_val_obj, mz_val, n_mz);
82        INVECTOR(vol_pix_obj, vol_pix, n_vol_pix);
83        sld2i = PyMem_Malloc(sizeof(GenI));
84        //printf("sldi:%p\n", sld2i);
85        if (sld2i != NULL) {
86                initGenI(sld2i,is_avg,(int)n_x,x_val,y_val,z_val,sldn_val,mx_val,my_val,mz_val,vol_pix,inspin,outspin,stheta);
87        }
88        obj = PyCapsule_New(sld2i, "GenI", del_sld2i);
89        //printf("constructed %p\n", obj);
90        return obj;
91}
92
93/**
94 * GenI the given input (2D) according to a given object
95 */
96PyObject * genicom_inputXY(PyObject *self, PyObject *args) {
97        PyObject *gen_obj;
98        PyObject *qx_obj;
99        PyObject *qy_obj;
100        PyObject *I_out_obj;
101        Py_ssize_t n_qx, n_qy, n_out;
102        double *qx;
103        double *qy;
104        double *I_out;
105        GenI* sld2i;
106
107        //printf("in genicom_inputXY\n");
108        if (!PyArg_ParseTuple(args, "OOOO",  &gen_obj, &qx_obj, &qy_obj, &I_out_obj)) return NULL;
109        sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI");
110        INVECTOR(qx_obj, qx, n_qx);
111        INVECTOR(qy_obj, qy, n_qy);
112        OUTVECTOR(I_out_obj, I_out, n_out);
113        //printf("qx, qy, I_out: %d %d %d, %d %d %d\n", qx, qy, I_out, n_qx, n_qy, n_out);
114
115        // Sanity check
116        //if(n_q!=n_out) return Py_BuildValue("i",-1);
117
118        genicomXY(sld2i, (int)n_qx, qx, qy, I_out);
119        //printf("done calc\n");
120        //return PyCObject_FromVoidPtr(s, del_genicom);
121        return Py_BuildValue("i",1);
122}
123
124/**
125 * GenI the given 1D input according to a given object
126 */
127PyObject * genicom_input(PyObject *self, PyObject *args) {
128        PyObject *gen_obj;
129        PyObject *q_obj;
130        PyObject *I_out_obj;
131        Py_ssize_t n_q, n_out;
132        double *q;
133        double *I_out;
134        GenI *sld2i;
135
136        if (!PyArg_ParseTuple(args, "OOO",  &gen_obj, &q_obj, &I_out_obj)) return NULL;
137        sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI");
138        INVECTOR(q_obj, q, n_q);
139        OUTVECTOR(I_out_obj, I_out, n_out);
140
141        // Sanity check
142        //if (n_q!=n_out) return Py_BuildValue("i",-1);
143
144        genicom(sld2i, (int)n_q, q, I_out);
145        return Py_BuildValue("i",1);
146}
147
148/**
149 * Define module methods
150 */
151static PyMethodDef module_methods[] = {
152        {"new_GenI", (PyCFunction)new_GenI, METH_VARARGS,
153                  "Create a new GenI object"},
154        {"genicom",(PyCFunction)genicom_input, METH_VARARGS,
155                  "genicom the given 1d input arrays"},
156        {"genicomXY",(PyCFunction)genicom_inputXY, METH_VARARGS,
157                  "genicomXY the given 2d input arrays"},
158    {NULL}
159};
160
161#define MODULE_DOC "Sld2i C Library"
162#define MODULE_NAME "sld2i"
163#define MODULE_INIT2 initsld2i
164#define MODULE_INIT3 PyInit_sld2i
165#define MODULE_METHODS module_methods
166
167/* ==== boilerplate python 2/3 interface bootstrap ==== */
168
169
170#if defined(WIN32) && !defined(__MINGW32__)
171    #define DLL_EXPORT __declspec(dllexport)
172#else
173    #define DLL_EXPORT
174#endif
175
176#if PY_MAJOR_VERSION >= 3
177
178  DLL_EXPORT PyMODINIT_FUNC MODULE_INIT3(void)
179  {
180    static struct PyModuleDef moduledef = {
181      PyModuleDef_HEAD_INIT,
182      MODULE_NAME,         /* m_name */
183      MODULE_DOC,          /* m_doc */
184      -1,                  /* m_size */
185      MODULE_METHODS,      /* m_methods */
186      NULL,                /* m_reload */
187      NULL,                /* m_traverse */
188      NULL,                /* m_clear */
189      NULL,                /* m_free */
190    };
191    return PyModule_Create(&moduledef);
192  }
193
194#else /* !PY_MAJOR_VERSION >= 3 */
195
196  DLL_EXPORT PyMODINIT_FUNC MODULE_INIT2(void)
197  {
198    Py_InitModule4(MODULE_NAME,
199                 MODULE_METHODS,
200                 MODULE_DOC,
201                 0,
202                 PYTHON_API_VERSION
203                 );
204  }
205
206#endif /* !PY_MAJOR_VERSION >= 3 */
Note: See TracBrowser for help on using the repository browser.