Skip to content

Commit 906a6d8

Browse files
Major update to nm_stats.py
Moved NumPy data array to nm_dimension class. Only one project now allowed. Major update to nm_stats.py using NumPy functions.
1 parent d0b218a commit 906a6d8

25 files changed

+4761
-778
lines changed

pyneuromatic/nm_channel.py

+17-18
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"""
77
from pyneuromatic.nm_object import NMObject
88
from pyneuromatic.nm_object_container import NMObjectContainer
9-
from pyneuromatic.nm_scale import NMScale, NMScaleX
9+
from pyneuromatic.nm_dimension import NMDimension, NMDimensionX
1010
import pyneuromatic.nm_utilities as nmu
1111
from typing import Dict, List, Union
1212

@@ -45,8 +45,8 @@ def __init__(
4545
self,
4646
parent: Union[object, None] = None,
4747
name: str = "NMChannel",
48-
xscale: Union[dict, nmu.NMScaleXType] = {},
49-
yscale: Union[dict, nmu.NMScaleType] = {},
48+
xscale: Union[dict, nmu.NMDimensionXType] = {},
49+
yscale: Union[dict, nmu.NMDimensionType] = {},
5050
copy: Union[nmu.NMChannelType, None] = None,
5151
) -> None:
5252
super().__init__(parent=parent, name=name, copy=copy)
@@ -63,7 +63,6 @@ def __init__(
6363
elif isinstance(copy, NMChannel):
6464
xscale = copy._NMChannel__x.scale
6565
yscale = copy._NMChannel__y.scale
66-
6766
if self._folder is None:
6867
# direct copy
6968
self.__thedata = list(copy._NMChannel__thedata)
@@ -80,29 +79,29 @@ def __init__(
8079

8180
if xscale is None:
8281
pass
83-
elif isinstance(xscale, NMScaleX):
82+
elif isinstance(xscale, NMDimensionX):
8483
self.__x = xscale
8584
elif isinstance(xscale, dict):
86-
self.__x = NMScaleX(parent=self, name="xscale", scale=xscale)
85+
self.__x = NMDimensionX(parent=self, name="xscale", scale=xscale)
8786
else:
88-
e = nmu.typeerror(xscale, "xscale", "dictionary or NMScaleX")
87+
e = nmu.typeerror(xscale, "xscale", "dictionary or NMDimensionX")
8988
raise TypeError(e)
9089

9190
if yscale is None:
9291
pass
93-
elif isinstance(yscale, NMScale):
92+
elif isinstance(yscale, NMDimension):
9493
self.__y = yscale
9594
elif isinstance(yscale, dict):
96-
self.__y = NMScale(parent=self, name="yscale", scale=yscale)
95+
self.__y = NMDimension(parent=self, name="yscale", scale=yscale)
9796
else:
98-
e = nmu.typeerror(yscale, "yscale", "dictionary or NMScale")
97+
e = nmu.typeerror(yscale, "yscale", "dictionary or NMDimension")
9998
raise TypeError(e)
10099

101-
if not isinstance(self.__x, NMScaleX):
102-
self.__x = NMScaleX(parent=self, name="xscale")
100+
if not isinstance(self.__x, NMDimensionX):
101+
self.__x = NMDimensionX(parent=self, name="xscale")
103102

104-
if not isinstance(self.__y, NMScale):
105-
self.__y = NMScale(parent=self, name="yscale")
103+
if not isinstance(self.__y, NMDimension):
104+
self.__y = NMDimension(parent=self, name="yscale")
106105

107106
return None
108107

@@ -139,11 +138,11 @@ def data(self) -> List[nmu.NMDataType]:
139138
return self.__thedata
140139

141140
@property
142-
def x(self) -> nmu.NMScaleXType:
141+
def x(self) -> nmu.NMDimensionXType:
143142
return self.__x
144143

145144
@property
146-
def y(self) -> nmu.NMScaleType:
145+
def y(self) -> nmu.NMDimensionType:
147146
return self.__y
148147

149148

@@ -182,8 +181,8 @@ def content_type(self) -> str:
182181
def new(
183182
self,
184183
# name: str = 'A', use name_next()
185-
xscale: Union[dict, nmu.NMScaleXType] = {},
186-
yscale: Union[dict, nmu.NMScaleType] = {},
184+
xscale: Union[dict, nmu.NMDimensionXType] = {},
185+
yscale: Union[dict, nmu.NMDimensionType] = {},
187186
select: bool = False,
188187
# quiet: bool = nmp.QUIET
189188
) -> nmu.NMChannelType:

pyneuromatic/nm_data.py

+32-166
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
nmpy - NeuroMatic in Python
44
Copyright 2019 Jason Rothman
55
"""
6-
# import math
6+
import math
77
import numpy
88

99
# import numpy.typing as npt # No module named 'numpy.typing
1010
from typing import Dict, Union
1111

1212
from pyneuromatic.nm_channel import NMChannel
1313
from pyneuromatic.nm_dataseries import NMDataSeries, NMDataSeriesContainer
14+
from pyneuromatic.nm_dimension import NMDimension, NMDimensionX
1415
from pyneuromatic.nm_epoch import NMEpoch
1516
from pyneuromatic.nm_object import NMObject
1617
from pyneuromatic.nm_object_container import NMObjectContainer
1718
import pyneuromatic.nm_preferences as nmp
18-
from pyneuromatic.nm_scale import NMScale, NMScaleX
1919
import pyneuromatic.nm_utilities as nmu
2020

2121

@@ -45,38 +45,30 @@
4545
class NMData(NMObject):
4646
"""
4747
NM Data class
48-
49-
np_array: NumPy N-dimensional array (ndarray)
5048
"""
5149

5250
def __init__(
5351
self,
5452
parent: object = None,
5553
name: str = "NMData",
56-
np_array=None, # TODO: typing
57-
xscale: Union[dict, nmu.NMScaleXType] = {},
58-
yscale: Union[dict, nmu.NMScaleType] = {},
59-
# pass dictionary for independent scale
60-
# pass reference to NMscale (master)
54+
xdim: Union[nmu.NMDimensionXType, None] = None,
55+
ydim: Union[nmu.NMDimensionType, None] = None,
6156
# dataseries: Union[nmu.NMDataSeriesType, None] = None,
6257
dataseries_channel: Union[nmu.NMChannelType, None] = None,
6358
dataseries_epoch: Union[nmu.NMEpochType, None] = None,
64-
copy: nmu.NMDataType = None, # see copy()
59+
copy: nmu.NMDataType = None # see copy()
6560
) -> None:
6661
super().__init__(parent=parent, name=name, copy=copy) # NMObject
6762

68-
self.__np_array = None
6963
# self.__dataseries = None
7064
self.__dataseries_channel = None
7165
self.__dataseries_epoch = None
7266

7367
if copy is None:
7468
pass
7569
elif isinstance(copy, NMData):
76-
if isinstance(copy.np_array, numpy.ndarray):
77-
np_array = copy.np_array.copy()
78-
xscale = copy._NMData__x.scale
79-
yscale = copy._NMData__y.scale
70+
xdim = copy.x.copy()
71+
ydim = copy.y.copy()
8072
# TODO
8173
# dataseries = copy._NMData__dataseries
8274
# dataseries_channel = copy._NMData__dataseries_channel
@@ -85,33 +77,25 @@ def __init__(
8577
e = nmu.typeerror(copy, "copy", "NMData")
8678
raise TypeError(e)
8779

88-
if np_array is None:
89-
pass
90-
elif isinstance(np_array, numpy.ndarray):
91-
self.__np_array = np_array
80+
if xdim is None:
81+
self.__x = NMDimensionX(self, "xscale")
82+
self.__x.start = 0
83+
self.__x.delta = 1
84+
elif isinstance(xdim, NMDimensionX):
85+
self.__x = xdim
9286
else:
93-
e = nmu.typeerror(np_array, "np_array", "NumPy.ndarray")
87+
e = nmu.typeerror(xdim, "xdim", "NMDimensionX")
9488
raise TypeError(e)
9589

96-
if isinstance(xscale, NMScaleX):
97-
self.__x = xscale
98-
elif xscale is None:
99-
self.__x = NMScaleX(self, "xscale")
100-
elif isinstance(xscale, dict):
101-
self.__x = NMScaleX(self, "xscale", scale=xscale)
90+
if ydim is None:
91+
self.__y = NMDimension(self, "yscale")
92+
elif isinstance(ydim, NMDimension):
93+
self.__y = ydim
10294
else:
103-
e = nmu.typeerror(xscale, "xscale", "dictionary or NMScaleX")
95+
e = nmu.typeerror(ydim, "ydim", "NMDimension")
10496
raise TypeError(e)
10597

106-
if isinstance(yscale, NMScale):
107-
self.__y = yscale
108-
elif yscale is None:
109-
self.__y = NMScale(self, "yscale")
110-
elif isinstance(yscale, dict):
111-
self.__y = NMScale(self, "yscale", scale=yscale)
112-
else:
113-
e = nmu.typeerror(yscale, "yscale", "dictionary or NMScale")
114-
raise TypeError(e)
98+
self.__x.ypair = self.__y.nparray
11599

116100
self._dataseries_set(dataseries_channel, dataseries_epoch)
117101

@@ -131,38 +115,10 @@ def __eq__(
131115
if not super().__eq__(other):
132116
return False
133117

134-
if self.x != other.x:
135-
return False
136-
if self.y != other.y:
118+
if self.__x != other.x:
137119
return False
138-
# print(isinstance(self.__np_array, numpy.ndarray))
139-
if isinstance(self.__np_array, numpy.ndarray):
140-
if isinstance(other.__np_array, numpy.ndarray):
141-
if self.__np_array.dtype != other.np_array.dtype:
142-
return False
143-
if self.__np_array.shape != other.np_array.shape:
144-
return False
145-
if self.__np_array.nbytes != other.np_array.nbytes:
146-
return False
147-
if not numpy.array_equal(self.__np_array, other.np_array):
148-
# array_equal returns false if both arrays filled with NANs
149-
if nmp.NAN_EQ_NAN:
150-
# compare array elements within a tolerance
151-
if not numpy.allclose(
152-
self.__np_array,
153-
other.np_array,
154-
rtol=0,
155-
atol=0,
156-
equal_nan=True,
157-
):
158-
return False
159-
else:
160-
return False
161-
else:
162-
return False
163-
elif isinstance(other.__np_array, numpy.ndarray):
120+
if self.__y != other.y:
164121
return False
165-
166122
if self._dataseries_channel != other._dataseries_channel:
167123
return False
168124
if self._dataseries_epoch != other._dataseries_epoch:
@@ -174,12 +130,8 @@ def __eq__(
174130
@property
175131
def parameters(self) -> Dict[str, object]:
176132
k = super().parameters
177-
k.update({"xscale": self.x.scale})
178-
k.update({"yscale": self.y.scale})
179-
if isinstance(self.__np_array, numpy.ndarray):
180-
k.update({"np_array": self.__np_array.dtype})
181-
else:
182-
k.update({"np_array": None})
133+
k.update({"x": self.x.parameters})
134+
k.update({"y": self.y.parameters})
183135
ds = self._dataseries
184136
if isinstance(ds, NMDataSeries):
185137
k.update({"dataseries": ds.name})
@@ -196,102 +148,19 @@ def parameters(self) -> Dict[str, object]:
196148
return k
197149

198150
@property
199-
def x(self) -> nmu.NMScaleXType:
151+
def x(self) -> nmu.NMDimensionXType:
200152
if isinstance(self.__dataseries_channel, NMChannel):
201-
if isinstance(self.__dataseries_channel.x, NMScaleX):
153+
if isinstance(self.__dataseries_channel.x, NMDimensionX):
202154
return self.__dataseries_channel.x
203155
return self.__x
204156

205157
@property
206-
def y(self) -> nmu.NMScaleType:
158+
def y(self) -> nmu.NMDimensionType:
207159
if isinstance(self.__dataseries_channel, NMChannel):
208-
if isinstance(self.__dataseries_channel.y, NMScale):
160+
if isinstance(self.__dataseries_channel.y, NMDimension):
209161
return self.__dataseries_channel.y
210162
return self.__y
211163

212-
@property
213-
def np_array(self):
214-
return self.__np_array
215-
216-
@np_array.setter
217-
def np_array(self, np_array) -> None:
218-
return self._np_array_set(np_array)
219-
220-
def _np_array_set(
221-
self,
222-
np_array,
223-
# quiet=nmp.QUIET
224-
) -> None:
225-
if np_array is None:
226-
pass # ok
227-
elif not isinstance(np_array, numpy.ndarray):
228-
e = nmu.typeerror(np_array, "np_array", "NumPy.ndarray")
229-
raise TypeError(e)
230-
if self.__np_array is None:
231-
old = None
232-
else:
233-
old = self.__np_array.__array_interface__["data"][0]
234-
self.__np_array = np_array
235-
self.modified()
236-
if self.__np_array is None:
237-
new = None
238-
else:
239-
new = self.__np_array.__array_interface__["data"][0]
240-
h = nmu.history_change("np_array reference", old, new)
241-
# self.__notes_container.new(h)
242-
# self._history(h, quiet=quiet)
243-
return None
244-
245-
def np_array_make(
246-
self,
247-
shape,
248-
fill_value=NP_FILL_VALUE,
249-
dtype=NP_DTYPE,
250-
order=NP_ORDER,
251-
# quiet=nmp.QUIET
252-
):
253-
# wrapper for NumPy.full
254-
self.__np_array = numpy.full(shape, fill_value, dtype=dtype, order=order)
255-
self.modified()
256-
if not isinstance(self.__np_array, numpy.ndarray):
257-
raise RuntimeError("failed to create numpy array")
258-
n = (
259-
"created numpy array (numpy.full): shape="
260-
+ str(shape)
261-
+ ", fill_value="
262-
+ str(fill_value)
263-
+ ", dtype="
264-
+ str(dtype)
265-
)
266-
# self.__notes_container.new(n)
267-
# self._history(n, quiet=quiet)
268-
return True
269-
270-
def np_array_make_random_normal(
271-
self,
272-
shape,
273-
mean=0,
274-
stdv=1,
275-
# quiet=nmp.QUIET
276-
):
277-
# wrapper for NumPy.random.normal
278-
# dtype = float64
279-
self.__np_array = numpy.random.normal(mean, stdv, shape)
280-
self.modified()
281-
if not isinstance(self.__np_array, numpy.ndarray):
282-
raise RuntimeError("failed to create numpy array")
283-
n = (
284-
"created data array (numpy.random.normal): shape="
285-
+ str(shape)
286-
+ ", mean="
287-
+ str(mean)
288-
+ ", stdv="
289-
+ str(stdv)
290-
)
291-
# self.__notes_container.new(n)
292-
# self._history(n, quiet=quiet)
293-
return True
294-
295164
@property
296165
def _dataseries(self) -> Union[nmu.NMDataSeriesType, None]:
297166
if not isinstance(self.__dataseries_channel, NMChannel):
@@ -370,20 +239,17 @@ def content_type(self) -> str:
370239
def new(
371240
self,
372241
name: str = "default",
373-
np_array=None, # TODO: typing
374-
xscale: Union[dict, nmu.NMScaleXType] = {},
375-
# TODO: can also be NMData?
376-
yscale: Union[dict, nmu.NMScaleType] = {},
242+
xdim: Union[nmu.NMDimensionXType, None] = None,
243+
ydim: Union[nmu.NMDimensionType, None] = None,
377244
select: bool = False,
378245
# quiet: bool = nmp.QUIET
379246
) -> nmu.NMDataType:
380247
name = self._newkey(name)
381248
d = NMData(
382249
parent=self._parent,
383250
name=name,
384-
np_array=np_array,
385-
xscale=xscale,
386-
yscale=yscale,
251+
xdim=xdim,
252+
ydim=ydim
387253
)
388254
super().new(d, select=select)
389255
return d

0 commit comments

Comments
 (0)