pastastore 1.7.1__py3-none-any.whl → 1.8.0__py3-none-any.whl

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.
@@ -0,0 +1,321 @@
1
+ # ruff: noqa: D100 D103
2
+ import os
3
+
4
+ import numpy as np
5
+ import pandas as pd
6
+ import pastas as ps
7
+ import pytest
8
+ from numpy import allclose
9
+ from packaging.version import parse
10
+ from pytest_dependency import depends
11
+
12
+ import pastastore as pst
13
+
14
+
15
+ @pytest.mark.dependency
16
+ def test_iter_oseries(pstore):
17
+ _ = list(pstore.iter_oseries())
18
+
19
+
20
+ @pytest.mark.dependency
21
+ def test_iter_stresses(pstore):
22
+ _ = list(pstore.iter_stresses())
23
+
24
+
25
+ @pytest.mark.dependency
26
+ def test_get_tmintmax(pstore):
27
+ ostt = pstore.get_tmin_tmax("oseries")
28
+ assert ostt.at["oseries1", "tmin"] == pd.Timestamp("2010-01-14")
29
+ sttt = pstore.get_tmin_tmax("stresses")
30
+ assert sttt.at["evap2", "tmax"] == pd.Timestamp("2016-11-22")
31
+ ml = pstore.create_model("oseries1")
32
+ ml.solve(report=False)
33
+ pstore.conn.add_model(ml)
34
+ mltt = pstore.get_tmin_tmax("models")
35
+ assert mltt.at["oseries1", "tmax"] == pd.Timestamp("2015-06-28")
36
+ pstore.del_model("oseries1")
37
+
38
+
39
+ @pytest.mark.dependency
40
+ def test_search(pstore):
41
+ results = pstore.search("oseries", "OSER", case_sensitive=False)
42
+ assert len(results) == 3
43
+ assert len(set(results) - {"oseries1", "oseries2", "oseries3"}) == 0
44
+
45
+
46
+ @pytest.mark.dependency
47
+ def test_create_model(pstore):
48
+ _ = pstore.create_model("oseries1")
49
+
50
+
51
+ @pytest.mark.dependency
52
+ def test_properties(pstore):
53
+ pstore.add_oseries(pd.Series(dtype=np.float64), "deleteme", validate=False)
54
+ pstore.add_stress(
55
+ pd.Series(dtype=np.float64), "deleteme", kind="useless", validate=False
56
+ )
57
+
58
+ _ = pstore.oseries
59
+ _ = pstore.stresses
60
+ _ = pstore.models
61
+
62
+ try:
63
+ assert pstore.n_oseries == pstore.conn.n_oseries
64
+ assert pstore.n_stresses == pstore.conn.n_stresses
65
+ finally:
66
+ pstore.del_oseries("deleteme")
67
+ pstore.del_stress("deleteme")
68
+
69
+
70
+ @pytest.mark.dependency
71
+ def test_store_model(request, pstore):
72
+ depends(request, [f"test_create_model[{pstore.type}]"])
73
+ ml = pstore.create_model("oseries1")
74
+ pstore.conn.add_model(ml)
75
+
76
+
77
+ @pytest.mark.dependency
78
+ def test_model_accessor(request, pstore):
79
+ depends(request, [f"test_store_model[{pstore.type}]"])
80
+ # repr
81
+ pstore.models.__repr__()
82
+ # getter
83
+ ml = pstore.models["oseries1"]
84
+ # setter
85
+ pstore.models["oseries1_2"] = ml
86
+ # iter
87
+ mnames = [ml.name for ml in pstore.models]
88
+ try:
89
+ assert len(mnames) == 2
90
+ assert mnames[0] in ["oseries1", "oseries1_2"]
91
+ assert mnames[1] in ["oseries1", "oseries1_2"]
92
+ finally:
93
+ pstore.del_models("oseries1_2")
94
+
95
+
96
+ @pytest.mark.dependency
97
+ def test_oseries_model_accessor(request, pstore):
98
+ depends(request, [f"test_store_model[{pstore.type}]"])
99
+ # repr
100
+ pstore.oseries_models.__repr__()
101
+ # get model names
102
+ ml = pstore.models["oseries1"]
103
+ ml_list1 = pstore.oseries_models["oseries1"]
104
+ assert len(ml_list1) == 1
105
+
106
+ # add model
107
+ pstore.models["oseries1_2"] = ml
108
+ ml_list2 = pstore.oseries_models["oseries1"]
109
+ assert len(ml_list2) == 2
110
+
111
+ # delete model
112
+ pstore.del_models("oseries1_2")
113
+ ml_list3 = pstore.oseries_models["oseries1"]
114
+ assert len(ml_list3) == 1
115
+
116
+
117
+ @pytest.mark.dependency
118
+ def test_store_model_missing_series(request, pstore):
119
+ depends(
120
+ request,
121
+ [
122
+ f"test_create_model[{pstore.type}]",
123
+ f"test_store_model[{pstore.type}]",
124
+ ],
125
+ )
126
+ ml = pstore.create_model("oseries1")
127
+ o = pstore.get_oseries("oseries1")
128
+ meta = pstore.get_metadata("oseries", "oseries1", as_frame=False)
129
+ pstore.del_models("oseries1")
130
+ pstore.del_oseries("oseries1")
131
+ try:
132
+ pstore.add_model(ml)
133
+ except LookupError:
134
+ pstore.add_oseries(o, "oseries1", metadata=meta)
135
+ pstore.add_model(ml)
136
+
137
+
138
+ @pytest.mark.dependency
139
+ def test_get_model(request, pstore):
140
+ depends(
141
+ request,
142
+ [
143
+ f"test_create_model[{pstore.type}]",
144
+ f"test_store_model[{pstore.type}]",
145
+ f"test_store_model_missing_series[{pstore.type}]",
146
+ ],
147
+ )
148
+ _ = pstore.conn.get_models("oseries1")
149
+
150
+
151
+ @pytest.mark.dependency
152
+ def test_del_model(request, pstore):
153
+ depends(
154
+ request,
155
+ [
156
+ f"test_create_model[{pstore.type}]",
157
+ f"test_store_model[{pstore.type}]",
158
+ f"test_store_model_missing_series[{pstore.type}]",
159
+ f"test_get_model[{pstore.type}]",
160
+ ],
161
+ )
162
+ pstore.conn.del_models("oseries1")
163
+
164
+
165
+ @pytest.mark.dependency
166
+ def test_create_models(pstore):
167
+ _ = pstore.create_models_bulk(
168
+ ["oseries1", "oseries2"], store=True, progressbar=False
169
+ )
170
+ _ = pstore.conn.models
171
+
172
+
173
+ @pytest.mark.dependency
174
+ def test_get_parameters(request, pstore):
175
+ depends(request, [f"test_create_models[{pstore.type}]"])
176
+ p = pstore.get_parameters(progressbar=False, param_value="initial")
177
+ assert p.index.size == 2
178
+ assert p.isna().sum().sum() == 0
179
+
180
+
181
+ @pytest.mark.dependency
182
+ def test_get_signatures(request, pstore):
183
+ depends(request, [f"test_create_models[{pstore.type}]"])
184
+ s = pstore.get_signatures(progressbar=False)
185
+ assert s.shape[1] == len(ps.stats.signatures.__all__)
186
+
187
+
188
+ @pytest.mark.dependency
189
+ def test_iter_models(request, pstore):
190
+ depends(request, [f"test_create_models[{pstore.type}]"])
191
+ _ = list(pstore.iter_models())
192
+
193
+
194
+ @pytest.mark.dependency
195
+ def test_solve_models_and_get_stats(request, pstore):
196
+ depends(request, [f"test_create_models[{pstore.type}]"])
197
+ _ = pstore.solve_models(
198
+ ignore_solve_errors=False, progressbar=False, parallel=False
199
+ )
200
+ stats = pstore.get_statistics(["evp", "aic"], progressbar=False)
201
+ assert stats.index.size == 2
202
+
203
+
204
+ @pytest.mark.dependency
205
+ def test_solve_models_parallel(request, pstore):
206
+ depends(request, [f"test_create_models[{pstore.type}]"])
207
+ _ = pstore.solve_models(ignore_solve_errors=False, progressbar=False, parallel=True)
208
+
209
+
210
+ def test_apply(request, pstore):
211
+ depends(request, [f"test_solve_models_and_get_stats[{pstore.type}]"])
212
+
213
+ def func(ml_name):
214
+ ml = pstore.conn.get_models(ml_name)
215
+ return ml.parameters.loc["recharge_A", "optimal"]
216
+
217
+ result = pstore.apply("models", func)
218
+ assert len(result) == 2
219
+
220
+
221
+ @pytest.mark.dependency
222
+ def test_save_and_load_model(request, pstore):
223
+ ml = pstore.create_model("oseries1")
224
+ ml.solve()
225
+ evp_ml = ml.stats.evp()
226
+ pstore.add_model(ml, overwrite=True)
227
+ ml2 = pstore.get_models(ml.name)
228
+ evp_ml2 = ml2.stats.evp()
229
+ assert allclose(evp_ml, evp_ml2)
230
+ assert pst.util.compare_models(ml, ml2)
231
+
232
+
233
+ def test_update_ts_settings(request, pstore):
234
+ pstore.set_check_model_series_values(False)
235
+
236
+ o = pstore.get_oseries("oseries2")
237
+ ml = ps.Model(o.loc[:"2013"], name="ml_oseries2")
238
+
239
+ pnam = pstore.get_nearest_stresses("oseries2", kind="prec").iloc[0]
240
+ p = pstore.get_stresses(pnam)
241
+ enam = pstore.get_nearest_stresses("oseries2", kind="evap").iloc[0]
242
+ e = pstore.get_stresses(enam)
243
+ rm = ps.RechargeModel(p.loc[:"2013"], e.loc[:"2013"])
244
+ ml.add_stressmodel(rm)
245
+ tmax = p.index.intersection(e.index).max()
246
+ ml.solve()
247
+
248
+ p2 = pstore.get_stresses("prec1")
249
+ sm = ps.StressModel(p2.loc[:"2013"], ps.Exponential(), "prec")
250
+ ml.add_stressmodel(sm)
251
+ pstore.add_model(ml)
252
+
253
+ ml2 = pstore.get_models(ml.name, update_ts_settings=True)
254
+
255
+ try:
256
+ assert ml2.oseries.settings["tmax"] == o.index[-1]
257
+ assert ml2.stressmodels["recharge"].prec.settings["tmax"] == tmax
258
+ assert ml2.stressmodels["recharge"].evap.settings["tmax"] == tmax
259
+ assert ml2.stressmodels["prec"].stress[0].settings["tmax"] == p2.index[-1]
260
+ except AssertionError:
261
+ pstore.del_models("ml_oseries2")
262
+ pstore.set_check_model_series_values(True)
263
+ raise
264
+
265
+
266
+ # @pytest.mark.dependency()
267
+ # def test_model_results(request, pstore):
268
+ # depends(request, [f"test_create_models[{pstore.type}]",
269
+ # f"test_solve_models[{pstore.type}]"])
270
+ # pstore.model_results(["oseries1", "oseries2"], progressbar=False)
271
+
272
+
273
+ def test_oseries_distances(pstore):
274
+ _ = pstore.get_nearest_oseries()
275
+
276
+
277
+ def test_repr(pstore):
278
+ pstore.__repr__()
279
+
280
+
281
+ def test_copy_dbase(pstore):
282
+ conn2 = pst.DictConnector("destination")
283
+ pst.util.copy_database(pstore.conn, conn2, overwrite=False, progressbar=True)
284
+
285
+
286
+ def test_to_from_zip(pstore):
287
+ if pstore.type == "arcticdb" and parse(ps.__version__) < parse("1.1.0"):
288
+ pytest.xfail("model datetime objects not supported")
289
+ zipname = f"test_{pstore.type}.zip"
290
+ pstore.to_zip(zipname, progressbar=False, overwrite=True)
291
+ conn = pst.DictConnector("test")
292
+ try:
293
+ store = pst.PastaStore.from_zip(zipname, conn)
294
+ assert not store.oseries.empty
295
+ finally:
296
+ os.remove(zipname)
297
+
298
+
299
+ def test_example_pastastore():
300
+ from pastastore.datasets import example_pastastore
301
+
302
+ _ = example_pastastore()
303
+
304
+
305
+ def test_validate_names():
306
+ from pastastore.util import validate_names
307
+
308
+ assert validate_names(s="(test)") == "test"
309
+ assert validate_names(d={"(test)": 2})["test"] == 2
310
+
311
+
312
+ def test_meta_with_name(pstore):
313
+ s = pd.Series(
314
+ index=pd.date_range("2020-01-01", periods=10, freq="D"),
315
+ data=np.arange(10),
316
+ dtype=float,
317
+ )
318
+ smeta = {"name": "not_what_i_want"}
319
+ pstore.add_stress(s, "what_i_want", kind="special", metadata=smeta)
320
+ assert "what_i_want" in pstore.stresses.index, "This is not right."
321
+ pstore.del_stress("what_i_want")
tests/test_004_yaml.py ADDED
@@ -0,0 +1,135 @@
1
+ # ruff: noqa: D100 D103
2
+ import os
3
+ import tempfile
4
+ from contextlib import contextmanager
5
+
6
+ import pytest
7
+ from pytest_dependency import depends
8
+
9
+ import pastastore as pst
10
+
11
+
12
+ @contextmanager
13
+ def tempyaml(yaml):
14
+ temp = tempfile.NamedTemporaryFile(delete=False)
15
+ temp.write(yaml.encode("utf-8"))
16
+ temp.close()
17
+ try:
18
+ yield temp.name
19
+ finally:
20
+ os.unlink(temp.name)
21
+
22
+
23
+ @pytest.mark.dependency
24
+ def test_load_yaml_rechargemodel(pstore):
25
+ yamlstr = """
26
+ my_first_model: # model name
27
+ oseries: oseries2 # head time series name, obtained from pastastore
28
+ stressmodels: # stressmodels dictionary
29
+ recharge: # name of the recharge stressmodel
30
+ class: RechargeModel # type of pastas StressModel
31
+ prec: prec2 # name of precipitation stress, from pastastore
32
+ evap: evap2 # name of evaporation stress, from pastastore
33
+ recharge: Linear # pastas recharge type
34
+ rfunc: Exponential # response function
35
+ """
36
+ with tempyaml(yamlstr) as f:
37
+ ml = pstore.yaml.load(f)[0]
38
+ pstore.add_model(ml)
39
+
40
+
41
+ @pytest.mark.dependency
42
+ def test_load_yaml_stressmodel(pstore):
43
+ yamlstr = """
44
+ my_second_model: # model name
45
+ oseries: oseries2 # head time series name, obtained from pastastore
46
+ stressmodels: # stressmodels dictionary
47
+ prec: # name of the recharge stressmodel
48
+ class: StressModel # type of pastas StressModel
49
+ stress: prec2 # name of precipitation stress, from pastastore
50
+ rfunc: Gamma # response function
51
+ """
52
+ with tempyaml(yamlstr) as f:
53
+ ml = pstore.yaml.load(f)[0]
54
+ pstore.add_model(ml)
55
+
56
+
57
+ @pytest.mark.dependency
58
+ def test_load_yaml_wellmodel(pstore):
59
+ yamlstr = """
60
+ my_third_model: # model name
61
+ oseries: oseries1 # head time series name, obtained from pastastore
62
+ stressmodels: # stressmodels dictionary
63
+ well: # name of the recharge stressmodel
64
+ class: WellModel # type of pastas StressModel
65
+ stress: well1 # name of well stress, obtained from pastastore
66
+ distances: [100]
67
+
68
+ """
69
+ with tempyaml(yamlstr) as f:
70
+ ml = pstore.yaml.load(f)[0]
71
+ pstore.add_model(ml)
72
+
73
+
74
+ @pytest.mark.dependency
75
+ def test_write_load_compare_yaml(request, pstore):
76
+ depends(
77
+ request,
78
+ [
79
+ f"test_load_yaml_rechargemodel[{pstore.type}]",
80
+ f"test_load_yaml_stressmodel[{pstore.type}]",
81
+ f"test_load_yaml_wellmodel[{pstore.type}]",
82
+ ],
83
+ )
84
+ pstore.yaml.export_models(modelnames=["my_first_model"])
85
+ ml1 = pstore.models["my_first_model"]
86
+ ml2 = pstore.yaml.load("my_first_model.yaml")[0]
87
+ assert (
88
+ pst.util.compare_models(ml1, ml2, detailed_comparison=True).iloc[1:, -1].all()
89
+ )
90
+ os.remove("my_first_model.yaml")
91
+
92
+
93
+ @pytest.mark.dependency
94
+ def test_write_yaml_per_oseries(request, pstore):
95
+ depends(
96
+ request,
97
+ [
98
+ f"test_load_yaml_rechargemodel[{pstore.type}]",
99
+ f"test_load_yaml_stressmodel[{pstore.type}]",
100
+ f"test_load_yaml_wellmodel[{pstore.type}]",
101
+ ],
102
+ )
103
+ pstore.yaml.export_stored_models_per_oseries()
104
+ os.remove("oseries1.yaml")
105
+ os.remove("oseries2.yaml")
106
+
107
+
108
+ @pytest.mark.dependency
109
+ def test_write_yaml_minimal(request, pstore):
110
+ depends(
111
+ request,
112
+ [
113
+ f"test_load_yaml_rechargemodel[{pstore.type}]",
114
+ f"test_load_yaml_stressmodel[{pstore.type}]",
115
+ f"test_load_yaml_wellmodel[{pstore.type}]",
116
+ ],
117
+ )
118
+ ml = pstore.models["my_first_model"]
119
+ pstore.yaml.export_model(ml, minimal_yaml=True)
120
+ os.remove("my_first_model.yaml")
121
+
122
+
123
+ @pytest.mark.dependency
124
+ def test_write_yaml_minimal_nearest(request, pstore):
125
+ depends(
126
+ request,
127
+ [
128
+ f"test_load_yaml_rechargemodel[{pstore.type}]",
129
+ f"test_load_yaml_stressmodel[{pstore.type}]",
130
+ f"test_load_yaml_wellmodel[{pstore.type}]",
131
+ ],
132
+ )
133
+ ml = pstore.models["my_third_model"]
134
+ pstore.yaml.export_model(ml, minimal_yaml=True, use_nearest=True)
135
+ os.remove("my_third_model.yaml")
@@ -0,0 +1,81 @@
1
+ # ruff: noqa: D100 D103
2
+ import matplotlib.pyplot as plt
3
+ import pytest
4
+ from conftest import requires_pkg
5
+ from pytest_dependency import depends
6
+
7
+ # %% plots
8
+
9
+
10
+ def test_plot_oseries(pstore):
11
+ ax = pstore.plots.oseries()
12
+ plt.close(ax.figure)
13
+
14
+
15
+ def test_plot_stresses(pstore):
16
+ ax = pstore.plots.stresses()
17
+ plt.close(ax.figure)
18
+
19
+
20
+ def test_plot_stresses_availability(pstore):
21
+ ax = pstore.plots.data_availability("stresses", kind="prec", set_yticks=True)
22
+ plt.close(ax.figure)
23
+
24
+
25
+ @pytest.mark.dependency
26
+ def test_cumulative_hist(request, pstore):
27
+ ml1 = pstore.create_model("oseries1")
28
+ pstore.add_model(ml1)
29
+ ml2 = pstore.create_model("oseries2")
30
+ pstore.add_model(ml2)
31
+ ax = pstore.plots.cumulative_hist()
32
+ plt.close(ax.figure)
33
+
34
+
35
+ # %% maps
36
+
37
+
38
+ @pytest.mark.bgmap
39
+ def test_map_oseries_w_bgmap(pstore):
40
+ ax = pstore.maps.oseries()
41
+ # only test bgmap once for pas
42
+ if pstore.type == "pas":
43
+ pstore.maps.add_background_map(ax)
44
+ plt.close(ax.figure)
45
+
46
+
47
+ @requires_pkg("adjustText")
48
+ def test_map_stresses(pstore):
49
+ ax = pstore.maps.stresses(kind="prec", adjust=True)
50
+ plt.close(ax.figure)
51
+
52
+
53
+ def test_map_stresslinks(pstore):
54
+ ml = pstore.create_model("oseries1", modelname="ml1")
55
+ pstore.add_model(ml)
56
+ ax = pstore.maps.stresslinks()
57
+ plt.close(ax.figure)
58
+
59
+
60
+ @pytest.mark.dependency
61
+ def test_map_models(request, pstore):
62
+ ax = pstore.maps.models()
63
+ plt.close(ax.figure)
64
+
65
+
66
+ @pytest.mark.dependency
67
+ def test_map_model(request, pstore):
68
+ depends(request, [f"test_map_models[{pstore.type}]"])
69
+ ax = pstore.maps.model("oseries1")
70
+ plt.close(ax.figure)
71
+
72
+
73
+ @pytest.mark.dependency
74
+ def test_map_modelstat(request, pstore):
75
+ ax = pstore.maps.modelstat("evp")
76
+ plt.close(ax.figure)
77
+
78
+
79
+ @pytest.mark.dependency
80
+ def test_list_ctx_providers(request, pstore):
81
+ pstore.maps._list_contextily_providers()