Пример #1
0
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;
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
// 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 );
}
Пример #7
0
/*@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;
    }
  }
}
Пример #8
0
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;
}
Пример #9
0
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, &notself, &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;
}
Пример #10
0
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;
}
Пример #11
0
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, &notself)) {
        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;
}
Пример #12
0
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, &notself, &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;
}
Пример #13
0
/**
 * @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_);
}
Пример #14
0
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;

};
Пример #15
0
/*@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;
    }
  }
}
Пример #16
0
// 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;
};
Пример #17
0
/*@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;
    }
  }
}
Пример #18
0
/* 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);
}
Пример #19
0
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);
};
Пример #20
0
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);
}
Пример #21
0
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);
}
Пример #22
0
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;
}
Пример #23
0
/**
 * @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;
}