smashbox 1.0__py2.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.
Files changed (73) hide show
  1. smashbox/.spyproject/config/backups/codestyle.ini.bak +8 -0
  2. smashbox/.spyproject/config/backups/encoding.ini.bak +6 -0
  3. smashbox/.spyproject/config/backups/vcs.ini.bak +7 -0
  4. smashbox/.spyproject/config/backups/workspace.ini.bak +12 -0
  5. smashbox/.spyproject/config/codestyle.ini +8 -0
  6. smashbox/.spyproject/config/defaults/defaults-codestyle-0.2.0.ini +5 -0
  7. smashbox/.spyproject/config/defaults/defaults-encoding-0.2.0.ini +3 -0
  8. smashbox/.spyproject/config/defaults/defaults-vcs-0.2.0.ini +4 -0
  9. smashbox/.spyproject/config/defaults/defaults-workspace-0.2.0.ini +6 -0
  10. smashbox/.spyproject/config/encoding.ini +6 -0
  11. smashbox/.spyproject/config/vcs.ini +7 -0
  12. smashbox/.spyproject/config/workspace.ini +12 -0
  13. smashbox/__init__.py +8 -0
  14. smashbox/asset/flwdir/flowdir_fr_1000m.tif +0 -0
  15. smashbox/asset/outlets/.Rhistory +0 -0
  16. smashbox/asset/outlets/db_bnbv_fr.csv +142704 -0
  17. smashbox/asset/outlets/db_bnbv_light.csv +42084 -0
  18. smashbox/asset/outlets/db_sites.csv +8700 -0
  19. smashbox/asset/outlets/db_stations.csv +2916 -0
  20. smashbox/asset/outlets/db_stations_example.csv +19 -0
  21. smashbox/asset/outlets/edit_database.py +185 -0
  22. smashbox/asset/outlets/readme.txt +5 -0
  23. smashbox/asset/params/ci.tif +0 -0
  24. smashbox/asset/params/cp.tif +0 -0
  25. smashbox/asset/params/ct.tif +0 -0
  26. smashbox/asset/params/kexc.tif +0 -0
  27. smashbox/asset/params/kmlt.tif +0 -0
  28. smashbox/asset/params/llr.tif +0 -0
  29. smashbox/asset/setup/setup_rhax_gr4_dt3600.yaml +15 -0
  30. smashbox/asset/setup/setup_rhax_gr4_dt900.yaml +15 -0
  31. smashbox/asset/setup/setup_rhax_gr5_dt3600.yaml +15 -0
  32. smashbox/asset/setup/setup_rhax_gr5_dt900.yaml +15 -0
  33. smashbox/init/README.md +3 -0
  34. smashbox/init/__init__.py +3 -0
  35. smashbox/init/multimodel_statistics.py +405 -0
  36. smashbox/init/param.py +799 -0
  37. smashbox/init/smashbox.py +186 -0
  38. smashbox/model/__init__.py +1 -0
  39. smashbox/model/atmos_data_connector.py +518 -0
  40. smashbox/model/mesh.py +185 -0
  41. smashbox/model/model.py +829 -0
  42. smashbox/model/setup.py +109 -0
  43. smashbox/plot/__init__.py +1 -0
  44. smashbox/plot/myplot.py +1133 -0
  45. smashbox/plot/plot.py +1662 -0
  46. smashbox/read_inputdata/__init__.py +1 -0
  47. smashbox/read_inputdata/read_data.py +1229 -0
  48. smashbox/read_inputdata/smashmodel.py +395 -0
  49. smashbox/stats/__init__.py +1 -0
  50. smashbox/stats/mystats.py +1632 -0
  51. smashbox/stats/stats.py +2022 -0
  52. smashbox/test.py +532 -0
  53. smashbox/test_average_stats.py +122 -0
  54. smashbox/test_mesh.r +8 -0
  55. smashbox/test_mesh_from_graffas.py +69 -0
  56. smashbox/tools/__init__.py +1 -0
  57. smashbox/tools/geo_toolbox.py +1028 -0
  58. smashbox/tools/tools.py +461 -0
  59. smashbox/tutorial_R.r +182 -0
  60. smashbox/tutorial_R_graffas.r +88 -0
  61. smashbox/tutorial_R_graffas_local.r +33 -0
  62. smashbox/tutorial_python.py +102 -0
  63. smashbox/tutorial_readme.py +261 -0
  64. smashbox/tutorial_report.py +58 -0
  65. smashbox/tutorials/Python_tutorial.md +124 -0
  66. smashbox/tutorials/R_Graffas_tutorial.md +153 -0
  67. smashbox/tutorials/R_tutorial.md +121 -0
  68. smashbox/tutorials/__init__.py +6 -0
  69. smashbox/tutorials/generate_doc.md +7 -0
  70. smashbox-1.0.dist-info/METADATA +998 -0
  71. smashbox-1.0.dist-info/RECORD +73 -0
  72. smashbox-1.0.dist-info/WHEEL +5 -0
  73. smashbox-1.0.dist-info/licenses/LICENSE +100 -0
smashbox/test.py ADDED
@@ -0,0 +1,532 @@
1
+ if __name__ == "__main__":
2
+
3
+ import smashbox
4
+
5
+ from smashbox import tools
6
+
7
+ @tools.tools.autocast_args
8
+ def test(
9
+ a: int | None = None,
10
+ b: None | int = None,
11
+ c: int | None = 1,
12
+ d: int = 2,
13
+ e: None = None,
14
+ f: None | dict | tuple = None,
15
+ g=1,
16
+ ):
17
+
18
+ print(a, b, c, d, e)
19
+
20
+ test(a=1.0, b=1.0, c=1.0, d=1.0, e=None, f=(2,), g=2)
21
+
22
+ # Main object creation
23
+ sb = smashbox.SmashBox()
24
+
25
+ # Main input parameters of main object: class param, attribute 'myparam'
26
+ # sb.currentmodel #current active model
27
+ sb.myparam.list_param() # list the parameters of the current active model
28
+ sb.myparam.set_param(
29
+ "outlets_database",
30
+ "/home/maxime/DEV/smashbox/smashbox/asset/outlets/db_stations_example.csv",
31
+ )
32
+
33
+ sb.myparam.set_param(
34
+ "outlets_database_fields",
35
+ {"coord_x": "X_L93", "coord_y": "Y_L93", "area": "SURF", "id": "ID_HYDRO"},
36
+ ) # change/update/set the value of the parameter 'outlets_database_fields'.
37
+
38
+ sb.myparam.set_param(
39
+ "smash_parameters", "/home/maxime/DEV/smashbox/smashbox/asset/params"
40
+ ) # change the value of myparam used byRealCollobrier
41
+
42
+ # Read/write param
43
+ # sb.myparam.write_param("param.yaml") #write smashbox param
44
+ sb.myparam.load_param("param.yaml") # load smashbox param
45
+
46
+ # New model creation
47
+ sb.newmodel(
48
+ "RealCollobrier"
49
+ ) # create a new model named RealCollobrier and copy the previous parameters used for mymodel1 (default behaviour, but it can turned off)
50
+
51
+ # create an second model with different parameters
52
+ sb.myparam.param.setup_file = "setup_rhax_gr5_dt3600.yaml"
53
+ sb.myparam.set_param(
54
+ "outlets_database_fields",
55
+ {"coord_x": "X", "coord_y": "Y", "area": "area", "id": "Nom"},
56
+ ) # change/update/set the value of the parameter 'outlets_database_fields'.
57
+ sb.newmodel(
58
+ "Lez"
59
+ ) # create a new model named RealCollobrier and copy the previous parameters used for mymodel1 (default behaviour, but it can turned off)
60
+
61
+ # Remove a model
62
+ sb.delmodel("Lez")
63
+
64
+ # Param associated to the model (hidden) has been copied
65
+ sb.RealCollobrier._myparam.list_param() # Notice that myparam is also stored in each model object. So you can access to the model param inside the model attribute.
66
+ sb.RealCollobrier._myparam.param.epsg
67
+
68
+ # Setup utilities
69
+ sb.RealCollobrier.mysetup.setup # print the setup to the screen
70
+ # sb.RealCollobrier.mysetup.write_setup("setup.yaml") #Write the Smash setup
71
+ sb.RealCollobrier.mysetup.load_setup("setup.yaml") # Read a custom Smash setup
72
+ sb.RealCollobrier.mysetup.update_setup(
73
+ {
74
+ "hydrological_module": "gr4",
75
+ "end_time": "2014-01-01 12:00",
76
+ "start_time": "2014-01-01 01:00",
77
+ "pet_directory": "/home/maxime/DATA/ETP-SFR-FRA-INTERA_L93",
78
+ "prcp_directory": "/home/maxime/DATA/PLUIE",
79
+ "qobs_directory": "/home/maxime/DATA/QOBS",
80
+ }
81
+ ) # Change value of the Smash setup
82
+ sb.RealCollobrier.mysetup.setup # print the setup to the screen
83
+
84
+ # Mesh utilities (hidden)
85
+ sb.RealCollobrier.mymesh.mesh # print the mesh to the screen
86
+ sb.RealCollobrier.mymesh.make_mesh(
87
+ sb.RealCollobrier._myparam.param
88
+ ) # Undirect method to build mesh, depend on myparam (unrecomended)
89
+ sb.RealCollobrier.mymesh.mesh
90
+ sb.RealCollobrier.mymesh.write_mesh("mesh.hdf5")
91
+ sb.RealCollobrier.mymesh.load_mesh("mesh.hdf5")
92
+ sb.RealCollobrier.mymesh.mesh # print the mesh to the screen
93
+
94
+ # Model utilities
95
+ sb.RealCollobrier.make_mesh() # direct method to build the mesh (recommended)
96
+ sb.RealCollobrier.build_model() # build the model with smash.Model()
97
+ sb.RealCollobrier.load_smashparam() # extract the smash parameter from a parameters set and fill the attribute mysmashparameter
98
+ sb.RealCollobrier.write_smashparam(
99
+ "smashparam.hdf5"
100
+ ) # write the extracted parameter in an hdf5 database
101
+ sb.RealCollobrier.write_smashparam_to_geotiff("geotiff_smashparam")
102
+ sb.RealCollobrier.make_model(
103
+ run=True
104
+ ) # direct build, extract param and run (default is True). Use option run=False to only build the model and extract parameter
105
+
106
+ # Stat utilities
107
+
108
+ # plot utilities
109
+ sb.RealCollobrier.myplot.plot_mesh()
110
+
111
+ import smashbox
112
+ import smash
113
+ from smashbox.plot import plot
114
+
115
+ # Testing graffas connector
116
+ import numpy as np
117
+
118
+ bbox = {"left": 925000.0, "bottom": 6230000.0, "right": 974000.0, "top": 6255000.0}
119
+
120
+ # graffas_prcp = np.zeros(shape=(145, 170, 1300))
121
+ # rng = np.random.default_rng()
122
+ # graffas_prcp = (
123
+ # graffas_prcp
124
+ # + rng.multinomial(20, [0.2, 0.8], size=graffas_prcp.shape)[:, :, :, 0]
125
+ # )
126
+ # graffas_pet = np.zeros(shape=(142, 166, 17520)) + 1.0
127
+
128
+ # Main object creation
129
+ sb = smashbox.SmashBox()
130
+
131
+ sb.myparam.set_param("bbox", bbox)
132
+ sb.myparam.set_param(
133
+ "smash_parameters", "/home/maxime/DEV/smashbox/smashbox/asset/params"
134
+ )
135
+ sb.myparam.set_param(
136
+ "outlets_database",
137
+ "/home/maxime/DEV/smashbox/smashbox/asset/outlets/db_sites.csv",
138
+ )
139
+ # sb.myparam.set_param(
140
+ # "outlets_shapefile", "/home/maxime/DATA/BNBVlight/BNBV_light_bassins.shp"
141
+ # )
142
+ # sb.myparam.set_param("enhanced_smash_input_data", True)
143
+
144
+ sb.newmodel("graffas_zone")
145
+ sb.graffas_zone.mysetup.load_setup("setup_rhax_gr4_dt3600")
146
+
147
+ sb.graffas_zone.mysetup.update_setup(
148
+ {
149
+ "pet_directory": "/home/maxime/DATA/ETP-SFR-FRA-INTERA_L93",
150
+ "prcp_directory": "/home/maxime/DATA/PLUIE",
151
+ "qobs_directory": "/home/maxime/DATA/QOBS",
152
+ }
153
+ ) # Change value of the Smash setup
154
+
155
+ sb.graffas_zone.generate_mesh() # direct method to build the mesh (recommended)
156
+
157
+ sb.graffas_zone.myplot.plot_catchment_surface_consistency(
158
+ fig_settings={
159
+ "figname": "../images/mesh_surface_consistency.png",
160
+ "xsize": 5,
161
+ "ysize": 5,
162
+ "font_ratio": 2,
163
+ },
164
+ ax_settings={"title_fontsize": 12},
165
+ )
166
+ sb.graffas_zone.myplot.plot_catchment_surface_error(
167
+ fig_settings={
168
+ "figname": "../images/mesh_surface_error.png",
169
+ "xsize": 5,
170
+ "ysize": 5,
171
+ "font_ratio": 2,
172
+ },
173
+ ax_settings={"title_fontsize": 12},
174
+ )
175
+
176
+ sb.graffas_zone.myplot.plot_mesh(
177
+ fig_settings={
178
+ "figname": "../images/mesh.png",
179
+ "xsize": 10,
180
+ "ysize": 10,
181
+ },
182
+ ax_settings={"title_fontsize": 20},
183
+ )
184
+
185
+ nrow = sb.graffas_zone.mymesh.mesh["nrow"]
186
+ ncol = sb.graffas_zone.mymesh.mesh["ncol"]
187
+ chunk_size = 18
188
+ nb_chunk = 21
189
+ graffas_prcp = np.zeros(shape=(nrow, ncol, nb_chunk * chunk_size))
190
+ fctr = 100
191
+ for i in range(nb_chunk):
192
+ graffas_prcp[:, :, i * chunk_size : (i + 1) * chunk_size] = (
193
+ fctr
194
+ * np.arange(i * chunk_size, (i + 1) * chunk_size)
195
+ / (chunk_size * nb_chunk)
196
+ * np.cos(np.arange(0, chunk_size * 10, 10) * np.pi / 180)
197
+ )
198
+ graffas_prcp = np.where(graffas_prcp < 0, 0.0, graffas_prcp)
199
+
200
+ sb.graffas_zone.atmos_data_connector(input_prcp=graffas_prcp)
201
+ # sb.graffas_zone.atmos_data_connector(input_prcp=graffas_prcp, input_pet=graffas_pet)
202
+
203
+ sb.graffas_zone.model()
204
+
205
+ sb.graffas_zone.myplot.plot_parameters(
206
+ param="cp",
207
+ fig_settings={
208
+ "figname": "../images/param_cp.png",
209
+ "xsize": 10,
210
+ "ysize": 10,
211
+ },
212
+ ax_settings={"title_fontsize": 12},
213
+ )
214
+ sb.graffas_zone.myplot.multiplot_parameters(
215
+ fig_settings={
216
+ "figname": "../images/multiplot_param.png",
217
+ "xsize": 10,
218
+ "ysize": 10,
219
+ "font_ratio": 1,
220
+ },
221
+ ax_settings={"title_fontsize": 10, "font_ratio": 1},
222
+ )
223
+
224
+ # sb.graffas_zone.generate_model(
225
+ # return_options={"q_domain": True}
226
+ # ) # build and run the model with smash.Model()
227
+
228
+ sb.graffas_zone.forward_run(invert_states=True, return_options={"q_domain": True})
229
+
230
+ # sb.graffas_zone.myplot.plot_parameters(param="cp")
231
+ # sb.graffas_zone.myplot.multiplot_parameters()
232
+ # import matplotlib.pyplot as plt
233
+ # from matplotlib.colors import LogNorm, SymLogNorm
234
+
235
+ # q = sb.graffas_zone.extra_smash_results.q_domain[:, :, 500]
236
+ # q = np.where(es.graffas_zone.mysmashmodel.mesh.active_cell == 0, np.nan, q)
237
+ # plt.imshow(q, norm=SymLogNorm(1e-4))
238
+
239
+ rand_q = np.random.rand(*sb.graffas_zone.mysmashmodel.response_data.q.shape)
240
+ sb.graffas_zone.mysmashmodel.response_data.q[
241
+ :
242
+ ] = sb.graffas_zone.mysmashmodel.response.q[
243
+ :
244
+ ] + sb.graffas_zone.mysmashmodel.response.q[
245
+ :
246
+ ] * (
247
+ rand_q[:] - 0.5
248
+ ) * np.repeat(
249
+ np.arange(rand_q.shape[0]).reshape((rand_q.shape[0], 1)), rand_q.shape[1], axis=1
250
+ )
251
+
252
+ sb.graffas_zone.mystats.fspatial_stats()
253
+ sb.graffas_zone.mystats.foutlets_stats()
254
+ sb.graffas_zone.mystats.fmisfit_stats()
255
+
256
+ sb.graffas_zone.mystats.fquantile_stats(
257
+ chunk_size=3,
258
+ estimate_method="MLE",
259
+ ncpu=6,
260
+ fit="gumbel",
261
+ compute_uncertainties=True,
262
+ )
263
+
264
+ # sb.graffas_zone.mystats.misfit.rmse()
265
+ # sb.graffas_zone.mystats.misfit.nse(outlets_name=["MedEst_528", "MedEst_617"])
266
+ # res = sb.graffas_zone.mystats.stats_misfit()
267
+
268
+ from smashbox.stats import stats
269
+
270
+ # results = stats.spatial_quantiles(
271
+ # sb.graffas_zone.extra_smash_results.q_domain,
272
+ # chunk_size=3,
273
+ # quantile_duration=48,
274
+ # estimate_method="MLE",
275
+ # )
276
+
277
+ # results = stats.spatial_quantiles(
278
+ # sb.graffas_zone.extra_smash_results.q_domain,
279
+ # chunk_size=3,
280
+ # quantile_duration=72,
281
+ # estimate_method="MLE",
282
+ # )
283
+
284
+ # array = stats.time_resample_array(
285
+ # array=es.graffas_zone.extra_smash_results.q_domain,
286
+ # quantile_duration=1,
287
+ # model_time_step=3600,
288
+ # t_axis=2,
289
+ # )
290
+ # array.shape
291
+
292
+ # stats.compute_maxima(
293
+ # array=array,
294
+ # t_axis=2,
295
+ # nb_minimum_chunks=4,
296
+ # chunk_size=2,
297
+ # quantile_duration=48,
298
+ # )
299
+
300
+ # array = stats.time_resample_array(
301
+ # array=es.graffas_zone.extra_smash_results.q_domain,
302
+ # quantile_duration=48,
303
+ # model_time_step=3600,
304
+ # t_axis=2,
305
+ # )
306
+ # array.shape
307
+
308
+ # maxima = stats.compute_maxima(
309
+ # array=array,
310
+ # t_axis=2,
311
+ # nb_minimum_chunks=5,
312
+ # chunk_size=2,
313
+ # quantile_duration=48,
314
+ # )
315
+
316
+ # sb.graffas_zone.mystats.fmaxima_stats(chunk_size=4, cumulated_maxima=False)
317
+
318
+ # sb.graffas_zone.mystats.fstats_quantile_2(
319
+ # chunk_size=10, estimate_method="MLE", ncpu=6, fit="gumbel"
320
+ # )
321
+
322
+ # sb.graffas_zone.mystats.fmaxima_stats(chunk_size=2, cumulated_maxima=True)
323
+
324
+ # sb.graffas_zone.mystats.quantile_stats.spatial_cumulated_maxima[100, 10, :, 0]
325
+
326
+ sb.graffas_zone.myplot.plot_spatial_stats(
327
+ fig_settings={
328
+ "figname": "../images/spatial_stats_max.png",
329
+ "xsize": 10,
330
+ "ysize": 10,
331
+ },
332
+ ax_settings={"font_ratio": 1.0},
333
+ )
334
+
335
+ # results = stats.fit_quantile(
336
+ # maxima=es.graffas_zone.mystats.quantile_stats.spatial_cumulated_maxima[
337
+ # :, :, :, 0
338
+ # ],
339
+ # t_axis=2,
340
+ # return_periods=[2, 5, 10, 20, 50, 100],
341
+ # fit="gumbel",
342
+ # estimate_method="MLE",
343
+ # quantile_duration=1,
344
+ # ncpu=6,
345
+ # )
346
+ # results = stats.parametric_bootstrap_uncertainties(q_results=results, ncpu=6)
347
+
348
+ # fig, ax = smashbox.plot.plot.plot_xy_quantile(
349
+ # results,
350
+ # X=100,
351
+ # Y=10,
352
+ # fig_settings={"figname": "../images/quantile_XY.png", "font_ratio": 2},
353
+ # ax_settings={"legend_fontsize": 20},
354
+ # )
355
+
356
+ sb.graffas_zone.myplot.plot_xy_quantile(
357
+ X=20,
358
+ Y=25,
359
+ fig_settings={"figname": "../images/quantile_XY.png", "font_ratio": 2},
360
+ ax_settings={"legend_fontsize": 20},
361
+ )
362
+
363
+ sb.graffas_zone.myplot.plot_outlets_quantile(
364
+ fig_settings={
365
+ "figname": "../images/quantile_outlets.png",
366
+ "xsize": 10,
367
+ "ysize": 10,
368
+ },
369
+ ax_settings={"font_ratio": 0.5},
370
+ )
371
+
372
+ sb.graffas_zone.myplot.plot_spatial_quantile(
373
+ T=2,
374
+ duration=1,
375
+ fig_settings={
376
+ "figname": "../images/spatial_quantile.png",
377
+ "xsize": 10,
378
+ "ysize": 10,
379
+ },
380
+ ax_settings={"font_ratio": 1.5},
381
+ )
382
+
383
+ sb.graffas_zone.myplot.multiplot_spatial_quantile(
384
+ duration=1,
385
+ fig_settings={
386
+ "figname": "../images/multiplot_spatial_quantile.png",
387
+ "xsize": 10,
388
+ "ysize": 10,
389
+ },
390
+ ax_settings={"font_ratio": 1.0},
391
+ )
392
+
393
+ # fig, ax = plot.plot_chro(
394
+ # sb.graffas_zone.mysmashmodel.response.q,
395
+ # ax_settings={"title": "my title", "title_fontsize": 42},
396
+ # plot_settings={"label": "discharge at gauge 0"},
397
+ # )
398
+
399
+ sb.graffas_zone.myplot.plot_hydrograph(
400
+ fig_settings={
401
+ "figname": "../images/hydrogram.png",
402
+ "xsize": 10,
403
+ "ysize": 10,
404
+ },
405
+ )
406
+
407
+ sb.graffas_zone.myplot.plot_misfit(
408
+ misfit="nse",
409
+ fig_settings={
410
+ "figname": "../images/nse.png",
411
+ "xsize": 10,
412
+ "ysize": 7,
413
+ },
414
+ )
415
+
416
+ sb.graffas_zone.myplot.multiplot_misfit(
417
+ fig_settings={
418
+ "figname": "../images/multiplot_misfit.png",
419
+ "xsize": 10,
420
+ "ysize": 10,
421
+ },
422
+ )
423
+
424
+ sb.graffas_zone.myplot.plot_misfit_map(
425
+ misfit="nse",
426
+ fig_settings={"figname": "../images/misfit_map.png", "xsize": 10, "ysize": 10},
427
+ ax_settings={"font_ratio": 1},
428
+ )
429
+
430
+ # sb.graffas_zone.export_parameters()
431
+
432
+ import smashbox
433
+ import smash
434
+ from smashbox.plot import plot
435
+
436
+ # Testing graffas connector
437
+ import numpy as np
438
+
439
+ bbox = {"left": 925000.0, "bottom": 6230000.0, "right": 974000.0, "top": 6255000.0}
440
+
441
+ sb = smashbox.SmashBox()
442
+
443
+ sb.myparam.set_param("bbox", bbox)
444
+ sb.myparam.set_param("outlets_database", "db_sites")
445
+ sb.myparam.set_param(
446
+ "outlets_shapefile",
447
+ "/home/maxime/DEV/smashbox/smashbox/asset/shapefile/Hydro_Bassins.shp",
448
+ )
449
+
450
+ sb.myparam.set_param(
451
+ "outlets_database_fields",
452
+ {
453
+ "coord_x": "X_L93",
454
+ "coord_y": "Y_L93",
455
+ "area": "SURF",
456
+ "id": "CODE_SITE",
457
+ },
458
+ )
459
+
460
+ sb.newmodel("rex")
461
+
462
+ sb.rex.mysetup.update_setup(
463
+ {
464
+ "pet_directory": "/home/maxime/DATA/ETP-SFR-FRA-INTERA_L93",
465
+ "prcp_directory": "/home/maxime/DATA/PLUIE",
466
+ "qobs_directory": "/home/maxime/DATA/QOBS_SITE_60M",
467
+ "start_time": "2014-01-01 00:00",
468
+ "end_time": "2014-02-01 00:00",
469
+ }
470
+ )
471
+
472
+ sb.rex.generate_mesh(query="(SURF>20)")
473
+ sb.rex.myplot.plot_mesh()
474
+
475
+ graffas_prcp = np.zeros(shape=(25, 49, 365 * 24 * 5)) + 1
476
+ rng = np.random.default_rng()
477
+ graffas_prcp = (
478
+ graffas_prcp
479
+ + rng.multinomial(20, [0.2, 0.8], size=graffas_prcp.shape)[:, :, :, 0]
480
+ )
481
+
482
+ sb.rex.atmos_data_connector(input_prcp=graffas_prcp[:, :, :])
483
+ sb.rex.forward_run(return_options={"q_domain": True})
484
+
485
+ sb.rex.mystats.fmaxima_stats(t_axis=2.0, chunk_size=365, cumulated_maxima=True)
486
+
487
+ graffas_prcp = np.zeros(shape=(25, 49, 365 * 24 * 5)) + 1
488
+ rng = np.random.default_rng()
489
+ graffas_prcp = (
490
+ graffas_prcp
491
+ + rng.multinomial(20, [0.2, 0.8], size=graffas_prcp.shape)[:, :, :, 0]
492
+ )
493
+
494
+ sb.rex.atmos_data_connector(input_prcp=graffas_prcp[:, :, :])
495
+ sb.rex.forward_run(invert_states=True, return_options={"q_domain": True})
496
+
497
+ sb.rex.mystats.fmaxima_stats(chunk_size=365, cumulated_maxima=True)
498
+
499
+ sb.rex.mystats.fquantile_stats(
500
+ chunk_size=365,
501
+ estimate_method="MLE",
502
+ ncpu=6,
503
+ fit="gumbel",
504
+ compute_uncertainties=True,
505
+ )
506
+
507
+ sb.rex.mystats.fquantile_stats2(
508
+ chunk_size=365, estimate_method="MLE", ncpu=6, fit="gumbel"
509
+ )
510
+
511
+ sb.rex.myplot.plot_outlets_quantile()
512
+ sb.rex.myplot.multiplot_spatial_quantile()
513
+
514
+ array = stats.time_resample_array(
515
+ array=sb.rex.extra_smash_results.q_domain,
516
+ quantile_duration=72,
517
+ model_time_step=3600,
518
+ t_axis=2,
519
+ )
520
+ array.shape
521
+
522
+ maxima = stats.compute_maxima(
523
+ array=array,
524
+ t_axis=2,
525
+ nb_minimum_chunks=4,
526
+ chunk_size=365,
527
+ quantile_duration=72,
528
+ )
529
+
530
+ sb.rex.mystats.fquantile_stats(
531
+ chunk_size=365, estimate_method="MLE", ncpu=6, fit="gumbel"
532
+ )
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Created on Tue Nov 4 14:11:45 2025
5
+
6
+ @author: maxime
7
+ """
8
+
9
+ if __name__ == "__main__":
10
+ ################ Test rapoort ################
11
+ import smashbox
12
+ import numpy as np
13
+
14
+ bbox = {"left": 875000.0, "bottom": 6228000.0, "right": 1001000.0, "top": 6320000.0}
15
+
16
+ sb = smashbox.SmashBox()
17
+
18
+ sb.myparam.set_param("bbox", bbox)
19
+
20
+ sb.newmodel("rex")
21
+
22
+ sb.rex.mysetup.update_setup({"read_pet": False})
23
+
24
+ sb.rex.generate_mesh(
25
+ query="(SURF>200) & (INFLUENCE=='Influence nulle ou faible')", area_error_th=0.2
26
+ )
27
+
28
+ ##########################################################
29
+ # Artificial rainfall
30
+ nrow = sb.rex.mymesh.mesh["nrow"]
31
+ ncol = sb.rex.mymesh.mesh["ncol"]
32
+ prcp = np.random.randint(-100, 100, size=(nrow, ncol, 24 * 30))
33
+ prcp = np.where(prcp < 0, 0.0, prcp)
34
+ ###########################################################
35
+
36
+ def model_creation(obj, prcp, qnoise):
37
+
38
+ obj.atmos_data_connector(input_prcp=prcp, input_dt=3600.0)
39
+ obj.model()
40
+
41
+ obj.mysmashmodel.atmos_data.pet = 0.0
42
+ obj.forward_run(return_options={"q_domain": True}, invert_states=True)
43
+
44
+ ##########################################################
45
+ # Artificial observed discharge
46
+ rand = (
47
+ np.random.randint(-qnoise, qnoise, obj.mysmashmodel.response_data.q.shape)
48
+ / 100.0
49
+ )
50
+ qsim = sb.rex.mysmashmodel.response.q[:]
51
+ obj.mysmashmodel.response_data.q = qsim + qsim * rand
52
+ ##########################################################
53
+
54
+ model_creation(sb.rex, prcp, 20.0)
55
+
56
+ sb.rex.mystats.fmisfit_stats()
57
+ sb.rex.mystats.foutlets_stats()
58
+ sb.rex.mystats.fspatial_stats()
59
+ sb.rex.mystats.fquantile_stats(
60
+ chunk_size=5,
61
+ estimate_method="MLE",
62
+ ncpu=6,
63
+ fit="gumbel",
64
+ compute_uncertainties=False,
65
+ )
66
+
67
+ sb.copymodel("rex", "rex2")
68
+ model_creation(sb.rex2, prcp * 1.5, 30.0)
69
+
70
+ sb.rex2.mystats.fmisfit_stats()
71
+ sb.rex2.mystats.foutlets_stats()
72
+ sb.rex2.mystats.fspatial_stats()
73
+ # sb.rex2.mystats.quantile_stats = sb.rex.mystats.quantile_stats
74
+ sb.rex2.mystats.fquantile_stats(
75
+ chunk_size=5,
76
+ estimate_method="MLE",
77
+ ncpu=6,
78
+ fit="gumbel",
79
+ compute_uncertainties=False,
80
+ )
81
+
82
+ sb.multimodel_statistics._get_model_list()
83
+
84
+ sb.multimodel_statistics.compute_multimodel_statistics()
85
+
86
+ sb.multimodel_statistics.compute_multimodel_statistics_misfit()
87
+ sb.multimodel_statistics.compute_multimodel_statistics_outlets()
88
+ sb.multimodel_statistics.compute_multimodel_statistics_outlets(obs=True)
89
+ sb.multimodel_statistics.compute_multimodel_statistics_spatial()
90
+ sb.multimodel_statistics.compute_multimodel_statistics_quantile()
91
+
92
+ sb.multimodel_statistics.multimodel_quantile_stats.Quantile_1h.Q_th.data.shape
93
+ sb.multimodel_statistics.multimodel_quantile_stats.Quantile_1h.Q_th.data[0, 60, 50, 0]
94
+ sb.multimodel_statistics.multimodel_quantile_stats.Quantile_1h.Q_th.data[1, 60, 50, 0]
95
+ sb.rex.mystats.quantile_stats.Quantile_1h.Q_th[60, 50, 0]
96
+ sb.rex2.mystats.quantile_stats.Quantile_1h.Q_th[60, 50, 0]
97
+
98
+ from smashbox.plot import plot
99
+
100
+ fig, ax = plot.plot_image(
101
+ sb.multimodel_statistics.multimodel_quantile_stats.Quantile_1h.Q_th.median[
102
+ :, :, 0
103
+ ]
104
+ )
105
+ fig.show()
106
+ fig, ax = plot.plot_image(sb.rex.mystats.quantile_stats.Quantile_1h.Q_th[:, :, 0])
107
+ fig.show()
108
+ fig, ax = plot.plot_image(sb.rex2.mystats.quantile_stats.Quantile_1h.Q_th[:, :, 0])
109
+ fig.show()
110
+
111
+ fig, ax = plot.plot_misfit(
112
+ sb.multimodel_statistics.multimodel_misfit_stats.nse.mean,
113
+ )
114
+ fig.show()
115
+ fig, ax = plot.plot_misfit(
116
+ sb.rex.mystats.misfit_stats.results.nse,
117
+ )
118
+ fig.show()
119
+ fig, ax = plot.plot_misfit(
120
+ sb.rex2.mystats.misfit_stats.results.nse,
121
+ )
122
+ fig.show()
smashbox/test_mesh.r ADDED
@@ -0,0 +1,8 @@
1
+ #import reticulate module to be able to import python module
2
+ library(reticulate)
3
+ use_virtualenv("~/python_venv/smashbox") #use a specific python environnement
4
+
5
+
6
+ #import the package smashbox (must be installed in the python environnement)
7
+ smashbox <- import("smashbox")
8
+