1 """Datatypes and helper functions.
2
3 @author: Stephan Wenger
4 @date: 2012-02-29
5 """
6
7 import numpy as _np
8
9 import glitter.raw as _gl
12 _nptype_db = {}
13 _gltype_db = {}
14 _db = {}
15
16 - def __init__(self, integer, signed, nptype, _gltype=None, charcode=None):
17 self._integer = bool(integer)
18 self._signed = bool(signed)
19 self._nptype = nptype
20 self._gltype = _gltype
21 self._charcode = charcode
22 self._nbytes = nptype().itemsize
23
24 Datatype._nptype_db[self._nptype] = self
25 Datatype._gltype_db[self._gltype] = self
26 Datatype._db[self._integer, self._signed, self._nbytes] = self
27
28 @classmethod
34
35 @classmethod
38
41
44
47
50
53
56
58 return not self._signed
59
62
64 return not self._integer
65
68
69 @property
72
73 @property
76
79
82
83 - def coerced(self, force_integer=False, force_unsigned=False, force_float=False, force_gl=True):
84 """Find a datatype with the specified properties.
85
86 The returned datatype will match `self` as closely as possible.
87 If `force_integer` is `True`, it will be an integer datatype.
88 If `force_unsigned` is `True`, it will be an unsigned datatype.
89 If `force_float` is `True`, it will be a floating point datatype.
90 If `force_gl` is `True`, it will have an OpenGL equivalent.
91
92 If conversion of `self` to the resulting datatype would likely result in a
93 severe loss of precision or overflows, an error may be raised.
94 """
95
96 if force_integer and not self.is_integer():
97 raise TypeError("no matching datatype")
98 if force_float and not self.is_float():
99 raise TypeError("no matching datatype")
100
101 dtype = self
102 if force_unsigned and not dtype.is_unsigned():
103 dtype = dtype.as_unsigned()
104 while force_gl and dtype._as_gl() is None:
105 dtype = dtype.as_nbytes(dtype.nbytes / 2)
106 return dtype
107
108 bool8 = Datatype(integer=True, signed=True, nptype=_np.bool8, _gltype=_gl.GL_BOOL, charcode="b")
109 uint8 = Datatype(integer=True, signed=False, nptype=_np.uint8, _gltype=_gl.GL_UNSIGNED_BYTE, charcode="ub")
110 uint16 = Datatype(integer=True, signed=False, nptype=_np.uint16, _gltype=_gl.GL_UNSIGNED_SHORT)
111 uint32 = Datatype(integer=True, signed=False, nptype=_np.uint32, _gltype=_gl.GL_UNSIGNED_INT, charcode="ui")
112 uint64 = Datatype(integer=True, signed=False, nptype=_np.uint64, charcode="ui64")
113 int8 = Datatype(integer=True, signed=True, nptype=_np.int8, _gltype=_gl.GL_BYTE)
114 int16 = Datatype(integer=True, signed=True, nptype=_np.int16, _gltype=_gl.GL_SHORT)
115 int32 = Datatype(integer=True, signed=True, nptype=_np.int32, _gltype=_gl.GL_INT, charcode="i")
116 int64 = Datatype(integer=True, signed=True, nptype=_np.int64, charcode="i64")
117 float32 = Datatype(integer=False, signed=True, nptype=_np.float32, _gltype=_gl.GL_FLOAT, charcode="f")
118 float64 = Datatype(integer=False, signed=True, nptype=_np.float64, charcode="d")
119
120 -def coerce_array(data, dtype=None, force_integer=False, force_unsigned=False, force_float=False, force_gl=True):
121 """Convert `data` to a contiguous array with the specified properties.
122
123 The datatype of the array will match `dtype` as closely as possible.
124 If `force_integer` is `True`, it will be an integer datatype.
125 If `force_unsigned` is `True`, it will be an unsigned datatype.
126 If `force_float` is `True`, it will be a floating point datatype.
127 If `force_gl` is `True`, it will have an OpenGL equivalent.
128
129 If conversion to the resulting datatype would likely result in a severe
130 loss of precision or overflows, an error may be raised.
131 """
132
133 if dtype is None:
134 if hasattr(data, "dtype"):
135 dtype = Datatype.from_numpy(data.dtype)
136 else:
137 if force_integer:
138 dtype = int32
139 else:
140 dtype = float32
141 dtype = dtype.coerced(force_integer, force_unsigned, force_float, force_gl)
142
143 return _np.ascontiguousarray(data, dtype.as_numpy())
144
145 __all__ = [
146 "Datatype",
147 "coerce_array",
148 "bool8",
149 "uint8",
150 "uint16",
151 "uint32",
152 "uint64",
153 "int8",
154 "int16",
155 "int32",
156 "int64",
157 "float32",
158 "float64",
159 ]
160