Py::Object _path_module::update_path_extents(const Py::Tuple& args) { args.verify_length(5); double x0, y0, x1, y1; PathIterator path(args[0]); agg::trans_affine trans = py_to_agg_transformation_matrix( args[1].ptr(), false); if (!py_convert_bbox(args[2].ptr(), x0, y0, x1, y1)) { throw Py::ValueError( "Must pass Bbox object as arg 3 of update_path_extents"); } Py::Object minpos_obj = args[3]; bool ignore = bool(Py::Int(args[4])); double xm, ym; PyArrayObject* input_minpos = NULL; try { input_minpos = (PyArrayObject*)PyArray_FromObject( minpos_obj.ptr(), PyArray_DOUBLE, 1, 1); if (!input_minpos || PyArray_DIM(input_minpos, 0) != 2) { throw Py::TypeError( "Argument 4 to update_path_extents must be a length-2 numpy array."); } xm = *(double*)PyArray_GETPTR1(input_minpos, 0); ym = *(double*)PyArray_GETPTR1(input_minpos, 1); } catch (...) { Py_XDECREF(input_minpos); throw; } Py_XDECREF(input_minpos); npy_intp extent_dims[] = { 2, 2, 0 }; double* extents_data = NULL; npy_intp minpos_dims[] = { 2, 0 }; double* minpos_data = NULL; PyArrayObject* extents = NULL; PyArrayObject* minpos = NULL; bool changed = false; try { extents = (PyArrayObject*)PyArray_SimpleNew (2, extent_dims, PyArray_DOUBLE); if (extents == NULL) { throw Py::MemoryError("Could not allocate result array"); } minpos = (PyArrayObject*)PyArray_SimpleNew (1, minpos_dims, PyArray_DOUBLE); if (minpos == NULL) { throw Py::MemoryError("Could not allocate result array"); } extents_data = (double*)PyArray_DATA(extents); minpos_data = (double*)PyArray_DATA(minpos); if (ignore) { extents_data[0] = std::numeric_limits<double>::infinity(); extents_data[1] = std::numeric_limits<double>::infinity(); extents_data[2] = -std::numeric_limits<double>::infinity(); extents_data[3] = -std::numeric_limits<double>::infinity(); minpos_data[0] = std::numeric_limits<double>::infinity(); minpos_data[1] = std::numeric_limits<double>::infinity(); } else { if (x0 > x1) { extents_data[0] = std::numeric_limits<double>::infinity(); extents_data[2] = -std::numeric_limits<double>::infinity(); } else { extents_data[0] = x0; extents_data[2] = x1; } if (y0 > y1) { extents_data[1] = std::numeric_limits<double>::infinity(); extents_data[3] = -std::numeric_limits<double>::infinity(); } else { extents_data[1] = y0; extents_data[3] = y1; } minpos_data[0] = xm; minpos_data[1] = ym; } ::get_path_extents(path, trans, &extents_data[0], &extents_data[1], &extents_data[2], &extents_data[3], &minpos_data[0], &minpos_data[1]); changed = (extents_data[0] != x0 || extents_data[1] != y0 || extents_data[2] != x1 || extents_data[3] != y1 || minpos_data[0] != xm || minpos_data[1] != ym); } catch (...) { Py_XDECREF(extents); Py_XDECREF(minpos); throw; } Py::Tuple result(3); result[0] = Py::Object((PyObject*) extents); result[1] = Py::Object((PyObject*) minpos); result[2] = Py::Int(changed ? 1 : 0); Py_XDECREF(extents); Py_XDECREF(minpos); return result; }
Py::Object _path_module::affine_transform(const Py::Tuple& args) { args.verify_length(2); Py::Object vertices_obj = args[0]; Py::Object transform_obj = args[1]; PyArrayObject* vertices = NULL; PyArrayObject* transform = NULL; PyArrayObject* result = NULL; try { vertices = (PyArrayObject*)PyArray_FromObject (vertices_obj.ptr(), PyArray_DOUBLE, 1, 2); if (!vertices || (PyArray_NDIM(vertices) == 2 && PyArray_DIM(vertices, 0) != 0 && PyArray_DIM(vertices, 1) != 2) || (PyArray_NDIM(vertices) == 1 && PyArray_DIM(vertices, 0) != 2 && PyArray_DIM(vertices, 0) != 0)) { throw Py::ValueError("Invalid vertices array."); } transform = (PyArrayObject*) PyArray_FromObject (transform_obj.ptr(), PyArray_DOUBLE, 2, 2); if (!transform || PyArray_DIM(transform, 0) != 3 || PyArray_DIM(transform, 1) != 3) { throw Py::ValueError("Invalid transform."); } double a, b, c, d, e, f; { size_t stride0 = PyArray_STRIDE(transform, 0); size_t stride1 = PyArray_STRIDE(transform, 1); char* row0 = PyArray_BYTES(transform); char* row1 = row0 + stride0; a = *(double*)(row0); row0 += stride1; c = *(double*)(row0); row0 += stride1; e = *(double*)(row0); b = *(double*)(row1); row1 += stride1; d = *(double*)(row1); row1 += stride1; f = *(double*)(row1); } result = (PyArrayObject*)PyArray_SimpleNew (PyArray_NDIM(vertices), PyArray_DIMS(vertices), PyArray_DOUBLE); if (result == NULL) { throw Py::MemoryError("Could not allocate memory for path"); } if (PyArray_NDIM(vertices) == 2) { size_t n = PyArray_DIM(vertices, 0); char* vertex_in = PyArray_BYTES(vertices); double* vertex_out = (double*)PyArray_DATA(result); size_t stride0 = PyArray_STRIDE(vertices, 0); size_t stride1 = PyArray_STRIDE(vertices, 1); double x; double y; for (size_t i = 0; i < n; ++i) { x = *(double*)(vertex_in); y = *(double*)(vertex_in + stride1); *vertex_out++ = a * x + c * y + e; *vertex_out++ = b * x + d * y + f; vertex_in += stride0; } } else if (PyArray_DIM(vertices, 0) != 0) { char* vertex_in = PyArray_BYTES(vertices); double* vertex_out = (double*)PyArray_DATA(result); size_t stride0 = PyArray_STRIDE(vertices, 0); double x; double y; x = *(double*)(vertex_in); y = *(double*)(vertex_in + stride0); *vertex_out++ = a * x + c * y + e; *vertex_out++ = b * x + d * y + f; } } catch (...) { Py_XDECREF(vertices); Py_XDECREF(transform); Py_XDECREF(result); throw; } Py_XDECREF(vertices); Py_XDECREF(transform); return Py::Object((PyObject*)result, true); }
static PyObject* evaluate_baseline_uvw(PyObject* self, PyObject* args) { int typenum, requirements, n; PyObject *x_ecef_o=NULL, *y_ecef_o=NULL, *z_ecef_o=NULL; double ra0, dec0, mjd; PyObject *x_ecef_=NULL, *y_ecef_=NULL, *z_ecef_=NULL; npy_intp* dims; double *x_ecef, *y_ecef, *z_ecef; npy_intp nb; PyObject *uu_, *vv_, *ww_; double *uu, *vv, *ww; /* Read input arguments */ if (!PyArg_ParseTuple(args, "O!O!O!ddd", &PyArray_Type, &x_ecef_o, &PyArray_Type, &y_ecef_o, &PyArray_Type, &z_ecef_o, &ra0, &dec0, &mjd)) return NULL; /* Convert Python objects to array of specified built-in data-type.*/ typenum = NPY_DOUBLE; requirements = NPY_ARRAY_IN_ARRAY; x_ecef_ = PyArray_FROM_OTF(x_ecef_o, typenum, requirements); if (!x_ecef_) goto fail; y_ecef_ = PyArray_FROM_OTF(y_ecef_o, typenum, requirements); if (!y_ecef_) goto fail; z_ecef_ = PyArray_FROM_OTF(z_ecef_o, typenum, requirements); if (!z_ecef_) goto fail; /* printf(" - A ref count: x_ecef_:%zi, y_ecef_:%zi, z_ecef_:%zi\n", PyArray_REFCOUNT(x_ecef_), PyArray_REFCOUNT(y_ecef_), PyArray_REFCOUNT(z_ecef_)); */ /* Extract dimensions and pointers. */ /* TODO Require input arrays be 1D, and check dimension consistency. * int nd = PyArray_NDIM(x_ecef_); */ dims = PyArray_DIMS((PyArrayObject*)x_ecef_); x_ecef = (double*)PyArray_DATA((PyArrayObject*)x_ecef_); y_ecef = (double*)PyArray_DATA((PyArrayObject*)y_ecef_); z_ecef = (double*)PyArray_DATA((PyArrayObject*)z_ecef_); /* Create New arrays for baseline coordinates. */ n = dims[0]; nb = (n * (n-1)) / 2; uu_ = PyArray_SimpleNew(1, &nb, NPY_DOUBLE); vv_ = PyArray_SimpleNew(1, &nb, NPY_DOUBLE); ww_ = PyArray_SimpleNew(1, &nb, NPY_DOUBLE); uu = (double*)PyArray_DATA((PyArrayObject*)uu_); vv = (double*)PyArray_DATA((PyArrayObject*)vv_); ww = (double*)PyArray_DATA((PyArrayObject*)ww_); /* printf(" - B ref count: uu_:%zi, vv_:%zi, ww_:%zi\n", PyArray_REFCOUNT(uu_), PyArray_REFCOUNT(vv_), PyArray_REFCOUNT(ww_)); */ /* Call function to evaluate baseline uvw */ uvwsim_evaluate_baseline_uvw(uu, vv, ww, n, x_ecef, y_ecef, z_ecef, ra0, dec0, mjd); /* Decrement references to local array objects. */ Py_DECREF(x_ecef_); Py_DECREF(y_ecef_); Py_DECREF(z_ecef_); /* printf(" - C ref count: x_ecef_:%zi, y_ecef_:%zi, z_ecef_:%zi\n", PyArray_REFCOUNT(x_ecef_), PyArray_REFCOUNT(x_ecef_), PyArray_REFCOUNT(x_ecef_)); */ /* Return baseline coordinates. */ return Py_BuildValue("NNN", uu_, vv_, ww_); fail: Py_XDECREF(x_ecef_); Py_XDECREF(y_ecef_); Py_XDECREF(z_ecef_); return NULL; }
Py::Object _path_module::cleanup_path(const Py::Tuple& args) { args.verify_length(8); PathIterator path(args[0]); agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); bool remove_nans = args[2].isTrue(); Py::Object clip_obj = args[3]; bool do_clip; agg::rect_base<double> clip_rect; if (clip_obj.isNone()) { do_clip = false; } else { double x1, y1, x2, y2; Py::Tuple clip_tuple(clip_obj); x1 = Py::Float(clip_tuple[0]); y1 = Py::Float(clip_tuple[1]); x2 = Py::Float(clip_tuple[2]); y2 = Py::Float(clip_tuple[3]); clip_rect.init(x1, y1, x2, y2); do_clip = true; } Py::Object snap_obj = args[4]; e_snap_mode snap_mode; if (snap_obj.isNone()) { snap_mode = SNAP_AUTO; } else if (snap_obj.isTrue()) { snap_mode = SNAP_TRUE; } else { snap_mode = SNAP_FALSE; } double stroke_width = Py::Float(args[5]); bool simplify; Py::Object simplify_obj = args[6]; if (simplify_obj.isNone()) { simplify = path.should_simplify(); } else { simplify = simplify_obj.isTrue(); } bool return_curves = args[7].isTrue(); std::vector<double> vertices; std::vector<npy_uint8> codes; _cleanup_path(path, trans, remove_nans, do_clip, clip_rect, snap_mode, stroke_width, simplify, return_curves, vertices, codes); npy_intp length = codes.size(); npy_intp dims[] = { length, 2, 0 }; PyArrayObject* vertices_obj = NULL; PyArrayObject* codes_obj = NULL; Py::Tuple result(2); try { vertices_obj = (PyArrayObject*)PyArray_SimpleNew (2, dims, PyArray_DOUBLE); if (vertices_obj == NULL) { throw Py::MemoryError("Could not allocate result array"); } codes_obj = (PyArrayObject*)PyArray_SimpleNew (1, dims, PyArray_UINT8); if (codes_obj == NULL) { throw Py::MemoryError("Could not allocate result array"); } memcpy(PyArray_DATA(vertices_obj), &vertices[0], sizeof(double) * 2 * length); memcpy(PyArray_DATA(codes_obj), &codes[0], sizeof(npy_uint8) * length); result[0] = Py::Object((PyObject*)vertices_obj, true); result[1] = Py::Object((PyObject*)codes_obj, true); } catch (...) { Py_XDECREF(vertices_obj); Py_XDECREF(codes_obj); throw; } return result; }
static PyObject * hungarian(PyObject *self, PyObject *args) //hungarian(costs) { PyObject *ocosts; PyArrayObject *costs; int n; npy_intp n2; long *rowsol; long *colsol; cost *buf,**ccosts; npy_intp *strides; PyObject * rowo; PyObject * colo; if (!PyArg_ParseTuple(args, "O", &ocosts)) return NULL; costs = (PyArrayObject*)PyArray_FromAny( ocosts,PyArray_DescrFromType(COST_TYPE_NPY),2,2, NPY_CONTIGUOUS|NPY_ALIGNED|NPY_FORCECAST,0 ); if (costs->nd!=2) { PyErr_SetString(PyExc_ValueError,"lap() requires a 2-D matrix"); goto error; } n = costs->dimensions[0]; n2 = costs->dimensions[0]; if (costs->dimensions[1]!=n) { PyErr_SetString(PyExc_ValueError,"lap() requires a square matrix"); goto error; } //get inputted matrix as a 1-D C array: buf = (cost*)PyArray_DATA(costs); //copy inputted matrix into a 2-dimensional C array: strides = PyArray_STRIDES(costs); assert(strides[1] == sizeof(cost)); ccosts = (cost **)malloc(sizeof(cost *)*n); if(!ccosts) { PyErr_NoMemory(); free(ccosts); goto error; } for(int i=0;i<n;i++) ccosts[i] = buf+i*(strides[0]/sizeof(cost)); //allocate data for the output array rowo = PyArray_SimpleNew(1, &n2, NPY_LONG); colo = PyArray_SimpleNew(1, &n2, NPY_LONG); rowsol = (long *) PyArray_DATA(rowo); colsol = (long *) PyArray_DATA(colo); if(!(rowsol&&colsol)) { PyErr_NoMemory(); free(ccosts); goto error; } //run hungarian!: asp(n,ccosts,rowsol,colsol); //NA_InputArray() incremented costs, but now we're done with it, so let it get GC'ed: Py_XDECREF(costs); free(ccosts); return Py_BuildValue("(NN)", rowo, colo ); error: Py_XDECREF(costs); return NULL; }
// Reduce the number of pointer-to-function warnings (since disabling them seems not possible) static PyArrayObject * PyArrayObject_New( int n, npy_intp * shape, int type ) { return (PyArrayObject*)PyArray_SimpleNew( n, shape, type ); }
/*@null@*/ static PyObject* Wcs_all_pix2sky( Wcs* self, PyObject* args, PyObject* kwds) { int naxis = 2; PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* world = NULL; int status = -1; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords( args, kwds, "Oi:all_pix2sky", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } naxis = self->x.wcs->naxis; pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(pixcrd_obj, PyArray_DOUBLE, 2, 2); if (pixcrd == NULL) { return NULL; } if (PyArray_DIM(pixcrd, 1) < naxis) { PyErr_Format( PyExc_RuntimeError, "Input array must be 2-dimensional, where the second dimension >= %d", naxis); goto exit; } world = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), PyArray_DOUBLE); if (world == NULL) { goto exit; } /* Make the call */ Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); wcsprm_python2c(self->x.wcs); status = pipeline_all_pixel2world(&self->x, (unsigned int)PyArray_DIM(pixcrd, 0), (unsigned int)PyArray_DIM(pixcrd, 1), (double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(world)); wcsprm_c2python(self->x.wcs); unoffset_array(pixcrd, origin); Py_END_ALLOW_THREADS /* unoffset_array(world, origin); */ exit: Py_XDECREF(pixcrd); if (status == 0 || status == 8) { return (PyObject*)world; } else if (status == -1) { PyErr_SetString( PyExc_ValueError, "Wrong number of dimensions in input array. Expected 2."); return NULL; } else { Py_DECREF(world); if (status == -1) { /* exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } }
static PyObject * potential_getattro(potential_t *self, PyObject *pyname) { char *name; property_t *p; PyObject *r = NULL; PyArrayObject *arr; npy_intp dims[3]; double *data; PyObject **odata; int i, j, k; name = PyString_AsString(pyname); if (!name) return NULL; p = self->f90members->first_property; while (p != NULL && strcmp(p->name, name)) { p = p->next; } if (p) { r = NULL; switch (p->kind) { case PK_INT: r = PyInt_FromLong(*((int*) p->ptr)); break; case PK_DOUBLE: r = PyFloat_FromDouble(*((double*) p->ptr)); break; case PK_BOOL: r = PyBool_FromLong(*((BOOL*) p->ptr)); break; case PK_LIST: if (*p->tag5 == 1) { r = PyFloat_FromDouble(*((double*) p->ptr)); } else { dims[0] = *p->tag5; arr = (PyArrayObject*) PyArray_SimpleNew(1, (npy_intp*) dims, NPY_DOUBLE); data = (double *) PyArray_DATA(arr); for (i = 0; i < *p->tag5; i++) { data[i] = ((double*) p->ptr)[i]; } r = (PyObject*) arr; } break; case PK_FORTRAN_STRING_LIST: if (*p->tag5 == 1) { r = fstring_to_pystring((char*) p->ptr, p->tag); } else { dims[0] = *p->tag5; arr = (PyArrayObject*) PyArray_SimpleNew(1, (npy_intp*) dims, NPY_OBJECT); odata = (PyObject **) PyArray_DATA(arr); for (i = 0; i < *p->tag5; i++) { odata[i] = fstring_to_pystring(((char*) p->ptr + i*p->tag), p->tag); } r = (PyObject*) arr; } break; case PK_ARRAY2D: dims[0] = p->tag; dims[1] = p->tag2; arr = (PyArrayObject*) PyArray_SimpleNew(2, (npy_intp*) dims, NPY_DOUBLE); data = (double *) PyArray_DATA(arr); for (i = 0; i < p->tag; i++) { for (j = 0; j < p->tag2; j++) { data[j + i*p->tag2] = ((double*) p->ptr)[i + j*p->tag]; } } // memcpy(data, p->ptr, p->tag*p->tag2*sizeof(double)); r = (PyObject*) arr; break; case PK_ARRAY3D: dims[0] = p->tag; dims[1] = p->tag2; dims[2] = p->tag3; arr = (PyArrayObject*) PyArray_SimpleNew(3, (npy_intp*) dims, NPY_DOUBLE); data = (double *) PyArray_DATA(arr); for (i = 0; i < p->tag; i++) { for (j = 0; j < p->tag2; j++) { for (k = 0; k < p->tag3; k++) { data[k + (j + i*p->tag2)*p->tag3] = ((double*) p->ptr)[i + (j + k*p->tag2)*p->tag]; } } } // memcpy(data, p->ptr, p->tag*p->tag2*p->tag3*sizeof(double)); r = (PyObject*) arr; break; default: PyErr_SetString(PyExc_TypeError, "Internal error: Unknown type encountered in section."); break; } } else { r = PyObject_GenericGetAttr((PyObject *) self, pyname); // Py_FindMethod(self->ob_type->tp_methods, (PyObject *) self, name); } return r; }
static PyObject* spherematch_nn2(PyObject* self, PyObject* args) { int i, j, NY, N; long p1, p2; kdtree_t *kd1, *kd2; npy_intp dims[1]; PyObject* I; PyObject* J; PyObject* dist2s; PyObject* counts = NULL; int *pi; int *pj; int *pc = NULL; double *pd; double rad; anbool notself; anbool docount; int* tempinds; int* tempcount = NULL; int** ptempcount = NULL; double* tempd2; PyObject* rtn; // So that ParseTuple("b") with a C "anbool" works assert(sizeof(anbool) == sizeof(unsigned char)); if (!PyArg_ParseTuple(args, "lldbb", &p1, &p2, &rad, ¬self, &docount)) { PyErr_SetString(PyExc_ValueError, "need five args: two kdtree identifiers (ints), search radius, notself (bool) and docount (bool)"); return NULL; } // Nasty! kd1 = (kdtree_t*)p1; kd2 = (kdtree_t*)p2; // quick check for no-overlap case if (kdtree_node_node_mindist2_exceeds(kd1, 0, kd2, 0, rad*rad)) { // allocate empty return arrays dims[0] = 0; I = PyArray_SimpleNew(1, dims, NPY_INT); J = PyArray_SimpleNew(1, dims, NPY_INT); dist2s = PyArray_SimpleNew(1, dims, NPY_DOUBLE); if (docount) { counts = PyArray_SimpleNew(1, dims, NPY_INT); rtn = Py_BuildValue("(OOOO)", I, J, dist2s, counts); Py_DECREF(counts); } else { rtn = Py_BuildValue("(OOO)", I, J, dist2s); } Py_DECREF(I); Py_DECREF(J); Py_DECREF(dist2s); return rtn; } NY = kdtree_n(kd2); tempinds = (int*)malloc(NY * sizeof(int)); tempd2 = (double*)malloc(NY * sizeof(double)); if (docount) { tempcount = (int*)calloc(NY, sizeof(int)); ptempcount = &tempcount; } dualtree_nearestneighbour(kd1, kd2, rad*rad, &tempd2, &tempinds, ptempcount, notself); // count number of matches N = 0; for (i=0; i<NY; i++) if (tempinds[i] != -1) N++; // allocate return arrays dims[0] = N; I = PyArray_SimpleNew(1, dims, NPY_INT); J = PyArray_SimpleNew(1, dims, NPY_INT); dist2s = PyArray_SimpleNew(1, dims, NPY_DOUBLE); pi = PyArray_DATA(I); pj = PyArray_DATA(J); pd = PyArray_DATA(dist2s); if (docount) { counts = PyArray_SimpleNew(1, dims, NPY_INT); pc = PyArray_DATA(counts); } j = 0; for (i=0; i<NY; i++) { if (tempinds[i] == -1) continue; pi[j] = kdtree_permute(kd1, tempinds[i]); pj[j] = kdtree_permute(kd2, i); pd[j] = tempd2[i]; if (docount) pc[j] = tempcount[i]; j++; } free(tempinds); free(tempd2); free(tempcount); if (docount) { rtn = Py_BuildValue("(OOOO)", I, J, dist2s, counts); Py_DECREF(counts); } else { rtn = Py_BuildValue("(OOO)", I, J, dist2s); } Py_DECREF(I); Py_DECREF(J); Py_DECREF(dist2s); return rtn; }
static PyObject* PyUnits_convert( PyUnits* self, PyObject* args, PyObject* kwds) { int status = 1; PyObject* input = NULL; PyArrayObject* input_arr = NULL; PyArrayObject* output_arr = NULL; PyObject* input_iter = NULL; PyObject* output_iter = NULL; double input_val; double output_val; if (!PyArg_ParseTuple(args, "O:UnitConverter.convert", &input)) { goto exit; } input_arr = (PyArrayObject*)PyArray_FromObject( input, NPY_DOUBLE, 0, NPY_MAXDIMS); if (input_arr == NULL) { goto exit; } output_arr = (PyArrayObject*)PyArray_SimpleNew( PyArray_NDIM(input_arr), PyArray_DIMS(input_arr), PyArray_DOUBLE); if (output_arr == NULL) { goto exit; } input_iter = PyArray_IterNew((PyObject*)input_arr); if (input_iter == NULL) { goto exit; } output_iter = PyArray_IterNew((PyObject*)output_arr); if (output_iter == NULL) { goto exit; } if (self->power != 1.0) { while (PyArray_ITER_NOTDONE(input_iter)) { input_val = *(double *)PyArray_ITER_DATA(input_iter); output_val = pow(self->scale*input_val + self->offset, self->power); if (errno) { PyErr_SetFromErrno(PyExc_ValueError); goto exit; } *(double *)PyArray_ITER_DATA(output_iter) = output_val; PyArray_ITER_NEXT(input_iter); PyArray_ITER_NEXT(output_iter); } } else { while (PyArray_ITER_NOTDONE(input_iter)) { input_val = *(double *)PyArray_ITER_DATA(input_iter); output_val = self->scale*input_val + self->offset; *(double *)PyArray_ITER_DATA(output_iter) = output_val; PyArray_ITER_NEXT(input_iter); PyArray_ITER_NEXT(output_iter); } } status = 0; exit: Py_XDECREF((PyObject*)input_arr); Py_XDECREF(input_iter); Py_XDECREF(output_iter); if (status) { Py_XDECREF((PyObject*)output_arr); return NULL; } return (PyObject*)output_arr; }
static PyObject* spherematch_nn(PyObject* self, PyObject* args) { int i, NY; long p1, p2; kdtree_t *kd1, *kd2; npy_intp dims[1]; PyArrayObject* inds; PyArrayObject* dist2s; int *pinds; double *pdist2s; double rad; anbool notself; int* tempinds; PyObject* rtn; // So that ParseTuple("b") with a C "anbool" works assert(sizeof(anbool) == sizeof(unsigned char)); if (!PyArg_ParseTuple(args, "lldb", &p1, &p2, &rad, ¬self)) { PyErr_SetString(PyExc_ValueError, "need three args: two kdtree identifiers (ints), and search radius"); return NULL; } // Nasty! kd1 = (kdtree_t*)p1; kd2 = (kdtree_t*)p2; NY = kdtree_n(kd2); dims[0] = NY; inds = (PyArrayObject*)PyArray_SimpleNew(1, dims, PyArray_INT); dist2s = (PyArrayObject*)PyArray_SimpleNew(1, dims, PyArray_DOUBLE); assert(PyArray_ITEMSIZE(inds) == sizeof(int)); assert(PyArray_ITEMSIZE(dist2s) == sizeof(double)); // YUCK! tempinds = (int*)malloc(NY * sizeof(int)); double* tempdists = (double*)malloc(NY * sizeof(double)); pinds = tempinds; //PyArray_DATA(inds); //pdist2s = PyArray_DATA(dist2s); pdist2s = tempdists; dualtree_nearestneighbour(kd1, kd2, rad*rad, &pdist2s, &pinds, NULL, notself); // now we have to apply kd1's permutation array! for (i=0; i<NY; i++) if (pinds[i] != -1) pinds[i] = kdtree_permute(kd1, pinds[i]); pinds = PyArray_DATA(inds); pdist2s = PyArray_DATA(dist2s); for (i=0; i<NY; i++) { pinds[i] = -1; pdist2s[i] = HUGE_VAL; } // and apply kd2's permutation array! for (i=0; i<NY; i++) { if (tempinds[i] != -1) { int j = kdtree_permute(kd2, i); pinds[j] = tempinds[i]; pdist2s[j] = tempdists[i]; } } free(tempinds); free(tempdists); rtn = Py_BuildValue("(OO)", inds, dist2s); Py_DECREF(inds); Py_DECREF(dist2s); return rtn; }
static PyObject* spherematch_match(PyObject* self, PyObject* args) { size_t i, N; long p1, p2; kdtree_t *kd1, *kd2; double rad; struct dualtree_results dtresults; PyArrayObject* inds; npy_intp dims[2]; PyArrayObject* dists; anbool notself; anbool permute; PyObject* rtn; // So that ParseTuple("b") with a C "anbool" works assert(sizeof(anbool) == sizeof(unsigned char)); if (!PyArg_ParseTuple(args, "lldbb", &p1, &p2, &rad, ¬self, &permute)) { PyErr_SetString(PyExc_ValueError, "spherematch_c.match: need five args: two kdtree identifiers (ints), search radius (float), notself (boolean), permuted (boolean)"); return NULL; } //printf("Notself = %i\n", (int)notself); // Nasty! kd1 = (kdtree_t*)p1; kd2 = (kdtree_t*)p2; dtresults.inds1 = il_new(256); dtresults.inds2 = il_new(256); dtresults.dists = dl_new(256); dualtree_rangesearch(kd1, kd2, 0.0, rad, notself, NULL, callback_dualtree, &dtresults, NULL, NULL); N = il_size(dtresults.inds1); dims[0] = N; dims[1] = 2; inds = (PyArrayObject*)PyArray_SimpleNew(2, dims, PyArray_INT); dims[1] = 1; dists = (PyArrayObject*)PyArray_SimpleNew(2, dims, PyArray_DOUBLE); for (i=0; i<N; i++) { int index; int* iptr; double* dptr; iptr = PyArray_GETPTR2(inds, i, 0); index = il_get(dtresults.inds1, i); if (permute) index = kdtree_permute(kd1, index); *iptr = index; iptr = PyArray_GETPTR2(inds, i, 1); index = il_get(dtresults.inds2, i); if (permute) index = kdtree_permute(kd2, index); *iptr = index; dptr = PyArray_GETPTR2(dists, i, 0); *dptr = dl_get(dtresults.dists, i); } il_free(dtresults.inds1); il_free(dtresults.inds2); dl_free(dtresults.dists); rtn = Py_BuildValue("(OO)", inds, dists); Py_DECREF(inds); Py_DECREF(dists); return rtn; }
/** * @brief Function to load station coordinates. * @details * This function loads coordinates from a specified layout file, returning * them as NumPy arrays. This function is a wrapper to * uvwsim_load_station_coords(). */ static PyObject* load_station_coords(PyObject* self, PyObject* args) { /* * http://docs.scipy.org/doc/numpy/user/c-info.how-to-extend.html * http://nedbatchelder.com/text/whirlext.html * https://docs.python.org/2/extending/extending.html#intermezzo-errors-and-exceptions */ int n, nread; npy_intp dims; const char* filename_ = 0; PyObject *x_, *y_, *z_; double *x, *y, *z; if (!PyArg_ParseTuple(args, "s", &filename_)) { return NULL; } /* Check if the file exists */ if (!uvwsim_file_exists(filename_)) { PyErr_SetString(PyExc_RuntimeError, "Specified station (antenna) " "layout file doesn't exist!"); /* PyErr_SetString(pyuvwsimError, "Specified station (antenna) " "layout file doesn't exist!"); */ return NULL; } /* Find number of stations and load station coordinates */ n = uvwsim_get_num_stations(filename_); /* Allocate arrays to hold coordinates. */ dims = n; x_ = PyArray_SimpleNew(1, &dims, NPY_DOUBLE); y_ = PyArray_SimpleNew(1, &dims, NPY_DOUBLE); z_ = PyArray_SimpleNew(1, &dims, NPY_DOUBLE); x = (double*)PyArray_DATA((PyArrayObject*)x_); y = (double*)PyArray_DATA((PyArrayObject*)y_); z = (double*)PyArray_DATA((PyArrayObject*)z_); /* Read station coordinates. */ nread = uvwsim_load_station_coords(filename_, n, x, y, z); if (nread != n) { PyErr_SetString(PyExc_RuntimeError, "Layout file read error. Incorrect " "number of station coordinates read."); /* PyErr_SetString(pyuvwsimError, "Layout file read error. Incorrect " "number of station coordinates read."); */ Py_DECREF(x_); Py_DECREF(y_); Py_DECREF(z_); return NULL; } /*printf(" - ref count: x_:%zi, y_:%zi, z_:%zi\n", PyArray_REFCOUNT(x_), PyArray_REFCOUNT(y_),PyArray_REFCOUNT(z_));*/ /* 'O' increases reference count by 1, 'N' doesn't */ /* https://docs.python.org/2.0/ext/buildValue.html */ return Py_BuildValue("NNN", x_, y_, z_); }
static PyObject* pyndf_aread(NDF *self, PyObject *args) { int iaxis; const char *MMOD = "READ"; const char *comp; if(!PyArg_ParseTuple(args, "si:pyndf_aread", &comp, &iaxis)) return NULL; int status = SAI__OK; errBegin(&status); int naxis = tr_iaxis(self->_ndfid, iaxis, &status); // Return None if component does not exist int state; ndfAstat(self->_ndfid, comp, naxis, &state, &status); if (raiseNDFException(&status)) return NULL; if(!state) Py_RETURN_NONE; // Get dimensions int idim[NDF__MXDIM], ndim; errBegin(&status); ndfDim(self->_ndfid, NDF__MXDIM, idim, &ndim, &status); if (raiseNDFException(&status)) return NULL; // get number for particular axis in question. int nelem = idim[naxis-1]; // Determine the data type const int MXLEN=33; char type[MXLEN]; errBegin(&status); ndfAtype(self->_ndfid, comp, naxis, type, MXLEN, &status); if (raiseNDFException(&status)) return NULL; // Create array of correct dimensions and type to save data to size_t nbyte; ndim = 1; npy_intp dim[1] = {nelem}; PyArrayObject* arr = NULL; int npytype = ndftype2numpy( type, &nbyte ); if (npytype ==0) return NULL; arr = (PyArrayObject*) PyArray_SimpleNew(ndim, dim, npytype); if(arr == NULL) goto fail; // map, store, unmap int nread; void *pntr[1]; errBegin(&status); ndfAmap(self->_ndfid, comp, naxis, type, MMOD, pntr, &nread, &status); if (raiseNDFException(&status)) goto fail; if(nelem != nread){ printf("nread = %d, nelem = %d, iaxis = %d, %d\n",nread,nelem,iaxis,naxis); PyErr_SetString(PyExc_IOError, "ndf_aread error: number of elements different from number expected"); goto fail; } memcpy(arr->data, pntr[0], nelem*nbyte); errBegin(&status); ndfAunmp(self->_ndfid, comp, naxis, &status); if (raiseNDFException(&status)) goto fail; return Py_BuildValue("N", PyArray_Return(arr)); fail: Py_XDECREF(arr); return NULL; };
/*@null@*/ static PyObject* Wcs_det2im( Wcs* self, PyObject* args, PyObject* kwds) { PyObject* detcrd_obj = NULL; int origin = 1; PyArrayObject* detcrd = NULL; PyArrayObject* imcrd = NULL; int status = -1; const char* keywords[] = { "detcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:det2im", (char **)keywords, &detcrd_obj, &origin)) { return NULL; } if (self->x.det2im[0] == NULL && self->x.det2im[1] == NULL) { Py_INCREF(detcrd_obj); return detcrd_obj; } detcrd = (PyArrayObject*)PyArray_ContiguousFromAny(detcrd_obj, PyArray_DOUBLE, 2, 2); if (detcrd == NULL) { return NULL; } if (PyArray_DIM(detcrd, 1) != NAXES) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto exit; } imcrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(detcrd), PyArray_DOUBLE); if (imcrd == NULL) { status = 2; goto exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(detcrd, origin); status = p4_pix2foc(2, (void *)self->x.det2im, (unsigned int)PyArray_DIM(detcrd, 0), (double*)PyArray_DATA(detcrd), (double*)PyArray_DATA(imcrd)); unoffset_array(detcrd, origin); unoffset_array(imcrd, origin); Py_END_ALLOW_THREADS exit: Py_XDECREF(detcrd); if (status == 0) { return (PyObject*)imcrd; } else { Py_XDECREF(imcrd); if (status == -1) { /* Exception already set */ return NULL; } else { PyErr_SetString(PyExc_MemoryError, "NULL pointer passed"); return NULL; } } }
// Reads an NDF into a numpy array static PyObject* pyndf_read(NDF *self, PyObject *args) { int i; const char *comp; if(!PyArg_ParseTuple(args, "s:pyndf_read", &comp)) return NULL; // series of declarations in an attempt to avoid problem with // goto fail const int MXLEN=32; char type[MXLEN+1]; size_t nbyte; int npix, nelem; // Return None if component does not exist int state, status = SAI__OK; errBegin(&status); ndfState(self->_ndfid, comp, &state, &status); if (raiseNDFException(&status)) return NULL; if(!state) Py_RETURN_NONE; PyArrayObject* arr = NULL; // Get dimensions, reverse order to account for C vs Fortran int idim[NDF__MXDIM]; npy_intp rdim[NDF__MXDIM]; int ndim; errBegin(&status); ndfDim(self->_ndfid, NDF__MXDIM, idim, &ndim, &status); if (raiseNDFException(&status)) return NULL; // Reverse order to account for C vs Fortran for(i=0; i<ndim; i++) rdim[i] = idim[ndim-i-1]; // Determine the data type errBegin(&status); ndfType(self->_ndfid, comp, type, MXLEN+1, &status); if (raiseNDFException(&status)) return NULL; // Create array of correct dimensions and type to save data to int npytype = ndftype2numpy( type, &nbyte ); if (npytype == 0) return NULL; arr = (PyArrayObject*) PyArray_SimpleNew(ndim, rdim, npytype); if(arr == NULL) goto fail; // get number of elements, allocate space, map, store errBegin(&status); ndfSize(self->_ndfid, &npix, &status); if (raiseNDFException(&status)) goto fail; void *pntr[1]; errBegin(&status); ndfMap(self->_ndfid, comp, type, "READ", pntr, &nelem, &status); if (raiseNDFException(&status)) goto fail; if(nelem != npix){ PyErr_SetString(PyExc_IOError, "ndf_read error: number of elements different from number expected"); goto fail; } memcpy(arr->data, pntr[0], npix*nbyte); errBegin(&status); ndfUnmap(self->_ndfid, comp, &status); if (raiseNDFException(&status)) goto fail; return Py_BuildValue("N", PyArray_Return(arr)); fail: Py_XDECREF(arr); return NULL; };
/*@null@*/ static PyObject* Wcs_pix2foc( Wcs* self, PyObject* args, PyObject* kwds) { PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* foccrd = NULL; int status = -1; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:pix2foc", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(pixcrd_obj, PyArray_DOUBLE, 2, 2); if (pixcrd == NULL) { return NULL; } if (PyArray_DIM(pixcrd, 1) != NAXES) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto _exit; } foccrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), PyArray_DOUBLE); if (foccrd == NULL) { goto _exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); status = pipeline_pix2foc(&self->x, (unsigned int)PyArray_DIM(pixcrd, 0), (unsigned int)PyArray_DIM(pixcrd, 1), (double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(foccrd)); unoffset_array(pixcrd, origin); unoffset_array(foccrd, origin); Py_END_ALLOW_THREADS _exit: Py_XDECREF(pixcrd); if (status == 0) { return (PyObject*)foccrd; } else { Py_XDECREF(foccrd); if (status == -1) { /* Exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } }
/* Function called on Python function call via method definition map below. Takes as args two np arrays and optionally a tuple, an int, a string and a double. It seems you need all args to have keyword names, which may be unused. */ static PyObject *rot_shift_scale_args(PyObject *dummy, PyObject *args, PyObject *kwords) { static char *kwlist[] = {"image", "rsmat", "offset", "kernel", "cubic", "mode", "cval", NULL}; PyObject *arg1 = NULL; // image PyObject *arg2 = NULL; // rot & scale PyObject *arr1 = NULL; // image formatted PyObject *arr2 = NULL; // rot & scale formatted // ## should these be const? double *rotscale; double offset[2] = {0.0, 0.0}; int ktype = BICUBIC; // default value double interp_param = -0.5; // bicubic iterp param char *mode = "constant"; double cval = 0.0; // optional arg int dims[2]; int ndim; int i; INTYPE *in_arr; int result; PyObject *out1; OUTTYPE *out_arr; /* Map via physical position between C variables and Python variables (in kwlist) - unused ones are simply left as previously defined. */ if (!PyArg_ParseTupleAndKeywords(args, kwords, "OO|(dd)idsd", kwlist, &arg1, &arg2, &offset[0], &offset[1], &ktype, &interp_param, &mode, &cval)) return NULL; //NULL says error /* Make a nice numpy array using macro for PyArray_FromAny laid out for C access as floats and doubles. The alignment is a bit tricky - sometimes you *don't* need FORCECAST, but often you do. */ // %% arr1 = PyArray_FROM_OTF(arg1, NPY_FLOAT32, NPY_CARRAY_RO | NPY_FORCECAST); arr1 = PyArray_FROM_OTF(arg1, PYIN_TYPE, NPY_CARRAY_RO | NPY_FORCECAST); arr2 = PyArray_FROM_OTF(arg2, NPY_DOUBLE, NPY_IN_ARRAY); // ##printf("E: type check %d %d\n",PyArray_TYPE(arr1), NPY_FLOAT32); // ## printf("E: Constant is %f, offset is %f %f\n", cval, offset[0], offset[1]); in_arr = PyArray_DATA(arr1); // that's where the data for C is ndim = PyArray_NDIM(arr1); // ## printf("E: Input array has %d dimensions\n", ndim); for (i=0; i<ndim; i++) { //## printf("E: Input dim %d is %d with stride %d\n",i,(int)PyArray_DIM(arr1,i),(int)PyArray_STRIDE(arr1,i)); dims[i] = (int)PyArray_DIM(arr1,i); // make sure alignment OK } //##printf("E: Sizeof input elements: %d\n",(int)sizeof(in_arr[0])); //##printf("E: Sizeof output elements: %d\n",(int)sizeof(out_arr[0])); rotscale = PyArray_DATA(arr2); // set to the location of the operator matrix // ## check dims or size e.g. PyArray_SIZE(arr2)) /*printf("E: Rotscale in order: "); for (i=0; i<4; i++) printf(" %f", rotscale[i]); printf("\n"); */ // free() ##? - well, the whole story in doc... // Make a new array the same size as the input array //%% out1 = PyArray_SimpleNew(PyArray_NDIM(arr1), PyArray_DIMS(arr1), PyArray_FLOAT32); out1 = PyArray_SimpleNew(PyArray_NDIM(arr1), PyArray_DIMS(arr1), PYOUT_TYPE); out_arr = PyArray_DATA(out1); // this is the place for the data from C //## printf("E: ktype (interp type) %d\n", ktype); /* Call to function that does the actual work. This one is external. */ result = affine_transform_kc( dims, out_arr, in_arr, rotscale, offset, ktype, interp_param, mode, cval ); Py_DECREF(arr1); Py_DECREF(arr2); if (result != 0) return NULL; return Py_BuildValue("N", out1); }
static PyObject *frgetvect(PyObject *self, PyObject *args, PyObject *keywds) { FrFile *iFile; FrVect *vect; int verbose, i, nDim; long nData; double start, span; double fr_start, fr_end, fr_span; char *filename, *channel, msg[MAX_STR_LEN]; npy_intp shape[MAX_VECT_DIMS]; npy_int16 *data_int16; npy_int32 *data_int32; npy_int64 *data_int64; npy_uint8 *data_uint8; npy_uint16 *data_uint16; npy_uint32 *data_uint32; npy_uint64 *data_uint64; npy_float32 *data_float32; npy_float64 *data_float64; static char *kwlist[] = {"filename", "channel", "start", "span", "verbose", NULL}; PyObject *out1, *out2, *out3, *out4, *out5, *out6; /*--------------- unpack arguments --------------------*/ start = -1.; span = -1.; verbose = 0; /* The | in the format string indicates the next arguments are optional. They are simply not assigned anything. */ if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss|ddi", kwlist, &filename, &channel, &start, &span, &verbose)) { PyErr_SetNone(PyExc_ValueError); return NULL; } FrLibSetLvl(verbose); /*-------------- open file --------------------------*/ if (verbose > 0) { printf("Opening %s for channel %s (start=%.2f, span=%.2f).\n", filename, channel, start, span); } iFile = FrFileINew(filename); if (iFile == NULL){ snprintf(msg, MAX_STR_LEN, "%s", FrErrorGetHistory()); PyErr_SetString(PyExc_IOError, msg); return NULL; } if (verbose > 0){ printf("Opened %s.\n", filename); } fr_start = FrFileITStart(iFile); fr_end = FrFileITEnd(iFile); fr_span = fr_end - fr_start; /* Error checking */ if (start != -1. && start < fr_start) { snprintf(msg, MAX_STR_LEN, "Requested start (%10.6f) is before frame start (%10.6f) in file %s", start, fr_start, filename); FrFileIEnd(iFile); PyErr_SetString(PyExc_ValueError, msg); return NULL; } // Start and span auto-detection requires a TOC in the frame file. if (start == -1.) { start = fr_start; } if (span != -1. && start + span > fr_start + fr_span) { snprintf(msg, MAX_STR_LEN, "Requested end (%10.6f) is after frame end (%10.6f) in file %s", start + span, fr_start + fr_span, filename); FrFileIEnd(iFile); PyErr_SetString(PyExc_ValueError, msg); return NULL; } // Start and span auto-detection requires a TOC in the frame file. if (span == -1.) { span = fr_end - fr_start; } /*-------------- get vector --------------------------*/ vect = FrFileIGetVect(iFile, channel, start, span); if (verbose > 0) FrVectDump(vect, stdout, verbose); if (vect == NULL) { /* Try to open it as StaticData */ FrStatData *sd; /* Here I'd like to do * sd = FrStatDataReadT(iFile, channel, start); * but FrStatDataReadT does *not* return samples after * "start". Doh. Instead, I have to do this: */ double frstart = FrFileITStart(iFile); sd = FrStatDataReadT(iFile, channel, frstart); /* and more below */ if (verbose > 0) FrStatDataDump(sd, stdout, verbose); if (sd == NULL) { snprintf(msg, MAX_STR_LEN, "In file %s, vector not found: %s", filename, channel); FrFileIEnd(iFile); PyErr_SetString(PyExc_KeyError, msg); return NULL; } if (sd->next != NULL) { snprintf(msg, MAX_STR_LEN, "In file %s, staticData channel %s has next!=NULL. " "Freaking out.", filename, channel); FrFileIEnd(iFile); PyErr_SetString(PyExc_KeyError, msg); return NULL; } vect = sd->data; if (vect == NULL) { snprintf(msg, MAX_STR_LEN, "In file %s, staticData channel %s has no vector. " "Freaking out.", filename, channel); FrFileIEnd(iFile); PyErr_SetString(PyExc_KeyError, msg); return NULL; } if (vect->nDim != 1) { snprintf(msg, MAX_STR_LEN, "In file %s, staticData channel %s has multiple " "dimensions. Freaking out.", filename, channel); FrFileIEnd(iFile); PyErr_SetString(PyExc_KeyError, msg); return NULL; } /* Recompute limits and pointers, so "vect" contains only the * subset of data we requested */ if (vect->nData > span / vect->dx[0]) { vect->nx[0] = span / vect->dx[0]; vect->nData = vect->nx[0]; } if (frstart < start) { /* thank you FrStatDataReadT() */ int shift = (start - frstart) / vect->dx[0]; if (vect->type == FR_VECT_2S) vect->dataS += shift; else if (vect->type == FR_VECT_4S) vect->dataI += shift; else if (vect->type == FR_VECT_8S) vect->dataL += shift; else if (vect->type == FR_VECT_1U) vect->dataU += shift; else if (vect->type == FR_VECT_2U) vect->dataUS += shift; else if (vect->type == FR_VECT_4U) vect->dataUI += shift; else if (vect->type == FR_VECT_8U) vect->dataUL += shift; else if (vect->type == FR_VECT_4R) vect->dataF += shift; else if (vect->type == FR_VECT_8R) vect->dataD += shift; // Note the 2* shift for complex types else if (vect->type == FR_VECT_8C) vect->dataF += 2 * shift; else if (vect->type == FR_VECT_16C) vect->dataD += 2 * shift; // If none of these types, it will fail later } } if (verbose > 0){ printf("Extracted channel %s successfully!\n", channel); } nData = vect->nData; nDim = vect->nDim; /*-------- copy data ------*/ for (i=0; i<nDim; i++) { shape[i] = (npy_intp)vect->nx[i]; } // Both FrVect and Numpy store data in C array order (vs Fortran) if(vect->type == FR_VECT_2S){ out1 = PyArray_SimpleNew(nDim, shape, NPY_INT16); data_int16 = (npy_int16 *)PyArray_DATA(out1); if (data_int16==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_int16[i] = vect->dataS[i];}} else if(vect->type == FR_VECT_4S){ out1 = PyArray_SimpleNew(nDim, shape, NPY_INT32); data_int32 = (npy_int32 *)PyArray_DATA(out1); if (data_int32==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_int32[i] = vect->dataI[i];}} else if(vect->type == FR_VECT_8S){ out1 = PyArray_SimpleNew(nDim, shape, NPY_INT64); data_int64 = (npy_int64 *)PyArray_DATA(out1); if (data_int64==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_int64[i] = vect->dataL[i];}} else if(vect->type == FR_VECT_1U){ out1 = PyArray_SimpleNew(nDim, shape, NPY_UINT8); data_uint8 = (npy_uint8 *)PyArray_DATA(out1); if (data_uint8==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_uint8[i] = vect->dataU[i];}} else if(vect->type == FR_VECT_2U){ out1 = PyArray_SimpleNew(nDim, shape, NPY_UINT16); data_uint16 = (npy_uint16 *)PyArray_DATA(out1); if (data_uint16==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_uint16[i] = vect->dataUS[i];}} else if(vect->type == FR_VECT_4U){ out1 = PyArray_SimpleNew(nDim, shape, NPY_UINT32); data_uint32 = (npy_uint32 *)PyArray_DATA(out1); if (data_uint32==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_uint32[i] = vect->dataUI[i];}} else if(vect->type == FR_VECT_8U){ out1 = PyArray_SimpleNew(nDim, shape, NPY_UINT64); data_uint64 = (npy_uint64 *)PyArray_DATA(out1); if (data_uint64==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_uint64[i] = vect->dataUL[i];}} else if(vect->type == FR_VECT_4R){ out1 = PyArray_SimpleNew(nDim, shape, NPY_FLOAT32); data_float32 = (npy_float32 *)PyArray_DATA(out1); if (data_float32==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_float32[i] = vect->dataF[i];}} else if(vect->type == FR_VECT_8R){ out1 = PyArray_SimpleNew(nDim, shape, NPY_FLOAT64); data_float64 = (npy_float64 *)PyArray_DATA(out1); if (data_float64==NULL) {OOM_ERROR;} for(i=0; i<nData; i++) {data_float64[i] = vect->dataD[i];}} // Note the 2*nData in the for loop for complex types else if(vect->type == FR_VECT_8C){ out1 = PyArray_SimpleNew(nDim, shape, NPY_COMPLEX64); data_float32 = (npy_float32 *)PyArray_DATA(out1); if (data_float32==NULL) {OOM_ERROR;} for(i=0; i<2*nData; i++) {data_float32[i] = vect->dataF[i];}} else if(vect->type == FR_VECT_16C){ out1 = PyArray_SimpleNew(nDim, shape, NPY_COMPLEX128); data_float64 = (npy_float64 *)PyArray_DATA(out1); if (data_float64==NULL) {OOM_ERROR;} for(i=0; i<2*nData; i++) {data_float64[i] = vect->dataD[i];}} else{ snprintf(msg, MAX_STR_LEN, "Unrecognized vect->type (= %d)\n", vect->type); FrVectFree(vect); FrFileIEnd(iFile); PyErr_SetString(PyExc_TypeError, msg); return NULL; } /*------------- other outputs ------------------------*/ // output2 = gps start time out2 = PyFloat_FromDouble(vect->GTime); // output3 = x-axes start values as a tuple of PyFloats // output4 = x-axes spacings as a tuple of PyFloats // output5 = x-axes units as a tuple of strings out3 = PyTuple_New((Py_ssize_t)nDim); out4 = PyTuple_New((Py_ssize_t)nDim); out5 = PyTuple_New((Py_ssize_t)nDim); for (i=0; i<nDim; i++) { PyTuple_SetItem(out3, (Py_ssize_t)i, PyFloat_FromDouble(vect->startX[i])); PyTuple_SetItem(out4, (Py_ssize_t)i, PyFloat_FromDouble(vect->dx[i])); PyTuple_SetItem(out5, (Py_ssize_t)i, PyString_FromString(vect->unitX[i])); } // output6 = unitY as a string out6 = PyString_FromString(vect->unitY); /*------------- clean up -----------------------------*/ FrVectFree(vect); FrFileIEnd(iFile); return Py_BuildValue("(NNNNNN)",out1,out2,out3,out4,out5, out6); };
static PyObject *get_array_from_vector(int n, const double *data) { npy_intp len = n; PyArrayObject *vecout = (PyArrayObject *) PyArray_SimpleNew(1, &len, NPY_DOUBLE); memcpy(vecout->data, data, sizeof(double) * n); return PyArray_Return(vecout); }
Py::Object _png_module::read_png(const Py::Tuple& args) { args.verify_length(1); std::string fname = Py::String(args[0]); png_byte header[8]; // 8 is the maximum size that can be checked FILE *fp = fopen(fname.c_str(), "rb"); if (!fp) throw Py::RuntimeError(Printf("_image_module::readpng could not open PNG file %s for reading", fname.c_str()).str()); if (fread(header, 1, 8, fp) != 8) throw Py::RuntimeError("_image_module::readpng: error reading PNG header"); if (png_sig_cmp(header, 0, 8)) throw Py::RuntimeError("_image_module::readpng: file not recognized as a PNG file"); /* initialize stuff */ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) throw Py::RuntimeError("_image_module::readpng: png_create_read_struct failed"); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) throw Py::RuntimeError("_image_module::readpng: png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) throw Py::RuntimeError("_image_module::readpng: error during init_io"); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_uint_32 width = info_ptr->width; png_uint_32 height = info_ptr->height; int bit_depth = info_ptr->bit_depth; // Unpack 1, 2, and 4-bit images if (bit_depth < 8) png_set_packing(png_ptr); // If sig bits are set, shift data png_color_8p sig_bit; if ((info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) png_set_shift(png_ptr, sig_bit); // Convert big endian to little if (bit_depth == 16) png_set_swap(png_ptr); // Convert palletes to full RGB if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); // If there's an alpha channel convert gray to RGB if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); /* read file */ if (setjmp(png_jmpbuf(png_ptr))) throw Py::RuntimeError("_image_module::readpng: error during read_image"); png_bytep *row_pointers = new png_bytep[height]; png_uint_32 row; for (row = 0; row < height; row++) row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr,info_ptr)]; png_read_image(png_ptr, row_pointers); npy_intp dimensions[3]; dimensions[0] = height; //numrows dimensions[1] = width; //numcols if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) dimensions[2] = 4; //RGBA images else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) dimensions[2] = 3; //RGB images else dimensions[2] = 1; //Greyscale images //For gray, return an x by y array, not an x by y by 1 int num_dims = (info_ptr->color_type & PNG_COLOR_MASK_COLOR) ? 3 : 2; double max_value = (1 << ((bit_depth < 8) ? 8 : bit_depth)) - 1; PyArrayObject *A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, PyArray_FLOAT); if (A == NULL) { throw Py::MemoryError("Could not allocate image array"); } for (png_uint_32 y = 0; y < height; y++) { png_byte* row = row_pointers[y]; for (png_uint_32 x = 0; x < width; x++) { size_t offset = y*A->strides[0] + x*A->strides[1]; if (bit_depth == 16) { png_uint_16* ptr = &reinterpret_cast<png_uint_16*> (row)[x * dimensions[2]]; for (png_uint_32 p = 0; p < dimensions[2]; p++) *(float*)(A->data + offset + p*A->strides[2]) = (float)(ptr[p]) / max_value; } else { png_byte* ptr = &(row[x * dimensions[2]]); for (png_uint_32 p = 0; p < dimensions[2]; p++) { *(float*)(A->data + offset + p*A->strides[2]) = (float)(ptr[p]) / max_value; } } } } //free the png memory png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); fclose(fp); for (row = 0; row < height; row++) delete [] row_pointers[row]; delete [] row_pointers; return Py::asObject((PyObject*)A); }
static PyObject* mseed_get_traces (PyObject *m, PyObject *args) { char *filename; MSTraceGroup *mstg = NULL; MSTrace *mst = NULL; int retcode; npy_intp array_dims[1] = {0}; PyObject *array = NULL; PyObject *out_traces = NULL; PyObject *out_trace = NULL; int numpytype; char strbuf[BUFSIZE]; PyObject *unpackdata = NULL; struct module_state *st = GETSTATE(m); if (!PyArg_ParseTuple(args, "sO", &filename, &unpackdata)) { PyErr_SetString(st->error, "usage get_traces(filename, dataflag)" ); return NULL; } if (!PyBool_Check(unpackdata)) { PyErr_SetString(st->error, "Second argument must be a boolean" ); return NULL; } /* get data from mseed file */ retcode = ms_readtraces (&mstg, filename, 0, -1.0, -1.0, 0, 1, (unpackdata == Py_True), 0); if ( retcode < 0 ) { snprintf (strbuf, BUFSIZE, "Cannot read file '%s': %s", filename, ms_errorstr(retcode)); PyErr_SetString(st->error, strbuf); return NULL; } if ( ! mstg ) { snprintf (strbuf, BUFSIZE, "Error reading file"); PyErr_SetString(st->error, strbuf); return NULL; } /* check that there is data in the traces */ if (unpackdata == Py_True) { mst = mstg->traces; while (mst) { if (mst->datasamples == NULL) { snprintf (strbuf, BUFSIZE, "Error reading file - datasamples is NULL"); PyErr_SetString(st->error, strbuf); return NULL; } mst = mst->next; } } out_traces = Py_BuildValue("[]"); mst = mstg->traces; /* convert data to python tuple */ while (mst) { if (unpackdata == Py_True) { array_dims[0] = mst->numsamples; switch (mst->sampletype) { case 'i': assert( ms_samplesize('i') == 4 ); numpytype = NPY_INT32; break; case 'a': assert( ms_samplesize('a') == 1 ); numpytype = NPY_INT8; break; case 'f': assert( ms_samplesize('f') == 4 ); numpytype = NPY_FLOAT32; break; case 'd': assert( ms_samplesize('d') == 8 ); numpytype = NPY_FLOAT64; break; default: snprintf (strbuf, BUFSIZE, "Unknown sampletype %c\n", mst->sampletype); PyErr_SetString(st->error, strbuf); Py_XDECREF(out_traces); return NULL; } array = PyArray_SimpleNew(1, array_dims, numpytype); memcpy( PyArray_DATA((PyArrayObject*)array), mst->datasamples, mst->numsamples*ms_samplesize(mst->sampletype) ); } else { Py_INCREF(Py_None); array = Py_None; } out_trace = Py_BuildValue( "(c,s,s,s,s,L,L,d,N)", mst->dataquality, mst->network, mst->station, mst->location, mst->channel, mst->starttime, mst->endtime, mst->samprate, array ); PyList_Append(out_traces, out_trace); Py_DECREF(out_trace); mst = mst->next; } mst_freegroup (&mstg); return out_traces; }
/** * @brief Function to convert coordinates from an ENU to an ECEF frame. * @details * This function is a wrapper to uvwsim_convert_enu_to_ecef() */ static PyObject* convert_enu_to_ecef(PyObject* self, PyObject* args) { int typenum, requirements, nd, n; double lon, lat, alt; PyObject *x_enu_o=NULL, *y_enu_o=NULL, *z_enu_o=NULL; PyObject *x_enu_=NULL, *y_enu_=NULL, *z_enu_=NULL; npy_intp* dims; double *x_enu, *y_enu, *z_enu; PyObject *x_ecef_=NULL, *y_ecef_=NULL, *z_ecef_=NULL; double *x_ecef, *y_ecef, *z_ecef; /* if (NPY_VERSION == 0x01000009) printf("INFO: Numpy version 1.9\n"); */ /* Read input arguments */ if (!PyArg_ParseTuple(args, "O!O!O!ddd", &PyArray_Type, &x_enu_o, &PyArray_Type, &y_enu_o, &PyArray_Type, &z_enu_o, &lon, &lat, &alt) ) return NULL; /* printf(" - A ref count: x_enu_o:%zi, y_enu_o:%zi, z_enu_o:%zi\n", PyArray_REFCOUNT(x_enu_o), PyArray_REFCOUNT(y_enu_o), PyArray_REFCOUNT(z_enu_o)); */ /* PyArray_FROM_OTF is a macro calling PyArray_FromAny * http://docs.scipy.org/doc/numpy/user/c-info.how-to-extend.html * It converts an arbitrary Python object to a well-behaved numpy array. */ typenum = NPY_DOUBLE; requirements = NPY_ARRAY_IN_ARRAY; x_enu_ = PyArray_FROM_OTF(x_enu_o, typenum, requirements); if (!x_enu_) goto fail; y_enu_ = PyArray_FROM_OTF(y_enu_o, typenum, requirements); if (!y_enu_) goto fail; z_enu_ = PyArray_FROM_OTF(z_enu_o, typenum, requirements); if (!z_enu_) goto fail; /* printf(" - B ref count: x_enu_:%zi, y_enu_:%zi, z_enu_:%zi\n", PyArray_REFCOUNT(x_enu_), PyArray_REFCOUNT(y_enu_), PyArray_REFCOUNT(z_enu_)); printf(" - C ref count: x_enu_o:%zi, y_enu_o:%zi, z_enu_o:%zi\n", PyArray_REFCOUNT(x_enu_o), PyArray_REFCOUNT(y_enu_o), PyArray_REFCOUNT(z_enu_o)); */ /* Extract dimensions and pointers. */ /* TODO Require input arrays be 1D, and check dimension consistency. */ nd = PyArray_NDIM((PyArrayObject*)x_enu_); dims = PyArray_DIMS((PyArrayObject*)x_enu_); x_enu = (double*)PyArray_DATA((PyArrayObject*)x_enu_); y_enu = (double*)PyArray_DATA((PyArrayObject*)y_enu_); z_enu = (double*)PyArray_DATA((PyArrayObject*)z_enu_); /* Create New arrays for ECEF coordinates. */ x_ecef_ = PyArray_SimpleNew(nd, dims, NPY_DOUBLE); y_ecef_ = PyArray_SimpleNew(nd, dims, NPY_DOUBLE); z_ecef_ = PyArray_SimpleNew(nd, dims, NPY_DOUBLE); x_ecef = (double*)PyArray_DATA((PyArrayObject*)x_ecef_); y_ecef = (double*)PyArray_DATA((PyArrayObject*)y_ecef_); z_ecef = (double*)PyArray_DATA((PyArrayObject*)z_ecef_); /* Call conversion function. */ n = dims[0]; uvwsim_convert_enu_to_ecef(n, x_ecef, y_ecef, z_ecef, x_enu, y_enu, z_enu, lon, lat, alt); /* printf(" - D ref count: x_enu_:%zi, y_enu_:%zi, z_enu_:%zi\n", PyArray_REFCOUNT(x_enu_), PyArray_REFCOUNT(y_enu_), PyArray_REFCOUNT(z_enu_)); */ /* Decrement references to temporary array objects. */ Py_DECREF(x_enu_); Py_DECREF(y_enu_); Py_DECREF(z_enu_); /* printf(" - E ref count: x_ecef_:%zi, y_ecef_:%zi, z_ecef_:%zi\n", PyArray_REFCOUNT(x_ecef_), PyArray_REFCOUNT(y_ecef_), PyArray_REFCOUNT(z_ecef_)); */ /* Return station ECEF coordinates. */ return Py_BuildValue("NNN", x_ecef_, y_ecef_, z_ecef_); fail: Py_XDECREF(x_enu_); Py_XDECREF(y_enu_); Py_XDECREF(z_enu_); return NULL; }