1 /*
2 Author: Michael Droettboom
3 mdroe@stsci.edu
4 */
5
6 #ifndef __PYUTIL_H__
7 #define __PYUTIL_H__
8
9 #include "util.h"
10
11 #define PY_ARRAY_UNIQUE_SYMBOL astropy_wcs_numpy_api
12
13 #include <Python.h>
14
15 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
16 #include <numpy/arrayobject.h>
17 #include <numpy/npy_math.h>
18
19 PyObject*
20 PyArrayProxy_New(
21 PyObject* self,
22 int nd,
23 const npy_intp* dims,
24 int typenum,
25 const void* data);
26
27 PyObject*
28 PyArrayReadOnlyProxy_New(
29 PyObject* self,
30 int nd,
31 const npy_intp* dims,
32 int typenum,
33 const void* data);
34
35 /*@null@*/ PyObject *
36 PyStrListProxy_New(
37 PyObject* owner,
38 Py_ssize_t size,
39 Py_ssize_t maxsize,
40 char (*array)[72]
41 );
42
43 int
44 _setup_str_list_proxy_type(
45 PyObject* m);
46
47 static INLINE void
offset_c_array(double * value,npy_intp size,double offset)48 offset_c_array(
49 double* value,
50 npy_intp size,
51 double offset) {
52 double* end = value + size;
53
54 for ( ; value != end; ++value) {
55 *value += offset;
56 }
57 }
58
59 static INLINE
nan2undefined(double * value,unsigned int nvalues)60 void nan2undefined(
61 double* value,
62 unsigned int nvalues) {
63
64 double* end = value + nvalues;
65
66 for ( ; value != end; ++value) {
67 if (isnan64(*value)) {
68 *value = UNDEFINED;
69 }
70 }
71 }
72
73 static INLINE
undefined2nan(double * value,unsigned int nvalues)74 void undefined2nan(
75 double* value,
76 unsigned int nvalues) {
77
78 double* end = value + nvalues;
79
80 for ( ; value != end; ++value) {
81 if (*value == UNDEFINED) {
82 *value = (double)NPY_NAN;
83 }
84 }
85 }
86
87 void
88 preoffset_array(
89 PyArrayObject* array,
90 int value);
91
92 void
93 unoffset_array(
94 PyArrayObject* array,
95 int value);
96
97 void
98 copy_array_to_c_double(
99 PyArrayObject* array,
100 double* dest);
101
102 void
103 copy_array_to_c_int(
104 PyArrayObject* array,
105 int* dest);
106
107 /**
108 Returns TRUE if pointer is NULL, and sets Python exception
109 */
110 int
111 is_null(/*@null@*/ void *);
112
113 typedef void (*value_fixer_t)(double*, unsigned int);
114
115 void
116 wcsprm_c2python(
117 /*@null@*/ struct wcsprm* x);
118
119 void
120 wcsprm_python2c(
121 /*@null@*/ struct wcsprm* x);
122
123 /***************************************************************************
124 * Exceptions *
125 ***************************************************************************/
126
127 extern PyObject* WcsExc_SingularMatrix;
128 extern PyObject* WcsExc_InconsistentAxisTypes;
129 extern PyObject* WcsExc_InvalidTransform;
130 extern PyObject* WcsExc_InvalidCoordinate;
131 extern PyObject* WcsExc_NoSolution;
132 extern PyObject* WcsExc_InvalidSubimageSpecification;
133 extern PyObject* WcsExc_NonseparableSubimageCoordinateSystem;
134 extern PyObject* WcsExc_NoWcsKeywordsFound;
135 extern PyObject* WcsExc_InvalidTabularParameters;
136
137 /* This is an array mapping the wcs status codes to Python exception
138 * types. The exception string is stored as part of wcslib itself in
139 * wcs_errmsg.
140 */
141 extern PyObject** wcs_errexc[14];
142 #define WCS_ERRMSG_MAX 14
143 #define WCSFIX_ERRMSG_MAX 11
144
145 int
146 _define_exceptions(PyObject* m);
147
148 const char*
149 wcslib_get_error_message(int stat);
150
151 void
152 wcserr_to_python_exc(const struct wcserr *err);
153
154 void
155 wcs_to_python_exc(const struct wcsprm *wcs);
156
157 void
158 wcshdr_err_to_python_exc(int status, const struct wcsprm *wcs);
159
160 void
161 wcserr_fix_to_python_exc(const struct wcserr *err);
162
163 /***************************************************************************
164 Property helpers
165 ***************************************************************************/
166 static INLINE int
check_delete(const char * propname,PyObject * value)167 check_delete(
168 const char* propname,
169 PyObject* value) {
170
171 if (value == NULL) {
172 PyErr_Format(PyExc_TypeError, "'%s' can not be deleted", propname);
173 return -1;
174 }
175
176 return 0;
177 }
178
179 static INLINE PyObject*
get_string(const char * propname,const char * value)180 get_string(
181 /*@unused@*/ const char* propname,
182 const char* value) {
183 return PyUnicode_FromString(value);
184 }
185
186 int
187 set_string(
188 const char* propname,
189 PyObject* value,
190 char* dest,
191 Py_ssize_t maxlen);
192
193 static INLINE PyObject*
get_bool(const char * propname,long value)194 get_bool(
195 /*@unused@*/ const char* propname,
196 long value) {
197
198 return PyBool_FromLong(value);
199 }
200
201 int
202 set_bool(
203 const char* propname,
204 PyObject* value,
205 int* dest);
206
207 static INLINE PyObject*
get_int(const char * propname,long value)208 get_int(
209 /*@unused@*/ const char* propname,
210 long value) {
211
212 return PyLong_FromLong(value);
213 }
214
215 int
216 set_int(
217 const char* propname,
218 PyObject* value,
219 int* dest);
220
221 static INLINE PyObject*
get_double(const char * propname,double value)222 get_double(
223 const char* propname,
224 double value) {
225
226 return PyFloat_FromDouble(value);
227 }
228
229 int
230 set_double(
231 const char* propname,
232 PyObject* value,
233 double* dest);
234
235 /*@null@*/ static INLINE PyObject*
get_double_array(const char * propname,double * value,int ndims,const npy_intp * dims,PyObject * owner)236 get_double_array(
237 /*@unused@*/ const char* propname,
238 double* value,
239 int ndims,
240 const npy_intp* dims,
241 /*@shared@*/ PyObject* owner) {
242
243 return PyArrayProxy_New(owner, ndims, dims, NPY_DOUBLE, value);
244 }
245
246 /*@null@*/ static INLINE PyObject*
get_double_array_readonly(const char * propname,double * value,int ndims,const npy_intp * dims,PyObject * owner)247 get_double_array_readonly(
248 /*@unused@*/ const char* propname,
249 double* value,
250 int ndims,
251 const npy_intp* dims,
252 /*@shared@*/ PyObject* owner) {
253
254 return PyArrayReadOnlyProxy_New(owner, ndims, dims, NPY_DOUBLE, value);
255 }
256
257 int
258 set_double_array(
259 const char* propname,
260 PyObject* value,
261 int ndims,
262 const npy_intp* dims,
263 double* dest);
264
265 /*@null@*/ static INLINE PyObject*
get_int_array(const char * propname,int * value,int ndims,const npy_intp * dims,PyObject * owner)266 get_int_array(
267 /*@unused@*/ const char* propname,
268 int* value,
269 int ndims,
270 const npy_intp* dims,
271 /*@shared@*/ PyObject* owner) {
272
273 return PyArrayProxy_New(owner, ndims, dims, NPY_INT, value);
274 }
275
276 int
277 set_int_array(
278 const char* propname,
279 PyObject* value,
280 int ndims,
281 const npy_intp* dims,
282 int* dest);
283
284 static INLINE PyObject*
get_str_list(const char * propname,char (* array)[72],Py_ssize_t len,Py_ssize_t maxlen,PyObject * owner)285 get_str_list(
286 /*@unused@*/ const char* propname,
287 char (*array)[72],
288 Py_ssize_t len,
289 Py_ssize_t maxlen,
290 PyObject* owner) {
291
292 return PyStrListProxy_New(owner, len, maxlen, array);
293 }
294
295 int
296 set_str_list(
297 const char* propname,
298 PyObject* value,
299 Py_ssize_t len,
300 Py_ssize_t maxlen,
301 char (*dest)[72]);
302
303 PyObject*
304 get_pscards(
305 const char* propname,
306 struct pscard* ps,
307 int nps);
308
309 int
310 set_pscards(
311 const char* propname,
312 PyObject* value,
313 struct pscard** ps,
314 int *nps,
315 int *npsmax);
316
317 PyObject*
318 get_pvcards(
319 const char* propname,
320 struct pvcard* pv,
321 int npv);
322
323 int
324 set_pvcards(
325 const char* propname,
326 PyObject* value,
327 struct pvcard** pv,
328 int *npv,
329 int *npvmax);
330
331 PyObject*
332 get_deepcopy(
333 PyObject* obj,
334 PyObject* memo);
335
336 /***************************************************************************
337 Miscellaneous helper functions
338 ***************************************************************************/
339
340 int
341 parse_unsafe_unit_conversion_spec(
342 const char* arg, int* ctrl);
343
344 #endif /* __PYUTIL_H__ */
345