#define NO_IMPORT_ARRAY #include "astropy_wcs/wcslib_celprm_wrap.h" #include "astropy_wcs/wcslib_prjprm_wrap.h" #include #include #include #include #include #include #include /* It gets to be really tedious to type long docstrings in ANSI C syntax (since multi-line strings literals are not valid). Therefore, the docstrings are written in doc/docstrings.py, which are then converted by setup.py into docstrings.h, which we include here. */ #include "astropy_wcs/docstrings.h" #include "astropy_wcs/wcslib_wrap.h" PyObject** cel_errexc[7]; static int wcslib_cel_to_python_exc(int status) { if (status > 0 && status < 7) { PyErr_SetString(*cel_errexc[status], cel_errmsg[status]); } else if (status > 6) { PyErr_SetString( PyExc_RuntimeError, "Unknown WCSLIB celprm-related error occurred."); } return status; } static int is_readonly(PyCelprm* self) { if (self != NULL && self->owner != NULL) { PyErr_SetString( PyExc_AttributeError, "Attribute 'cel' of 'astropy.wcs.Wcsprm' objects is read-only."); return 1; } else { return 0; } } static int is_cel_null(PyCelprm* self) { if (self->x == NULL) { PyErr_SetString( PyExc_MemoryError, "Underlying 'celprm' object is NULL."); return 1; } else { return 0; } } /*************************************************************************** * PyCelprm methods * ***************************************************************************/ static PyObject* PyCelprm_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { PyCelprm* self; self = (PyCelprm*)type->tp_alloc(type, 0); if (self == NULL) return NULL; self->owner = NULL; self->prefcount = NULL; if ((self->x = calloc(1, sizeof(struct celprm))) == 0x0) { PyErr_SetString(PyExc_MemoryError, "Could not allocate memory for celprm structure."); return NULL; } if ((self->prefcount = (int*) malloc(sizeof(int))) == 0x0) { PyErr_SetString(PyExc_MemoryError, "Could not allocate memory."); free(self->x); return NULL; } if (wcslib_cel_to_python_exc(celini(self->x))) { free(self->x); free(self->prefcount); return NULL; } *(self->prefcount) = 1; return (PyObject*)self; } static int PyCelprm_traverse(PyCelprm* self, visitproc visit, void *arg) { Py_VISIT(self->owner); return 0; } static int PyCelprm_clear(PyCelprm* self) { Py_CLEAR(self->owner); return 0; } static void PyCelprm_dealloc(PyCelprm* self) { PyCelprm_clear(self); wcslib_cel_to_python_exc(celfree(self->x)); // free memory used for err msg if (self->prefcount && (--(*self->prefcount)) == 0) { free(self->x); free(self->prefcount); } Py_TYPE(self)->tp_free((PyObject*)self); } static int PyCelprm_cset(PyCelprm* self) { if (wcslib_cel_to_python_exc(celset(self->x))) { return -1; } return 0; } static PyObject* PyCelprm_set(PyCelprm* self) { if (is_readonly(self) || PyCelprm_cset(self)) return NULL; Py_RETURN_NONE; } PyCelprm* PyCelprm_cnew(PyObject* wcsprm_obj, struct celprm* x, int* prefcount) { PyCelprm* self; self = (PyCelprm*)(&PyCelprmType)->tp_alloc(&PyCelprmType, 0); if (self == NULL) return NULL; self->x = x; Py_XINCREF(wcsprm_obj); self->owner = wcsprm_obj; self->prefcount = prefcount; if (prefcount) (*prefcount)++; return self; } static PyObject* PyCelprm_copy(PyCelprm* self) { PyCelprm* copy = NULL; copy = PyCelprm_cnew(self->owner, self->x, self->prefcount); if (copy == NULL) return NULL; return (PyObject*)copy; } static PyObject* PyCelprm_deepcopy(PyCelprm* self) { PyCelprm* copy = (PyCelprm*) PyCelprm_new(&PyCelprmType, NULL, NULL); if (copy == NULL) return NULL; memcpy(copy->x, self->x, sizeof(struct celprm)); copy->x->err = NULL; return (PyObject*)copy; } static PyObject* PyCelprm___str__(PyCelprm* self) { /* if (PyCelprm_cset(self)) return NULL; */ /* This is not thread-safe, but since we're holding onto the GIL, we can assume we won't have thread conflicts */ wcsprintf_set(NULL); if (wcslib_cel_to_python_exc(celprt(self->x))) { return NULL; } return PyUnicode_FromString(wcsprintf_buf()); } /*************************************************************************** * Member getters/setters (properties) */ static PyObject* PyCelprm_get_flag(PyCelprm* self, void* closure) { if (is_cel_null(self)) { return NULL; } else { return get_int("flag", self->x->flag); } } static PyObject* PyCelprm_get_offset(PyCelprm* self, void* closure) { if (is_cel_null(self)) { return NULL; } else { return get_bool("offset", self->x->offset); } } static int PyCelprm_set_offset(PyCelprm* self, PyObject* value, void* closure) { if (is_cel_null(self) || is_readonly(self)) { return -1; } else if (value == Py_None) { self->x->offset = 0; return 0; } else { return set_bool("offset", value, &self->x->offset); } } static PyObject* PyCelprm_get_phi0(PyCelprm* self, void* closure) { if (is_cel_null(self)) { return NULL; } else if (self->x->phi0 != UNDEFINED) { return get_double("phi0", self->x->phi0); } Py_RETURN_NONE; } static int PyCelprm_set_phi0(PyCelprm* self, PyObject* value, void* closure) { int result; double phi0; if (is_cel_null(self) || is_readonly(self)) { return -1; } else if (value == Py_None) { if (self->x->phi0 != UNDEFINED) { self->x->phi0 = UNDEFINED; self->x->flag = 0; } } else { result = set_double("phi0", value, &phi0); if (result) return result; if (phi0 != self->x->phi0) { self->x->phi0 = phi0; self->x->flag = 0; } } return 0; } static PyObject* PyCelprm_get_theta0(PyCelprm* self, void* closure) { if (is_cel_null(self)) { return NULL; } else if (self->x->theta0 != UNDEFINED) { return get_double("theta0", self->x->theta0); } Py_RETURN_NONE; } static int PyCelprm_set_theta0(PyCelprm* self, PyObject* value, void* closure) { int result; double theta0; if(is_cel_null(self) || is_readonly(self)) { return -1; } else if (value == Py_None) { if (self->x->theta0 != UNDEFINED) { self->x->theta0 = UNDEFINED; self->x->flag = 0; } } else { result = set_double("theta0", value, &theta0); if (result) return result; if (theta0 != self->x->theta0) { self->x->theta0 = theta0; self->x->flag = 0; } } return 0; } static PyObject* PyCelprm_get_ref(PyCelprm* self, void* closure) { Py_ssize_t size = 4; if (is_cel_null(self)) { return NULL; } else { return get_double_array("ref", self->x->ref, 1, &size, (PyObject*) self); } } static int PyCelprm_set_ref(PyCelprm* self, PyObject* value, void* closure) { int i; int skip[4] = {0, 0, 0, 0}; double ref[4] = {0.0, 0.0, UNDEFINED, +90.0}; npy_intp size; double *data; if (is_cel_null(self) || is_readonly(self)) return -1; if (value == Py_None) { /* If ref is set to None - reset ref to celini values: */ for (i = 0; i < 4; i++) { self->x->ref[i] = ref[i]; } self->x->flag = 0; return 0; } PyArrayObject* value_array = (PyArrayObject*) PyArray_ContiguousFromAny(value, NPY_DOUBLE, 1, 1); if (!value_array) return -1; size = PyArray_SIZE(value_array); if (size < 1) { Py_DECREF(value_array); PyErr_SetString(PyExc_ValueError, "'ref' must be a non-empty 1-dimentional list of values or None."); return -1; } if (size > 4) { Py_DECREF(value_array); PyErr_SetString(PyExc_RuntimeError, "Number of 'ref' values cannot exceed 4."); return -1; } if (PyList_Check(value)) { for (i = 0; i < size; i++) { skip[i] = (PyList_GetItem(value, i) == Py_None); } } data = (double*) PyArray_DATA(value_array); for (i = 0; i < size; i++) { if (skip[i]) continue; if (npy_isnan(self->x->ref[i])) { self->x->ref[i] = UNDEFINED; } else { self->x->ref[i] = data[i]; } } for (i = size; i < 4; i++) { self->x->ref[i] = ref[i]; } self->x->flag = 0; Py_DECREF(value_array); return 0; } static PyObject* PyCelprm_get_prj(PyCelprm* self, void* closure) { if (is_cel_null(self)) return NULL; return (PyObject*)PyPrjprm_cnew((PyObject *)self, &(self->x->prj), NULL); } static PyObject* PyCelprm_get_euler(PyCelprm* self, void* closure) { Py_ssize_t size = 5; if (is_cel_null(self)) return NULL; return get_double_array("euler", self->x->euler, 1, &size, (PyObject*) self); } static PyObject* PyCelprm_get_latpreq(PyCelprm* self, void* closure) { if (is_cel_null(self)) return NULL; return get_int("lapreq", self->x->latpreq); } static PyObject* PyCelprm_get_isolat(PyCelprm* self, void* closure) { if (is_cel_null(self)) { return NULL; } else { return get_bool("isolat", self->x->isolat); } } /*************************************************************************** * PyCelprm definition structures */ static PyGetSetDef PyCelprm_getset[] = { {"offset", (getter)PyCelprm_get_offset, (setter)PyCelprm_set_offset, (char *)doc_cel_offset}, {"phi0", (getter)PyCelprm_get_phi0, (setter)PyCelprm_set_phi0, (char *)doc_celprm_phi0}, {"theta0", (getter)PyCelprm_get_theta0, (setter)PyCelprm_set_theta0, (char *)doc_celprm_theta0}, {"ref", (getter)PyCelprm_get_ref, (setter)PyCelprm_set_ref, (char *)doc_celprm_ref}, {"euler", (getter)PyCelprm_get_euler, NULL, (char *)doc_celprm_euler}, {"latpreq", (getter)PyCelprm_get_latpreq, NULL, (char *)doc_celprm_latpreq}, {"isolat", (getter)PyCelprm_get_isolat, NULL, (char *)doc_celprm_isolat}, {"_flag", (getter)PyCelprm_get_flag, NULL, ""}, {"prj", (getter)PyCelprm_get_prj, NULL, (char *)doc_celprm_prj}, {NULL} }; static PyMethodDef PyCelprm_methods[] = { {"set", (PyCFunction)PyCelprm_set, METH_NOARGS, doc_set_celprm}, {"__copy__", (PyCFunction)PyCelprm_copy, METH_NOARGS, ""}, {"__deepcopy__", (PyCFunction)PyCelprm_deepcopy, METH_O, ""}, {NULL} }; PyTypeObject PyCelprmType = { PyVarObject_HEAD_INIT(NULL, 0) "astropy.wcs.Celprm", /*tp_name*/ sizeof(PyCelprm), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyCelprm_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)PyCelprm___str__, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ doc_Celprm, /* tp_doc */ (traverseproc)PyCelprm_traverse, /* tp_traverse */ (inquiry)PyCelprm_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyCelprm_methods, /* tp_methods */ 0, /* tp_members */ PyCelprm_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ PyCelprm_new, /* tp_new */ }; int _setup_celprm_type(PyObject* m) { if (PyType_Ready(&PyCelprmType) < 0) return -1; Py_INCREF(&PyCelprmType); PyModule_AddObject(m, "Celprm", (PyObject *)&PyCelprmType); cel_errexc[0] = NULL; /* Success */ cel_errexc[1] = &PyExc_MemoryError; /* Null celprm pointer passed */ cel_errexc[2] = &WcsExc_InvalidPrjParameters; /* Invalid projection parameters */ cel_errexc[3] = &WcsExc_InvalidTransform; /* Invalid coordinate transformation parameters */ cel_errexc[4] = &WcsExc_InvalidTransform; /* Ill-conditioned coordinate transformation parameters */ cel_errexc[5] = &WcsExc_InvalidCoordinate; /* One or more of the (x,y) coordinates were invalid */ cel_errexc[6] = &WcsExc_InvalidCoordinate; /* One or more of the (lng,lat) coordinates were invalid */ return 0; }