Пример #1
0
static PyObject* write_coords(PyObject* self, PyObject* args)
{
    oskar_MeasurementSet* h = 0;
    PyObject *capsule = 0;
    PyObject *obj[] = {0, 0, 0};
    PyArrayObject *uu = 0, *vv = 0, *ww = 0;
    int start_row = 0, num_baselines = 0;
    double exposure_sec = 0.0, interval_sec = 0.0, time_stamp = 0.0;
    if (!PyArg_ParseTuple(args, "OiiOOOddd", &capsule,
            &start_row, &num_baselines, &obj[0], &obj[1], &obj[2],
            &exposure_sec, &interval_sec, &time_stamp))
        return 0;
    if (!(h = (oskar_MeasurementSet*) get_handle(capsule, name))) return 0;

    /* Make sure input objects are arrays. Convert if required. */
    uu = (PyArrayObject*) PyArray_FROM_OF(obj[0], NPY_ARRAY_IN_ARRAY);
    vv = (PyArrayObject*) PyArray_FROM_OF(obj[1], NPY_ARRAY_IN_ARRAY);
    ww = (PyArrayObject*) PyArray_FROM_OF(obj[2], NPY_ARRAY_IN_ARRAY);
    if (!uu || !vv || !ww)
        goto fail;

    /* Check dimensions. */
    if (num_baselines != (int) PyArray_SIZE(uu) ||
            num_baselines != (int) PyArray_SIZE(vv) ||
            num_baselines != (int) PyArray_SIZE(ww))
    {
        PyErr_SetString(PyExc_RuntimeError, "Input data dimension mismatch.");
        goto fail;
    }

    /* Write the coordinates. */
    Py_BEGIN_ALLOW_THREADS
    if (PyArray_TYPE(uu) == NPY_DOUBLE)
        oskar_ms_write_coords_d(h, start_row, num_baselines,
                (const double*)PyArray_DATA(uu),
                (const double*)PyArray_DATA(vv),
                (const double*)PyArray_DATA(ww),
                exposure_sec, interval_sec, time_stamp);
    else
        oskar_ms_write_coords_f(h, start_row, num_baselines,
                (const float*)PyArray_DATA(uu),
                (const float*)PyArray_DATA(vv),
                (const float*)PyArray_DATA(ww),
                exposure_sec, interval_sec, time_stamp);
    Py_END_ALLOW_THREADS

    Py_XDECREF(uu);
    Py_XDECREF(vv);
    Py_XDECREF(ww);
    return Py_BuildValue("");

fail:
    Py_XDECREF(uu);
    Py_XDECREF(vv);
    Py_XDECREF(ww);
    return 0;
}
Пример #2
0
static PyObject* write_vis(PyObject* self, PyObject* args)
{
    oskar_MeasurementSet* h = 0;
    PyObject *capsule = 0;
    PyObject *obj = 0;
    PyArrayObject *vis = 0;
    int start_row = 0, start_channel = 0;
    int num_channels = 0, num_baselines = 0, num_pols = 0;
    if (!PyArg_ParseTuple(args, "OiiiiO", &capsule, &start_row,
            &start_channel, &num_channels, &num_baselines, &obj))
        return 0;
    if (!(h = get_handle(capsule))) return 0;

    /* Make sure input objects are arrays. Convert if required. */
    vis = (PyArrayObject*) PyArray_FROM_OF(obj, NPY_ARRAY_IN_ARRAY);
    if (!vis)
        goto fail;

    /* Get precision of complex visibility data. */
    if (!PyArray_ISCOMPLEX(vis))
    {
        PyErr_SetString(PyExc_RuntimeError,
                "Input visibility data must be complex.");
        goto fail;
    }

    /* Check dimensions. */
    num_pols = oskar_ms_num_pols(h);
    if (num_baselines * num_channels * num_pols != (int) PyArray_SIZE(vis))
    {
        PyErr_SetString(PyExc_RuntimeError, "Input data dimension mismatch.");
        goto fail;
    }

    /* Allow threads. */
    Py_BEGIN_ALLOW_THREADS

    /* Write the visibilities. */
    if (PyArray_TYPE(vis) == NPY_DOUBLE)
        oskar_ms_write_vis_d(h, start_row, start_channel, num_channels,
                num_baselines, (const double*)PyArray_DATA(vis));
    else
        oskar_ms_write_vis_f(h, start_row, start_channel, num_channels,
                num_baselines, (const float*)PyArray_DATA(vis));

    /* Disallow threads. */
    Py_END_ALLOW_THREADS

    Py_XDECREF(vis);
    return Py_BuildValue("");

fail:
    Py_XDECREF(vis);
    return 0;
}
Пример #3
0
/*NUMPY_API
 *
 * Useful to pass as converter function for O& processing in PyArgs_ParseTuple.
 *
 * This conversion function can be used with the "O&" argument for
 * PyArg_ParseTuple.  It will immediately return an object of array type
 * or will convert to a NPY_ARRAY_CARRAY any other object.
 *
 * If you use PyArray_Converter, you must DECREF the array when finished
 * as you get a new reference to it.
 */
NPY_NO_EXPORT int
PyArray_Converter(PyObject *object, PyObject **address)
{
    if (PyArray_Check(object)) {
        *address = object;
        Py_INCREF(object);
        return NPY_SUCCEED;
    }
    else {
        *address = PyArray_FROM_OF(object, NPY_ARRAY_CARRAY);
        if (*address == NULL) {
            return NPY_FAIL;
        }
        return NPY_SUCCEED;
    }
}
Пример #4
0
static size_t wrap_send(uhd::tx_streamer *tx_stream,
                        bp::object &np_array,
                        bp::object &metadata,
                        const double timeout = 0.1)
{
    // Extract the metadata
    bp::extract<uhd::tx_metadata_t&> get_metadata(metadata);
    // TODO: throw an error here?
    if (not get_metadata.check())
    {
        return 0;
    }

    // Get a numpy array object from given python object
    // No sanity checking possible!
    // Note: this increases the ref count, which we'll need to manually decrease at the end
    PyObject* array_obj = PyArray_FROM_OF(np_array.ptr(),NPY_ARRAY_CARRAY);
    PyArrayObject* array_type_obj = reinterpret_cast<PyArrayObject*>(array_obj);

    // Get dimensions of the numpy array
    const size_t dims = PyArray_NDIM(array_type_obj);
    const npy_intp* shape = PyArray_SHAPE(array_type_obj);

    // How many bytes to jump to get to the next element of the stride
    // (next row)
    const npy_intp* strides = PyArray_STRIDES(array_type_obj);
    const size_t channels = tx_stream->get_num_channels();

    // Check if numpy array sizes are ok
    if (((channels > 1) && (dims != 2))
     or ((size_t) shape[0] < channels))
    {
        // Manually decrement the ref count
        Py_DECREF(array_obj);
        // If we don't have a 2D NumPy array, assume we have a 1D array
        size_t input_channels = (dims != 2) ? 1 : shape[0];
        throw uhd::runtime_error(str(boost::format(
            "Number of TX channels (%d) does not match the dimensions of the data array (%d)")
            % channels % input_channels));
    }

    // Get a pointer to the storage
    std::vector<void*> channel_storage;
    char* data = PyArray_BYTES(array_type_obj);
    for (size_t i = 0; i < channels; ++i)
    {
        channel_storage.push_back((void*)(data + i * strides[0]));
    }

    // Get data buffer and size of the array
    size_t nsamps_per_buff = (dims > 1) ? (size_t) shape[1] : PyArray_SIZE(array_type_obj);

    // Release the GIL only for the send() call
    const size_t result = [&]() {
        scoped_gil_release gil_release;
        // Call the real send()
        return tx_stream->send(
            channel_storage,
            nsamps_per_buff,
            get_metadata(),
            timeout
        );
    }();

    // Manually decrement the ref count
    Py_DECREF(array_obj);
    return result;
}
Пример #5
0
/*
 * Returns input array with values inserted sequentially into places
 * indicated by the mask
 */
NPY_NO_EXPORT PyObject *
arr_insert(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict)
{
    PyObject *mask = NULL, *vals = NULL;
    PyArrayObject *ainput = NULL, *amask = NULL, *avals = NULL, *tmp = NULL;
    int numvals, totmask, sameshape;
    char *input_data, *mptr, *vptr, *zero = NULL;
    int melsize, delsize, nd, objarray, k;
    npy_intp *instrides, *inshape;

    static char *kwlist[] = {"input", "mask", "vals", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O&OO", kwlist,
                PyArray_Converter, &ainput,
                &mask, &vals)) {
        goto fail;
    }

    amask = (PyArrayObject *)PyArray_FROM_OF(mask, NPY_ARRAY_CARRAY);
    if (amask == NULL) {
        goto fail;
    }
    /* Cast an object array */
    if (PyArray_DESCR(amask)->type_num == NPY_OBJECT) {
        tmp = (PyArrayObject *)PyArray_Cast(amask, NPY_INTP);
        if (tmp == NULL) {
            goto fail;
        }
        Py_DECREF(amask);
        amask = tmp;
    }

    sameshape = 1;
    if (PyArray_NDIM(amask) == PyArray_NDIM(ainput)) {
        for (k = 0; k < PyArray_NDIM(amask); k++) {
            if (PyArray_DIMS(amask)[k] != PyArray_DIMS(ainput)[k]) {
                sameshape = 0;
            }
        }
    }
    else {
        /* Test to see if amask is 1d */
        if (PyArray_NDIM(amask) != 1) {
            sameshape = 0;
        }
        else if ((PyArray_SIZE(ainput)) != PyArray_SIZE(amask)) {
            sameshape = 0;
        }
    }
    if (!sameshape) {
        PyErr_SetString(PyExc_TypeError,
                        "mask array must be 1-d or same shape as input array");
        goto fail;
    }

    avals = (PyArrayObject *)PyArray_FromObject(vals,
                                        PyArray_DESCR(ainput)->type_num, 0, 1);
    if (avals == NULL) {
        goto fail;
    }
    numvals = PyArray_SIZE(avals);
    nd = PyArray_NDIM(ainput);
    input_data = PyArray_DATA(ainput);
    mptr = PyArray_DATA(amask);
    melsize = PyArray_DESCR(amask)->elsize;
    vptr = PyArray_DATA(avals);
    delsize = PyArray_DESCR(avals)->elsize;
    zero = PyArray_Zero(amask);
    if (zero == NULL) {
        goto fail;
    }
    objarray = (PyArray_DESCR(ainput)->type_num == NPY_OBJECT);

    if (!numvals) {
        /* nothing to insert! fail unless none of mask is true */
        const char *iter = mptr;
        const char *const last = iter + PyArray_NBYTES(amask);
        while (iter != last && !memcmp(iter, zero, melsize)) {
            iter += melsize;
        }
        if (iter != last) {
            PyErr_SetString(PyExc_ValueError,
                    "Cannot insert from an empty array!");
            goto fail;
        }
        goto finish;
    }

    /* Handle zero-dimensional case separately */
    if (nd == 0) {
        if (memcmp(mptr,zero,melsize) != 0) {
            /* Copy value element over to input array */
            memcpy(input_data,vptr,delsize);
            if (objarray) {
                Py_INCREF(*((PyObject **)vptr));
            }
        }
        Py_DECREF(amask);
        Py_DECREF(avals);
        PyDataMem_FREE(zero);
        Py_DECREF(ainput);
        Py_RETURN_NONE;
    }

    totmask = (int) PyArray_SIZE(amask);
    instrides = PyArray_STRIDES(ainput);
    inshape = PyArray_DIMS(ainput);
    if (objarray) {
        /* object array, need to refcount, can't release the GIL */
        arr_insert_loop(mptr, vptr, input_data, zero, PyArray_DATA(avals),
                        melsize, delsize, objarray, totmask, numvals, nd,
                        instrides, inshape);
    }
    else {
        /* No increfs take place in arr_insert_loop, so release the GIL */
        NPY_BEGIN_ALLOW_THREADS;
        arr_insert_loop(mptr, vptr, input_data, zero, PyArray_DATA(avals),
                        melsize, delsize, objarray, totmask, numvals, nd,
                        instrides, inshape);
        NPY_END_ALLOW_THREADS;
    }

finish:
    Py_DECREF(amask);
    Py_DECREF(avals);
    PyDataMem_FREE(zero);
    Py_DECREF(ainput);
    Py_RETURN_NONE;

fail:
    PyDataMem_FREE(zero);
    Py_XDECREF(ainput);
    Py_XDECREF(amask);
    Py_XDECREF(avals);
    return NULL;
}