1 /*
2 Author: Michael Droettboom
3 mdroe@stsci.edu
4 */
5
6 #define NO_IMPORT_ARRAY
7
8 #include "astropy_wcs/distortion_wrap.h"
9 #include "astropy_wcs/docstrings.h"
10
11 #include <structmember.h> /* From Python */
12
13 static int
PyDistLookup_traverse(PyDistLookup * self,visitproc visit,void * arg)14 PyDistLookup_traverse(
15 PyDistLookup* self,
16 visitproc visit,
17 void* arg) {
18
19 Py_VISIT(self->py_data);
20
21 return 0;
22 }
23
24 static int
PyDistLookup_clear(PyDistLookup * self)25 PyDistLookup_clear(
26 PyDistLookup* self) {
27
28 Py_CLEAR(self->py_data);
29
30 return 0;
31 }
32
33 static void
PyDistLookup_dealloc(PyDistLookup * self)34 PyDistLookup_dealloc(
35 PyDistLookup* self) {
36
37 PyObject_GC_UnTrack(self);
38 distortion_lookup_t_free(&self->x);
39 Py_XDECREF(self->py_data);
40 Py_TYPE(self)->tp_free((PyObject*)self);
41 }
42
43 /*@null@*/ static PyObject *
PyDistLookup_new(PyTypeObject * type,PyObject * args,PyObject * kwds)44 PyDistLookup_new(
45 PyTypeObject* type,
46 /*@unused@*/ PyObject* args,
47 /*@unused@*/ PyObject* kwds) {
48
49 PyDistLookup* self;
50
51 self = (PyDistLookup*)type->tp_alloc(type, 0);
52 if (self != NULL) {
53 if (distortion_lookup_t_init(&self->x)) {
54 return NULL;
55 }
56 self->py_data = NULL;
57 }
58 return (PyObject*)self;
59 }
60
61 static int
PyDistLookup_init(PyDistLookup * self,PyObject * args,PyObject * kwds)62 PyDistLookup_init(
63 PyDistLookup* self,
64 PyObject* args,
65 /*@unused@*/ PyObject* kwds) {
66
67 PyObject* py_array_obj = NULL;
68 PyArrayObject* array_obj = NULL;
69
70 if (!PyArg_ParseTuple(args, "O(dd)(dd)(dd):DistortionLookupTable.__init__",
71 &py_array_obj,
72 &(self->x.crpix[0]), &(self->x.crpix[1]),
73 &(self->x.crval[0]), &(self->x.crval[1]),
74 &(self->x.cdelt[0]), &(self->x.cdelt[1]))) {
75 return -1;
76 }
77
78 array_obj = (PyArrayObject*)PyArray_ContiguousFromAny(py_array_obj, NPY_FLOAT32, 2, 2);
79 if (array_obj == NULL) {
80 return -1;
81 }
82
83 self->py_data = array_obj;
84 self->x.naxis[0] = (unsigned int)PyArray_DIM(array_obj, 1);
85 self->x.naxis[1] = (unsigned int)PyArray_DIM(array_obj, 0);
86 self->x.data = (float *)PyArray_DATA(array_obj);
87
88 return 0;
89 }
90
91 static PyObject*
PyDistLookup_get_cdelt(PyDistLookup * self,void * closure)92 PyDistLookup_get_cdelt(
93 PyDistLookup* self,
94 /*@unused@*/ void* closure) {
95
96 Py_ssize_t naxis = 2;
97
98 return get_double_array("cdelt", self->x.cdelt, 1, &naxis, (PyObject*)self);
99 }
100
101 static int
PyDistLookup_set_cdelt(PyDistLookup * self,PyObject * value,void * closure)102 PyDistLookup_set_cdelt(
103 PyDistLookup* self,
104 PyObject* value,
105 /*@unused@*/ void* closure) {
106
107 npy_intp naxis = 2;
108
109 return set_double_array("cdelt", value, 1, &naxis, self->x.cdelt);
110 }
111
112 static PyObject*
PyDistLookup_get_crpix(PyDistLookup * self,void * closure)113 PyDistLookup_get_crpix(
114 PyDistLookup* self,
115 /*@unused@*/ void* closure) {
116
117 Py_ssize_t naxis = 2;
118
119 return get_double_array("crpix", self->x.crpix, 1, &naxis, (PyObject*)self);
120 }
121
122 static int
PyDistLookup_set_crpix(PyDistLookup * self,PyObject * value,void * closure)123 PyDistLookup_set_crpix(
124 PyDistLookup* self,
125 PyObject* value,
126 /*@unused@*/ void* closure) {
127
128 npy_intp naxis = 2;
129
130 return set_double_array("crpix", value, 1, &naxis, self->x.crpix);
131 }
132
133 static PyObject*
PyDistLookup_get_crval(PyDistLookup * self,void * closure)134 PyDistLookup_get_crval(
135 PyDistLookup* self,
136 /*@unused@*/ void* closure) {
137
138 Py_ssize_t naxis = 2;
139
140 return get_double_array("crval", self->x.crval, 1, &naxis, (PyObject*)self);
141 }
142
143 static int
PyDistLookup_set_crval(PyDistLookup * self,PyObject * value,void * closure)144 PyDistLookup_set_crval(
145 PyDistLookup* self,
146 PyObject* value,
147 /*@unused@*/ void* closure) {
148
149 npy_intp naxis = 2;
150
151 return set_double_array("crval", value, 1, &naxis, self->x.crval);
152 }
153
154 /*@shared@*/ static PyObject*
PyDistLookup_get_data(PyDistLookup * self,void * closure)155 PyDistLookup_get_data(
156 PyDistLookup* self,
157 /*@unused@*/ void* closure) {
158
159 if (self->py_data == NULL) {
160 Py_INCREF(Py_None);
161 return Py_None;
162 } else {
163 Py_INCREF(self->py_data);
164 return (PyObject*)self->py_data;
165 }
166 }
167
168 static int
PyDistLookup_set_data(PyDistLookup * self,PyObject * value,void * closure)169 PyDistLookup_set_data(
170 PyDistLookup* self,
171 PyObject* value,
172 /*@unused@*/ void* closure) {
173
174 PyArrayObject* value_array = NULL;
175
176 if (value == NULL) {
177 Py_CLEAR(self->py_data);
178 self->x.data = NULL;
179 return 0;
180 }
181
182 value_array = (PyArrayObject*)PyArray_ContiguousFromAny(value, NPY_FLOAT32, 2, 2);
183
184 if (value_array == NULL) {
185 return -1;
186 }
187
188 Py_XDECREF(self->py_data);
189
190 self->py_data = value_array;
191 self->x.naxis[0] = (unsigned int)PyArray_DIM(value_array, 1);
192 self->x.naxis[1] = (unsigned int)PyArray_DIM(value_array, 0);
193 self->x.data = (float *)PyArray_DATA(value_array);
194
195 return 0;
196 }
197
198 /*@null@*/ static PyObject*
PyDistLookup_get_offset(PyDistLookup * self,PyObject * args,PyObject * kwds)199 PyDistLookup_get_offset(
200 PyDistLookup* self,
201 PyObject* args,
202 /*@unused@*/ PyObject* kwds) {
203
204 double coord[NAXES];
205 double result;
206
207 if (self->x.data == NULL) {
208 PyErr_SetString(PyExc_RuntimeError,
209 "No data has been set for the lookup table");
210 return NULL;
211 }
212
213 if (!PyArg_ParseTuple(args, "dd:get_offset", &coord[0], &coord[1])) {
214 return NULL;
215 }
216
217 result = get_distortion_offset(&self->x, coord);
218 return PyFloat_FromDouble(result);
219 }
220
221 static PyObject*
PyDistLookup___copy__(PyDistLookup * self,PyObject * args,PyObject * kwds)222 PyDistLookup___copy__(
223 PyDistLookup* self,
224 /*@unused@*/ PyObject* args,
225 /*@unused@*/ PyObject* kwds) {
226
227 PyDistLookup* copy = NULL;
228 int i = 0;
229
230 copy = (PyDistLookup*)PyDistLookup_new(&PyDistLookupType, NULL, NULL);
231 if (copy == NULL) {
232 return NULL;
233 }
234
235 for (i = 0; i < 2; ++i) {
236 copy->x.naxis[i] = self->x.naxis[i];
237 copy->x.crpix[i] = self->x.crpix[i];
238 copy->x.crval[i] = self->x.crval[i];
239 copy->x.cdelt[i] = self->x.cdelt[i];
240 }
241
242 if (self->py_data) {
243 PyDistLookup_set_data(copy, (PyObject*)self->py_data, NULL);
244 }
245
246 return (PyObject*)copy;
247 }
248
249 static PyObject*
PyDistLookup___deepcopy__(PyDistLookup * self,PyObject * memo,PyObject * kwds)250 PyDistLookup___deepcopy__(
251 PyDistLookup* self,
252 PyObject* memo,
253 /*@unused@*/ PyObject* kwds) {
254
255 PyDistLookup* copy;
256 PyObject* obj_copy;
257 int i = 0;
258
259 copy = (PyDistLookup*)PyDistLookup_new(&PyDistLookupType, NULL, NULL);
260 if (copy == NULL) {
261 return NULL;
262 }
263
264 for (i = 0; i < 2; ++i) {
265 copy->x.naxis[i] = self->x.naxis[i];
266 copy->x.crpix[i] = self->x.crpix[i];
267 copy->x.crval[i] = self->x.crval[i];
268 copy->x.cdelt[i] = self->x.cdelt[i];
269 }
270
271 if (self->py_data) {
272 obj_copy = get_deepcopy((PyObject*)self->py_data, memo);
273 if (obj_copy == NULL) {
274 Py_DECREF(copy);
275 return NULL;
276 }
277 PyDistLookup_set_data(copy, (PyObject*)obj_copy, NULL);
278 Py_DECREF(obj_copy);
279 }
280
281 return (PyObject*)copy;
282 }
283
284
285 static PyGetSetDef PyDistLookup_getset[] = {
286 {"cdelt", (getter)PyDistLookup_get_cdelt, (setter)PyDistLookup_set_cdelt, (char *)doc_cdelt},
287 {"crpix", (getter)PyDistLookup_get_crpix, (setter)PyDistLookup_set_crpix, (char *)doc_crpix},
288 {"crval", (getter)PyDistLookup_get_crval, (setter)PyDistLookup_set_crval, (char *)doc_crval},
289 {"data", (getter)PyDistLookup_get_data, (setter)PyDistLookup_set_data, (char *)doc_data},
290 {NULL}
291 };
292
293 static PyMethodDef PyDistLookup_methods[] = {
294 {"__copy__", (PyCFunction)PyDistLookup___copy__, METH_NOARGS, NULL},
295 {"__deepcopy__", (PyCFunction)PyDistLookup___deepcopy__, METH_O, NULL},
296 {"get_offset", (PyCFunction)PyDistLookup_get_offset, METH_VARARGS, doc_get_offset},
297 {NULL}
298 };
299
300 PyTypeObject PyDistLookupType = {
301 PyVarObject_HEAD_INIT(NULL, 0)
302 "astropy.wcs.DistortionLookupTable", /*tp_name*/
303 sizeof(PyDistLookup), /*tp_basicsize*/
304 0, /*tp_itemsize*/
305 (destructor)PyDistLookup_dealloc, /*tp_dealloc*/
306 0, /*tp_print*/
307 0, /*tp_getattr*/
308 0, /*tp_setattr*/
309 0, /*tp_compare*/
310 0, /*tp_repr*/
311 0, /*tp_as_number*/
312 0, /*tp_as_sequence*/
313 0, /*tp_as_mapping*/
314 0, /*tp_hash */
315 0, /*tp_call*/
316 0, /*tp_str*/
317 0, /*tp_getattro*/
318 0, /*tp_setattro*/
319 0, /*tp_as_buffer*/
320 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
321 doc_DistortionLookupTable, /* tp_doc */
322 (traverseproc)PyDistLookup_traverse, /* tp_traverse */
323 (inquiry)PyDistLookup_clear, /* tp_clear */
324 0, /* tp_richcompare */
325 0, /* tp_weaklistoffset */
326 0, /* tp_iter */
327 0, /* tp_iternext */
328 PyDistLookup_methods, /* tp_methods */
329 0, /* tp_members */
330 PyDistLookup_getset, /* tp_getset */
331 0, /* tp_base */
332 0, /* tp_dict */
333 0, /* tp_descr_get */
334 0, /* tp_descr_set */
335 0, /* tp_dictoffset */
336 (initproc)PyDistLookup_init, /* tp_init */
337 0, /* tp_alloc */
338 PyDistLookup_new, /* tp_new */
339 };
340
_setup_distortion_type(PyObject * m)341 int _setup_distortion_type(
342 PyObject* m) {
343
344 if (PyType_Ready(&PyDistLookupType) < 0) {
345 return -1;
346 }
347
348 Py_INCREF(&PyDistLookupType);
349 return PyModule_AddObject(m, "DistortionLookupTable", (PyObject *)&PyDistLookupType);
350 }
351