/** * Returns a V3D object from the Python object given * to the converter * @returns A newly constructed V3D object converted * from the PyObject. */ Kernel::Matrix<double> PyObjectToMatrix::operator()() { if (m_alreadyMatrix) { return extract<Kernel::Matrix<double>>(m_obj)(); } PyArrayObject *ndarray = (PyArrayObject *)PyArray_View( (PyArrayObject *)m_obj.ptr(), PyArray_DescrFromType(NPY_DOUBLE), &PyArray_Type); const auto shape = PyArray_DIMS(ndarray); npy_intp nx(shape[0]), ny(shape[1]); Kernel::Matrix<double> matrix(nx, ny); for (npy_intp i = 0; i < nx; i++) { auto row = matrix[i]; for (npy_intp j = 0; j < ny; j++) { row[j] = *((double *)PyArray_GETPTR2(ndarray, i, j)); } } return matrix; }
/* * This function initializes a result array for a reduction operation * which has no identity. This means it needs to copy the first element * it sees along the reduction axes to result, then return a view of * the operand which excludes that element. * * If a reduction has an identity, such as 0 or 1, the result should be * initialized by calling PyArray_AssignZero(result, NULL, NULL) or * PyArray_AssignOne(result, NULL, NULL), because this function raises an * exception when there are no elements to reduce (which appropriate iff the * reduction operation has no identity). * * This means it copies the subarray indexed at zero along each reduction axis * into 'result', then returns a view into 'operand' excluding those copied * elements. * * result : The array into which the result is computed. This must have * the same number of dimensions as 'operand', but for each * axis i where 'axis_flags[i]' is True, it has a single element. * operand : The array being reduced. * axis_flags : An array of boolean flags, one for each axis of 'operand'. * When a flag is True, it indicates to reduce along that axis. * reorderable : If True, the reduction being done is reorderable, which * means specifying multiple axes of reduction at once is ok, * and the reduction code may calculate the reduction in an * arbitrary order. The calculation may be reordered because * of cache behavior or multithreading requirements. * out_skip_first_count : This gets populated with the number of first-visit * elements that should be skipped during the * iteration loop. * funcname : The name of the reduction operation, for the purpose of * better quality error messages. For example, "numpy.max" * would be a good name for NumPy's max function. * * Returns a view which contains the remaining elements on which to do * the reduction. */ NPY_NO_EXPORT PyArrayObject * PyArray_InitializeReduceResult( PyArrayObject *result, PyArrayObject *operand, npy_bool *axis_flags, int reorderable, npy_intp *out_skip_first_count, const char *funcname) { npy_intp *strides, *shape, shape_orig[NPY_MAXDIMS]; PyArrayObject *op_view = NULL; int idim, ndim, nreduce_axes; ndim = PyArray_NDIM(operand); /* Default to no skipping first-visit elements in the iteration */ *out_skip_first_count = 0; /* * If this reduction is non-reorderable, make sure there are * only 0 or 1 axes in axis_flags. */ if (!reorderable && check_nonreorderable_axes(ndim, axis_flags, funcname) < 0) { return NULL; } /* Take a view into 'operand' which we can modify. */ op_view = (PyArrayObject *)PyArray_View(operand, NULL, &PyArray_Type); if (op_view == NULL) { return NULL; } /* * Now copy the subarray of the first element along each reduction axis, * then return a view to the rest. * * Adjust the shape to only look at the first element along * any of the reduction axes. We count the number of reduction axes * at the same time. */ shape = PyArray_SHAPE(op_view); nreduce_axes = 0; memcpy(shape_orig, shape, ndim * sizeof(npy_intp)); for (idim = 0; idim < ndim; ++idim) { if (axis_flags[idim]) { if (shape[idim] == 0) { PyErr_Format(PyExc_ValueError, "zero-size array to reduction operation %s " "which has no identity", funcname); Py_DECREF(op_view); return NULL; } shape[idim] = 1; ++nreduce_axes; } } /* * Copy the elements into the result to start. */ if (PyArray_CopyInto(result, op_view) < 0) { Py_DECREF(op_view); return NULL; } /* * If there is one reduction axis, adjust the view's * shape to only look at the remaining elements */ if (nreduce_axes == 1) { strides = PyArray_STRIDES(op_view); for (idim = 0; idim < ndim; ++idim) { if (axis_flags[idim]) { shape[idim] = shape_orig[idim] - 1; ((PyArrayObject_fields *)op_view)->data += strides[idim]; } } } /* If there are zero reduction axes, make the view empty */ else if (nreduce_axes == 0) { for (idim = 0; idim < ndim; ++idim) { shape[idim] = 0; } } /* * Otherwise iterate over the whole operand, but tell the inner loop * to skip the elements we already copied by setting the skip_first_count. */ else { *out_skip_first_count = PyArray_SIZE(result); Py_DECREF(op_view); Py_INCREF(operand); op_view = operand; } return op_view; }
NPY_NO_EXPORT PyObject * __New_PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject *out, int variance, int num) { PyObject *obj1 = NULL, *obj2 = NULL, *obj3 = NULL; PyArrayObject *arr1 = NULL, *arr2 = NULL, *arrnew = NULL; PyObject *ret = NULL, *newshape = NULL; int i, n; npy_intp val; arrnew = (PyArrayObject *)PyArray_CheckAxis(self, &axis, 0); if (arrnew == NULL) { return NULL; } /* Compute and reshape mean */ arr1 = (PyArrayObject *)PyArray_EnsureAnyArray( PyArray_Mean(arrnew, axis, rtype, NULL)); if (arr1 == NULL) { Py_DECREF(arrnew); return NULL; } n = PyArray_NDIM(arrnew); newshape = PyTuple_New(n); if (newshape == NULL) { Py_DECREF(arr1); Py_DECREF(arrnew); return NULL; } for (i = 0; i < n; i++) { if (i == axis) { val = 1; } else { val = PyArray_DIM(arrnew,i); } PyTuple_SET_ITEM(newshape, i, PyInt_FromLong((long)val)); } arr2 = (PyArrayObject *)PyArray_Reshape(arr1, newshape); Py_DECREF(arr1); Py_DECREF(newshape); if (arr2 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute x = x - mx */ arr1 = (PyArrayObject *)PyArray_EnsureAnyArray( PyNumber_Subtract((PyObject *)arrnew, (PyObject *)arr2)); Py_DECREF(arr2); if (arr1 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute x * x */ if (PyArray_ISCOMPLEX(arr1)) { obj3 = PyArray_Conjugate(arr1, NULL); } else { obj3 = (PyObject *)arr1; Py_INCREF(arr1); } if (obj3 == NULL) { Py_DECREF(arrnew); return NULL; } arr2 = (PyArrayObject *)PyArray_EnsureAnyArray( PyArray_GenericBinaryFunction(arr1, obj3, n_ops.multiply)); Py_DECREF(arr1); Py_DECREF(obj3); if (arr2 == NULL) { Py_DECREF(arrnew); return NULL; } if (PyArray_ISCOMPLEX(arr2)) { obj3 = PyObject_GetAttrString((PyObject *)arr2, "real"); switch(rtype) { case NPY_CDOUBLE: rtype = NPY_DOUBLE; break; case NPY_CFLOAT: rtype = NPY_FLOAT; break; case NPY_CLONGDOUBLE: rtype = NPY_LONGDOUBLE; break; } } else { obj3 = (PyObject *)arr2; Py_INCREF(arr2); } if (obj3 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute add.reduce(x*x,axis) */ obj1 = PyArray_GenericReduceFunction((PyArrayObject *)obj3, n_ops.add, axis, rtype, NULL); Py_DECREF(obj3); Py_DECREF(arr2); if (obj1 == NULL) { Py_DECREF(arrnew); return NULL; } n = PyArray_DIM(arrnew,axis); Py_DECREF(arrnew); n = (n-num); if (n == 0) { n = 1; } obj2 = PyFloat_FromDouble(1.0/((double )n)); if (obj2 == NULL) { Py_DECREF(obj1); return NULL; } ret = PyNumber_Multiply(obj1, obj2); Py_DECREF(obj1); Py_DECREF(obj2); if (!variance) { arr1 = (PyArrayObject *)PyArray_EnsureAnyArray(ret); /* sqrt() */ ret = PyArray_GenericUnaryFunction(arr1, n_ops.sqrt); Py_DECREF(arr1); } if (ret == NULL) { return NULL; } if (PyArray_CheckExact(self)) { goto finish; } if (PyArray_Check(self) && Py_TYPE(self) == Py_TYPE(ret)) { goto finish; } arr1 = (PyArrayObject *)PyArray_EnsureArray(ret); if (arr1 == NULL) { return NULL; } ret = PyArray_View(arr1, NULL, Py_TYPE(self)); Py_DECREF(arr1); finish: if (out) { if (PyArray_AssignArray(out, (PyArrayObject *)ret, NULL, NPY_DEFAULT_ASSIGN_CASTING) < 0) { Py_DECREF(ret); return NULL; } Py_DECREF(ret); Py_INCREF(out); return (PyObject *)out; } return ret; }
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; };