datastock 0.0.45__tar.gz → 0.0.47__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {datastock-0.0.45/datastock.egg-info → datastock-0.0.47}/PKG-INFO +1 -1
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class1.py +27 -0
- datastock-0.0.47/datastock/_class1_color_touch.py +269 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class1_compute.py +1 -1
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class1_interpolate.py +17 -5
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class2_interactivity.py +9 -3
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_generic_check.py +121 -1
- {datastock-0.0.45 → datastock-0.0.47}/datastock/tests/test_01_DataStock.py +75 -19
- {datastock-0.0.45 → datastock-0.0.47}/datastock/version.py +1 -1
- {datastock-0.0.45 → datastock-0.0.47/datastock.egg-info}/PKG-INFO +1 -1
- {datastock-0.0.45 → datastock-0.0.47}/datastock.egg-info/SOURCES.txt +1 -0
- {datastock-0.0.45 → datastock-0.0.47}/LICENSE +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/MANIFEST.in +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/README.md +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/_updateversion.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_DataCollection_utils.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/__init__.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class0.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class1_binning.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class1_check.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class1_domain.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class1_show.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class1_uniformize.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class2.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_class3.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_direct_calls.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_export_dataframe.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_find_plateau.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_generic_utils.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_generic_utils_plot.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_BvsA_as_distribution.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_BvsA_as_distribution_check.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_as_array.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_as_array_1d.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_as_array_234d.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_as_mobile_lines.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_as_profile1d.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_correlations.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_old_backup.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_plot_text.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/_saveload.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/tests/__init__.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock/tests/output/__init__.py +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock.egg-info/dependency_links.txt +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock.egg-info/requires.txt +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/datastock.egg-info/top_level.txt +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/pyproject.toml +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/setup.cfg +0 -0
- {datastock-0.0.45 → datastock-0.0.47}/setup.py +0 -0
@@ -21,6 +21,7 @@ from . import _class1_domain
|
|
21
21
|
from . import _class1_binning
|
22
22
|
from . import _class1_interpolate
|
23
23
|
from . import _class1_uniformize
|
24
|
+
from . import _class1_color_touch as _color_touch
|
24
25
|
from . import _export_dataframe
|
25
26
|
from . import _find_plateau
|
26
27
|
|
@@ -923,6 +924,32 @@ class DataStock1(DataStock0):
|
|
923
924
|
inplace=inplace,
|
924
925
|
)
|
925
926
|
|
927
|
+
# ---------------------
|
928
|
+
# color touch array
|
929
|
+
# ---------------------
|
930
|
+
|
931
|
+
def get_color_touch(
|
932
|
+
self,
|
933
|
+
data=None,
|
934
|
+
dcolor=None,
|
935
|
+
# options
|
936
|
+
color_default=None,
|
937
|
+
vmin=None,
|
938
|
+
vmax=None,
|
939
|
+
log=None,
|
940
|
+
):
|
941
|
+
|
942
|
+
return _color_touch.main(
|
943
|
+
coll=self,
|
944
|
+
data=data,
|
945
|
+
dcolor=dcolor,
|
946
|
+
# options
|
947
|
+
color_default=color_default,
|
948
|
+
vmin=vmin,
|
949
|
+
vmax=vmax,
|
950
|
+
log=log,
|
951
|
+
)
|
952
|
+
|
926
953
|
# ---------------------
|
927
954
|
# Methods computing correlations
|
928
955
|
# ---------------------
|
@@ -0,0 +1,269 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
Created on Fri Feb 28 08:53:00 2025
|
4
|
+
|
5
|
+
@author: dvezinet
|
6
|
+
"""
|
7
|
+
|
8
|
+
|
9
|
+
import numpy as np
|
10
|
+
import matplotlib.pyplot as plt
|
11
|
+
import matplotlib.colors as mcolors
|
12
|
+
import datastock as ds
|
13
|
+
|
14
|
+
|
15
|
+
# ###############################################################
|
16
|
+
# ###############################################################
|
17
|
+
# Main
|
18
|
+
# ###############################################################
|
19
|
+
|
20
|
+
|
21
|
+
def main(
|
22
|
+
coll=None,
|
23
|
+
data=None,
|
24
|
+
dcolor=None,
|
25
|
+
# options
|
26
|
+
color_default=None,
|
27
|
+
vmin=None,
|
28
|
+
vmax=None,
|
29
|
+
log=None,
|
30
|
+
):
|
31
|
+
|
32
|
+
# ------------------
|
33
|
+
# check inputs
|
34
|
+
# ------------------
|
35
|
+
|
36
|
+
data, dcolor, color_default, vmin, vmax, log = _check(
|
37
|
+
coll=coll,
|
38
|
+
data=data,
|
39
|
+
dcolor=dcolor,
|
40
|
+
color_default=color_default,
|
41
|
+
vmin=vmin,
|
42
|
+
vmax=vmax,
|
43
|
+
log=log,
|
44
|
+
)
|
45
|
+
|
46
|
+
# ------------------
|
47
|
+
# initialize
|
48
|
+
# ------------------
|
49
|
+
|
50
|
+
shape = data.shape + (4,)
|
51
|
+
color = np.zeros(shape, dtype=float)
|
52
|
+
|
53
|
+
# ------------------
|
54
|
+
# compute - alpha
|
55
|
+
# ------------------
|
56
|
+
|
57
|
+
if log is True:
|
58
|
+
vmin = np.log10(vmin)
|
59
|
+
vmax = np.log10(vmax)
|
60
|
+
|
61
|
+
alpha = (np.log10(data) - vmin) / (vmax - vmin)
|
62
|
+
|
63
|
+
else:
|
64
|
+
alpha = (data - vmin) / (vmax - vmin)
|
65
|
+
|
66
|
+
# ------------------
|
67
|
+
# compute - colors
|
68
|
+
# ------------------
|
69
|
+
|
70
|
+
for k0, v0 in dcolor.items():
|
71
|
+
|
72
|
+
sli = (v0['ind'], slice(0, 3))
|
73
|
+
color[sli] = v0['color']
|
74
|
+
|
75
|
+
sli = tuple([slice(None) for ii in range(data.ndim)] + [-1])
|
76
|
+
color[sli] = alpha
|
77
|
+
|
78
|
+
# ------------------
|
79
|
+
# output
|
80
|
+
# ------------------
|
81
|
+
|
82
|
+
lcol = set([v0['color'] for v0 in dcolor.values()])
|
83
|
+
dcolor = {
|
84
|
+
'color': color,
|
85
|
+
'meaning': {
|
86
|
+
kc: [k0 for k0, v0 in dcolor.items() if v0['color'] == kc]
|
87
|
+
for kc in lcol
|
88
|
+
},
|
89
|
+
}
|
90
|
+
|
91
|
+
return dcolor
|
92
|
+
|
93
|
+
|
94
|
+
# ###############################################################
|
95
|
+
# ###############################################################
|
96
|
+
# check
|
97
|
+
# ###############################################################
|
98
|
+
|
99
|
+
|
100
|
+
def _check(
|
101
|
+
coll=None,
|
102
|
+
data=None,
|
103
|
+
dcolor=None,
|
104
|
+
# options
|
105
|
+
color_default=None,
|
106
|
+
vmin=None,
|
107
|
+
vmax=None,
|
108
|
+
log=None,
|
109
|
+
):
|
110
|
+
|
111
|
+
# ------------------
|
112
|
+
# data
|
113
|
+
# ------------------
|
114
|
+
|
115
|
+
lc = [
|
116
|
+
isinstance(data, np.ndarray),
|
117
|
+
isinstance(data, str) and data in coll.ddata.keys(),
|
118
|
+
]
|
119
|
+
if lc[0]:
|
120
|
+
pass
|
121
|
+
elif lc[1]:
|
122
|
+
data = coll.ddata[data]['data']
|
123
|
+
else:
|
124
|
+
msg = (
|
125
|
+
"Arg data must be a np.ndarray or a key to an existing data!\n"
|
126
|
+
f"Provided: {data}\n"
|
127
|
+
)
|
128
|
+
raise Exception(msg)
|
129
|
+
|
130
|
+
|
131
|
+
# ------------------
|
132
|
+
# dcolor
|
133
|
+
# ------------------
|
134
|
+
|
135
|
+
# --------------------
|
136
|
+
# dcolor format check
|
137
|
+
|
138
|
+
c0 = (
|
139
|
+
isinstance(dcolor, dict)
|
140
|
+
and all([
|
141
|
+
isinstance(k0, str)
|
142
|
+
and isinstance(v0, dict)
|
143
|
+
and sorted(v0.keys()) == ['color', 'ind']
|
144
|
+
for k0, v0 in dcolor.items()
|
145
|
+
])
|
146
|
+
)
|
147
|
+
if not c0:
|
148
|
+
msg = (
|
149
|
+
"Arg dcolor must be a dict of sub-dicts of shape:\n"
|
150
|
+
"\t- 'key0': {'ind': ..., 'color': ...}\n"
|
151
|
+
"\t- ...\n"
|
152
|
+
"\t- 'keyN': {'ind': ..., 'color': ...}\n"
|
153
|
+
f"Provided:\n{dcolor}\n"
|
154
|
+
)
|
155
|
+
raise Exception(msg)
|
156
|
+
|
157
|
+
# --------------------
|
158
|
+
# ind and color checks
|
159
|
+
|
160
|
+
dfail = {}
|
161
|
+
shape = data.shape
|
162
|
+
for k0, v0 in dcolor.items():
|
163
|
+
|
164
|
+
c0 = (
|
165
|
+
isinstance(v0['ind'], np.ndarray)
|
166
|
+
and v0['ind'].shape == data.shape
|
167
|
+
and v0['ind'].dtype == bool
|
168
|
+
)
|
169
|
+
if not c0:
|
170
|
+
msg = f"'ind' must be a {shape} bool array, not {v0['ind']}"
|
171
|
+
dfail[k0] = (msg,)
|
172
|
+
|
173
|
+
if not mcolors.is_color_like(v0['color']):
|
174
|
+
msg = f"'color' must be color-like, not {v0['color']}"
|
175
|
+
if k0 in dfail:
|
176
|
+
dfail[k0] = dfail[k0] + (msg,)
|
177
|
+
else:
|
178
|
+
dfail[k0] = (msg,)
|
179
|
+
|
180
|
+
# raise exception
|
181
|
+
if len(dfail) > 0:
|
182
|
+
lmax = np.max([len(f"\t- {k0}: ") for k0 in dfail.keys()])
|
183
|
+
lstr = [
|
184
|
+
f"\t- {k0}:\n".ljust(lmax) + '\n'.join([
|
185
|
+
"".ljust(lmax+4) + f"\t- {v1}".rjust(lmax)
|
186
|
+
for ii, v1 in enumerate(v0)
|
187
|
+
])
|
188
|
+
for k0, v0 in dfail.items()
|
189
|
+
]
|
190
|
+
msg = (
|
191
|
+
"Arg dcolor, the following keys have incorrect keys / values:\n"
|
192
|
+
+ "\n".join(lstr)
|
193
|
+
)
|
194
|
+
raise Exception(msg)
|
195
|
+
|
196
|
+
# ----------------------
|
197
|
+
# format colors to rgb
|
198
|
+
|
199
|
+
dcol = {}
|
200
|
+
for k0, v0 in dcolor.items():
|
201
|
+
if np.any(v0['ind']):
|
202
|
+
dcol[k0] = {
|
203
|
+
'ind': v0['ind'],
|
204
|
+
'color': mcolors.to_rgb(v0['color']),
|
205
|
+
}
|
206
|
+
|
207
|
+
# ------------------
|
208
|
+
# color_default
|
209
|
+
# ------------------
|
210
|
+
|
211
|
+
if color_default is None:
|
212
|
+
color_default = 'k'
|
213
|
+
if not mcolors.is_color_like(color_default):
|
214
|
+
msg = (
|
215
|
+
"Arg color_default must be color-like!\n"
|
216
|
+
f"Provided: {color_default}\n"
|
217
|
+
)
|
218
|
+
raise Exception(msg)
|
219
|
+
|
220
|
+
color_default = mcolors.to_rgb(color_default)
|
221
|
+
|
222
|
+
# ------------------
|
223
|
+
# vmin, vmax
|
224
|
+
# ------------------
|
225
|
+
|
226
|
+
vmin0 = np.nanmin(data)
|
227
|
+
vmax0 = np.nanmax(data)
|
228
|
+
|
229
|
+
# vmin
|
230
|
+
if vmin is None:
|
231
|
+
vmin = vmin0
|
232
|
+
c0 = (np.isscalar(vmin) and np.isfinite(vmin) and vmin < vmax0)
|
233
|
+
if not c0:
|
234
|
+
msg = (
|
235
|
+
f"Arg vmin must be a finite scalar below max ({vmax0})\n"
|
236
|
+
f"Provided: {vmin}\n"
|
237
|
+
)
|
238
|
+
raise Exception(msg)
|
239
|
+
|
240
|
+
# vmax
|
241
|
+
if vmax is None:
|
242
|
+
vmax = vmax0
|
243
|
+
c0 = (np.isscalar(vmax) and np.isfinite(vmax) and vmax > vmin0)
|
244
|
+
if not c0:
|
245
|
+
msg = (
|
246
|
+
f"Arg vmax must be a finite scalar above min ({vmin0})\n"
|
247
|
+
f"Provided: {vmax}\n"
|
248
|
+
)
|
249
|
+
raise Exception(msg)
|
250
|
+
|
251
|
+
# ordering
|
252
|
+
if vmin >= vmax:
|
253
|
+
msg = (
|
254
|
+
"Arg vmin must be below vmax!\n"
|
255
|
+
f"Provided:\n\t- vmin = {vmin}\n\t- vmax = {vmax}\n"
|
256
|
+
)
|
257
|
+
raise Exception(msg)
|
258
|
+
|
259
|
+
# ------------------
|
260
|
+
# log
|
261
|
+
# ------------------
|
262
|
+
|
263
|
+
log = ds._generic_check._check_var(
|
264
|
+
log, 'log',
|
265
|
+
types=bool,
|
266
|
+
default=False,
|
267
|
+
)
|
268
|
+
|
269
|
+
return data, dcol, color_default, vmin, vmax, log
|
@@ -1574,7 +1574,8 @@ def _xunique(dout=None, domain=None):
|
|
1574
1574
|
}
|
1575
1575
|
|
1576
1576
|
# Number of Nones expected
|
1577
|
-
|
1577
|
+
ndom = 0 if domain is None else len(domain)
|
1578
|
+
nNone = 1 + ndom
|
1578
1579
|
|
1579
1580
|
# check
|
1580
1581
|
dwrong = {k0: v0 for k0, v0 in dind.items() if len(v0) != nNone}
|
@@ -1583,7 +1584,7 @@ def _xunique(dout=None, domain=None):
|
|
1583
1584
|
f"\t- {k0}: {dout[k0]['ref']} => {v0}" for k0, v0 in dwrong.items()
|
1584
1585
|
]
|
1585
1586
|
msg = (
|
1586
|
-
"Interpolate unique pt => ref should have nNone = 1 + {
|
1587
|
+
"Interpolate unique pt => ref should have nNone = 1 + {ndom}:\n"
|
1587
1588
|
+ "\n".join(lstr)
|
1588
1589
|
)
|
1589
1590
|
raise Exception(msg)
|
@@ -1626,7 +1627,12 @@ def _store(
|
|
1626
1627
|
ldata = list(set(itt.chain.from_iterable([
|
1627
1628
|
v0['ref'] for v0 in dout.values()
|
1628
1629
|
])))
|
1629
|
-
|
1630
|
+
|
1631
|
+
coll2 = coll.extract(
|
1632
|
+
keys=ldata,
|
1633
|
+
inc_vectors=True,
|
1634
|
+
return_keys=False,
|
1635
|
+
)
|
1630
1636
|
|
1631
1637
|
# -------------
|
1632
1638
|
# store_keys
|
@@ -1644,7 +1650,13 @@ def _store(
|
|
1644
1650
|
excluded=lout,
|
1645
1651
|
)
|
1646
1652
|
|
1647
|
-
|
1653
|
+
if len(store_keys) != len(dout):
|
1654
|
+
msg = (
|
1655
|
+
"Nb of store_keys != nb of keys in dout!\n"
|
1656
|
+
f"\t- store_keys:\n{store_keys}\n "
|
1657
|
+
f"\t- dout.keys():\n{sorted(dout.keys())}\n "
|
1658
|
+
)
|
1659
|
+
raise Exception(msg)
|
1648
1660
|
|
1649
1661
|
# ---------
|
1650
1662
|
# add data
|
@@ -1658,4 +1670,4 @@ def _store(
|
|
1658
1670
|
units=v0['units'],
|
1659
1671
|
)
|
1660
1672
|
|
1661
|
-
return coll2
|
1673
|
+
return coll2
|
@@ -459,12 +459,18 @@ def _get_ix_for_refx_only_1or2d(
|
|
459
459
|
|
460
460
|
|
461
461
|
def get_fupdate(handle=None, dtype=None, norm=None, bstr=None):
|
462
|
+
|
463
|
+
# Note: set_xdata() and set_ydata() do not accept scalar values
|
464
|
+
# Deprecation warning since matplotlib 3.7
|
465
|
+
# see https://github.com/matplotlib/matplotlib/pull/22329
|
466
|
+
# see https://github.com/matplotlib/matplotlib/issues/28927
|
467
|
+
|
462
468
|
if dtype == 'xdata':
|
463
469
|
def func(val, handle=handle):
|
464
|
-
handle.set_xdata(val)
|
470
|
+
handle.set_xdata(np.atleast_1d(val))
|
465
471
|
elif dtype == 'ydata':
|
466
472
|
def func(val, handle=handle):
|
467
|
-
handle.set_ydata(val)
|
473
|
+
handle.set_ydata(np.atleast_1d(val))
|
468
474
|
elif dtype in ['data']: # Also works for imshow
|
469
475
|
def func(val, handle=handle):
|
470
476
|
handle.set_data(val)
|
@@ -588,4 +594,4 @@ def _update_mobile(k0=None, dmobile=None, dref=None, ddata=None):
|
|
588
594
|
# ddata[dmobile[k0]['data'][ii]]['data'][
|
589
595
|
# dmobile[k0]['func_slice'][ii](iref[ii])
|
590
596
|
# ]
|
591
|
-
# )
|
597
|
+
# )
|
@@ -550,6 +550,126 @@ def _obj_key(d0=None, short=None, key=None, ndigits=None):
|
|
550
550
|
)
|
551
551
|
|
552
552
|
|
553
|
+
# #############################################################################
|
554
|
+
# #############################################################################
|
555
|
+
# Utilities for plotting
|
556
|
+
# #############################################################################
|
557
|
+
|
558
|
+
|
559
|
+
def _check_all_broadcastable(
|
560
|
+
return_full_arrays=None,
|
561
|
+
**kwdargs,
|
562
|
+
):
|
563
|
+
|
564
|
+
# -------------------
|
565
|
+
# return_full_arrays
|
566
|
+
# -------------------
|
567
|
+
|
568
|
+
return_full_arrays = _check_var(
|
569
|
+
return_full_arrays, 'return_full_arrays',
|
570
|
+
types=bool,
|
571
|
+
default=False,
|
572
|
+
)
|
573
|
+
|
574
|
+
# -------------------
|
575
|
+
# Preliminary check
|
576
|
+
# -------------------
|
577
|
+
|
578
|
+
dout = {}
|
579
|
+
dfail = {}
|
580
|
+
for k0, v0 in kwdargs.items():
|
581
|
+
try:
|
582
|
+
dout[k0] = np.atleast_1d(v0)
|
583
|
+
except Exception:
|
584
|
+
dfail[k0] = f"Not convertible to np.ndarray! - {v0}"
|
585
|
+
|
586
|
+
# Raise Exception
|
587
|
+
if len(dfail) > 0:
|
588
|
+
lstr = [f"\t- {k0}: {v0}" for k0, v0 in dfail.items()]
|
589
|
+
msg = (
|
590
|
+
"The following kwdargs are non-conform:\n"
|
591
|
+
+ "\n".join(lstr)
|
592
|
+
)
|
593
|
+
raise Exception(msg)
|
594
|
+
|
595
|
+
# -------------------
|
596
|
+
# check ndim
|
597
|
+
# -------------------
|
598
|
+
|
599
|
+
dndim = {k0: v0.ndim for k0, v0 in dout.items() if v0.shape != (1,)}
|
600
|
+
lndim = list(set(dndim.values()))
|
601
|
+
|
602
|
+
if len(lndim) == 0:
|
603
|
+
# all scalar
|
604
|
+
if return_full_arrays:
|
605
|
+
return dout, (1,)
|
606
|
+
else:
|
607
|
+
return {k0: v0[0] for k0, v0 in dout.items()}, None
|
608
|
+
|
609
|
+
elif len(lndim) == 1:
|
610
|
+
ndim = lndim[0]
|
611
|
+
|
612
|
+
else:
|
613
|
+
lstr = [f"-t {k0}: {v0}" for k0, v0 in dndim.items()]
|
614
|
+
msg = (
|
615
|
+
"Some keyword args have non-compatible dimensions:\n"
|
616
|
+
+ "\n".join(lstr)
|
617
|
+
)
|
618
|
+
raise Exception(msg)
|
619
|
+
|
620
|
+
# -------------------
|
621
|
+
# check shapes
|
622
|
+
# -------------------
|
623
|
+
|
624
|
+
dfail = {}
|
625
|
+
shapef = np.ones((ndim,), dtype=int)
|
626
|
+
for k0, v0 in dout.items():
|
627
|
+
|
628
|
+
if v0.shape == (1,):
|
629
|
+
continue
|
630
|
+
|
631
|
+
for ii in range(ndim):
|
632
|
+
if v0.shape[ii] == 1:
|
633
|
+
pass
|
634
|
+
elif shapef[ii] == 1:
|
635
|
+
shapef[ii] = v0.shape[ii]
|
636
|
+
elif v0.shape[ii] == shapef[ii]:
|
637
|
+
pass
|
638
|
+
else:
|
639
|
+
dfail[k0] = f"Non-compatible shape = {v0.shape} (ii = {ii})"
|
640
|
+
continue
|
641
|
+
|
642
|
+
shapef = tuple(shapef)
|
643
|
+
|
644
|
+
# raise Exception if needed
|
645
|
+
if len(dfail) > 0:
|
646
|
+
lstr = [f"\t- {k0}: {v0}" for k0, v0 in dfail.items()]
|
647
|
+
msg = (
|
648
|
+
"The following keywords args have non-compatible shape:\n"
|
649
|
+
+ "\n".join(lstr)
|
650
|
+
+ f"\nReference shape: {shapef}\n"
|
651
|
+
)
|
652
|
+
raise Exception(msg)
|
653
|
+
|
654
|
+
# -------------------
|
655
|
+
# reshape output
|
656
|
+
# -------------------
|
657
|
+
|
658
|
+
if return_full_arrays is True:
|
659
|
+
for k0, v0 in dout.items():
|
660
|
+
if v0.shape == (1,):
|
661
|
+
dout[k0] = np.full(shapef, v0[0])
|
662
|
+
elif v0.shape != shapef:
|
663
|
+
dout[k0] = np.broadcast_to(v0, shapef)
|
664
|
+
|
665
|
+
else:
|
666
|
+
for k0, v0 in dout.items():
|
667
|
+
if v0.shape == (1,):
|
668
|
+
dout[k0] = v0[0]
|
669
|
+
|
670
|
+
return dout, shapef
|
671
|
+
|
672
|
+
|
553
673
|
# #############################################################################
|
554
674
|
# #############################################################################
|
555
675
|
# Utilities for plotting
|
@@ -929,4 +1049,4 @@ def _check_cmap_vminvmax(data=None, cmap=None, vmin=None, vmax=None):
|
|
929
1049
|
else:
|
930
1050
|
vmax = nanmax
|
931
1051
|
|
932
|
-
return cmap, vmin, vmax
|
1052
|
+
return cmap, vmin, vmax
|
@@ -14,6 +14,7 @@ import numpy as np
|
|
14
14
|
import matplotlib.pyplot as plt
|
15
15
|
|
16
16
|
# datastock-specific
|
17
|
+
from .._generic_check import _check_all_broadcastable
|
17
18
|
from .._class import DataStock
|
18
19
|
from .._saveload import load
|
19
20
|
|
@@ -228,6 +229,46 @@ class Test01_Instanciate():
|
|
228
229
|
def test03_add_obj(self):
|
229
230
|
_add_obj(st=self.st, nc=self.nc)
|
230
231
|
|
232
|
+
# ------------------------
|
233
|
+
# Tools
|
234
|
+
# ------------------------
|
235
|
+
|
236
|
+
def test04_check_all_broadcastable(self):
|
237
|
+
# all scalar
|
238
|
+
dout, shape = _check_all_broadcastable(a=1, b=2)
|
239
|
+
|
240
|
+
# scalar + arrays
|
241
|
+
dout, shape = _check_all_broadcastable(a=1, b=(1, 2, 3))
|
242
|
+
|
243
|
+
# all arrays
|
244
|
+
dout, shape = _check_all_broadcastable(
|
245
|
+
a=(1, 2, 3),
|
246
|
+
b=(1, 2, 3),
|
247
|
+
)
|
248
|
+
|
249
|
+
# all arrays - 2d
|
250
|
+
dout, shape = _check_all_broadcastable(
|
251
|
+
a=np.r_[1, 2, 3][:, None],
|
252
|
+
b=np.r_[10, 20][None, :],
|
253
|
+
)
|
254
|
+
|
255
|
+
# check flag
|
256
|
+
err = False
|
257
|
+
try:
|
258
|
+
dout, shape = _check_all_broadcastable(a=(1, 2), b=(1, 2, 3))
|
259
|
+
except Exception:
|
260
|
+
err = True
|
261
|
+
assert err is True
|
262
|
+
|
263
|
+
# all arrays - mix
|
264
|
+
dout, shape = _check_all_broadcastable(
|
265
|
+
a=np.r_[1, 2, 3][:, None],
|
266
|
+
b=np.r_[10, 20][None, :],
|
267
|
+
c=3,
|
268
|
+
return_full_arrays=True,
|
269
|
+
)
|
270
|
+
assert all([v0.shape == (3, 2) for v0 in dout.values()])
|
271
|
+
|
231
272
|
|
232
273
|
#######################################################
|
233
274
|
#
|
@@ -306,11 +347,26 @@ class Test02_Manipulate():
|
|
306
347
|
self.st.show_data()
|
307
348
|
self.st.show_obj()
|
308
349
|
|
350
|
+
# ------------------------
|
351
|
+
# dcolor
|
352
|
+
# ------------------------
|
353
|
+
|
354
|
+
def test06_get_dcolor_touch(self):
|
355
|
+
xx = np.arange(50)
|
356
|
+
aa = np.exp(-(xx[:, None]-25)**2/10**2 - (xx[None, :]-25)**2/10**2)
|
357
|
+
ind = (aa>0.3) & (np.arange(50)[None, :] > 25)
|
358
|
+
dcolor = self.st.get_color_touch(
|
359
|
+
aa,
|
360
|
+
dcolor={'foo': {'ind': ind, 'color': 'r'}}
|
361
|
+
)
|
362
|
+
assert dcolor['color'].shape == aa.shape + (4,)
|
363
|
+
assert dcolor['meaning'][(1.0, 0.0, 0.0)] == ['foo']
|
364
|
+
|
309
365
|
# ------------------------
|
310
366
|
# Interpolate
|
311
367
|
# ------------------------
|
312
368
|
|
313
|
-
def
|
369
|
+
def test07_get_ref_vector(self):
|
314
370
|
(
|
315
371
|
hasref, hasvector,
|
316
372
|
ref, key_vector,
|
@@ -325,13 +381,13 @@ class Test02_Manipulate():
|
|
325
381
|
assert values.size == dind['ind'].size == 4
|
326
382
|
assert dind['indr'].shape == (2, 4)
|
327
383
|
|
328
|
-
def
|
384
|
+
def test08_get_ref_vector_common(self):
|
329
385
|
hasref, ref, key, val, dout = self.st.get_ref_vector_common(
|
330
386
|
keys=['t0', 'prof0', 'prof1', 't3'],
|
331
387
|
dim='time',
|
332
388
|
)
|
333
389
|
|
334
|
-
def
|
390
|
+
def test09_domain_ref(self):
|
335
391
|
|
336
392
|
domain = {
|
337
393
|
'nx': [1.5, 2],
|
@@ -347,7 +403,7 @@ class Test02_Manipulate():
|
|
347
403
|
lk = list(domain.keys())
|
348
404
|
assert all([isinstance(dout[k0]['ind'], np.ndarray) for k0 in lk])
|
349
405
|
|
350
|
-
def
|
406
|
+
def test10_binning(self):
|
351
407
|
|
352
408
|
bins = np.linspace(1, 5, 8)
|
353
409
|
lk = [
|
@@ -399,7 +455,7 @@ class Test02_Manipulate():
|
|
399
455
|
)
|
400
456
|
raise Exception(msg)
|
401
457
|
|
402
|
-
def
|
458
|
+
def test11_interpolate(self):
|
403
459
|
|
404
460
|
lk = ['y', 'y', 'prof0', 'prof0', 'prof0', '3d']
|
405
461
|
lref = [None, 'nx', 't0', ['nt0', 'nx'], ['t0', 'x'], ['t0', 'x']]
|
@@ -443,7 +499,7 @@ class Test02_Manipulate():
|
|
443
499
|
msg = str(dout[kk]['data'].shape, shape, kk, rr)
|
444
500
|
raise Exception(msg)
|
445
501
|
|
446
|
-
def
|
502
|
+
def test12_interpolate_common_refs(self):
|
447
503
|
lk = ['3d', '3d', '3d']
|
448
504
|
lref = ['t0', ['nt0', 'nx'], ['nx']]
|
449
505
|
lrefc = ['nc', 'nc', 'nt0']
|
@@ -519,17 +575,17 @@ class Test02_Manipulate():
|
|
519
575
|
# Plotting
|
520
576
|
# ------------------------
|
521
577
|
|
522
|
-
def
|
578
|
+
def test13_plot_as_array_1d(self):
|
523
579
|
dax = self.st.plot_as_array(key='t0')
|
524
580
|
plt.close('all')
|
525
581
|
del dax
|
526
582
|
|
527
|
-
def
|
583
|
+
def test14_plot_as_array_2d(self):
|
528
584
|
dax = self.st.plot_as_array(key='prof0')
|
529
585
|
plt.close('all')
|
530
586
|
del dax
|
531
587
|
|
532
|
-
def
|
588
|
+
def test15_plot_as_array_2d_log(self):
|
533
589
|
dax = self.st.plot_as_array(
|
534
590
|
key='pec', keyX='ne', keyY='Te',
|
535
591
|
dscale={'data': 'log'},
|
@@ -537,17 +593,17 @@ class Test02_Manipulate():
|
|
537
593
|
plt.close('all')
|
538
594
|
del dax
|
539
595
|
|
540
|
-
def
|
596
|
+
def test16_plot_as_array_3d(self):
|
541
597
|
dax = self.st.plot_as_array(key='3d', dvminmax={'keyX': {'min': 0}})
|
542
598
|
plt.close('all')
|
543
599
|
del dax
|
544
600
|
|
545
|
-
def
|
601
|
+
def test17_plot_as_array_3d_ZNonMonot(self):
|
546
602
|
dax = self.st.plot_as_array(key='3d', keyZ='y')
|
547
603
|
plt.close('all')
|
548
604
|
del dax
|
549
605
|
|
550
|
-
def
|
606
|
+
def test18_plot_as_array_4d(self):
|
551
607
|
dax = self.st.plot_as_array(key='4d', dscale={'keyU': 'linear'})
|
552
608
|
plt.close('all')
|
553
609
|
del dax
|
@@ -557,7 +613,7 @@ class Test02_Manipulate():
|
|
557
613
|
# plt.close('all')
|
558
614
|
# del dax
|
559
615
|
|
560
|
-
def
|
616
|
+
def test20_plot_as_profile1d(self):
|
561
617
|
dax = self.st.plot_as_profile1d(
|
562
618
|
key='prof0',
|
563
619
|
key_time='t0',
|
@@ -591,7 +647,7 @@ class Test02_Manipulate():
|
|
591
647
|
# File handling
|
592
648
|
# ------------------------
|
593
649
|
|
594
|
-
def
|
650
|
+
def test22_copy_equal(self):
|
595
651
|
st2 = self.st.copy()
|
596
652
|
assert st2 is not self.st
|
597
653
|
|
@@ -599,15 +655,15 @@ class Test02_Manipulate():
|
|
599
655
|
if msg is not True:
|
600
656
|
raise Exception(msg)
|
601
657
|
|
602
|
-
def
|
658
|
+
def test23_get_nbytes(self):
|
603
659
|
nb, dnb = self.st.get_nbytes()
|
604
660
|
|
605
|
-
def
|
661
|
+
def test24_save_pfe(self, verb=False):
|
606
662
|
pfe = os.path.join(_PATH_OUTPUT, 'testsave.npz')
|
607
663
|
self.st.save(pfe=pfe, return_pfe=False)
|
608
664
|
os.remove(pfe)
|
609
665
|
|
610
|
-
def
|
666
|
+
def test25_saveload(self, verb=False):
|
611
667
|
pfe = self.st.save(path=_PATH_OUTPUT, verb=verb, return_pfe=True)
|
612
668
|
st2 = load(pfe, verb=verb)
|
613
669
|
# Just to check the loaded version works fine
|
@@ -616,7 +672,7 @@ class Test02_Manipulate():
|
|
616
672
|
raise Exception(msg)
|
617
673
|
os.remove(pfe)
|
618
674
|
|
619
|
-
def
|
675
|
+
def test26_saveload_coll(self, verb=False):
|
620
676
|
pfe = self.st.save(path=_PATH_OUTPUT, verb=verb, return_pfe=True)
|
621
677
|
st = DataStock()
|
622
678
|
st2 = load(pfe, coll=st, verb=verb)
|
@@ -624,4 +680,4 @@ class Test02_Manipulate():
|
|
624
680
|
msg = st2.__eq__(self.st, returnas=str)
|
625
681
|
if msg is not True:
|
626
682
|
raise Exception(msg)
|
627
|
-
os.remove(pfe)
|
683
|
+
os.remove(pfe)
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# Do not edit, pipeline versioning governed by git tags!
|
2
|
-
__version__ = '0.0.
|
2
|
+
__version__ = '0.0.47'
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|