Beispiel #1
0
void apply_polyaffine(PyArrayObject* XYZ, 
		      const PyArrayObject* Centers, 
		      const PyArrayObject* Affines, 
		      const PyArrayObject* Sigma)

{

  PyArrayIterObject *iter_xyz, *iter_centers, *iter_affines;
  int axis = 1; 
  double *xyz, *center, *affine, *sigma; 
  double w, W; 
  double mat[12], t_xyz[3]; 
  size_t bytes_mat = 12*sizeof(double); 
  size_t bytes_xyz = 3*sizeof(double); 

  /* Initialize arrays and iterators */ 
  sigma = PyArray_DATA(Sigma);
  iter_xyz = (PyArrayIterObject*)PyArray_IterAllButAxis((PyObject*)XYZ, &axis);
  iter_centers = (PyArrayIterObject*)PyArray_IterAllButAxis((PyObject*)Centers, &axis);
  iter_affines = (PyArrayIterObject*)PyArray_IterAllButAxis((PyObject*)Affines, &axis);
    
  /* Loop over input points */ 
  while(iter_xyz->index < iter_xyz->size) {

    xyz = PyArray_ITER_DATA(iter_xyz);
    PyArray_ITER_RESET(iter_centers);
    PyArray_ITER_RESET(iter_affines);
    memset((void*)mat, 0, bytes_mat); 
    W = 0.0; 

    /* Loop over centers */
    while(iter_centers->index < iter_centers->size) {
      center = PyArray_ITER_DATA(iter_centers);
      affine = PyArray_ITER_DATA(iter_affines);
      w = _gaussian(xyz, center, sigma); 
      W += w; 
      _add_weighted_affine(mat, affine, w); 
      PyArray_ITER_NEXT(iter_centers); 
      PyArray_ITER_NEXT(iter_affines); 
    }

    /* Apply matrix */ 
    _apply_affine(t_xyz, mat, xyz, W); 
    memcpy((void*)xyz, (void*)t_xyz, bytes_xyz); 

    /* Update xyz iterator */ 
    PyArray_ITER_NEXT(iter_xyz); 
  }

  /* Free memory */ 
  Py_XDECREF(iter_xyz);
  Py_XDECREF(iter_centers);
  Py_XDECREF(iter_affines);

  return; 
}
// the data should be FLOAT32 and should be ensured in the wrapper 
static PyObject *interp3(PyObject *self, PyObject *args)
{
	PyArrayObject *volume, *result, *C, *R, *S;
	float *pr, *pc, *ps;
        float *pvol, *pvc;
        int xdim, ydim, zdim;

	// We expect 4 arguments of the PyArray_Type
	if(!PyArg_ParseTuple(args, "O!O!O!O!", 
				&PyArray_Type, &volume,
				&PyArray_Type, &R,
				&PyArray_Type, &C,
				&PyArray_Type, &S)) return NULL;

	if ( NULL == volume ) return NULL;
	if ( NULL == C ) return NULL;
	if ( NULL == R ) return NULL;
	if ( NULL == S ) return NULL;

	// result matrix is the same size as C and is float
	result = (PyArrayObject*) PyArray_ZEROS(PyArray_NDIM(C), C->dimensions, NPY_FLOAT, 0); 
	// This is for reference counting ( I think )
	PyArray_FLAGS(result) |= NPY_OWNDATA; 

	// massive use of iterators to progress through the data
	PyArrayIterObject *itr_v, *itr_r, *itr_c, *itr_s;
    itr_v = (PyArrayIterObject *) PyArray_IterNew(result);
    itr_r = (PyArrayIterObject *) PyArray_IterNew(R);
    itr_c = (PyArrayIterObject *) PyArray_IterNew(C);
    itr_s = (PyArrayIterObject *) PyArray_IterNew(S);
    pvol = (float *)PyArray_DATA(volume);
    xdim = PyArray_DIM(volume, 0);
    ydim = PyArray_DIM(volume, 1);
    zdim = PyArray_DIM(volume, 2);
    //printf("%f\n", pvol[4*20*30 + 11*30 + 15]);
    while(PyArray_ITER_NOTDONE(itr_v)) 
    {
		pvc = (float *) PyArray_ITER_DATA(itr_v);
		pr = (float *) PyArray_ITER_DATA(itr_r);
		pc = (float *) PyArray_ITER_DATA(itr_c);
		ps = (float *) PyArray_ITER_DATA(itr_s);
        // The order is weird because the tricubic code below is 
        // for Fortran ordering. Note that the xdim changes fast in
        // the code, whereas the rightmost dim should change fast
        // in C multidimensional arrays.
		*pvc = TriCubic(*ps, *pc, *pr, pvol, zdim, ydim, xdim); 
		PyArray_ITER_NEXT(itr_v);
		PyArray_ITER_NEXT(itr_r);
		PyArray_ITER_NEXT(itr_c);
		PyArray_ITER_NEXT(itr_s);
    }

	return result;
}
/*  wrapped cosine function */
static PyObject* cos_func_np(PyObject* self, PyObject* args)
{

    PyArrayObject *in_array;
    PyObject      *out_array;
    PyArrayIterObject *in_iter;
    PyArrayIterObject *out_iter;

    /*  parse single numpy array argument */
    if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &in_array))
        return NULL;

    /*  construct the output array, like the input array */
    out_array = PyArray_NewLikeArray(in_array, NPY_ANYORDER, NULL, 0);
    if (out_array == NULL)
        return NULL;

    /*  create the iterators */
    /* TODO: this iterator API is deprecated since 1.6
     *       replace in favour of the new NpyIter API */
    in_iter  = (PyArrayIterObject *)PyArray_IterNew((PyObject*)in_array);
    out_iter = (PyArrayIterObject *)PyArray_IterNew(out_array);
    if (in_iter == NULL || out_iter == NULL)
        goto fail;

    /*  iterate over the arrays */
    while (in_iter->index < in_iter->size
            && out_iter->index < out_iter->size) {
        /* get the datapointers */
        double * in_dataptr = (double *)in_iter->dataptr;
        double * out_dataptr = (double *)out_iter->dataptr;
        /* cosine of input into output */
        *out_dataptr = cos(*in_dataptr);
        /* update the iterator */
        PyArray_ITER_NEXT(in_iter);
        PyArray_ITER_NEXT(out_iter);
    }

    /*  clean up and return the result */
    Py_DECREF(in_iter);
    Py_DECREF(out_iter);
    Py_INCREF(out_array);
    return out_array;

    /*  in case bad things happen */
    fail:
        Py_XDECREF(out_array);
        Py_XDECREF(in_iter);
        Py_XDECREF(out_iter);
        return NULL;
}
Beispiel #4
0
void histogram(double* H, 
	       unsigned int clamp, 
	       PyArrayIterObject* iter)
{
  signed short *buf;
  signed short i;

  /* Reset the source image iterator */
  PyArray_ITER_RESET(iter);

  /* Re-initialize joint histogram */ 
  memset((void*)H, 0, clamp*sizeof(double));

  /* Loop over source voxels */
  while(iter->index < iter->size) {
  
    /* Source voxel intensity */
    buf = (signed short*)PyArray_ITER_DATA(iter); 
    i = buf[0];

    /* Update the histogram only if the current voxel is below the
       intensity threshold */
    if (i>=0) 
      H[i]++; 
    
    /* Update source index */ 
    PyArray_ITER_NEXT(iter); 
    
  } /* End of loop over voxels */ 
  

  return; 
}
Beispiel #5
0
/* 
   Compute the interaction energy:

   sum_i,j qi^T U qj
   = sum_i qi^T sum_j U qj   
   
*/
double interaction_energy(PyArrayObject* ppm, 
			  const PyArrayObject* XYZ,
			  const PyArrayObject* U,
			  int ngb_size)

{
  npy_intp k, x, y, z, pos;
  double *p, *buf;
  double res = 0.0, tmp;  
  PyArrayIterObject* iter;
  int axis = 1; 
  double* ppm_data;
  npy_intp K = ppm->dimensions[3]; 
  npy_intp u2 = ppm->dimensions[2]*K; 
  npy_intp u1 = ppm->dimensions[1]*u2;
  npy_intp* xyz; 
  const double* U_data = (double*)U->data;
  int* ngb;

  /* Neighborhood system */
  ngb = _select_neighborhood_system(ngb_size);

  /* Pointer to ppm array */
  ppm_data = (double*)ppm->data;

  /* Allocate auxiliary vector */
  p = (double*)calloc(K, sizeof(double)); 
  
  /* Loop over points */ 
  iter = (PyArrayIterObject*)PyArray_IterAllButAxis((PyObject*)XYZ, &axis);
  while(iter->index < iter->size) {
    
    /* Compute the average ppm in the neighborhood */ 
    xyz = PyArray_ITER_DATA(iter); 
    x = xyz[0];
    y = xyz[1];
    z = xyz[2];
    _ngb_integrate(p, ppm, x, y, z, U_data, (const int*)ngb, ngb_size);
    
    /* Calculate the dot product qi^T p where qi is the local
       posterior */
    tmp = 0.0; 
    pos = x*u1 + y*u2 + z*K; 
    for (k=0, buf=p; k<K; k++, pos++, buf++)
      tmp += ppm_data[pos]*(*buf);

    /* Update overall energy */ 
    res += tmp; 

    /* Update iterator */ 
    PyArray_ITER_NEXT(iter); 
  }

  /* Free memory */ 
  free(p);
  Py_XDECREF(iter);

  return res; 
}
void allstats_ubyte(PyObject *inputarray, stats *result) {
	PyObject *iter;
	npy_ubyte *ptr;

	iter = PyArray_IterNew(inputarray);

	while (PyArray_ITER_NOTDONE(iter)) {
		ptr = (npy_ubyte *)PyArray_ITER_DATA(iter);
		updateStats(result, (double) (*ptr));
		PyArray_ITER_NEXT(iter);
	}
	Py_XDECREF(iter);
}
Beispiel #7
0
static int
map_inc(PyArrayMapIterObject *mit, PyObject *op)
{
    PyObject *arr = NULL;
    PyArrayIterObject *it;
    int index;
    PyArray_Descr *descr;

    /* Unbound Map Iterator */
    if (mit->ait == NULL) {
        return -1;
    }
    descr = mit->ait->ao->descr;
    Py_INCREF(descr);
    arr = PyArray_FromAny(op, descr, 0, 0, NPY_FORCECAST, NULL);
    if (arr == NULL) {
        return -1;
    }
    if ((mit->subspace != NULL) && (mit->consec)) {
        if (mit->iteraxes[0] > 0) {  /* then we need to swap */
            _swap_axes(mit, (PyArrayObject **)&arr, 0);
            if (arr == NULL) {
                return -1;
            }
        }
    }

    /* Be sure values array is "broadcastable"
       to shape of mit->dimensions, mit->nd */

    if ((it = (PyArrayIterObject *)\
         PyArray_BroadcastToShape(arr, mit->dimensions, mit->nd))==NULL) {
        Py_DECREF(arr);
        return -1;
    }

    index = mit->size;

    PyArray_MapIterReset(mit);

    while(index--) {
        memmove(mit->dataptr, it->dataptr, PyArray_ITEMSIZE(arr));
        	*(double*)(mit->dataptr) = *(double*)(mit->dataptr) + *(double*)(it->dataptr); 
        	
        PyArray_MapIterNext(mit);
        PyArray_ITER_NEXT(it);
    }
    Py_DECREF(arr);
    Py_DECREF(it);
    return 0;
}
Beispiel #8
0
/* 
   Resample a 3d image submitted to an affine transformation.
   Tvox is the voxel transformation from the image to the destination grid.  
*/
void cubic_spline_resample3d(PyArrayObject* im_resampled, const PyArrayObject* im,   
			     const double* Tvox, int cast_integer, 
			     int mode_x, int mode_y, int mode_z)
{
  double i1;
  PyObject* py_i1;
  PyArrayObject* im_spline_coeff;
  PyArrayIterObject* imIter = (PyArrayIterObject*)PyArray_IterNew((PyObject*)im_resampled); 
  unsigned int x, y, z;
  unsigned dimX = PyArray_DIM(im, 0);
  unsigned dimY = PyArray_DIM(im, 1);
  unsigned dimZ = PyArray_DIM(im, 2);
  npy_intp dims[3] = {dimX, dimY, dimZ}; 
  double Tx, Ty, Tz;

  /* Compute the spline coefficient image */
  im_spline_coeff = (PyArrayObject*)PyArray_SimpleNew(3, dims, NPY_DOUBLE);
  cubic_spline_transform(im_spline_coeff, im);

  /* Force iterator coordinates to be updated */
  UPDATE_ITERATOR_COORDS(imIter); 

  /* Resampling loop */
  while(imIter->index < imIter->size) {
    x = imIter->coordinates[0];
    y = imIter->coordinates[1]; 
    z = imIter->coordinates[2]; 
    _apply_affine_transform(&Tx, &Ty, &Tz, Tvox, x, y, z); 
    i1 = cubic_spline_sample3d(Tx, Ty, Tz, im_spline_coeff, mode_x, mode_y, mode_z); 
    if (cast_integer)
      i1 = ROUND(i1); 

    /* Copy interpolated value into numpy array */
    py_i1 = PyFloat_FromDouble(i1); 
    PyArray_SETITEM(im_resampled, PyArray_ITER_DATA(imIter), py_i1); 
    Py_DECREF(py_i1); 
    
    /* Increment iterator */
    PyArray_ITER_NEXT(imIter); 

  }

  /* Free memory */
  Py_DECREF(imIter);
  Py_DECREF(im_spline_coeff); 
    
  return;
}
static int copy_int(PyArrayIterObject *itx, PyArrayNeighborhoodIterObject *niterx,
        npy_intp *bounds,
        PyObject **out)
{
    npy_intp i, j;
    npy_int *ptr;
    npy_intp odims[NPY_MAXDIMS];
    PyArrayObject *aout;

    /*
     * For each point in itx, copy the current neighborhood into an array which
     * is appended at the output list
     */
    for (i = 0; i < itx->size; ++i) {
        PyArrayNeighborhoodIter_Reset(niterx);

        for (j = 0; j < PyArray_NDIM(itx->ao); ++j) {
            odims[j] = bounds[2 * j + 1] - bounds[2 * j] + 1;
        }
        aout = (PyArrayObject*)PyArray_SimpleNew(
                                PyArray_NDIM(itx->ao), odims, NPY_INT);
        if (aout == NULL) {
            return -1;
        }

        ptr = (npy_int*)PyArray_DATA(aout);

        for (j = 0; j < niterx->size; ++j) {
            *ptr = *((npy_int*)niterx->dataptr);
            PyArrayNeighborhoodIter_Next(niterx);
            ptr += 1;
        }

        PyList_Append(*out, (PyObject*)aout);
        Py_DECREF(aout);
        PyArray_ITER_NEXT(itx);
    }

    return 0;
}
Beispiel #10
0
/* Array evaluates as "TRUE" if any of the elements are non-zero*/
static int
array_any_nonzero(PyArrayObject *arr)
{
    npy_intp counter;
    PyArrayIterObject *it;
    npy_bool anyTRUE = NPY_FALSE;

    it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)arr);
    if (it == NULL) {
        return anyTRUE;
    }
    counter = it->size;
    while (counter--) {
        if (PyArray_DESCR(arr)->f->nonzero(it->dataptr, arr)) {
            anyTRUE = NPY_TRUE;
            break;
        }
        PyArray_ITER_NEXT(it);
    }
    Py_DECREF(it);
    return anyTRUE;
}
Beispiel #11
0
static void _cubic_spline_transform(PyArrayObject* res, int axis, double* work)
{
  PyArrayIterObject* iter;
  unsigned int dim, stride;

  /* Instantiate iterator and views */ 
  iter = (PyArrayIterObject*)PyArray_IterAllButAxis((PyObject*)res, &axis);
  dim = PyArray_DIM((PyArrayObject*)iter->ao, axis); 
  stride = PyArray_STRIDE((PyArrayObject*)iter->ao, axis)/sizeof(double); 

  /* Apply the cubic spline transform along given axis */ 
  while(iter->index < iter->size) {
    _copy_double_buffer(work, PyArray_ITER_DATA(iter), dim, stride); 
    _cubic_spline_transform1d(PyArray_ITER_DATA(iter), work, dim, stride, 1); 
    PyArray_ITER_NEXT(iter); 
  }

  /* Free local structures */ 
  Py_DECREF(iter); 

  return; 
}
static int copy_object(PyArrayIterObject *itx, PyArrayNeighborhoodIterObject *niterx,
        npy_intp *bounds,
        PyObject **out)
{
    npy_intp i, j;
    npy_intp odims[NPY_MAXDIMS];
    PyArrayObject *aout;
    PyArray_CopySwapFunc *copyswap = PyArray_DESCR(itx->ao)->f->copyswap;
    npy_int itemsize = PyArray_ITEMSIZE(itx->ao);

    /*
     * For each point in itx, copy the current neighborhood into an array which
     * is appended at the output list
     */
    for (i = 0; i < itx->size; ++i) {
        PyArrayNeighborhoodIter_Reset(niterx);

        for (j = 0; j < PyArray_NDIM(itx->ao); ++j) {
            odims[j] = bounds[2 * j + 1] - bounds[2 * j] + 1;
        }
        aout = (PyArrayObject*)PyArray_SimpleNew(PyArray_NDIM(itx->ao), odims, NPY_OBJECT);
        if (aout == NULL) {
            return -1;
        }

        for (j = 0; j < niterx->size; ++j) {
            copyswap(PyArray_BYTES(aout) + j * itemsize, niterx->dataptr, 0, NULL);
            PyArrayNeighborhoodIter_Next(niterx);
        }

        PyList_Append(*out, (PyObject*)aout);
        Py_DECREF(aout);
        PyArray_ITER_NEXT(itx);
    }

    return 0;
}
Beispiel #13
0
//query the ball tree.  Arguments are the array of search points
// and the number of nearest neighbors, k (optional)
static PyObject *
BallTree_query(BallTreeObject *self, PyObject *args, PyObject *kwds){
  //we use goto statements : all variables should be declared up front
    int return_distance = 1;
    long int k = 1;
    PyObject *arg = NULL;
    PyObject *arr = NULL;
    PyObject *nbrs = NULL;
    PyObject *dist = NULL;
    PyArrayIterObject *arr_iter = NULL;
    PyArrayIterObject *nbrs_iter = NULL;
    PyArrayIterObject *dist_iter = NULL;
    long int* nbrs_data;
    double* dist_data;
    static char *kwlist[] = {"x", "k", "return_distance", NULL};

    int nd, pt_size, pt_inc;
    npy_intp* dim;

  //parse arguments.  If k is not provided, the default is 1
    if(!PyArg_ParseTupleAndKeywords(args,kwds,"O|li",kwlist,
    &arg,&k,&return_distance)){
        goto fail;
    }

  //check value of k
    if(k < 1){
        PyErr_SetString(PyExc_ValueError,
            "k must be positive");
        goto fail;
    }

    if(k > self->size){
        PyErr_SetString(PyExc_ValueError,
            "k must not be greater than number of points");
        goto fail;
    }

  //get the array object from the first argument
    arr = PyArray_FROM_OTF(arg,NPY_DOUBLE,NPY_ALIGNED);

  //check that the array was properly constructed
    if(arr==NULL){
        PyErr_SetString(PyExc_ValueError,
            "pt must be convertable to array");
        goto fail;
    }

    nd = PyArray_NDIM(arr);
    if(nd == 0){
        PyErr_SetString(PyExc_ValueError,
            "pt cannot be zero-sized array");
        goto fail;
    }
    pt_size = PyArray_DIM(arr,nd-1);
    if( pt_size != self->tree->PointSize() ){
        PyErr_SetString(PyExc_ValueError,
            "points are incorrect dimension");
        goto fail;
    }

  //create a neighbors array and distance array
    dim = new npy_intp[nd];
    for(int i=0; i<nd-1;i++)
        dim[i] = PyArray_DIM(arr,i);
    dim[nd-1] = k;
    nbrs = (PyObject*)PyArray_SimpleNew(nd,dim,PyArray_LONG);
    if(return_distance)
        dist = (PyObject*)PyArray_SimpleNew(nd,dim,PyArray_DOUBLE);
    delete[] dim;

    if(nbrs==NULL)
        goto fail;

  //create iterators to cycle through points
    nd-=1;
    arr_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(arr,&nd);
    nbrs_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(nbrs,&nd);
    if(return_distance)
        dist_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(dist,&nd);
    nd+=1;

    if( arr_iter==NULL || nbrs_iter==NULL ||
        (arr_iter->size != nbrs_iter->size) ||
        (return_distance &&
    (dist_iter==NULL || (arr_iter->size != dist_iter->size))) ){
        PyErr_SetString(PyExc_ValueError,
            "failure constructing iterators");
        goto fail;
    }

    pt_inc = PyArray_STRIDES(arr)[nd-1] / PyArray_DESCR(arr)->elsize;
    if( (PyArray_STRIDES(nbrs)[nd-1] != PyArray_DESCR(nbrs)->elsize ) ||
        (return_distance &&
    (PyArray_STRIDES(dist)[nd-1] != PyArray_DESCR(dist)->elsize )) ){
        PyErr_SetString(PyExc_ValueError,
            "nbrs & dist not allocated as a C-array");
        goto fail;
    }

  //iterate through points and determine neighbors
  //warning: if nbrs is not a C-array, or if we're not iterating
  // over the last dimension, this may cause a seg fault.
    if(return_distance){
        while(arr_iter->index < arr_iter->size){
            BallTree_Point pt(arr,
                (double*)PyArray_ITER_DATA(arr_iter),
                pt_inc,pt_size);
            nbrs_data = (long int*)(PyArray_ITER_DATA(nbrs_iter));
            dist_data = (double*)(PyArray_ITER_DATA(dist_iter));
            self->tree->query(pt,k,nbrs_data,dist_data);
            PyArray_ITER_NEXT(arr_iter);
            PyArray_ITER_NEXT(nbrs_iter);
            PyArray_ITER_NEXT(dist_iter);
        }
    }else{
        while(arr_iter->index < arr_iter->size){
            BallTree_Point pt(arr,
                (double*)PyArray_ITER_DATA(arr_iter),
                pt_inc,pt_size);
            nbrs_data = (long int*)(PyArray_ITER_DATA(nbrs_iter));
            self->tree->query(pt,k,nbrs_data);
            PyArray_ITER_NEXT(arr_iter);
            PyArray_ITER_NEXT(nbrs_iter);
        }
    }

  //if only one neighbor is requested, then resize the neighbors array
    if(k==1){
        PyArray_Dims dims;
        dims.ptr = PyArray_DIMS(arr);
        dims.len = PyArray_NDIM(arr)-1;

    //PyArray_Resize returns None - this needs to be picked
    // up and dereferenced.
        PyObject *NoneObj = PyArray_Resize( (PyArrayObject*)nbrs, &dims,
            0, NPY_ANYORDER );
        if (NoneObj == NULL){
            goto fail;
        }
        Py_DECREF(NoneObj);

        if(return_distance){
            NoneObj = PyArray_Resize( (PyArrayObject*)dist, &dims,
                0, NPY_ANYORDER );
            if (NoneObj == NULL){
                goto fail;
            }
            Py_DECREF(NoneObj);
        }
    }

    if(return_distance){
        Py_DECREF(arr_iter);
        Py_DECREF(nbrs_iter);
        Py_DECREF(dist_iter);
        Py_DECREF(arr);

        arr = Py_BuildValue("(OO)",dist,nbrs);
        Py_DECREF(nbrs);
        Py_DECREF(dist);
        return arr;

    }else{
        Py_DECREF(arr_iter);
        Py_DECREF(nbrs_iter);
        Py_DECREF(arr);
        return nbrs;
    }

    fail:
    Py_XDECREF(arr);
    Py_XDECREF(nbrs);
    Py_XDECREF(dist);
    Py_XDECREF(arr_iter);
    Py_XDECREF(nbrs_iter);
    Py_XDECREF(dist_iter);
    return NULL;
}
Beispiel #14
0
PyArrayObject* make_edges(const PyArrayObject* idx,
			  int ngb_size)
{
  int* ngb = _select_neighborhood_system(ngb_size);
  PyArrayIterObject* iter = (PyArrayIterObject*)PyArray_IterNew((PyObject*)idx);
  int* buf_ngb; 
  npy_intp xi, yi, zi, xj, yj, zj;
  npy_intp u2 = idx->dimensions[2]; 
  npy_intp u1 = idx->dimensions[1]*u2;
  npy_intp u0 = idx->dimensions[0]*u1;
  npy_intp mask_size = 0, n_edges = 0;
  npy_intp idx_i;
  npy_intp *buf_idx;
  npy_intp *edges_data, *buf_edges;
  npy_intp ngb_idx;
  npy_intp pos;
  PyArrayObject* edges;
  npy_intp dim[2] = {0, 2};
 
  /* First loop over the input array to determine the mask size */
  while(iter->index < iter->size) {
    buf_idx = (npy_intp*)PyArray_ITER_DATA(iter);
    if (*buf_idx >= 0)
      mask_size ++;
    PyArray_ITER_NEXT(iter); 
  }

  /* Allocate the array of edges using an upper bound of the required
     memory space */
  edges_data = (npy_intp*)malloc(2 * ngb_size * mask_size * sizeof(npy_intp)); 

  /* Second loop over the input array */
  PyArray_ITER_RESET(iter);
  iter->contiguous = 0; /* To force coordinates to be updated */
  buf_edges = edges_data;
  while(iter->index < iter->size) {

    xi = iter->coordinates[0];
    yi = iter->coordinates[1]; 
    zi = iter->coordinates[2]; 
    buf_idx = (npy_intp*)PyArray_ITER_DATA(iter);
    idx_i = *buf_idx;

    /* Loop over neighbors if current point is within the mask */
    if (idx_i >= 0) {
      buf_ngb = ngb;
      for (ngb_idx=0; ngb_idx<ngb_size; ngb_idx++) {

	/* Get neighbor coordinates */
	xj = xi + *buf_ngb; buf_ngb++; 
	yj = yi + *buf_ngb; buf_ngb++;
	zj = zi + *buf_ngb; buf_ngb++;
	pos = xj*u1 + yj*u2 + zj;

	/* Store edge if neighbor is within the mask */
	if ((pos < 0) || (pos >= u0))
	  continue;
	buf_idx = (npy_intp*)idx->data + pos;
	if (*buf_idx < 0)
	  continue;
	buf_edges[0] = idx_i;
	buf_edges[1] = *buf_idx;
	n_edges ++;
	buf_edges += 2;

      }
    }
    
    /* Increment iterator */
    PyArray_ITER_NEXT(iter); 
    
  }

  /* Reallocate edges array to account for connections suppressed due to masking */
  edges_data = realloc((void *)edges_data, 2 * n_edges * sizeof(npy_intp)); 
  dim[0] = n_edges;
  edges = (PyArrayObject*) PyArray_SimpleNewFromData(2, dim, NPY_INTP, (void*)edges_data);

  /* Transfer ownership to python (to avoid memory leaks!) */
  edges->flags = (edges->flags) | NPY_OWNDATA;

  /* Free memory */
  Py_XDECREF(iter);

  return edges;
}
Beispiel #15
0
void ve_step(PyArrayObject* ppm, 
	     const PyArrayObject* ref,
	     const PyArrayObject* XYZ, 
	     const PyArrayObject* U,
	     int ngb_size,
	     double beta)

{
  npy_intp k, x, y, z, pos;
  double *p, *buf, *ppm_data;
  double psum, tmp;  
  PyArrayIterObject* iter;
  int axis = 1; 
  npy_intp K = ppm->dimensions[3]; 
  npy_intp u2 = ppm->dimensions[2]*K; 
  npy_intp u1 = ppm->dimensions[1]*u2;
  const double* ref_data = (double*)ref->data;
  const double* U_data = (double*)U->data;
  npy_intp* xyz;
  int* ngb;

  /* Neighborhood system */
  ngb = _select_neighborhood_system(ngb_size);

  /* Pointer to the data array */
  ppm_data = (double*)ppm->data;
  
  /* Allocate auxiliary vectors */
  p = (double*)calloc(K, sizeof(double)); 

  /* Loop over points */ 
  iter = (PyArrayIterObject*)PyArray_IterAllButAxis((PyObject*)XYZ, &axis);

  while(iter->index < iter->size) {

    /* Integrate the energy over the neighborhood */
    xyz = PyArray_ITER_DATA(iter);
    x = xyz[0];
    y = xyz[1];
    z = xyz[2];
    _ngb_integrate(p, ppm, x, y, z, U_data, (const int*)ngb, ngb_size);

    /* Apply exponential transform, multiply with reference and
       compute normalization constant */
    psum = 0.0;
    for (k=0, pos=(iter->index)*K, buf=p; k<K; k++, pos++, buf++) {
      tmp = exp(-2 * beta * (*buf)) * ref_data[pos];
      psum += tmp;
      *buf = tmp;
    }
    
    /* Normalize to unitary sum */
    pos = x*u1 + y*u2 + z*K; 
    if (psum > TINY) 
      for (k=0, buf=p; k<K; k++, pos++, buf++)
	ppm_data[pos] = *buf/psum; 
    else
      for (k=0, buf=p; k<K; k++, pos++, buf++)
	ppm_data[pos] = (*buf+TINY/(double)K)/(psum+TINY); 

    /* Update iterator */ 
    PyArray_ITER_NEXT(iter); 
  
  }

  /* Free memory */ 
  free(p);
  Py_XDECREF(iter);

  return; 
}
Beispiel #16
0
static PyObject *AscanfCall( ascanf_Function *af, PyObject *arglist, long repeats, int asarray, int deref,
						PAO_Options *opts, char *caller )
{ int fargs= 0, aargc= 0, volatile_args= 0;
  double result= 0, *aresult=NULL;
  static double *AARGS= NULL;
  static char *ATYPE= NULL;
  static ascanf_Function *LAF= NULL;
  static size_t LAFN= 0;
  double *aargs= NULL;
  char *atype= NULL;
  ascanf_Function *laf= NULL, *af_array= NULL;
  size_t lafN= 0;
  PyObject *ret= NULL;
  static ascanf_Function *nDindex= NULL;
  int aV = ascanf_verbose;

	if( arglist ){
		if( PyList_Check(arglist) ){
			if( !(arglist= PyList_AsTuple(arglist)) ){
 				PyErr_SetString( XG_PythonError, "unexpected failure converting argument list to tuple" );
// 				PyErr_SetString( PyExc_RuntimeError, "unexpected failure converting argument list to tuple" );
				return(NULL);
			}
		}
		if( !PyTuple_Check(arglist) ){
			PyErr_SetString(
 				XG_PythonError,
// 				PyExc_SyntaxError,
				"arguments to the ascanf method should be passed as a tuple or list\n"
				" NB: a 1-element tuple is specified as (value , ) !!\n"
			);
			return(NULL);
		}

		aargc= PyTuple_Size(arglist);
	}
	else{
		aargc= 0;
	}
	if( !af ){
		goto PAC_ESCAPE;
	}
	if( af->type!= _ascanf_procedure && af->Nargs> 0 ){
	  /* procedures can have as many arguments as MaxArguments, which is probably too much to allocate here.
	   \ However, we know how many arguments a function can get (if all's well...), and we can assure that
	   \ it will have space for those arguments
	   \ 20061015: unless it also has MaxArguments, i.e. Nargs<0 ...
	   */
		fargs= af->Nargs;
	}
	{ long n= (aargc+fargs+1)*2;
		if( opts->call_reentrant ){
			lafN= n;
			aargs= (double*) calloc( lafN, sizeof(double) );
			atype= (char*)  calloc( lafN, sizeof(char) );
			if( !aargs || !atype || !(laf= (ascanf_Function*) calloc( lafN, sizeof(ascanf_Function) )) ){
				PyErr_NoMemory();
				return(NULL);
			}
		}
		else{
			if( !LAF ){
				LAFN= n;
				AARGS= (double*) calloc( LAFN, sizeof(double) );
				ATYPE= (char*) calloc( LAFN, sizeof(char) );
				if( !AARGS || !ATYPE || !(LAF= (ascanf_Function*) calloc( LAFN, sizeof(ascanf_Function) )) ){
					PyErr_NoMemory();
					return(NULL);
				}
			}
			else if( n> LAFN ){
				AARGS= (double*) realloc( AARGS, n * sizeof(double) );
				ATYPE= (char*) realloc( ATYPE, n * sizeof(char) );
				if( !AARGS || !ATYPE || !(LAF= (ascanf_Function*) realloc( LAF, n * sizeof(ascanf_Function) )) ){
					PyErr_NoMemory();
					return(NULL);
				}
				else{
					for( ; LAFN< n; LAFN++ ){
						AARGS[LAFN]= 0;
						memset( &LAF[LAFN], 0, sizeof(ascanf_Function) );
					}
				}
				LAFN= n;
			}
			aargs= AARGS;
			atype= ATYPE;
			laf= LAF;
			lafN= LAFN;
		}
	}

	{ int a= 0, i;
		if( opts->verbose > 1 ){
			ascanf_verbose = 1;
		}
		if( af->type== _ascanf_array ){
			if( !nDindex ){
				nDindex= Py_getNamedAscanfVariable("nDindex");
			}
			if( nDindex ){
				af_array= af;
				aargs[a]= (af->own_address)? af->own_address : take_ascanf_address(af);
				af= nDindex;
				a+= 1;
			}
		}
		for( i= 0; i< aargc; i++, a++ ){
		  PyObject *arg= PyTuple_GetItem(arglist, i);
		  ascanf_Function *aaf;

			if( PyFloat_Check(arg) ){
				aargs[a]= PyFloat_AsDouble(arg);
				atype[a]= 1;
			}
#ifdef USE_COBJ
			else if( PyCObject_Check(arg) ){
				if( (aaf= PyCObject_AsVoidPtr(arg)) && (PyCObject_GetDesc(arg)== aaf->function) ){
					aargs[a]= (aaf->own_address)? aaf->own_address : take_ascanf_address(aaf);
					atype[a]= 2;
				}
				else{
 					PyErr_SetString( XG_PythonError, "unsupported PyCObject type does not contain ascanf pointer" );
// 					PyErr_SetString( PyExc_TypeError, "unsupported PyCObject type does not contain ascanf pointer" );
					goto PAC_ESCAPE;
				}
			}
#else
			else if( PyAscanfObject_Check(arg) ){
				if( (aaf= PyAscanfObject_AsAscanfFunction(arg)) ){
					aargs[a]= (aaf->own_address)? aaf->own_address : take_ascanf_address(aaf);
					atype[a]= 2;
				}
				else{
 					PyErr_SetString( XG_PythonError, "invalid PyAscanfObject type does not contain ascanf pointer" );
// 					PyErr_SetString( PyExc_TypeError, "invalid PyAscanfObject type does not contain ascanf pointer" );
					goto PAC_ESCAPE;
				}
			}
#endif
			else if( PyInt_Check(arg) || PyLong_Check(arg) ){
				aargs[a]= PyInt_AsLong(arg);
				atype[a]= 3;
			}
			else if( PyBytes_Check(arg)
#ifdef IS_PY3K
				|| PyUnicode_Check(arg)
#endif
			){
			  static char *AFname= "AscanfCall-Static-StringPointer";
			  ascanf_Function *saf= &laf[a];
				memset( saf, 0, sizeof(ascanf_Function) );
				saf->type= _ascanf_variable;
				saf->function= ascanf_Variable;
				if( !(saf->name= PyObject_Name(arg)) ){
					saf->name= XGstrdup(AFname);
				}
				saf->is_address= saf->take_address= True;
				saf->is_usage= saf->take_usage= True;
				saf->internal= True;
#ifdef IS_PY3K
				if( PyUnicode_Check(arg) ){
				  PyObject *bytes = NULL;
				  char *str = NULL;
					PYUNIC_TOSTRING( arg, bytes, str );
					if( !str ){
						if( bytes ){
							Py_XDECREF(bytes);
						}
						goto PAC_ESCAPE;
					}
					saf->usage= parse_codes( XGstrdup(str) );
					Py_XDECREF(bytes);
				}
				else
#endif
				{
					saf->usage= parse_codes( XGstrdup( PyBytes_AsString(arg) ) );
				}
				aargs[a]= take_ascanf_address(saf);
				atype[a]= 4;
				if( i && af_array ){
					volatile_args+= 1;
				}
			}
			else if( PyArray_Check(arg)
				|| PyTuple_Check(arg)
				|| PyList_Check(arg)
			){
			  static char *AFname= "AscanfCall-Static-ArrayPointer";
			  ascanf_Function *saf= &laf[a];
			  PyArrayObject *parray;
				atype[a]= 6;
				if( PyList_Check(arg) ){
					if( !(arg= PyList_AsTuple(arg)) ){
 						PyErr_SetString( XG_PythonError, "unexpected failure converting argument to tuple" );
// 						PyErr_SetString( PyExc_RuntimeError, "unexpected failure converting argument to tuple" );
						goto PAC_ESCAPE;
/* 						return(NULL);	*/
					}
					else{
						atype[a]= 5;
					}
				}
				memset( saf, 0, sizeof(ascanf_Function) );
				saf->type= _ascanf_array;
				saf->function= ascanf_Variable;
				if( !(saf->name= PyObject_Name(arg)) ){
					saf->name= XGstrdup(AFname);
				}
				saf->is_address= saf->take_address= True;
				saf->internal= True;
				if( a ){
					saf->car= &laf[a-1];
				}
				else{
					saf->car= &laf[lafN-1];
				}
				if( PyTuple_Check(arg) ){
					saf->N= PyTuple_Size(arg);
					parray= NULL;
				}
				else{
					saf->N= PyArray_Size(arg);
					parray= (PyArrayObject*) arg;
					atype[a]= 7;
				}
				if( (saf->array= (double*) malloc( saf->N * sizeof(double) )) ){
				  int j;
					if( parray ){
					  PyArrayObject* xd= NULL;
					  double *PyArrayBuf= NULL;
					  PyArrayIterObject *it;
						if( (xd = (PyArrayObject*) PyArray_ContiguousFromObject( (PyObject*) arg, PyArray_DOUBLE, 0, 0 )) ){
							PyArrayBuf= (double*)PyArray_DATA(xd); /* size would be N*sizeof(double) */
						}
						else{
							it= (PyArrayIterObject*) PyArray_IterNew(arg);
						}
						if( PyArrayBuf ){
// 							for( j= 0; j< saf->N; j++ ){
// 								  /* 20061016: indices used to be i?!?! */
// 								saf->array[j]= PyArrayBuf[j];
// 							}
							if( saf->array != PyArrayBuf ){
								memcpy( saf->array, PyArrayBuf, saf->N * sizeof(double) );
							}
						}
						else{
							for( j= 0; j< saf->N; j++ ){
								saf->array[j]= PyFloat_AsDouble( PyArray_DESCR(parray)->f->getitem( it->dataptr, arg) );
								PyArray_ITER_NEXT(it);
							}
						}
						if( xd ){
							Py_XDECREF(xd);
						}
						else{
							Py_DECREF(it);
						}
					}
					else{
						for( j= 0; j< saf->N; j++ ){
							saf->array[j]= PyFloat_AsDouble( PyTuple_GetItem(arg,j) );
						}
					}
					aargs[a]= take_ascanf_address(saf);
					if( i && af_array ){
						volatile_args+= 1;
					}
				}
				else{
					PyErr_NoMemory();
					goto PAC_ESCAPE;
				}
			}
#if 0
			else{
 				PyErr_SetString( XG_PythonError, "arguments should be scalars, strings, arrays or ascanf pointers" );
// 				PyErr_SetString( PyExc_SyntaxError, "arguments should be scalars, strings, arrays or ascanf pointers" );
				goto PAC_ESCAPE;
			}
#else
			else{
			  static char *AFname= "AscanfCall-Static-PyObject";
			  ascanf_Function *saf= &laf[a];
				memset( saf, 0, sizeof(ascanf_Function) );
				saf->function= ascanf_Variable;
				saf->internal= True;
				saf= make_ascanf_python_object( saf, arg, "AscanfCall" );
				if( !saf->name ){
					if( saf->PyObject_Name ){
						saf->name= XGstrdup(saf->PyObject_Name);
					}
					else{
						saf->name= XGstrdup(AFname);
					}
				}
				aargs[a]= take_ascanf_address(saf);
				atype[a]= 4;
				if( i && af_array ){
					volatile_args+= 1;
				}
			}
#endif
		}
		if( a> aargc ){
			aargc= a;
		}
	}
Beispiel #17
0
static PyObject* py_fitexpsin(PyObject *obj, PyObject *args, PyObject *kwds)
{
    PyArrayObject *data = NULL;
    PyArrayObject *fitt = NULL;
    PyArrayObject *rslt = NULL;
    PyArrayIterObject *data_it = NULL;
    PyArrayIterObject *fitt_it = NULL;
    PyArrayIterObject *rslt_it = NULL;
    Py_ssize_t newshape[NPY_MAXDIMS];
    double *poly = NULL;
    double *coef = NULL;
    double *buff = NULL;
    int i, j, error, lastaxis, numdata;
    int startcoef = -1;
    int numcoef = MAXCOEF;
    int axis = NPY_MAXDIMS;
    double deltat = 1.0;
    static char *kwlist[] = {"data", "numcoef",
                             "deltat", "axis", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|idO&", kwlist,
        PyConverter_AnyDoubleArray, &data, &numcoef, &deltat,
        PyArray_AxisConverter, &axis)) return NULL;

    if (axis < 0) {
        axis += PyArray_NDIM(data);
    }
    if ((axis < 0) || (axis >= NPY_MAXDIMS)) {
        PyErr_Format(PyExc_ValueError, "invalid axis");
        goto _fail;
    }
    lastaxis = PyArray_NDIM(data) - 1;

    if ((numcoef < 1) || (numcoef > MAXCOEF)) {
        PyErr_Format(PyExc_ValueError, "numcoef out of bounds");
        goto _fail;
    }

    if (startcoef < 0) { /* start regression away from zero coefficients */
        startcoef = 4;
    }
    if (startcoef > numcoef - 2) {
        PyErr_Format(PyExc_ValueError, "startcoef out of bounds");
        goto _fail;
    }

    numdata = (int)PyArray_DIM(data, axis);
    if (numcoef > numdata)
        numcoef = numdata;

    if ((numcoef - startcoef - 1) < 3) {
        PyErr_Format(PyExc_ValueError,
            "number of coefficients insufficient to fit data");
        goto _fail;
    }

    /* fitted data */
    fitt = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(data),
                                              PyArray_DIMS(data), NPY_DOUBLE);
    if (fitt == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate fitt array");
        goto _fail;
    }

    /* fitted parameters */
    j = 0;
    for (i = 0; i < PyArray_NDIM(data); i++) {
        if (i != axis)
            newshape[j++] = PyArray_DIM(data, i);
    }
    newshape[j] = 5;
    rslt = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(data),
                                              newshape, NPY_DOUBLE);
    if (rslt == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate rslt array");
        goto _fail;
    }

    /* working buffer */
    buff = (double *)PyMem_Malloc(3*numdata * sizeof(double));
    if (buff == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate buff array");
        goto _fail;
    }

    /* buffer for differential coefficients */
    coef = (double *)PyMem_Malloc((3+1)*(numcoef+1) * sizeof(double));
    if (coef == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate coef array");
        goto _fail;
    }

    /* precalculate normalized Chebyshev polynomial */
    poly = (double *)PyMem_Malloc(numdata * (numcoef+1) * sizeof(double));
    if (poly == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate poly");
        goto _fail;
    }

    error = chebypoly(numdata, numcoef, poly, 1);
    if (error != 0) {
        PyErr_Format(PyExc_ValueError,
            "chebypoly() failed with error code %i", error);
        goto _fail;
    }

    /* iterate over all but specified axis */
    data_it = (PyArrayIterObject *)PyArray_IterAllButAxis(
                                            (PyObject *)data, &axis);
    fitt_it = (PyArrayIterObject *)PyArray_IterAllButAxis(
                                            (PyObject *)fitt, &axis);
    rslt_it = (PyArrayIterObject *)PyArray_IterAllButAxis(
                                            (PyObject *)rslt, &lastaxis);

    while (data_it->index < data_it->size) {
        error = fitexpsin(
            (char *)data_it->dataptr,
            (int)PyArray_STRIDE(data, axis),
            numdata,
            poly,
            coef,
            numcoef,
            deltat,
            startcoef,
            buff,
            (double *)rslt_it->dataptr,
            (char *)fitt_it->dataptr,
            (int)PyArray_STRIDE(fitt, axis));

        if (error != 0) {
            PyErr_Format(PyExc_ValueError,
                "fitexpsin() failed with error code %i", error);
            goto _fail;
        }

        PyArray_ITER_NEXT(data_it);
        PyArray_ITER_NEXT(fitt_it);
        PyArray_ITER_NEXT(rslt_it);
    }

    Py_XDECREF(data_it);
    Py_XDECREF(fitt_it);
    Py_XDECREF(rslt_it);
    Py_XDECREF(data);
    PyMem_Free(poly);
    PyMem_Free(coef);
    PyMem_Free(buff);

    return Py_BuildValue("(N, N)", rslt, fitt);

  _fail:
    Py_XDECREF(data_it);
    Py_XDECREF(fitt_it);
    Py_XDECREF(rslt_it);
    Py_XDECREF(data);
    Py_XDECREF(fitt);
    Py_XDECREF(rslt);
    PyMem_Free(poly);
    PyMem_Free(coef);
    PyMem_Free(buff);

    return NULL;
}
Beispiel #18
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;
}
Beispiel #19
0
//Wrapper for Brute-Force neighbor search
static PyObject*
BallTree_knn_brute(PyObject *self, PyObject *args, PyObject *kwds){
    long int k = 1;
    std::vector<BallTree_Point*> Points;

    PyObject *arg1 = NULL;
    PyObject *arg2 = NULL;
    PyObject *arr1 = NULL;
    PyObject *arr2 = NULL;
    PyObject *nbrs = NULL;

    long int* nbrs_data;
    PyArrayIterObject *arr2_iter = NULL;
    PyArrayIterObject *nbrs_iter = NULL;
    static char *kwlist[] = {"x", "pt", "k", NULL};

    npy_intp* dim;
    int nd, pt_size, pt_inc;
    long int N;
    long int D;

  //parse arguments.  If k is not provided, the default is 1
    if(!PyArg_ParseTupleAndKeywords(args,kwds,"OO|l",kwlist,
        &arg1,&arg2,&k))
        goto fail;

  //First array should be a 2D array of doubles
    arr1 = PyArray_FROM_OTF(arg1,NPY_DOUBLE,0);
    if(arr1==NULL)
        goto fail;
    if( PyArray_NDIM(arr1) != 2){
        PyErr_SetString(PyExc_ValueError,
            "x must be two dimensions");
        goto fail;
    }

  //Second array should be a 1D array of doubles
    arr2 = PyArray_FROM_OTF(arg2,NPY_DOUBLE,0);
    if(arr2==NULL)
        goto fail;

    nd = PyArray_NDIM(arr2);

    if(nd == 0){
        PyErr_SetString(PyExc_ValueError,
            "pt cannot be zero-sized array");
        goto fail;
    }
    pt_size = PyArray_DIM(arr2,nd-1);

  //Check that dimensions match
    N = PyArray_DIMS(arr1)[0];
    D = PyArray_DIMS(arr1)[1];
    if( pt_size != D ){
        PyErr_SetString(PyExc_ValueError,
            "pt must be same dimension as x");
        goto fail;
    }

  //check the value of k
    if(k<1){
        PyErr_SetString(PyExc_ValueError,
            "k must be a positive integer");
        goto fail;
    }

    if(k>N){
        PyErr_SetString(PyExc_ValueError,
            "k must be less than the number of points");
        goto fail;
    }

  //create a neighbors array and distance array
    dim = new npy_intp[nd];
    for(int i=0; i<nd-1;i++)
        dim[i] = PyArray_DIM(arr2,i);
    dim[nd-1] = k;
    nbrs = (PyObject*)PyArray_SimpleNew(nd,dim,PyArray_LONG);
    delete[] dim;

    if(nbrs==NULL)
        goto fail;

  //create iterators to cycle through points
    nd-=1;
    arr2_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(arr2,&nd);
    nbrs_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(nbrs,&nd);
    nd+=1;

    if( arr2_iter==NULL ||
        nbrs_iter==NULL ||
        (arr2_iter->size != nbrs_iter->size) ){
        PyErr_SetString(PyExc_ValueError,
            "failure constructing iterators");
        goto fail;
    }

    pt_inc = PyArray_STRIDES(arr2)[nd-1] / PyArray_DESCR(arr2)->elsize;
    if(PyArray_STRIDES(nbrs)[nd-1] != PyArray_DESCR(nbrs)->elsize ){
        PyErr_SetString(PyExc_ValueError,
            "nbrs not allocated as a C-array");
        goto fail;
    }

  //create the list of points
    pt_inc = PyArray_STRIDES(arr1)[1]/PyArray_DESCR(arr1)->elsize;
    Points.resize(N);
    for(int i=0;i<N;i++)
        Points[i] = new BallTree_Point(arr1,
        (double*)PyArray_GETPTR2(arr1,i,0),
        pt_inc, PyArray_DIM(arr1,1));

  //iterate through points and determine neighbors
  //warning: if nbrs is not a C-array, or if we're not iterating
  // over the last dimension, this may cause a seg fault.
    while(arr2_iter->index < arr2_iter->size){
        BallTree_Point Query_Point(arr2,
            (double*)PyArray_ITER_DATA(arr2_iter),
            pt_inc,pt_size);
        nbrs_data = (long int*)(PyArray_ITER_DATA(nbrs_iter));
        BruteForceNeighbors(Points, Query_Point,
            k, nbrs_data );
        PyArray_ITER_NEXT(arr2_iter);
        PyArray_ITER_NEXT(nbrs_iter);
    }

    for(int i=0;i<N;i++)
        delete Points[i];

  //if only one neighbor is requested, then resize the neighbors array
    if(k==1){
        PyArray_Dims dims;
        dims.ptr = PyArray_DIMS(arr2);
        dims.len = PyArray_NDIM(arr2)-1;

    //PyArray_Resize returns None - this needs to be picked
    // up and dereferenced.
        PyObject *NoneObj = PyArray_Resize( (PyArrayObject*)nbrs, &dims,
            0, NPY_ANYORDER );
        if (NoneObj == NULL){
            goto fail;
        }
        Py_DECREF(NoneObj);
    }

    return nbrs;

    fail:
    Py_XDECREF(arr1);
    Py_XDECREF(arr2);
    Py_XDECREF(nbrs);
    Py_XDECREF(arr2_iter);
    Py_XDECREF(nbrs_iter);
    return NULL;
}
Beispiel #20
0
int joint_histogram(PyArrayObject* JH, 
		    unsigned int clampI, 
		    unsigned int clampJ,  
		    PyArrayIterObject* iterI,
		    const PyArrayObject* imJ_padded, 
		    const PyArrayObject* Tvox, 
		    long interp)
{
  const signed short* J=(signed short*)imJ_padded->data; 
  size_t dimJX=imJ_padded->dimensions[0]-2;
  size_t dimJY=imJ_padded->dimensions[1]-2; 
  size_t dimJZ=imJ_padded->dimensions[2]-2;  
  signed short Jnn[8]; 
  double W[8]; 
  signed short *bufI, *bufJnn; 
  double *bufW; 
  signed short i, j;
  size_t off;
  size_t u2 = imJ_padded->dimensions[2]; 
  size_t u3 = u2+1; 
  size_t u4 = imJ_padded->dimensions[1]*u2;
  size_t u5 = u4+1; 
  size_t u6 = u4+u2; 
  size_t u7 = u6+1; 
  double wx, wy, wz, wxwy, wxwz, wywz; 
  double W0, W2, W3, W4; 
  int nn, nx, ny, nz;
  double *H = (double*)PyArray_DATA(JH);  
  double Tx, Ty, Tz; 
  double *tvox = (double*)PyArray_DATA(Tvox); 
  void (*interpolate)(unsigned int, double*, unsigned int, const signed short*, const double*, int, void*); 
  void* interp_params = NULL; 
  prng_state rng; 


  /* 
     Check assumptions regarding input arrays. If it fails, the
     function will return -1 without doing anything else. 
     
     iterI : assumed to iterate over a signed short encoded, possibly
     non-contiguous array.
     
     imJ_padded : assumed C-contiguous (last index varies faster) & signed
     short encoded.
     
     H : assumed C-contiguous. 
     
     Tvox : assumed C-contiguous: 
     
       either a 3x4=12-sized array (or bigger) for an affine transformation

       or a 3xN array for a pre-computed transformation, with N equal
       to the size of the array corresponding to iterI (no checking
       done)
  
  */
  if (PyArray_TYPE(iterI->ao) != NPY_SHORT) {
    fprintf(stderr, "Invalid type for the array iterator\n");
    return -1; 
  }
  if ( (!PyArray_ISCONTIGUOUS(imJ_padded)) || 
       (!PyArray_ISCONTIGUOUS(JH)) ||
       (!PyArray_ISCONTIGUOUS(Tvox)) ) {
    fprintf(stderr, "Some non-contiguous arrays\n");
    return -1; 
  }

  /* Reset the source image iterator */
  PyArray_ITER_RESET(iterI);

  /* Set interpolation method */ 
  if (interp==0) 
    interpolate = &_pv_interpolation;
  else if (interp>0) 
    interpolate = &_tri_interpolation; 
  else { /* interp < 0 */ 
    interpolate = &_rand_interpolation;
    prng_seed(-interp, &rng); 
    interp_params = (void*)(&rng); 
  }

  /* Re-initialize joint histogram */ 
  memset((void*)H, 0, clampI*clampJ*sizeof(double));

  /* Looop over source voxels */
  while(iterI->index < iterI->size) {
  
    /* Source voxel intensity */
    bufI = (signed short*)PyArray_ITER_DATA(iterI); 
    i = bufI[0];

    /* Compute the transformed grid coordinates of current voxel */ 
    Tx = *tvox; tvox++;
    Ty = *tvox; tvox++;
    Tz = *tvox; tvox++; 

    /* Test whether the current voxel is below the intensity
       threshold, or the transformed point is completly outside
       the reference grid */
    if ((i>=0) && 
	(Tx>-1) && (Tx<dimJX) && 
	(Ty>-1) && (Ty<dimJY) && 
	(Tz>-1) && (Tz<dimJZ)) {
	
      /* 
	 Nearest neighbor (floor coordinates in the padded
	 image, hence +1). 
	 
	 Notice that using the floor function doubles excetution time.
	 
	 FIXME: see if we can replace this with assembler instructions. 
      */
      nx = FLOOR(Tx) + 1;
      ny = FLOOR(Ty) + 1;
      nz = FLOOR(Tz) + 1;
      
      /* The convention for neighbor indexing is as follows:
       *
       *   Floor slice        Ceil slice
       *
       *     2----6             3----7                     y          
       *     |    |             |    |                     ^ 
       *     |    |             |    |                     |
       *     0----4             1----5                     ---> x
       */
      
      /*** Trilinear interpolation weights.  
	   Note: wx = nnx + 1 - Tx, where nnx is the location in
	   the NON-PADDED grid */ 
      wx = nx - Tx; 
      wy = ny - Ty;
      wz = nz - Tz;
      wxwy = wx*wy;    
      wxwz = wx*wz;
      wywz = wy*wz;
      
      /*** Prepare buffers */ 
      bufJnn = Jnn;
      bufW = W; 
      
      /*** Initialize neighbor list */
      off = nx*u4 + ny*u2 + nz; 
      nn = 0; 
      
      /*** Neighbor 0: (0,0,0) */ 
      W0 = wxwy*wz; 
      APPEND_NEIGHBOR(off, W0); 
      
      /*** Neighbor 1: (0,0,1) */ 
      APPEND_NEIGHBOR(off+1, wxwy-W0);
      
      /*** Neighbor 2: (0,1,0) */ 
      W2 = wxwz-W0; 
      APPEND_NEIGHBOR(off+u2, W2);  
      
      /*** Neightbor 3: (0,1,1) */
      W3 = wx-wxwy-W2;  
      APPEND_NEIGHBOR(off+u3, W3);  
      
      /*** Neighbor 4: (1,0,0) */
      W4 = wywz-W0;  
      APPEND_NEIGHBOR(off+u4, W4); 
      
      /*** Neighbor 5: (1,0,1) */ 
      APPEND_NEIGHBOR(off+u5, wy-wxwy-W4);   
      
      /*** Neighbor 6: (1,1,0) */ 
      APPEND_NEIGHBOR(off+u6, wz-wxwz-W4);  
      
      /*** Neighbor 7: (1,1,1) */ 
      APPEND_NEIGHBOR(off+u7, 1-W3-wy-wz+wywz);  
      
      /* Update the joint histogram using the desired interpolation technique */ 
      interpolate(i, H, clampJ, Jnn, W, nn, interp_params); 
      
      
    } /* End of IF TRANSFORMS INSIDE */
    
    /* Update source index */ 
    PyArray_ITER_NEXT(iterI); 
    
  } /* End of loop over voxels */ 
  

  return 0; 
}
Beispiel #21
0
static PyObject *
py_interpolate(
    PyObject *obj,
    PyObject *args,
    PyObject *kwds)
{
    PyArrayObject *xdata = NULL;
    PyArrayObject *data = NULL;
    PyArrayObject *xout = NULL;
    PyArrayObject *out = NULL;
    PyArrayObject *oout = NULL;
    PyArrayIterObject *dit = NULL;
    PyArrayIterObject *oit = NULL;
    npy_intp dstride, ostride, xdstride, xostride, size, outsize;
    Py_ssize_t newshape[NPY_MAXDIMS];
    int axis = NPY_MAXDIMS;
    int i, ndim, error;
    double *buffer = NULL;

    static char *kwlist[] = {"x", "y", "x_new", "axis", "out", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O&O&|O&O&", kwlist,
                                     PyConverter_AnyDoubleArray, &xdata,
                                     PyConverter_AnyDoubleArray, &data,
                                     PyConverter_AnyDoubleArray, &xout,
                                     PyArray_AxisConverter, &axis,
                                     PyOutputConverter_AnyDoubleArrayOrNone, &oout))
        goto _fail;

    /* check axis */
    ndim = PyArray_NDIM(data);
    if ((axis == NPY_MAXDIMS) || (axis == -1)) {
        axis = ndim - 1;
    } else if ((axis < 0) || (axis > NPY_MAXDIMS)) {
        PyErr_Format(PyExc_ValueError, "invalid axis");
        goto _fail;
    }

    if ((PyArray_NDIM(xdata) != 1) || (PyArray_NDIM(xout) != 1)) {
        PyErr_Format(PyExc_ValueError,
                     "x-arrays must be one dimensional");
        goto _fail;
    }

    size = PyArray_DIM(data, axis);
    outsize = PyArray_DIM(xout, 0);

    if (size < 3) {
        PyErr_Format(PyExc_ValueError, "size along axis is too small");
        goto _fail;
    }

    if (size != PyArray_DIM(xdata, 0)) {
        PyErr_Format(PyExc_ValueError,
                     "size of x-array must match data shape at axis");
        goto _fail;
    }

    for (i = 0; i < ndim; i++) {
        newshape[i] = (i == axis) ? outsize : PyArray_DIM(data, i);
    }

    if (oout == NULL) {
        /* create a new output array */
        out = (PyArrayObject*)PyArray_SimpleNew(ndim, newshape, NPY_DOUBLE);
        if (out == NULL) {
            PyErr_Format(PyExc_ValueError, "failed to allocate output array");
            goto _fail;
        }
    } else if (ndim != PyArray_NDIM(oout)) {
        PyErr_Format(PyExc_ValueError,
                     "output and data array dimension mismatch");
        goto _fail;
    } else {
        for (i = 0; i < ndim; i++) {
            if (newshape[i] != PyArray_DIM(oout, i)) {
                PyErr_Format(PyExc_ValueError, "wrong output shape");
                goto _fail;
            }
        }
        out = oout;
    }

    /* iterate over all but specified axis */
    dit = (PyArrayIterObject *)PyArray_IterAllButAxis((PyObject *)data, &axis);
    oit = (PyArrayIterObject *)PyArray_IterAllButAxis((PyObject *)out, &axis);
    dstride = PyArray_STRIDE(data, axis);
    ostride = PyArray_STRIDE(out, axis);
    xdstride = PyArray_STRIDE(xdata, 0);
    xostride = PyArray_STRIDE(xout, 0);

    buffer = (double *)PyMem_Malloc((size * 4 + 4) * sizeof(double));
    if (buffer == NULL) {
        PyErr_Format(PyExc_ValueError, "failed to allocate output buffer");
        goto _fail;
    }

    while (dit->index < dit->size) {
        error = interpolate(
                    size,
                    PyArray_DATA(xdata), xdstride,
                    dit->dataptr, dstride,
                    outsize,
                    PyArray_DATA(xout), xostride,
                    oit->dataptr, ostride,
                    buffer);

        if (error != 0) {
            PyErr_Format(PyExc_ValueError, "interpolate() failed");
            goto _fail;
        }

        PyArray_ITER_NEXT(oit);
        PyArray_ITER_NEXT(dit);
    }

    PyMem_Free(buffer);
    Py_DECREF(oit);
    Py_DECREF(dit);
    Py_DECREF(data);
    Py_DECREF(xout);
    Py_DECREF(xdata);

    /* Return output vector if not provided as argument */
    if (oout == NULL) {
        return PyArray_Return(out);
    } else {
        Py_INCREF(Py_None);
        return Py_None;
    }

_fail:
    Py_XDECREF(xdata);
    Py_XDECREF(xout);
    Py_XDECREF(data);
    Py_XDECREF(oit);
    Py_XDECREF(dit);
    if (buffer != NULL)
        PyMem_Free(buffer);
    if (oout == NULL)
        Py_XDECREF(out);
    else
        Py_XDECREF(oout);
    return NULL;
}
Beispiel #22
0
void joint_histogram(double* H, 
		     unsigned int clampI, 
		     unsigned int clampJ,  
		     PyArrayIterObject* iterI,
		     const PyArrayObject* imJ_padded, 
		     const double* Tvox, 
		     int affine, 
		     int interp)
{
  const signed short* J=(signed short*)imJ_padded->data; 
  size_t dimJX=imJ_padded->dimensions[0]-2;
  size_t dimJY=imJ_padded->dimensions[1]-2; 
  size_t dimJZ=imJ_padded->dimensions[2]-2;  
  signed short Jnn[8]; 
  double W[8]; 
  signed short *bufI, *bufJnn; 
  double *bufW; 
  signed short i, j;
  size_t off;
  size_t u2 = imJ_padded->dimensions[2]; 
  size_t u3 = u2+1; 
  size_t u4 = imJ_padded->dimensions[1]*u2;
  size_t u5 = u4+1; 
  size_t u6 = u4+u2; 
  size_t u7 = u6+1; 
  double wx, wy, wz, wxwy, wxwz, wywz; 
  double W0, W2, W3, W4; 
  size_t x, y, z; 
  int nn, nx, ny, nz;
  double Tx, Ty, Tz; 
  double *bufTvox = (double*)Tvox; 
  void (*interpolate)(unsigned int, double*, unsigned int, const signed short*, const double*, int, void*); 
  void* interp_params = NULL; 
  rk_state rng; 

  /* Reset the source image iterator */
  PyArray_ITER_RESET(iterI);

  /* Make sure the iterator the iterator will update coordinate values */ 
  UPDATE_ITERATOR_COORDS(iterI); 

  /* Set interpolation method */ 
  if (interp==0) 
    interpolate = &_pv_interpolation;
  else if (interp>0) 
    interpolate = &_tri_interpolation; 
  else { /* interp < 0 */ 
    interpolate = &_rand_interpolation;
    rk_seed(-interp, &rng); 
    interp_params = (void*)(&rng); 
  }

  /* Re-initialize joint histogram */ 
  memset((void*)H, 0, clampI*clampJ*sizeof(double));

  /* Looop over source voxels */
  while(iterI->index < iterI->size) {
  
    /* Source voxel intensity */
    bufI = (signed short*)PyArray_ITER_DATA(iterI); 
    i = bufI[0];

    /* Compute the transformed grid coordinates of current voxel */ 
    if (affine) {
      /* Get voxel coordinates and apply transformation on-the-fly*/
      x = iterI->coordinates[0];
      y = iterI->coordinates[1];
      z = iterI->coordinates[2];
      _affine_transform(&Tx, &Ty, &Tz, Tvox, x, y, z); 
    }
    else 
      /* Use precomputed transformed coordinates */ 
      bufTvox = _precomputed_transform(&Tx, &Ty, &Tz, (const double*)bufTvox);
       
    /* Test whether the current voxel is below the intensity
       threshold, or the transformed point is completly outside
       the reference grid */
    if ((i>=0) && 
	(Tx>-1) && (Tx<dimJX) && 
	(Ty>-1) && (Ty<dimJY) && 
	(Tz>-1) && (Tz<dimJZ)) {
	
      /* 
	 Nearest neighbor (floor coordinates in the padded
	 image, hence +1). 
	 
	 Notice that using the floor function doubles excetution time.
	 
	 FIXME: see if we can replace this with assembler instructions. 
      */
      nx = FLOOR(Tx) + 1;
      ny = FLOOR(Ty) + 1;
      nz = FLOOR(Tz) + 1;
      
      /* The convention for neighbor indexing is as follows:
       *
       *   Floor slice        Ceil slice
       *
       *     2----6             3----7                     y          
       *     |    |             |    |                     ^ 
       *     |    |             |    |                     |
       *     0----4             1----5                     ---> x
       */
      
      /*** Trilinear interpolation weights.  
	   Note: wx = nnx + 1 - Tx, where nnx is the location in
	   the NON-PADDED grid */ 
      wx = nx - Tx; 
      wy = ny - Ty;
      wz = nz - Tz;
      wxwy = wx*wy;    
      wxwz = wx*wz;
      wywz = wy*wz;
      
      /*** Prepare buffers */ 
      bufJnn = Jnn;
      bufW = W; 
      
      /*** Initialize neighbor list */
      off = nx*u4 + ny*u2 + nz; 
      nn = 0; 
      
      /*** Neighbor 0: (0,0,0) */ 
      W0 = wxwy*wz; 
      APPEND_NEIGHBOR(off, W0); 
      
      /*** Neighbor 1: (0,0,1) */ 
      APPEND_NEIGHBOR(off+1, wxwy-W0);
      
      /*** Neighbor 2: (0,1,0) */ 
      W2 = wxwz-W0; 
      APPEND_NEIGHBOR(off+u2, W2);  
      
      /*** Neightbor 3: (0,1,1) */
      W3 = wx-wxwy-W2;  
      APPEND_NEIGHBOR(off+u3, W3);  
      
      /*** Neighbor 4: (1,0,0) */
      W4 = wywz-W0;  
      APPEND_NEIGHBOR(off+u4, W4); 
      
      /*** Neighbor 5: (1,0,1) */ 
      APPEND_NEIGHBOR(off+u5, wy-wxwy-W4);   
      
      /*** Neighbor 6: (1,1,0) */ 
      APPEND_NEIGHBOR(off+u6, wz-wxwz-W4);  
      
      /*** Neighbor 7: (1,1,1) */ 
      APPEND_NEIGHBOR(off+u7, 1-W3-wy-wz+wywz);  
      
      /* Update the joint histogram using the desired interpolation technique */ 
      interpolate(i, H, clampJ, Jnn, W, nn, interp_params); 
      
      
    } /* End of IF TRANSFORMS INSIDE */
    
    /* Update source index */ 
    PyArray_ITER_NEXT(iterI); 
    
  } /* End of loop over voxels */ 
  

  return; 
}
Beispiel #23
0
//query the ball tree.  Arguments are the array of search points
// and the radius around each point to search
static PyObject *
BallTree_queryball(BallTreeObject *self, PyObject *args, PyObject *kwds){
  //we use goto statements : all variables should be declared up front
    int count_only = 0;
    double r;
    PyObject *arg = NULL;
    PyObject *arr = NULL;
    PyObject *nbrs = NULL;
    PyArrayIterObject* arr_iter = NULL;
    PyArrayIterObject* nbrs_iter = NULL;
    int nd, pt_size, pt_inc;
    static char *kwlist[] = {"x", "r", "count_only", NULL};

  //parse arguments.  If kmax is not provided, the default is 20
    if(!PyArg_ParseTupleAndKeywords(args,kwds,"Od|i",
                                    kwlist,&arg,&r,&count_only)){
        goto fail;
    }

  //check value of r
    if(r < 0){
        PyErr_SetString(PyExc_ValueError,
            "r must not be negative");
        goto fail;
    }

  //get the array object from the first argument
    arr = PyArray_FROM_OTF(arg,NPY_DOUBLE,NPY_ALIGNED);

  //check that the array was properly constructed
    if(arr==NULL){
        PyErr_SetString(PyExc_ValueError,
            "pt must be convertable to array");
        goto fail;
    }

    nd = PyArray_NDIM(arr);
    if(nd == 0){
        PyErr_SetString(PyExc_ValueError,
            "pt cannot be zero-sized array");
        goto fail;
    }
    pt_size = PyArray_DIM(arr,nd-1);
    if( pt_size != self->tree->PointSize() ){
        PyErr_SetString(PyExc_ValueError,
            "points are incorrect dimension");
        goto fail;
    }


  // Case 1: return arrays of all neighbors for each point
  //
    if(!count_only){
    //create a neighbors array.  This is an array of python objects.
    // each of which will be a numpy array of neighbors
        nbrs = (PyObject*)PyArray_SimpleNew(nd-1,PyArray_DIMS(arr),
                                            PyArray_OBJECT);

        if(nbrs==NULL){
            goto fail;
        }

    //create iterators to cycle through points
        --nd;
        arr_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(arr,&nd);
        nbrs_iter = (PyArrayIterObject*)PyArray_IterNew(nbrs);
        ++nd;

        if( arr_iter==NULL || nbrs_iter==NULL ||
        (arr_iter->size != nbrs_iter->size)){
            PyErr_SetString(PyExc_ValueError,
                "unable to construct iterator");
            goto fail;
        }


        pt_inc = PyArray_STRIDES(arr)[nd-1] / PyArray_DESCR(arr)->elsize;
        if(PyArray_NDIM(nbrs)==0){
            BallTree_Point pt(arr,
                (double*)PyArray_ITER_DATA(arr_iter),
                pt_inc,pt_size);
            std::vector<long int> nbrs_vec;
            self->tree->query_ball(pt,r,nbrs_vec);
            npy_intp N_nbrs = nbrs_vec.size();
            PyObject* nbrs_obj = PyArray_SimpleNew(1, &N_nbrs, PyArray_LONG);
            long int* data = (long int*)PyArray_DATA(nbrs_obj);
            for(int i=0; i<N_nbrs; i++)
                data[i] = nbrs_vec[i];
            PyObject* tmp = nbrs;
            nbrs = nbrs_obj;
            Py_DECREF(tmp);
        }else{
            while(arr_iter->index < arr_iter->size){
                BallTree_Point pt(arr,
                    (double*)PyArray_ITER_DATA(arr_iter),
                    pt_inc,pt_size);
                std::vector<long int> nbrs_vec;
                self->tree->query_ball(pt,r,nbrs_vec);

                npy_intp N_nbrs = nbrs_vec.size();

                PyObject* nbrs_obj = PyArray_SimpleNew(1, &N_nbrs,
                                                       PyArray_LONG);
                long int* data = (long int*)PyArray_DATA(nbrs_obj);
                for(int i=0; i<N_nbrs; i++)
                    data[i] = nbrs_vec[i];

                PyObject** nbrs_data = (PyObject**)PyArray_ITER_DATA(nbrs_iter);
                PyObject* tmp = nbrs_data[0];
                nbrs_data[0] = nbrs_obj;
                Py_XDECREF(tmp);

                PyArray_ITER_NEXT(arr_iter);
                PyArray_ITER_NEXT(nbrs_iter);
            }
        }
    }

  // Case 2 : return number of neighbors for each point
    else{
    //create an array to keep track of the count
        nbrs = (PyObject*)PyArray_SimpleNew(nd-1,PyArray_DIMS(arr),
                                            PyArray_LONG);
        if(nbrs==NULL){
            goto fail;
        }

    //create iterators to cycle through points
        --nd;
        arr_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(arr,&nd);
        nbrs_iter = (PyArrayIterObject*)PyArray_IterNew(nbrs);
        ++nd;

        if( arr_iter==NULL || nbrs_iter==NULL ||
            (arr_iter->size != nbrs_iter->size)){
            PyErr_SetString(PyExc_ValueError,
                "unable to construct iterator");
            goto fail;
        }

    //go through points and call BallTree::query_ball to count neighbors
        pt_inc = PyArray_STRIDES(arr)[nd-1] / PyArray_DESCR(arr)->elsize;
        while(arr_iter->index < arr_iter->size){
            BallTree_Point pt(arr,
                (double*)PyArray_ITER_DATA(arr_iter),
                pt_inc,pt_size);

            long int* nbrs_count = (long int*)PyArray_ITER_DATA(nbrs_iter);
            *nbrs_count = self->tree->query_ball(pt,r);

            PyArray_ITER_NEXT(arr_iter);
            PyArray_ITER_NEXT(nbrs_iter);
        }
    }
    Py_DECREF(nbrs_iter);
    Py_DECREF(arr_iter);
    Py_DECREF(arr);
    return nbrs;

    fail:
    Py_XDECREF(nbrs_iter);
    Py_XDECREF(arr_iter);
    Py_XDECREF(arr);
    Py_XDECREF(nbrs);
    return NULL;
}
Beispiel #24
0
static PyObject *frputvect(PyObject *self, PyObject *args, PyObject *keywds) {
    FrFile *oFile;
    FrameH *frame;
    FrProcData *proc;
    FrAdcData *adc;
    FrSimData *sim;
    FrVect *vect;
    int verbose=0, nData, nBits, type, subType, arrayType;
    double dx, sampleRate, start;
    char blank[] = "";
    char *filename=NULL, *history=NULL;
    char channel[MAX_STR_LEN], x_unit[MAX_STR_LEN], y_unit[MAX_STR_LEN], kind[MAX_STR_LEN];
    PyObject *temp;
    char msg[MAX_STR_LEN];

    PyObject *channellist, *channellist_iter, *framedict, *array;
    PyArrayIterObject *arrayIter;
    PyArray_Descr *temp_descr;

    static char *kwlist[] = {"filename", "channellist", "history", "verbose",
                             NULL};

    /*--------------- unpack arguments --------------------*/
    verbose = 0;

    /* The | in the format string indicates the next arguments are
       optional.  They are simply not assigned anything. */
    if (!PyArg_ParseTupleAndKeywords(args, keywds, "sO|si", kwlist,
        &filename, &channellist, &history, &verbose)) {
        Py_RETURN_NONE;
    }

    FrLibSetLvl(verbose);

    if (history == NULL) {
        history = blank;
    }

    /*-------- create frames, create vectors, and fill them. ------*/

    // Channel-list must be any type of sequence
    if (!PySequence_Check(channellist)) {
        PyErr_SetNone(PyExc_TypeError);
        return NULL;
    }

    // Get channel name from first dictionary
    framedict = PySequence_GetItem(channellist, (Py_ssize_t)0);
    if (framedict == NULL) {
        PyErr_SetString(PyExc_ValueError, "channellist is empty!");
        return NULL;
    }

    PyDict_ExtractString(channel, framedict, "name");
    Py_XDECREF(framedict);
    if (PyErr_Occurred()) {return NULL;}

    if (verbose > 0) {
        printf("Creating frame %s...\n", channel);
    }

    frame = FrameNew(channel);
    if (frame == NULL) {
        snprintf(msg, MAX_STR_LEN, "FrameNew failed (%s)", FrErrorGetHistory());
        PyErr_SetString(PyExc_FrError, msg);
        return NULL;
    }

    if (verbose > 0) {
        printf("Now iterating...\n");
    }

    // Iterators allow one to deal with non-contiguous arrays
    channellist_iter = PyObject_GetIter(channellist);
    arrayIter = NULL;
    while ((framedict = PyIter_Next(channellist_iter))) {
        if (verbose > 0) {
            printf("In loop...\n");
        }

        // Extract quantities from dict -- all borrowed references
        PyDict_ExtractString(channel, framedict, "name");
        CHECK_ERROR;

        start = PyDict_ExtractDouble(framedict, "start");
        CHECK_ERROR;

        dx = PyDict_ExtractDouble(framedict, "dx");
        CHECK_ERROR;

        array = PyDict_GetItemString(framedict, "data");
        if (!PyArray_Check(array)) {
            snprintf(msg, MAX_STR_LEN, "data is not an array");
            PyErr_SetString(PyExc_TypeError, msg);
        }
        CHECK_ERROR;

        nData = PyArray_SIZE(array);
        nBits = PyArray_ITEMSIZE(array)*8;
        arrayType = PyArray_TYPE(array);

        // kind, x_unit, y_unit, type, and subType have default values
        temp = PyDict_GetItemString(framedict, "kind");
        if (temp != NULL) {strncpy(kind, PyString_AsString(temp), MAX_STR_LEN);}
        else {snprintf(kind, MAX_STR_LEN, "PROC");}

        temp = PyDict_GetItemString(framedict, "x_unit");
        if (temp != NULL) {strncpy(x_unit, PyString_AsString(temp), MAX_STR_LEN);}
        else {strncpy(x_unit, blank, MAX_STR_LEN);}

        temp = PyDict_GetItemString(framedict, "y_unit");
        if (temp != NULL) {strncpy(y_unit, PyString_AsString(temp), MAX_STR_LEN);}
        else {strncpy(y_unit, blank, MAX_STR_LEN);}

        temp = PyDict_GetItemString(framedict, "type");
        if (temp != NULL) {type = (int)PyInt_AsLong(temp);}
        else {type = 1;}

        temp = PyDict_GetItemString(framedict, "subType");
        if (temp != NULL) {subType = (int)PyInt_AsLong(temp);}
        else {subType = 0;}

        // check for errors
        CHECK_ERROR;
        if (dx <= 0 || array == NULL || nData==0) {
            temp = PyObject_Str(framedict);
            snprintf(msg, MAX_STR_LEN, "Input dictionary contents: %s", PyString_AsString(temp));
            Py_XDECREF(temp);
            FrameFree(frame);
            Py_XDECREF(framedict);
            Py_XDECREF(channellist_iter);
            PyErr_SetString(PyExc_ValueError, msg);
            return NULL;
        }


        if (verbose > 0) {
            printf("type = %d, subType = %d, start = %f, dx = %f\n",
                type, subType, start, dx);
        }

        sampleRate = 1./dx;

        if (verbose > 0) {
            printf("Now copying data to vector...\n");
        }

        // Create empty vector (-typecode ==> empty) with metadata,
        // then copy data to vector
        vect = NULL;
        arrayIter = (PyArrayIterObject *)PyArray_IterNew(array);
        if(arrayType == NPY_INT16) {
            vect = FrVectNew1D(channel,-FR_VECT_2S,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataS[arrayIter->index] = *((npy_int16 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        else if(arrayType == NPY_INT32) {
            vect = FrVectNew1D(channel,-FR_VECT_4S,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataI[arrayIter->index] = *((npy_int32 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        else if(arrayType == NPY_INT64) {
            vect = FrVectNew1D(channel,-FR_VECT_8S,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataL[arrayIter->index] = *((npy_int64 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        else if(arrayType == NPY_UINT8) {
            vect = FrVectNew1D(channel,-FR_VECT_1U,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataU[arrayIter->index] = *((npy_uint8 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        else if(arrayType == NPY_UINT16) {
            vect = FrVectNew1D(channel,-FR_VECT_2U,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataUS[arrayIter->index] = *((npy_uint16 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        else if(arrayType == NPY_UINT32) {
            vect = FrVectNew1D(channel,-FR_VECT_4U,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataUI[arrayIter->index] = *((npy_uint32 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        else if(arrayType == NPY_UINT64) {
            vect = FrVectNew1D(channel,-FR_VECT_8U,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataUL[arrayIter->index] = *((npy_uint64 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        else if(arrayType == NPY_FLOAT32) {
            vect = FrVectNew1D(channel,-FR_VECT_4R,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataF[arrayIter->index] = *((npy_float32 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        else if(arrayType == NPY_FLOAT64) {
            vect = FrVectNew1D(channel,-FR_VECT_8R,nData,dx,x_unit,y_unit);
            while (arrayIter->index < arrayIter->size) {
                vect->dataD[arrayIter->index] = *((npy_float64 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}}
        /* FrVects don't have complex pointers.  Numpy stores complex
           numbers in the same way, but we have to trick it into giving
           us a (real) float pointer. */
        else if(arrayType == NPY_COMPLEX64) {
            vect = FrVectNew1D(channel,-FR_VECT_8C,nData,dx,x_unit,y_unit);
            temp_descr = PyArray_DescrFromType(NPY_FLOAT32);
            temp = PyArray_View((PyArrayObject *)array, temp_descr, NULL);
            Py_XDECREF(temp_descr);
            Py_XDECREF(arrayIter);
            arrayIter = (PyArrayIterObject *)PyArray_IterNew(temp);
            while (arrayIter->index < arrayIter->size) {
                vect->dataF[arrayIter->index] = *((npy_float32 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}
            Py_XDECREF(temp);}
        else if(arrayType == NPY_COMPLEX128) {
            vect = FrVectNew1D(channel,-FR_VECT_16C,nData,dx,x_unit,y_unit);
            temp_descr = PyArray_DescrFromType(NPY_FLOAT64);
            temp = PyArray_View((PyArrayObject *)array, temp_descr, NULL);
            Py_XDECREF(temp_descr);
            Py_XDECREF(arrayIter);
            arrayIter = (PyArrayIterObject *)PyArray_IterNew(temp);
            while (arrayIter->index < arrayIter->size) {
                vect->dataD[arrayIter->index] = *((npy_float64 *)arrayIter->dataptr);
                PyArray_ITER_NEXT(arrayIter);}
            Py_XDECREF(temp);}
        else PyErr_SetString(PyExc_TypeError, msg);

        if (PyErr_Occurred()) {
            if (vect != NULL) FrVectFree(vect);
            FrameFree(frame);
            Py_XDECREF(framedict);
            Py_XDECREF(channellist_iter);
            Py_XDECREF(arrayIter);
            return NULL;
        }

        if (verbose > 0) {
            printf("Done copying...\n");
            FrameDump(frame, stdout, 6);
        }

        // Add Fr*Data to frame and attach vector to Fr*Data
        if (strncmp(kind, "PROC", MAX_STR_LEN)==0) {
            proc = FrProcDataNew(frame, channel, sampleRate, 1, nBits);
            FrVectFree(proc->data);
            proc->data = vect;
            proc->type = type;
            proc->subType = subType;
            frame->GTimeS = (npy_uint32)start;
            frame->GTimeN = (npy_uint32)((start-(frame->GTimeS))*1e9);
            if (type==1) {  // time series
                proc->tRange = nData*dx;
                frame->dt = nData*dx;
            } else if (type==2) {  // frequency series
                proc->fRange = nData*dx;
            }
        } else if (strncmp(kind, "ADC", MAX_STR_LEN)==0) {
            adc = FrAdcDataNew(frame, channel, sampleRate, 1, nBits);
            FrVectFree(adc->data);
            adc->data = vect;
            frame->dt = nData*dx;
            frame->GTimeS = (npy_uint32)start;
            frame->GTimeN = (npy_uint32)((start-(frame->GTimeS))*1e9);
        } else {// Already tested that kind is one of these strings above
            sim = FrSimDataNew(frame, channel, sampleRate, 1, nBits);
            FrVectFree(sim->data);
            sim->data = vect;
            frame->dt = nData*dx;
            frame->GTimeS = (npy_uint32)start;
            frame->GTimeN = (npy_uint32)((start-(frame->GTimeS))*1e9);
        }

        if (verbose > 0) {
            printf("Attached vect to frame.\n");
        }

        // Clean up (all python objects in loop should be borrowed references)
        Py_XDECREF(framedict);
        Py_XDECREF(arrayIter);
    } // end iteration over channellist

    Py_XDECREF(channellist_iter);
    // At this point, there should be no Python references left!

    /*------------- Write file -----------------------------*/
    oFile = FrFileONewH(filename, 1, history); // 1 ==> gzip contents

    if (oFile == NULL) {
        snprintf(msg, MAX_STR_LEN, "%s\n", FrErrorGetHistory());
        PyErr_SetString(PyExc_FrError, msg);
        FrFileOEnd(oFile);
        return NULL;
    }
    if (FrameWrite(frame, oFile) != FR_OK) {
        snprintf(msg, MAX_STR_LEN, "%s\n", FrErrorGetHistory());
        PyErr_SetString(PyExc_FrError, msg);
        FrFileOEnd(oFile);
        return NULL;
    }

    /* The FrFile owns data and vector memory. Do not free them separately. */
    FrFileOEnd(oFile);
    FrameFree(frame);
    Py_RETURN_NONE;
};