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/init/param.py ADDED
@@ -0,0 +1,799 @@
1
+ import smashbox
2
+ import os
3
+ import yaml
4
+ from smashbox.tools.tools import check_asset_path, print_tree
5
+
6
+
7
+ class param:
8
+ """
9
+ Class param(): object which own :
10
+ - one attribute `param` with all necessary parameters fro building
11
+ an hydrological model with SmashBoxfunctions
12
+ - Some functions to maniuplate these parameters (stored in attribute param)
13
+
14
+ attributes
15
+ ----------
16
+
17
+ param : class smashboxparam()
18
+ Class which stores the main parameters
19
+
20
+ """
21
+
22
+ def __init__(self):
23
+
24
+ # self._parent_class=parent_class
25
+ self.param = smashboxparam()
26
+ """parent variable for class smashboxparam with all main parameters
27
+ of smashbox.
28
+ """
29
+
30
+ def list_param(self):
31
+ """
32
+ List all parameters in self.param
33
+
34
+ Examples
35
+ --------
36
+
37
+ >>> es=smashbox.SmashBox()
38
+ >>> sb.newmodel("RealCollobrier")
39
+ >>> sb.RealCollobrier.list_param()
40
+
41
+ """
42
+ for name, value in vars(type(self.param)).items():
43
+ if isinstance(value, property):
44
+ print(f"{name}={getattr(self.param, name)}")
45
+
46
+ def set_param(self, attr, value):
47
+ """
48
+ Setter for class attribute param().
49
+
50
+ parameters
51
+ ----------
52
+ attr : str
53
+ name of the attributes
54
+
55
+ value: any
56
+ value of the attribute
57
+
58
+ example
59
+ -------
60
+
61
+ self.set_param("flowdir", "path/to/the/flowdir")
62
+ """
63
+ setattr(self.param, attr, value)
64
+
65
+ def set_param_as_dict(self, param_dict):
66
+ """
67
+ Setter for class attribute param() from a dictionary of keys/values.
68
+
69
+ parameters
70
+ ----------
71
+ param_dict : dict
72
+ Dictionary with keys and values
73
+
74
+ example
75
+ -------
76
+
77
+ self.set_param_as_dict({"flowdir": "path/to/the/flowdir","epsg":2154})
78
+ """
79
+ for key, value in param_dict.items():
80
+ self.set_param(key, value)
81
+
82
+ def get_param(self, attr):
83
+ """
84
+ Getter for class attribute param().
85
+
86
+ parameters
87
+ ----------
88
+ attr : str
89
+ name of the attributes
90
+
91
+ return:
92
+ -------
93
+ any, the value stored in the attribute `attr`.
94
+ example
95
+
96
+ self.get_param("flowdir", "path/to/the/flowdir")
97
+ """
98
+ getattr(self.param, attr)
99
+
100
+ def write_param(self, filename="param.yaml"):
101
+ """
102
+ Dump all param attribute in a yaml file.
103
+
104
+ parameters
105
+ ----------
106
+ filename : str
107
+ name of file to save the parameter formated in yaml
108
+
109
+ exemple:
110
+ --------
111
+
112
+ self.get_param("flowdir", "path/to/the/flowdir")
113
+ """
114
+ with open(filename, "w") as file:
115
+ yaml.dump(self.param.__dict__, file)
116
+
117
+ def load_param(self, filename=None):
118
+ """
119
+ Load the parameters stored in a yaml file.
120
+
121
+ parameters
122
+ ----------
123
+ filename : str
124
+ name of file to save the parameter formated in yaml
125
+
126
+ exemple:
127
+ --------
128
+
129
+ self.get_param("flowdir", "path/to/the/flowdir")
130
+ """
131
+ if os.path.exists(filename):
132
+
133
+ with open(filename, "r") as file:
134
+
135
+ param = yaml.safe_load(file)
136
+
137
+ for key, value in param.items():
138
+ self.set_param(key, value)
139
+
140
+ def list_assets_files(self):
141
+ """
142
+ List all assets files owned by SmashBox. Thes files are data such as
143
+ the flow directions and outlets database.
144
+
145
+ """
146
+ print_tree(os.path.join(smashbox.__path__[0], "asset"))
147
+
148
+
149
+ class smashboxparam:
150
+ """
151
+ The class `smashboxparam` contains the main parameters needed to build an
152
+ SmashBox model. Thes parameters are stored in different attributes.
153
+
154
+ """
155
+
156
+ def __init__(self):
157
+ """
158
+ Initialisation of the attributes of class smashboxparam. All attributes
159
+ have a default value.
160
+ """
161
+ self._assets_dir = None
162
+ """Path to the asset directory. str"""
163
+ if not os.path.exists(
164
+ os.path.join(os.path.expanduser("~"), ".smashbox", "asset")
165
+ ):
166
+ self._assets_dir = os.path.join(smashbox.__path__[0], "asset")
167
+ """Path to the asset directory. str"""
168
+ else:
169
+ self._assets_dir = os.path.join(
170
+ os.path.expanduser("~"), ".smashbox", "asset"
171
+ )
172
+ """Path to the asset directory. str"""
173
+
174
+ self._flowdir = os.path.join(self._assets_dir, "flwdir", "flowdir_fr_1000m.tif")
175
+ """Path to the flow direction file formated in geotif. str"""
176
+
177
+ self._outlets_database = os.path.join(self._assets_dir, "outlets", "db_sites.csv")
178
+ """ Path to the outlet database iformatted in csv. str."""
179
+
180
+ self._setup_file = os.path.join(
181
+ self._assets_dir,
182
+ "setup",
183
+ "setup_rhax_gr4_dt3600.yaml",
184
+ )
185
+ """Path to a Smash setup file to be used. Format yaml. If only the name
186
+ of the file is given, the file will be searched in the asset directory.
187
+ """
188
+ self._bbox = None # {"left": 0, "bottom": 0, "right": 0, "top": 0}
189
+ """Bounding box of the area to be modeled. dict | None, Optional.
190
+ bbox is a dictionary with
191
+ the following convention:
192
+ bbox={"left": c_weast, "bottom": y_south, "right": x_east, "top": x_north}
193
+ """
194
+
195
+ self._epsg = 2154
196
+ """EPSG code of the coordinate system used. Integer."""
197
+
198
+ self._outletsID = []
199
+ """List of the outlets (key or name) to include in the mesh.
200
+ If the list is left empty, all outlets found in the area
201
+ defined by bbox will be included. If None, no outlet will be added.
202
+ The outlet name must be chosen
203
+ among the list of the outlet_database file in the column defined
204
+ by the attribute outlets_database_fields ('id')
205
+ """
206
+
207
+ self._outlets_shapefile = None
208
+ """Path to the shape file containing the oultlet boundaries. Optional"""
209
+
210
+ self._smash_parameters = os.path.join(self._assets_dir, "params")
211
+ """Path to a directory with calibrated smash parameters. String | None.
212
+ All parameters must be stroed separetly in geotiff file.
213
+ """
214
+
215
+ self._smash_parameters_dt = None
216
+ """Time-step for which the smash_parameters has been originaly calibrated.
217
+ int | float. If not None and if the model parameters is different, the parameters
218
+ "ct", "kexc", "llr" will be transformed according the relation
219
+ described in A.Ficchi, 2017.
220
+ """
221
+
222
+ self._outlets_database_fields = {
223
+ "coord_x": "X_L93",
224
+ "coord_y": "Y_L93",
225
+ "area": "SURF",
226
+ "id": "CODE_SITE",
227
+ }
228
+ """Dictionary with the name of the useful column field {key: field name}.
229
+ dict.
230
+ """
231
+
232
+ self.enhanced_smash_input_data = False
233
+ """
234
+ Use an enhanced version of the smash.model() method. The reading of the input atmospheric data functions used by smash have been rewritten in a different way provide more options and flexibility.
235
+ - read same type of data like SMASH: precipitation, snow, temperature and evapotranspration.
236
+ Support Geotiff format only.
237
+ - Merge all reading function in one.
238
+ - Configure the pattern of the date to search in the filename. Use common date formatters.
239
+ Handle the occurence number (starting from 0) with %n at the end of the date pattern. ex: %Y%m%d%H%1.
240
+ - Improve logs: new log clearly warn user about which files have been read and which files are missing.
241
+ - Fix a mistake during the reading of the evapotranspration. In SMASH the
242
+ evapotranspiration from the previous day is read instead of the current one.
243
+ - Read several data source by priority: each kind of data may have different source.
244
+ If one is missing, the model will read the second one, ect...
245
+ - Partially handle the reading of the continuous evapotranspiration in an operationnal context.
246
+ To do that, a sim-link of the etp data (delayed by 1 day) is created named with the date
247
+ of the current day.
248
+ - Handle time zone to shift the desagregation curve of the PET during the day.
249
+ - Improve the speed of the reading. Technically, an index of the dates and the
250
+ corresponding data files is created. To eficiency run through the long list of data files
251
+ and performs a regex search to match a date, a simple searh algorithm is build on top of
252
+ the main loop to avoid performing a regex on thousand files.
253
+ This improvement is noticable for model running on few time-step. It is particulary
254
+ important when running smash in an operationnal context.
255
+ """
256
+
257
+ @property
258
+ def asset_dir(self):
259
+ """
260
+ Type:
261
+ -----
262
+ Property/Setter: str | os.PathLike
263
+
264
+ Description:
265
+ ------------
266
+ Path to the asset directory. Default value is the asset directory of
267
+ SmashBox copied in the user space.
268
+
269
+ exemple
270
+ -------
271
+ self.asset_dir = "path/to/my/asset/dir"
272
+
273
+ """
274
+ return self._assets_dir
275
+
276
+ @asset_dir.setter
277
+ def asset_dir(self, value: os.PathLike):
278
+ """
279
+ Setter. Path to the asset directory.
280
+ value : os.PathLike
281
+
282
+ exemple
283
+ -------
284
+ self.asset_dir = "path/to/my/asset/dir"
285
+
286
+ """
287
+ if os.path.isdir(value):
288
+ self._asset_dir = value
289
+ else:
290
+ raise ValueError(f"{value} is not a valid directory.")
291
+
292
+ @property
293
+ def outlets_database(self):
294
+ """
295
+ Type:
296
+ -----
297
+ Property/Setter: str | os.PathLike.
298
+
299
+ Description:
300
+ ------------
301
+ Path to the outlet database formatted in csv. Field name,
302
+ coordinates (X and Y) and the surface of the catchment must exists.
303
+ Field name can be configure with attribute outlets_database_fields.
304
+
305
+ exemple
306
+ -------
307
+ self.outlets_database = "path/to/my/database.csv"
308
+
309
+ """
310
+ return self._outlets_database
311
+
312
+ @outlets_database.setter
313
+ def outlets_database(self, value: os.PathLike):
314
+ """
315
+ Setter. Path to the outlet database formatted in csv. Field name,
316
+ coordinates (X and Y) and the surface of the catchment must exists.
317
+ Field name can be configure with attribute outlets_database_fields.
318
+ value : os.PathLike
319
+
320
+ exemple
321
+ -------
322
+ self.outlets_database = "path/to/my/database.csv"
323
+
324
+ """
325
+ self._outlets_database = check_asset_path(
326
+ os.path.join(self.asset_dir, "outlets"), value
327
+ )
328
+
329
+ @property
330
+ def setup_file(self):
331
+ """
332
+ Type:
333
+ -----
334
+ Property/Setter: str | os.PathLike.
335
+
336
+ Description:
337
+ ------------
338
+ Path to the smash setup file formatted in yaml. If only the name
339
+ of the file is given, the infered path will be the asset directory.
340
+
341
+ exemple
342
+ -------
343
+ self.setup_file = "path/to/my/setup.yaml"
344
+
345
+ """
346
+ return self._setup_file
347
+
348
+ @setup_file.setter
349
+ def setup_file(self, value: os.PathLike):
350
+ """
351
+ Setter. Path to the smash setup file formatted in yaml.
352
+ value : os.PathLike
353
+
354
+ exemple
355
+ -------
356
+ self.setup_file = "path/to/my/setup.yaml"
357
+
358
+ """
359
+ self._setup_file = check_asset_path(os.path.join(self.asset_dir, "setup"), value)
360
+ # self._parent_class._parent_class.mysetup.load_setup(self._setup_file)
361
+
362
+ @property
363
+ def flowdir(self):
364
+ """
365
+ Type:
366
+ -----
367
+ Property/Setter: str | os.PathLike.
368
+
369
+ Description:
370
+ ------------
371
+ The path to the flowdir (flow direction) file formatted in Geotif. Refer to the Smash
372
+ documentation for more details: `https://smash.recover.inrae.fr/user_guide/
373
+ data_and_format_description/cance.html#flow-direction`
374
+
375
+ """
376
+ return self._flowdir
377
+
378
+ @flowdir.setter
379
+ def flowdir(self, value: os.PathLike):
380
+ """
381
+ Setter. Path to the flowdir file formatted in Geotif.
382
+ value : os.PathLike
383
+
384
+ exemple
385
+ -------
386
+ self.flowdir = "path/to/my/flowdir.tif"
387
+
388
+ """
389
+ self._flowdir = check_asset_path(os.path.join(self.asset_dir, "flowdir"), value)
390
+
391
+ @property
392
+ def bbox(self):
393
+ """
394
+ Type:
395
+ -----
396
+ Property/Setter: dict
397
+
398
+ Description:
399
+ ------------
400
+ The Bounding box of the area to be modeled. dict | None, Optional.
401
+ bbox is a dictionary with the following convention:
402
+ bbox={"left": c_weast, "bottom": y_south, "right": x_east, "top": x_north}
403
+
404
+ exemple
405
+ -------
406
+ self.bbox = {'left': 0, 'bottom': 0, 'right': 10, 'top': 10}
407
+
408
+ """
409
+ return self._bbox
410
+
411
+ @bbox.setter
412
+ def bbox(self, value: dict | None):
413
+ """
414
+ Setter. Set the bounding box of the domain.
415
+ value : dict | None
416
+
417
+ exemple
418
+ -------
419
+ self.bbox = {'left': 0, 'bottom': 0, 'right': 10, 'top': 10}
420
+
421
+ """
422
+ if value is None:
423
+ self._bbox = value
424
+
425
+ if sorted(["left", "bottom", "right", "top"]) == sorted(list(value.keys())):
426
+ self._bbox = value
427
+ else:
428
+ raise ValueError(
429
+ f"{value} is not a boundingbox. A boundingbox must be a dict"
430
+ "like {'left': 0, 'bottom': 0, 'right': 0, 'top': 0}"
431
+ )
432
+
433
+ @property
434
+ def epsg(self):
435
+ """
436
+ Type:
437
+ -----
438
+ Property/Setter: int
439
+
440
+ Descripion:
441
+ -----------
442
+ EPSG code of the coordinate system used.
443
+
444
+ exemple
445
+ -------
446
+ self.epsg = 2154
447
+
448
+ """
449
+ return self._epsg
450
+
451
+ @epsg.setter
452
+ def epsg(self, value: int):
453
+ """
454
+ Setter. Set the epsg code of the coordinate system used.
455
+ value : int
456
+
457
+ exemple
458
+ -------
459
+ self.epsg = 2154
460
+
461
+ """
462
+ self._epsg = value
463
+
464
+ @property
465
+ def outletsID(self):
466
+ """
467
+ Type:
468
+ -----
469
+ Property/Setter : list
470
+
471
+ Descripion:
472
+ -----------
473
+ List of the outlets (key or name) to include in the mesh.
474
+ If the list is left empty, all outlets found in the area
475
+ defined by bbox will be included. If None, no outlet will be added.
476
+ The outlet name must be chosen
477
+ among the list of the outlet_database file in the column defined
478
+ by the attribute outlets_database_fields ('id')
479
+
480
+ exemple
481
+ -------
482
+ self.outletsID = ['V156730', 'V200820']
483
+
484
+ """
485
+ return self._outletsID
486
+
487
+ @outletsID.setter
488
+ def outletsID(self, value: list):
489
+ """
490
+ Setter. Set the list of the outlet code (or name) used to build
491
+ the mesh.
492
+ value : list of str
493
+
494
+ exemple
495
+ -------
496
+ self.outletsID = ['V156730', 'V200820']
497
+
498
+ """
499
+ self._outletsID = value
500
+
501
+ @property
502
+ def outlets_shapefile(self):
503
+ """
504
+ Type:
505
+ -----
506
+ Property/Setter: str | os.PathLike.
507
+
508
+ Descripion:
509
+ -----------
510
+ Path of the shapefile used to position the outlets.
511
+
512
+ exemple
513
+ -------
514
+ self.outlets_shapefile = 'path/to/the/shapefile.shp'
515
+ """
516
+ return self._outlets_shapefile
517
+
518
+ @outlets_shapefile.setter
519
+ def outlets_shapefile(self, value: None | os.PathLike = None):
520
+ """
521
+ Setter. Set the path of the shapefile used to position the outlets.
522
+ value : None | os.PathLike
523
+
524
+ exemple
525
+ -------
526
+ self.outlets_shapefile = 'path/to/the/shapefile.shp'
527
+
528
+ """
529
+ if value is None:
530
+ return
531
+
532
+ if os.path.exists(value):
533
+ self._outlets_shapefile = value
534
+ else:
535
+ raise ValueError(f"'{value}' is not a valid path.")
536
+
537
+ @property
538
+ def smash_parameters(self):
539
+ """
540
+ Type:
541
+ -----
542
+ Property/Setter: str | os.PathLike.
543
+
544
+ Path to a directory which contain the calibrated smash parameters.
545
+ Each parameter must be stored separetly in a geotiff file
546
+
547
+ exemple
548
+ -------
549
+ self.smash_parameters = 'path/to/the/directory/'
550
+
551
+ """
552
+ return self._smash_parameters
553
+
554
+ @smash_parameters.setter
555
+ def smash_parameters(self, value: None | os.PathLike = None):
556
+ """
557
+ Setter. Set the path to a directory where the smash parameters are
558
+ stored.
559
+ value : None | os.PathLike
560
+
561
+ exemple
562
+ -------
563
+ self.smash_parameters = 'path/to/the/directory/'
564
+
565
+ """
566
+ if value is None:
567
+ return
568
+
569
+ if os.path.isdir(value):
570
+
571
+ if len(os.listdir(value)) == 0:
572
+ raise ValueError(f"'{value}' is an empty directory.")
573
+
574
+ for file in os.listdir(value):
575
+ if not file.endswith(".tif"):
576
+ raise ValueError(
577
+ f"'{value}' contains files other than geotiff .tif format."
578
+ " These files are likely not compatible with SMASH parameters."
579
+ )
580
+
581
+ self._smash_parameters = value
582
+ else:
583
+ raise ValueError(f"'{value}' is not a valid directory.")
584
+
585
+ @property
586
+ def smash_parameters_dt(self):
587
+ """
588
+ Type:
589
+ -----
590
+ Property/Setter: int | float.
591
+
592
+ Time-step for which the smash_parameters has been originaly calibrated.
593
+ int | float.If not None and if the model parameters is different, the parameters
594
+ "ct", "kexc", "llr" will be transformed according the relation
595
+ described in A.Ficchi, 2017.
596
+
597
+ exemple
598
+ -------
599
+ self.smash_parameters_dt = 900
600
+
601
+ """
602
+ return self._smash_parameters_dt
603
+
604
+ @smash_parameters_dt.setter
605
+ def smash_parameters_dt(self, value: None | os.PathLike = None):
606
+ """
607
+ Setter. Set the time-step for which the smash_parameters has been originaly calibrated.
608
+ int | float. If not None and if the model parameters is different, the parameters
609
+ "ct", "kexc", "llr" will be transformed according the relation
610
+ described in A.Ficchi, 2017.
611
+ value : int | float
612
+
613
+ exemple
614
+ -------
615
+ self.smash_parameters_dt = 900.
616
+
617
+ """
618
+
619
+ self._smash_parameters_dt = value
620
+
621
+ @property
622
+ def outlets_database_fields(self):
623
+ """
624
+ type:
625
+ ----
626
+ Property/Setter: dict
627
+
628
+ Description:
629
+ ------------
630
+ A dictionary with a corresponding `key` - `column name`. The 'key' of the dictionary
631
+ must match with desired 'column name' in the selected `outlet_database`.
632
+ Needed keys are:
633
+
634
+ - coord_x : X coordinate of the outlet
635
+
636
+ - coord_y : Y coordinate of the outlet
637
+
638
+ - area : Surface of the catchment
639
+
640
+ - id : Name or label of the outlet
641
+
642
+ exemple
643
+ -------
644
+ self.outlets_database_fields = '{
645
+ "coord_x": "X_L93",
646
+ "coord_y": "Y_L93",
647
+ "area": "SURF",
648
+ "id": "ID_EX",
649
+ }
650
+
651
+ """
652
+ return self._outlets_database_fields
653
+
654
+ @outlets_database_fields.setter
655
+ def outlets_database_fields(self, value: dict):
656
+ """
657
+ type:
658
+ ----
659
+ Property/Setter: dict
660
+
661
+ Description:
662
+ ------------
663
+ A dictionary with a corresponding `key` - `column name`. The 'key' of the dictionary
664
+ must match with desired 'column name' in the selected `outlet_database`.
665
+ Needed keys are:
666
+ - coord_x : X coordinate of the outlet
667
+ - coord_y : Y coordinate of the outlet
668
+ -.area : Surface of the catchment
669
+ - id : Name or label of the outlet
670
+
671
+ exemple
672
+ -------
673
+ self.outlets_database_fields = '{
674
+ "coord_x": "X_L93",
675
+ "coord_y": "Y_L93",
676
+ "area": "SURF",
677
+ "id": "ID_EX",
678
+ }
679
+
680
+ """
681
+ if sorted(["coord_x", "coord_y", "area", "id"]) == sorted(list(value.keys())):
682
+ self._outlets_database_fields = value
683
+ else:
684
+ raise ValueError(
685
+ f"{value} doe not correspond to any outlets_database_fields."
686
+ " outlets_database_fields must look like"
687
+ " {'coord_x': 'X_L93','coord_y': 'Y_L93','area':'SURF','id':'ID_EX'}"
688
+ )
689
+ self._outlets_database_fields = value
690
+
691
+ @property
692
+ def enhanced_smash_input_data(self):
693
+ """
694
+ type:
695
+ ----
696
+ Property/Setter: bool
697
+
698
+ Description:
699
+ ------------
700
+ Use an enhanced version of the smash.model() method. The reading of the input
701
+ atmospheric data functions used by smash have been rewritten in a different way
702
+ provide more options and flexibility.
703
+ - read same type of data like SMASH: precipitation, snow, temperature and
704
+ evapotranspration.
705
+ Support Geotiff format only.
706
+ - Merge all reading function in one.
707
+ - Configure the pattern of the date to search in the filename. Use common date
708
+ formatters. Handle the occurence number (starting from 0) with %n at the end of
709
+ the date pattern. ex: %Y%m%d%H%1.
710
+ - Improve logs: new log clearly warn user about which files have been read and
711
+ which files are missing.
712
+ - Fix a mistake during the reading of the evapotranspration. In SMASH the
713
+ evapotranspiration from the previous day is read instead of the current one.
714
+ - Read several data source by priority: each kind of data may have different source.
715
+ If one is missing, the model will read the second one, ect...
716
+ - Partially handle the reading of the continuous evapotranspiration in an
717
+ operationnal context. To do that, a sim-link of the etp data (delayed by 1 day)
718
+ is created named with the date
719
+ of the current day.
720
+ - Handle time zone to shift the desagregation curve of the PET during the day.
721
+ - Improve the speed of the reading. Technically, an index of the dates and the
722
+ corresponding data files is created. To eficiency run through the long list of data files
723
+ and performs a regex search to match a date, a simple searh algorithm is build on top of
724
+ the main loop to avoid performing a regex on thousand files.
725
+ This improvement is noticable for model running on few time-step. It is particulary
726
+ important when running smash in an operationnal context.
727
+
728
+ new setup options:
729
+ ------------------
730
+ prcp_date_pattern=%Y%m%d%H%0
731
+ prcp_directories:
732
+ 1 : '/home/maxime/DATA/REUNION/PLUIE_REUNION/tests_tr/ANTILOPE_J1'
733
+ 2 : '/home/maxime/DATA/REUNION/PLUIE_REUNION/tests_tr/ANTILOPE_TR'
734
+ 3 : '/home/maxime/DATA/REUNION/PLUIE_REUNION/tests_tr/GRID_LESOL_500m'
735
+ pet_directories:
736
+ 1 : "/home/maxime/DATA/REUNION/ETPJ_continue"
737
+ 2 : "/home/maxime/DATA/REUNION/ETPJ_interannuelle_250_lnZ"
738
+ continuous_pet:
739
+ 1: true
740
+ 2: false
741
+ timezone: "UTC"
742
+
743
+ """
744
+ return self._enhanced_smash_input_data
745
+
746
+ @enhanced_smash_input_data.setter
747
+ def enhanced_smash_input_data(self, value: bool):
748
+ """
749
+ type:
750
+ ----
751
+ Property/Setter: bool
752
+
753
+ Description:
754
+ ------------
755
+ Use an enhanced version of the smash.model() method. The reading of the input
756
+ atmospheric data functions used by smash have been rewritten in a different way
757
+ provide more options and flexibility.
758
+ - read same type of data like SMASH: precipitation, snow, temperature and
759
+ evapotranspration.
760
+ Support Geotiff format only.
761
+ - Merge all reading function in one.
762
+ - Configure the pattern of the date to search in the filename. Use common date
763
+ formatters. Handle the occurence number (starting from 0) with %n at the end of
764
+ the date pattern. ex: %Y%m%d%H%1.
765
+ - Improve logs: new log clearly warn user about which files have been read and
766
+ which files are missing.
767
+ - Fix a mistake during the reading of the evapotranspration. In SMASH the
768
+ evapotranspiration from the previous day is read instead of the current one.
769
+ - Read several data source by priority: each kind of data may have different source.
770
+ If one is missing, the model will read the second one, ect...
771
+ - Partially handle the reading of the continuous evapotranspiration in an
772
+ operationnal context. To do that, a sim-link of the etp data (delayed by 1 day)
773
+ is created named with the date
774
+ of the current day.
775
+ - Handle time zone to shift the desagregation curve of the PET during the day.
776
+ - Improve the speed of the reading. Technically, an index of the dates and the
777
+ corresponding data files is created. To eficiency run through the long list of data files
778
+ and performs a regex search to match a date, a simple searh algorithm is build on top of
779
+ the main loop to avoid performing a regex on thousand files.
780
+ This improvement is noticable for model running on few time-step. It is particulary
781
+ important when running smash in an operationnal context.
782
+
783
+ new setup options:
784
+ ------------------
785
+ prcp_date_pattern=%Y%m%d%H%0
786
+ prcp_directories:
787
+ 1 : '/home/maxime/DATA/REUNION/PLUIE_REUNION/tests_tr/ANTILOPE_J1'
788
+ 2 : '/home/maxime/DATA/REUNION/PLUIE_REUNION/tests_tr/ANTILOPE_TR'
789
+ 3 : '/home/maxime/DATA/REUNION/PLUIE_REUNION/tests_tr/GRID_LESOL_500m'
790
+ pet_directories:
791
+ 1 : "/home/maxime/DATA/REUNION/ETPJ_continue"
792
+ 2 : "/home/maxime/DATA/REUNION/ETPJ_interannuelle_250_lnZ"
793
+ continuous_pet:
794
+ 1: true
795
+ 2: false
796
+ timezone: "UTC"
797
+
798
+ """
799
+ self._enhanced_smash_input_data = value