File: to_py_numpy.hpp

package info (click to toggle)
pytango 10.0.2-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 10,216 kB
  • sloc: python: 28,206; cpp: 16,380; sql: 255; sh: 82; makefile: 43
file content (158 lines) | stat: -rw-r--r-- 4,905 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * SPDX-FileCopyrightText: All Contributors to the PyTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#pragma once

#include "tango_numpy.h"

/// @name Array extraction
/// @{

template <long tangoArrayTypeConst>
inline bopy::object to_py_numpy(const typename TANGO_const2type(tangoArrayTypeConst) * tg_array, bopy::object parent)
{
    static const int typenum = TANGO_const2scalarnumpy(tangoArrayTypeConst);

    if(tg_array == 0)
    {
        // Empty
        PyObject *value = PyArray_SimpleNew(0, 0, typenum);
        if(!value)
        {
            bopy::throw_error_already_set();
        }
        return bopy::object(bopy::handle<>(value));
    }

    // Create a new numpy.ndarray() object. It uses ch_ptr as the data,
    // so no costy memory copies when handling big images.
    const void *ch_ptr = reinterpret_cast<const void *>(tg_array->get_buffer());
    int nd = 1;
    npy_intp dims[1];
    dims[0] = tg_array->length();
    PyObject *py_array = PyArray_SimpleNewFromData(nd, dims, typenum, const_cast<void *>(ch_ptr));
    if(!py_array)
    {
        bopy::throw_error_already_set();
    }

    // numpy.ndarray() does not own it's memory, so we need to manage it.
    // We can assign a 'parent' object that will be informed (decref'd)
    // when the last copy of numpy.ndarray() disappears. That should
    // actually destroy the memory in its destructor
    PyObject *guard = parent.ptr();
    Py_INCREF(guard);

    PyArray_SetBaseObject(to_PyArrayObject(py_array), guard);

    return bopy::object(bopy::handle<>(py_array));
}

template <>
inline bopy::object to_py_numpy<Tango::DEVVAR_STRINGARRAY>(const Tango::DevVarStringArray *tg_array,
                                                           bopy::object parent)
{
    return to_py_list(tg_array);
}

template <>
inline bopy::object to_py_numpy<Tango::DEVVAR_STATEARRAY>(const Tango::DevVarStateArray *tg_array, bopy::object parent)
{
    return to_py_list(tg_array);
}

template <>
inline bopy::object to_py_numpy<Tango::DEVVAR_LONGSTRINGARRAY>(const Tango::DevVarLongStringArray *tg_array,
                                                               bopy::object parent)
{
    bopy::list result;

    result.append(to_py_numpy<Tango::DEVVAR_LONGARRAY>(&tg_array->lvalue, parent));
    result.append(to_py_numpy<Tango::DEVVAR_STRINGARRAY>(&tg_array->svalue, parent));

    return result;
}

template <>
inline bopy::object to_py_numpy<Tango::DEVVAR_DOUBLESTRINGARRAY>(const Tango::DevVarDoubleStringArray *tg_array,
                                                                 bopy::object parent)
{
    bopy::list result;

    result.append(to_py_numpy<Tango::DEVVAR_DOUBLEARRAY>(&tg_array->dvalue, parent));
    result.append(to_py_numpy<Tango::DEVVAR_STRINGARRAY>(&tg_array->svalue, parent));

    return result;
}

/// @}
// ~Array Extraction
// -----------------------------------------------------------------------

template <long tangoArrayTypeConst>
inline bopy::object to_py_numpy(typename TANGO_const2type(tangoArrayTypeConst) * tg_array, int orphan)
{
    static const int typenum = TANGO_const2scalarnumpy(tangoArrayTypeConst);

    if(tg_array == 0)
    {
        // Empty
        PyObject *value = PyArray_SimpleNew(0, 0, typenum);
        if(!value)
        {
            bopy::throw_error_already_set();
        }
        return bopy::object(bopy::handle<>(value));
    }

    // Create a new numpy.ndarray() object. It uses ch_ptr as the data,
    // so no costy memory copies when handling big images.
    int nd = 1;
    npy_intp dims[1];
    dims[0] = tg_array->length();
    void *ch_ptr = (void *) (tg_array->get_buffer(orphan));
    PyObject *py_array = PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, ch_ptr, -1, 0, NULL);
    if(!py_array)
    {
        bopy::throw_error_already_set();
    }

    return bopy::object(bopy::handle<>(py_array));
}

template <>
inline bopy::object to_py_numpy<Tango::DEVVAR_STRINGARRAY>(Tango::DevVarStringArray *tg_array, int orphan)
{
    return to_py_list(tg_array);
}

template <>
inline bopy::object to_py_numpy<Tango::DEVVAR_STATEARRAY>(Tango::DevVarStateArray *tg_array, int orphan)
{
    return to_py_list(tg_array);
}

template <>
inline bopy::object to_py_numpy<Tango::DEVVAR_LONGSTRINGARRAY>(Tango::DevVarLongStringArray *tg_array, int orphan)
{
    bopy::list result;

    result.append(to_py_numpy<Tango::DEVVAR_LONGARRAY>(&tg_array->lvalue, orphan));
    result.append(to_py_numpy<Tango::DEVVAR_STRINGARRAY>(&tg_array->svalue, orphan));

    return result;
}

template <>
inline bopy::object to_py_numpy<Tango::DEVVAR_DOUBLESTRINGARRAY>(Tango::DevVarDoubleStringArray *tg_array, int orphan)
{
    bopy::list result;

    result.append(to_py_numpy<Tango::DEVVAR_DOUBLEARRAY>(&tg_array->dvalue, orphan));
    result.append(to_py_numpy<Tango::DEVVAR_STRINGARRAY>(&tg_array->svalue, orphan));

    return result;
}