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; }
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; }
/* 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); }
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; }
/* 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; }
/* 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; }
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; }
//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; }
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; }
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; }
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; } }
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; }
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; }
//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; }
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; }
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; }
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; }
//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; }
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; };