pydra-core 0.0.1__py2.py3-none-any.whl → 0.0.3__py2.py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (368) hide show
  1. pydra_core/__init__.py +32 -32
  2. pydra_core/common/common.py +98 -98
  3. pydra_core/common/enum.py +63 -63
  4. pydra_core/common/interpolate.py +345 -345
  5. pydra_core/common/probability.py +293 -293
  6. pydra_core/core/calculation.py +51 -51
  7. pydra_core/core/datamodels/frequency_line.py +60 -60
  8. pydra_core/core/exceedance_frequency_line.py +224 -224
  9. pydra_core/core/exceedance_frequency_line_experimental.py +163 -163
  10. pydra_core/core/hbn.py +226 -226
  11. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_2017.txt +36 -36
  12. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_2017_metOnzHeid.txt +45 -45
  13. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2015_metOnzHeid_v02.txt +50 -50
  14. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2015_v02.txt +42 -42
  15. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2050_metOnzHeid_v02.txt +56 -56
  16. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2050_v02.txt +48 -48
  17. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2100_metOnzHeid_v02.txt +56 -56
  18. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2100_v02.txt +48 -48
  19. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2015_metOnzHeid_v02.txt +50 -50
  20. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2015_v02.txt +42 -42
  21. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2050_metOnzHeid_v02.txt +56 -56
  22. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2050_v02.txt +48 -48
  23. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2100_metOnzHeid_v02.txt +51 -51
  24. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2100_v02.txt +44 -44
  25. pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_Ref.txt +27 -27
  26. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_2017.txt +30 -30
  27. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_2017_metOnzHeid.txt +32 -32
  28. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2015.txt +44 -44
  29. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2015_metOnzHeid.txt +33 -33
  30. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2050.txt +44 -44
  31. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2050_metOnzHeid.txt +33 -33
  32. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2100.txt +44 -44
  33. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2100_metOnzHeid.txt +38 -38
  34. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2015.txt +44 -44
  35. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2015_metOnzHeid.txt +33 -33
  36. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2050.txt +44 -44
  37. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2050_metOnzHeid.txt +33 -33
  38. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2100.txt +44 -44
  39. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2100_metOnzHeid.txt +33 -33
  40. pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_Ref.txt +13 -13
  41. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_2017.txt +47 -47
  42. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_2017_metOnzHeid.txt +47 -47
  43. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2015.txt +49 -49
  44. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2015_metOnzHeid.txt +58 -58
  45. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2050.txt +49 -49
  46. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2050_metOnzHeid.txt +58 -58
  47. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2100.txt +49 -49
  48. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2100_metOnzHeid.txt +58 -58
  49. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2015.txt +49 -49
  50. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2015_metOnzHeid.txt +58 -58
  51. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2050.txt +49 -49
  52. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2050_metOnzHeid.txt +58 -58
  53. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2100.txt +49 -49
  54. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2100_metOnzHeid.txt +58 -58
  55. pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_Ref.txt +20 -20
  56. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_2017.txt +33 -33
  57. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_2017_metOnzHeid.txt +59 -59
  58. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2015.txt +49 -49
  59. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2015_BenedenRijn.txt +49 -49
  60. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2015_metOnzHeid.txt +62 -62
  61. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2015_metOnzHeid_BenedenRijn.txt +65 -65
  62. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2050.txt +49 -49
  63. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2050_BenedenRijn.txt +49 -49
  64. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2050_metOnzHeid.txt +62 -62
  65. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2050_metOnzHeid_BenedenRijn.txt +64 -64
  66. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2100.txt +49 -49
  67. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2100_BenedenRijn.txt +49 -49
  68. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2100_metOnzHeid.txt +62 -62
  69. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2100_metOnzHeid_BenedenRijn.txt +64 -64
  70. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2015.txt +50 -50
  71. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2015_BenedenRijn.txt +50 -50
  72. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2015_metOnzHeid.txt +62 -62
  73. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2015_metOnzHeid_BenedenRijn.txt +64 -64
  74. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2050.txt +50 -50
  75. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2050_BenedenRijn.txt +50 -50
  76. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2050_metOnzHeid.txt +62 -62
  77. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2050_metOnzHeid_BenedenRijn.txt +64 -64
  78. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2100.txt +50 -50
  79. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2100_BenedenRijn.txt +50 -50
  80. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2100_metOnzHeid.txt +62 -62
  81. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2100_metOnzHeid_BenedenRijn.txt +65 -65
  82. pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_Ref.txt +22 -22
  83. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_2017.txt +55 -55
  84. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_2017_metOnzHeid.txt +55 -55
  85. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2015.txt +46 -46
  86. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2015_metOnzHeid.txt +64 -64
  87. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2050.txt +46 -46
  88. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2050_metOnzHeid.txt +64 -64
  89. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2100.txt +46 -46
  90. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2100_metOnzHeid.txt +64 -64
  91. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2015.txt +47 -47
  92. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2015_metOnzHeid.txt +64 -64
  93. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2050.txt +47 -47
  94. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2050_metOnzHeid.txt +64 -64
  95. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2100.txt +47 -47
  96. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2100_metOnzHeid.txt +64 -64
  97. pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_Ref.txt +14 -14
  98. pydra_core/data/statistics/Golfvorm/Borgharen/Golfvormen_Borgharen.txt +76 -76
  99. pydra_core/data/statistics/Golfvorm/Dalfsen/Golfvormen_Dalfsen.txt +83 -83
  100. pydra_core/data/statistics/Golfvorm/Grevelingenmeer/Golfvormen_Grevelingenmeer.txt +33 -33
  101. pydra_core/data/statistics/Golfvorm/IJsselmeer/Golfvormen_IJsselmeer.txt +83 -83
  102. pydra_core/data/statistics/Golfvorm/Lith/Golfvormen_Lith.txt +76 -76
  103. pydra_core/data/statistics/Golfvorm/Lobith/Golfvormen_Lobith.txt +76 -76
  104. pydra_core/data/statistics/Golfvorm/Markermeer/Golfvormen_Markermeer.txt +139 -139
  105. pydra_core/data/statistics/Golfvorm/Olst/Golfvormen_Olst.txt +83 -83
  106. pydra_core/data/statistics/Golfvorm/Veerse Meer/Golfvormen_Veersemeer.txt +53 -53
  107. pydra_core/data/statistics/Golfvorm/Veluwerandmeer/Golfvormen_Veluwerandmeer.txt +139 -139
  108. pydra_core/data/statistics/Golfvorm/Volkerak-Zoommeer/Golfvormen_Volkerakzoommeer.txt +73 -73
  109. pydra_core/data/statistics/Meerpeil/Grevelingenmeer/Ovkans_Grevelingenmeer_piekmeerpeil_2017.txt +12 -12
  110. pydra_core/data/statistics/Meerpeil/Grevelingenmeer/Ovkans_Grevelingenmeer_piekmeerpeil_2017_metOnzHeid.txt +24 -24
  111. pydra_core/data/statistics/Meerpeil/Grevelingenmeer/Ovkans_Grevelingenmeer_piekmeerpeil_v01.txt +12 -12
  112. pydra_core/data/statistics/Meerpeil/IJsselmeer/Ovkans_IJsselmeer_piekmeerpeil_2017.txt +25 -25
  113. pydra_core/data/statistics/Meerpeil/IJsselmeer/Ovkans_IJsselmeer_piekmeerpeil_2017_metOnzHeid.txt +39 -39
  114. pydra_core/data/statistics/Meerpeil/IJsselmeer/Ovkans_IJsselmeer_piekmeerpeil_v01.txt +14 -14
  115. pydra_core/data/statistics/Meerpeil/Markermeer/Ovkans_Markermeer_piekmeerpeil_2017.txt +18 -18
  116. pydra_core/data/statistics/Meerpeil/Markermeer/Ovkans_Markermeer_piekmeerpeil_2017_metOnzHeid.txt +37 -37
  117. pydra_core/data/statistics/Meerpeil/Markermeer/Ovkans_Markermeer_piekmeerpeil_v01.txt +10 -10
  118. pydra_core/data/statistics/Meerpeil/Veerse Meer/Ovkans_Veersemeer_piekmeerpeil_excl_peilverhoging.txt +13 -13
  119. pydra_core/data/statistics/Meerpeil/Veerse Meer/Ovkans_Veersemeer_piekmeerpeil_v01.txt +15 -15
  120. pydra_core/data/statistics/Meerpeil/Veluwerandmeer/Ovkans_Veluwerandmeer_piekmeerpeil_2017.txt +13 -13
  121. pydra_core/data/statistics/Meerpeil/Veluwerandmeer/Ovkans_Veluwerandmeer_piekmeerpeil_2017_metOnzHeid.txt +36 -36
  122. pydra_core/data/statistics/Meerpeil/Veluwerandmeer/Ovkans_Veluwerandmeer_piekmeerpeil_v01.txt +13 -13
  123. pydra_core/data/statistics/Meerpeil/Volkerak-Zoommeer/Ovkans_VZM_piekmeerpeil_BER-VZM.txt +17 -17
  124. pydra_core/data/statistics/Meerpeil/Volkerak-Zoommeer/Ovkans_VZM_piekmeerpeil_BER-VZM_metOnzHeid.txt +42 -42
  125. pydra_core/data/statistics/Restant/Oosterschelde/BesliskansenOSKering.txt +524 -524
  126. pydra_core/data/statistics/Restant/Oosterschelde/KansenFaseverschil_2023.txt +7 -7
  127. pydra_core/data/statistics/Restant/Oosterschelde/KansenFaseverschil_OS.txt +13 -13
  128. pydra_core/data/statistics/Restant/Oosterschelde/KansenStormduur_OS.txt +14 -14
  129. pydra_core/data/statistics/Restant/Oosterschelde/KansenStormduur_OS_40_60_80uur_2023.txt +16 -16
  130. pydra_core/data/statistics/Restant/Oosterschelde/ScenariokansenOSKering_2008.txt +23 -23
  131. pydra_core/data/statistics/Restant/Oosterschelde/ScenariokansenOSKering_2013.txt +18 -18
  132. pydra_core/data/statistics/Restant/Oosterschelde/ScenariokansenOSKering_2017.txt +18 -18
  133. pydra_core/data/statistics/Restant/Oosterschelde/ScenariokansenOSKering_2023.txt +13 -13
  134. pydra_core/data/statistics/Restant/Up2U/Up2U10.dat +59 -59
  135. pydra_core/data/statistics/Restant/Up2U/Up2Up.dat +59 -59
  136. pydra_core/data/statistics/Restant/Up2U/Up2Ustar.dat +59 -59
  137. pydra_core/data/statistics/Restant/hulpdijken.txt +59 -59
  138. pydra_core/data/statistics/Restant/hulpgolfhoogtes.txt +23 -23
  139. pydra_core/data/statistics/Restant/hulpgolfperiodes.txt +38 -38
  140. pydra_core/data/statistics/Restant/kansstormduur.txt +8 -8
  141. pydra_core/data/statistics/Restant/pwind_west.txt +33 -33
  142. pydra_core/data/statistics/Restant/pwind_west_met_Volkerfactor.txt +33 -33
  143. pydra_core/data/statistics/Restant/pwind_west_zonder_Volkerfactor.txt +33 -33
  144. pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Midden/VS_sigmafunctie_Kust_Midden.txt +18 -18
  145. pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Midden/VS_sigmafunctie_Kust_Midden_2017.txt +22 -22
  146. pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Noord/VS_sigmafunctie_Kust_Noord.txt +18 -18
  147. pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Noord/VS_sigmafunctie_Kust_Noord_2017.txt +22 -22
  148. pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Zuid/VS_sigmafunctie_Kust_Zuid.txt +18 -18
  149. pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Zuid/VS_sigmafunctie_Kust_Zuid_2017.txt +22 -22
  150. pydra_core/data/statistics/Sigmafunctie/Oosterschelde/VS_sigmafunctie_OS.txt +21 -21
  151. pydra_core/data/statistics/Sigmafunctie/Oosterschelde/VS_sigmafunctie_OS_16sectoren_2023.txt +23 -23
  152. pydra_core/data/statistics/Sigmafunctie/Oosterschelde/VS_sigmafunctie_OS_2017.txt +21 -21
  153. pydra_core/data/statistics/Sigmafunctie/Waddenzee Oost/VS_sigmafunctie_WZ_oost.txt +18 -18
  154. pydra_core/data/statistics/Sigmafunctie/Waddenzee Oost/VS_sigmafunctie_WZ_oost_2017.txt +22 -22
  155. pydra_core/data/statistics/Sigmafunctie/Waddenzee West/VS_sigmafunctie_WZ_west.txt +18 -18
  156. pydra_core/data/statistics/Sigmafunctie/Waddenzee West/VS_sigmafunctie_WZ_west_2017.txt +22 -22
  157. pydra_core/data/statistics/Sigmafunctie/Westerschelde/VS_sigmafunctie_WS.txt +18 -18
  158. pydra_core/data/statistics/Sigmafunctie/Westerschelde/VS_sigmafunctie_WS_2017.txt +22 -22
  159. pydra_core/data/statistics/Sluitpeilen/Sluitfunctie Europoortkering Maas 2017.csv +630 -630
  160. pydra_core/data/statistics/Sluitpeilen/Sluitfunctie Europoortkering Rijn 2017.csv +630 -630
  161. pydra_core/data/statistics/Sluitpeilen/Sluitfunctie Hollandsche IJsselkering.csv +757 -757
  162. pydra_core/data/statistics/Sluitpeilen/Sluitfunctie Oosterscheldekering 2017.csv +55080 -55080
  163. pydra_core/data/statistics/Topduur/Borgharen/Topduur_Borgharen_2017.txt +18 -18
  164. pydra_core/data/statistics/Topduur/Borgharen/Topduur_Borgharen_v00.txt +14 -14
  165. pydra_core/data/statistics/Topduur/Dalfsen/Topduur_Dalfsen_2017.txt +19 -19
  166. pydra_core/data/statistics/Topduur/Dalfsen/Topduur_Dalfsen_v01.txt +15 -15
  167. pydra_core/data/statistics/Topduur/Grevelingenmeer/Topduur_Grevelingenmeer_2017.txt +13 -13
  168. pydra_core/data/statistics/Topduur/Grevelingenmeer/Topduur_Grevelingenmeer_v01.txt +13 -13
  169. pydra_core/data/statistics/Topduur/IJsselmeer/Topduur_IJsselmeer_2017.txt +19 -19
  170. pydra_core/data/statistics/Topduur/IJsselmeer/Topduur_IJsselmeer_v01.txt +14 -14
  171. pydra_core/data/statistics/Topduur/Lith/Topduur_Lith_2017.txt +18 -18
  172. pydra_core/data/statistics/Topduur/Lith/Topduur_Lith_v01.txt +17 -17
  173. pydra_core/data/statistics/Topduur/Lobith/Topduur_Lobith_2017.txt +18 -18
  174. pydra_core/data/statistics/Topduur/Lobith/Topduur_Lobith_v01.txt +16 -16
  175. pydra_core/data/statistics/Topduur/Markermeer/Topduur_Markermeer_2017.txt +19 -19
  176. pydra_core/data/statistics/Topduur/Markermeer/Topduur_Markermeer_v01.txt +11 -11
  177. pydra_core/data/statistics/Topduur/Olst/Topduur_Olst_2017.txt +19 -19
  178. pydra_core/data/statistics/Topduur/Olst/Topduur_Olst_v01.txt +15 -15
  179. pydra_core/data/statistics/Topduur/Veerse Meer/Topduur_Veersemeer_excl_peilverhoging.txt +12 -12
  180. pydra_core/data/statistics/Topduur/Veerse Meer/Topduur_Veersemeer_v01.txt +15 -15
  181. pydra_core/data/statistics/Topduur/Veluwerandmeer/Topduur_Veluwerandmeer_2017.txt +11 -11
  182. pydra_core/data/statistics/Topduur/Veluwerandmeer/Topduur_Veluwerandmeer_v01.txt +11 -11
  183. pydra_core/data/statistics/Topduur/Volkerak-Zoommeer/Topduur_Volkerakzoommeer_BER-VZM.txt +17 -17
  184. pydra_core/data/statistics/Windrichting/Deelen/Richtingskansen_Deelen_2017.txt +27 -27
  185. pydra_core/data/statistics/Windrichting/Hollandse Kust/KansenWindrichting_Kust.txt +16 -16
  186. pydra_core/data/statistics/Windrichting/Hollandse Kust/KansenWindrichting_Kust_2017.txt +23 -23
  187. pydra_core/data/statistics/Windrichting/Oosterschelde/KansenWindrichting_16sectoren_OS_2023.txt +30 -30
  188. pydra_core/data/statistics/Windrichting/Oosterschelde/KansenWindrichting_OS.txt +19 -19
  189. pydra_core/data/statistics/Windrichting/Oosterschelde/KansenWindrichting_OS_2017.txt +23 -23
  190. pydra_core/data/statistics/Windrichting/Schiphol/Richtingskansen_Schiphol_12sectoren.txt +19 -19
  191. pydra_core/data/statistics/Windrichting/Schiphol/Richtingskansen_Schiphol_12sectoren_2017.txt +19 -19
  192. pydra_core/data/statistics/Windrichting/Schiphol/Richtingskansen_Schiphol_2017.txt +27 -27
  193. pydra_core/data/statistics/Windrichting/Schiphol/kanswindrichting_v01.txt +28 -28
  194. pydra_core/data/statistics/Windrichting/Waddenzee/KansenWindrichting_WZ.txt +16 -16
  195. pydra_core/data/statistics/Windrichting/Waddenzee/KansenWindrichting_WZ_2017.txt +23 -23
  196. pydra_core/data/statistics/Windrichting/Westerschelde/KansenWindrichting_WS.txt +16 -16
  197. pydra_core/data/statistics/Windrichting/Westerschelde/KansenWindrichting_WS_2017.txt +23 -23
  198. pydra_core/data/statistics/Windsnelheid/De Kooy/OvkansWindsnelheid_Texel.txt +69 -69
  199. pydra_core/data/statistics/Windsnelheid/De Kooy/Ovkanswind_de Kooy_2017.txt +91 -91
  200. pydra_core/data/statistics/Windsnelheid/De Kooy/Ovkanswind_de Kooy_2017_metOnzHeid.txt +91 -91
  201. pydra_core/data/statistics/Windsnelheid/Deelen/Ovkanswind_Deelen_2017.txt +90 -90
  202. pydra_core/data/statistics/Windsnelheid/Deelen/Ovkanswind_Deelen_2017_metOnzHeid.txt +90 -90
  203. pydra_core/data/statistics/Windsnelheid/Hoek van Holland/OvkansWindsnelheid_Hoek van Holland.txt +69 -69
  204. pydra_core/data/statistics/Windsnelheid/Hoek van Holland/Ovkanswind_Hoek van Holland_2017.txt +91 -91
  205. pydra_core/data/statistics/Windsnelheid/Hoek van Holland/Ovkanswind_Hoek van Holland_2017_metOnzHeid.txt +91 -91
  206. pydra_core/data/statistics/Windsnelheid/IJmuiden/OvkansWindsnelheid_IJmuiden.txt +69 -69
  207. pydra_core/data/statistics/Windsnelheid/IJmuiden/Ovkanswind_IJmuiden_2017.txt +91 -91
  208. pydra_core/data/statistics/Windsnelheid/IJmuiden/Ovkanswind_IJmuiden_2017_metOnzHeid.txt +91 -91
  209. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren.txt +50 -50
  210. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren_2017.txt +90 -90
  211. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren_2017_metOnzHeid.txt +90 -90
  212. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren_2017_metWindDrag.txt +96 -96
  213. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren_2017_metWindDrag_metOnzHeid.txt +96 -96
  214. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_16sectoren_2017_metWindDrag.txt +96 -96
  215. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_16sectoren_2017_metWindDrag_metOnzHeid.txt +96 -96
  216. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_2017.txt +90 -90
  217. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_2017_metOnzHeid.txt +90 -90
  218. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_met_Volkerfactor_2017.txt +90 -90
  219. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_met_Volkerfactor_2017_metOnzHeid.txt +90 -90
  220. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_schiphol.txt +57 -57
  221. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_schiphol_10%.txt +63 -63
  222. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_schiphol_5%.txt +61 -61
  223. pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_schiphol_B_met volker.txt +59 -59
  224. pydra_core/data/statistics/Windsnelheid/Vlissingen/OvkansWindsnelheid_OS.txt +66 -66
  225. pydra_core/data/statistics/Windsnelheid/Vlissingen/OvkansWindsnelheid_Vlissingen.txt +69 -69
  226. pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_16sectoren_2023.txt +91 -91
  227. pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_16sectoren_2023_metOnzHeid.txt +90 -90
  228. pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_2017.txt +91 -91
  229. pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_2017_metOnzHeid.txt +91 -91
  230. pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_2017_metWindDrag.txt +96 -96
  231. pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_2017_metWindDrag_metOnzHeid.txt +96 -96
  232. pydra_core/data/statistics/Windsnelheid/West-Terschelling/OvkansWindsnelheid_West-Tersch.txt +69 -69
  233. pydra_core/data/statistics/Windsnelheid/West-Terschelling/Ovkanswind_West Terschelling_2017.txt +91 -91
  234. pydra_core/data/statistics/Windsnelheid/West-Terschelling/Ovkanswind_West Terschelling_2017_metOnzHeid.txt +91 -91
  235. pydra_core/data/statistics/Zeewaterstand/Delfzijl/CondPovDelfzijl_12u_zichtjaar1985_2017.txt +81 -81
  236. pydra_core/data/statistics/Zeewaterstand/Delfzijl/CondPovDelfzijl_12u_zichtjaar1985_2017_metOnzHeid.txt +81 -81
  237. pydra_core/data/statistics/Zeewaterstand/Delfzijl/CondPovDelfzijl_12u_zichtjaar2017.txt +81 -81
  238. pydra_core/data/statistics/Zeewaterstand/Delfzijl/CondPovDelfzijl_12u_zichtjaar2017_metOnzHeid.txt +81 -81
  239. pydra_core/data/statistics/Zeewaterstand/Delfzijl/OvkansZee_Delfzijl.txt +70 -70
  240. pydra_core/data/statistics/Zeewaterstand/Den Helder/CondPovDenHelder_12u_zichtjaar1985_2017.txt +89 -89
  241. pydra_core/data/statistics/Zeewaterstand/Den Helder/CondPovDenHelder_12u_zichtjaar1985_2017_metOnzHeid.txt +89 -89
  242. pydra_core/data/statistics/Zeewaterstand/Den Helder/CondPovDenHelder_12u_zichtjaar2017.txt +88 -88
  243. pydra_core/data/statistics/Zeewaterstand/Den Helder/CondPovDenHelder_12u_zichtjaar2017_metOnzHeid.txt +88 -88
  244. pydra_core/data/statistics/Zeewaterstand/Den Helder/OvkansZee_Den Helder.txt +70 -70
  245. pydra_core/data/statistics/Zeewaterstand/Den Oever/CondPovDenOeverBuiten_12u_zichtjaar1985_2017.txt +88 -88
  246. pydra_core/data/statistics/Zeewaterstand/Den Oever/CondPovDenOeverBuiten_12u_zichtjaar1985_2017_metOnzHeid.txt +88 -88
  247. pydra_core/data/statistics/Zeewaterstand/Den Oever/CondPovDenOeverBuiten_12u_zichtjaar2017.txt +87 -87
  248. pydra_core/data/statistics/Zeewaterstand/Den Oever/CondPovDenOeverBuiten_12u_zichtjaar2017_metOnzHeid.txt +87 -87
  249. pydra_core/data/statistics/Zeewaterstand/Den Oever/OvkansZee_Den Oever.txt +70 -70
  250. pydra_core/data/statistics/Zeewaterstand/Hansweert/CondPovHansweert_12u_zichtjaar1985_2017.txt +71 -71
  251. pydra_core/data/statistics/Zeewaterstand/Hansweert/CondPovHansweert_12u_zichtjaar1985_2017_metOnzHeid.txt +71 -71
  252. pydra_core/data/statistics/Zeewaterstand/Hansweert/CondPovHansweert_12u_zichtjaar2017.txt +70 -70
  253. pydra_core/data/statistics/Zeewaterstand/Hansweert/CondPovHansweert_12u_zichtjaar2017_metOnzHeid.txt +70 -70
  254. pydra_core/data/statistics/Zeewaterstand/Hansweert/OvkansZee_Hansweert.txt +70 -70
  255. pydra_core/data/statistics/Zeewaterstand/Harlingen/CondPovHarlingen_12u_zichtjaar1985_2017.txt +85 -85
  256. pydra_core/data/statistics/Zeewaterstand/Harlingen/CondPovHarlingen_12u_zichtjaar1985_2017_metOnzHeid.txt +85 -85
  257. pydra_core/data/statistics/Zeewaterstand/Harlingen/CondPovHarlingen_12u_zichtjaar2017.txt +84 -84
  258. pydra_core/data/statistics/Zeewaterstand/Harlingen/CondPovHarlingen_12u_zichtjaar2017_metOnzHeid.txt +84 -84
  259. pydra_core/data/statistics/Zeewaterstand/Harlingen/OvkansZee_Harlingen.txt +70 -70
  260. pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/CondPovHoekvanHolland_12u_zichtjaar1985_2017.txt +84 -84
  261. pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/CondPovHoekvanHolland_12u_zichtjaar1985_2017_metOnzHeid.txt +84 -84
  262. pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/CondPovHoekvanHolland_12u_zichtjaar2017.txt +83 -83
  263. pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/CondPovHoekvanHolland_12u_zichtjaar2017_metOnzHeid.txt +83 -83
  264. pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/OvkansZee_Hoek van Holland.txt +70 -70
  265. pydra_core/data/statistics/Zeewaterstand/Huibertgat/CondPovHuibertgat_12u_zichtjaar1985_2017.txt +86 -86
  266. pydra_core/data/statistics/Zeewaterstand/Huibertgat/CondPovHuibertgat_12u_zichtjaar1985_2017_metOnzHeid.txt +86 -86
  267. pydra_core/data/statistics/Zeewaterstand/Huibertgat/CondPovHuibertgat_12u_zichtjaar2017.txt +85 -85
  268. pydra_core/data/statistics/Zeewaterstand/Huibertgat/CondPovHuibertgat_12u_zichtjaar2017_metOnzHeid.txt +85 -85
  269. pydra_core/data/statistics/Zeewaterstand/Huibertgat/OvkansZee_Huibertgat.txt +70 -70
  270. pydra_core/data/statistics/Zeewaterstand/IJmuiden/CondPovIJmuiden_12u_zichtjaar1985_2017.txt +85 -85
  271. pydra_core/data/statistics/Zeewaterstand/IJmuiden/CondPovIJmuiden_12u_zichtjaar1985_2017_metOnzHeid.txt +85 -85
  272. pydra_core/data/statistics/Zeewaterstand/IJmuiden/CondPovIJmuiden_12u_zichtjaar2017.txt +85 -85
  273. pydra_core/data/statistics/Zeewaterstand/IJmuiden/CondPovIJmuiden_12u_zichtjaar2017_metOnzHeid.txt +85 -85
  274. pydra_core/data/statistics/Zeewaterstand/IJmuiden/OvkansZee_IJmuiden.txt +70 -70
  275. pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/CondPovIJmuiden-Additional_12u_zichtjaar1985_2017.txt +85 -85
  276. pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/CondPovIJmuiden-Additional_12u_zichtjaar1985_2017_metOnzHeid.txt +85 -85
  277. pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/CondPovIJmuiden-Additional_12u_zichtjaar2017.txt +85 -85
  278. pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/CondPovIJmuiden-Additional_12u_zichtjaar2017_metOnzHeid.txt +85 -85
  279. pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/OvkansZee_IJmuiden_virtueel.txt +70 -70
  280. pydra_core/data/statistics/Zeewaterstand/Lauwersoog/CondPovLauwersoog_12u_zichtjaar1985_2017.txt +85 -85
  281. pydra_core/data/statistics/Zeewaterstand/Lauwersoog/CondPovLauwersoog_12u_zichtjaar1985_2017_metOnzHeid.txt +85 -85
  282. pydra_core/data/statistics/Zeewaterstand/Lauwersoog/CondPovLauwersoog_12u_zichtjaar2017.txt +84 -84
  283. pydra_core/data/statistics/Zeewaterstand/Lauwersoog/CondPovLauwersoog_12u_zichtjaar2017_metOnzHeid.txt +84 -84
  284. pydra_core/data/statistics/Zeewaterstand/Lauwersoog/OvkansZee_Lauwersoog.txt +70 -70
  285. pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar1985_2011.txt +88 -88
  286. pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar1985_2017.txt +88 -88
  287. pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar1985_2017_metOnzheid.txt +92 -92
  288. pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar2017.txt +85 -85
  289. pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar2017_metOnzheid.txt +85 -85
  290. pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_12u_zichtjaar1985_2017.txt +79 -79
  291. pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_12u_zichtjaar1985_2017_metOnzHeid.txt +79 -79
  292. pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_12u_zichtjaar2017.txt +79 -79
  293. pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_12u_zichtjaar2017_metOnzHeid.txt +79 -79
  294. pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_16sectoren_12u_2023.txt +74 -74
  295. pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_16sectoren_12u_2023_metOnzHeid.txt +73 -73
  296. pydra_core/data/statistics/Zeewaterstand/Oosterschelde/OvkansZee_OS11.txt +70 -70
  297. pydra_core/data/statistics/Zeewaterstand/Oosterschelde/OvkansZeewaterstand_OS.txt +71 -71
  298. pydra_core/data/statistics/Zeewaterstand/Vlissingen/CondPovVlissingen_12u_zichtjaar1985_2017.txt +74 -74
  299. pydra_core/data/statistics/Zeewaterstand/Vlissingen/CondPovVlissingen_12u_zichtjaar1985_2017_metOnzHeid.txt +74 -74
  300. pydra_core/data/statistics/Zeewaterstand/Vlissingen/CondPovVlissingen_12u_zichtjaar2017.txt +74 -74
  301. pydra_core/data/statistics/Zeewaterstand/Vlissingen/CondPovVlissingen_12u_zichtjaar2017_metOnzHeid.txt +74 -74
  302. pydra_core/data/statistics/Zeewaterstand/Vlissingen/OvkansZee_Vlissingen.txt +70 -70
  303. pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/CondPovVlissingen-Additional_12u_zichtjaar1985_2017.txt +74 -74
  304. pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/CondPovVlissingen-Additional_12u_zichtjaar1985_2017_metOnzHeid.txt +74 -74
  305. pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/CondPovVlissingen-Additional_12u_zichtjaar2017.txt +74 -74
  306. pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/CondPovVlissingen-Additional_12u_zichtjaar2017_metOnzHeid.txt +74 -74
  307. pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/OvkansZee_Vlissingen_virtueel.txt +70 -70
  308. pydra_core/data/statistics/Zeewaterstand/West-Terschelling/CondPovWestTerschelling_12u_zichtjaar1985_2017.txt +87 -87
  309. pydra_core/data/statistics/Zeewaterstand/West-Terschelling/CondPovWestTerschelling_12u_zichtjaar1985_2017_metOnzHeid.txt +87 -87
  310. pydra_core/data/statistics/Zeewaterstand/West-Terschelling/CondPovWestTerschelling_12u_zichtjaar2017.txt +86 -86
  311. pydra_core/data/statistics/Zeewaterstand/West-Terschelling/CondPovWestTerschelling_12u_zichtjaar2017_metOnzHeid.txt +86 -86
  312. pydra_core/data/statistics/Zeewaterstand/West-Terschelling/OvkansZee_West-Terschelling.txt +70 -70
  313. pydra_core/hrdatabase/hrdatabase.py +177 -177
  314. pydra_core/io/database_hr.py +598 -598
  315. pydra_core/io/database_settings.py +183 -183
  316. pydra_core/io/file_hydranl.py +92 -92
  317. pydra_core/location/location.py +115 -115
  318. pydra_core/location/model/base_model.py +270 -270
  319. pydra_core/location/model/loading/loading.py +368 -368
  320. pydra_core/location/model/loading/loading_factory.py +89 -89
  321. pydra_core/location/model/loading/loading_model/loading_model.py +324 -324
  322. pydra_core/location/model/loading/other_systems/loading_wave_overtopping.py +122 -122
  323. pydra_core/location/model/loading/water_systems/loading_coast.py +54 -54
  324. pydra_core/location/model/loading/water_systems/loading_eastern_scheldt.py +169 -169
  325. pydra_core/location/model/loading/water_systems/loading_ijssel_vechtdelta.py +55 -55
  326. pydra_core/location/model/loading/water_systems/loading_lake.py +55 -55
  327. pydra_core/location/model/loading/water_systems/loading_lower_rivier.py +68 -68
  328. pydra_core/location/model/loading/water_systems/loading_upper_river.py +55 -55
  329. pydra_core/location/model/statistics/other_systems/statistics_wave_overtopping.py +72 -72
  330. pydra_core/location/model/statistics/statistics.py +171 -171
  331. pydra_core/location/model/statistics/statistics_factory.py +89 -89
  332. pydra_core/location/model/statistics/stochastics/barrier/barrier.py +43 -43
  333. pydra_core/location/model/statistics/stochastics/barrier/barrier_easternscheldt.py +147 -147
  334. pydra_core/location/model/statistics/stochastics/barrier/barrier_europoort.py +209 -209
  335. pydra_core/location/model/statistics/stochastics/barrier/barrier_ramspol.py +41 -41
  336. pydra_core/location/model/statistics/stochastics/barrier/no_barrier.py +21 -21
  337. pydra_core/location/model/statistics/stochastics/discharge.py +108 -108
  338. pydra_core/location/model/statistics/stochastics/discrete_probability.py +55 -55
  339. pydra_core/location/model/statistics/stochastics/lake_level.py +158 -158
  340. pydra_core/location/model/statistics/stochastics/model_uncertainty.py +358 -358
  341. pydra_core/location/model/statistics/stochastics/sea_level/sea_level.py +53 -53
  342. pydra_core/location/model/statistics/stochastics/sea_level/sea_level_lower_river.py +93 -93
  343. pydra_core/location/model/statistics/stochastics/sea_level/sea_level_point.py +65 -65
  344. pydra_core/location/model/statistics/stochastics/sea_level/sea_level_triangular.py +158 -158
  345. pydra_core/location/model/statistics/stochastics/sigma_function.py +24 -24
  346. pydra_core/location/model/statistics/stochastics/wave_shape.py +624 -624
  347. pydra_core/location/model/statistics/stochastics/wind_speed.py +196 -196
  348. pydra_core/location/model/statistics/water_systems/statistics_coast.py +153 -153
  349. pydra_core/location/model/statistics/water_systems/statistics_eastern_scheldt.py +177 -177
  350. pydra_core/location/model/statistics/water_systems/statistics_ijssel_vechtdelta.py +229 -229
  351. pydra_core/location/model/statistics/water_systems/statistics_lake.py +86 -86
  352. pydra_core/location/model/statistics/water_systems/statistics_lower_river.py +321 -321
  353. pydra_core/location/model/statistics/water_systems/statistics_upper_river.py +86 -86
  354. pydra_core/location/model/water_system.py +249 -249
  355. pydra_core/location/model/wave_overtopping.py +25 -25
  356. pydra_core/location/profile/foreland.py +246 -246
  357. pydra_core/location/profile/lib/CombOverloopOverslag64.dll +0 -0
  358. pydra_core/location/profile/lib/DynamicLib-DaF.dll +0 -0
  359. pydra_core/location/profile/lib/README.MD +10 -10
  360. pydra_core/location/profile/lib/dllDikesOvertopping.dll +0 -0
  361. pydra_core/location/profile/lib/feedbackDLL.dll +0 -0
  362. pydra_core/location/profile/profile.py +971 -971
  363. pydra_core/location/profile/profile_loading.py +473 -473
  364. pydra_core/location/settings/settings.py +387 -387
  365. {pydra_core-0.0.1.dist-info → pydra_core-0.0.3.dist-info}/METADATA +25 -5
  366. pydra_core-0.0.3.dist-info/RECORD +393 -0
  367. pydra_core-0.0.1.dist-info/RECORD +0 -389
  368. {pydra_core-0.0.1.dist-info → pydra_core-0.0.3.dist-info}/WHEEL +0 -0
@@ -1,971 +1,971 @@
1
- import ast
2
- import matplotlib.pyplot as plt
3
- import numpy as np
4
- import os
5
-
6
- from typing import Tuple, Union
7
-
8
- from .foreland import Foreland
9
- from .profile_loading import ProfileLoading
10
- from ...common.enum import Breakwater
11
- from ...common.interpolate import Interpolate
12
-
13
-
14
- class Profile:
15
- """
16
- Profile class
17
-
18
- TODO: Implement support for sheet piles
19
- """
20
-
21
- # Profile name
22
- profile_name = None
23
-
24
- # Breakwater
25
- breakwater_type = Breakwater.NO_BREAKWATER
26
- breakwater_level = 0.0
27
-
28
- # Foreland
29
- foreland_x_coordinates: None | list = None
30
- foreland_y_coordinates: None | list = None
31
-
32
- # Dike schematisation
33
- dike_orientation: None | float = None
34
- dike_crest_level: None | float = None
35
- dike_x_coordinates: None | list = None
36
- dike_y_coordinates: None | list = None
37
- dike_roughness: None | list = None
38
-
39
- def __init__(self, profile_name: str = "Profile"):
40
- """
41
- Create a new profile
42
-
43
- Parameters
44
- ----------
45
- profile_name: str
46
- Name of the profile (default: 'Profile')
47
- """
48
- # Save the profile name
49
- self.profile_name = profile_name
50
-
51
- def validate_profile(self) -> bool:
52
- """
53
- Function to validate the profile.
54
-
55
- Returns
56
- -------
57
- bool
58
- True if the profile is OK
59
- """
60
- # TODO: Improve validation
61
- # Check necessary components
62
- # Orientation
63
- if self.dike_orientation is None:
64
- return False
65
-
66
- # Crest height
67
- if self.dike_crest_level is None:
68
- return False
69
-
70
- # Geometry
71
- if (
72
- (self.dike_x_coordinates is None)
73
- or (self.dike_y_coordinates is None)
74
- or (self.dike_roughness is None)
75
- ):
76
- return False
77
-
78
- return True
79
-
80
- def set_dike_orientation(self, dike_orientation: float):
81
- """
82
- Change the dike orientation
83
-
84
- Parameters
85
- ----------
86
- dike_orientation : float
87
- The dike orientation
88
- """
89
- self.dike_orientation = dike_orientation
90
-
91
- def set_dike_crest_level(self, dike_crest_level: float):
92
- """
93
- Change the crest level
94
-
95
- Parameters
96
- ----------
97
- dike_crest_level : float
98
- The crest level of the dike
99
- """
100
- self.dike_crest_level = dike_crest_level
101
-
102
- def set_dike_geometry(
103
- self,
104
- dike_x_coordinates: list,
105
- dike_y_coordinates: list,
106
- dike_roughness: list = None,
107
- ):
108
- """
109
- Change the geometry of the outer slope of the dike
110
-
111
- Parameters
112
- ----------
113
- dike_x_coordinates : list
114
- A list with the x coordinates of the profile
115
- dike_y_coordinates : list
116
- A list with the y coordinates of the profile
117
- dike_roughness : list, optional
118
- A list with the roughness of the profile (default : all parts 1.0)
119
- """
120
- # Make sure the dike geometry starts at (x = 0)
121
- min_x = np.min(dike_x_coordinates)
122
-
123
- # If dike roughness is None, the roughness of every part is 1.0
124
- if dike_roughness is None:
125
- dike_roughness = [1.0] * len(dike_x_coordinates)
126
-
127
- # Save the dike geometry coordinates
128
- self.dike_x_coordinates = dike_x_coordinates - min_x
129
- self.dike_y_coordinates = dike_y_coordinates
130
- self.dike_roughness = dike_roughness
131
-
132
- def has_foreland(self) -> bool:
133
- """
134
- Returns whether the profile has a foreland or breakwater
135
-
136
- Returns
137
- -------
138
- bool
139
- True if the profile has a foreland or breakwater
140
- """
141
- # Check for a breakwater
142
- if self.breakwater_type != Breakwater.NO_BREAKWATER:
143
- return True
144
-
145
- # Check for a foreland
146
- if self.foreland_x_coordinates is not None:
147
- return True
148
-
149
- # No foreland or breakwater
150
- return False
151
-
152
- def set_foreland_geometry(
153
- self, foreland_x_coordinates: list = None, foreland_y_coordinates: list = None
154
- ):
155
- """
156
- Change the geometry of the foreland
157
- Setting the foreland x and y coordinates to None will remove the foreland.
158
-
159
- Parameters
160
- ----------
161
- foreland_x_coordinates : list
162
- A list with the x coordinates of the foreland (default: None)
163
- foreland_y_coordinates : list
164
- A list with the y coordinates of the foreland (default: None)
165
- """
166
- # Add foreland
167
- if foreland_x_coordinates is not None:
168
- # Make sure the foreland ends at (x = 0)
169
- max_x = np.max(foreland_x_coordinates)
170
-
171
- # Save the foreland coordinates
172
- self.foreland_x_coordinates = foreland_x_coordinates - max_x
173
- self.foreland_y_coordinates = foreland_y_coordinates
174
-
175
- # Delete foreland
176
- else:
177
- self.foreland_x_coordinates = None
178
- self.foreland_y_coordinates = None
179
-
180
- def remove_foreland(self) -> None:
181
- """
182
- Remove the foreland
183
- Wrapper for set_foreland_geometry()
184
- """
185
- self.set_foreland_geometry(
186
- foreland_x_coordinates=None, foreland_y_coordinates=None
187
- )
188
-
189
- def set_breakwater(
190
- self, breakwater_type: Breakwater = None, breakwater_level: float = 0.0
191
- ):
192
- """
193
- Change the breakwater
194
- """
195
- # None equals no breakwater
196
- if breakwater_type is None:
197
- breakwater_type = Breakwater.NO_BREAKWATER
198
-
199
- # If there is no breakwater, the height will be set to None
200
- if breakwater_type == Breakwater.NO_BREAKWATER:
201
- breakwater_level = 0.0
202
-
203
- # Apply settings
204
- self.breakwater_type = breakwater_type
205
- self.breakwater_level = breakwater_level
206
-
207
- def remove_breakwater(self) -> None:
208
- """
209
- Remove the breakwater
210
- Wrapper for set_breakwater()
211
- """
212
- self.set_breakwater(
213
- breakwater_type=Breakwater.NO_BREAKWATER, breakwater_level=0.0
214
- )
215
-
216
- def calculate_overtopping(
217
- self,
218
- water_level: Union[float, list],
219
- significant_wave_height: Union[float, list],
220
- spectral_wave_period: Union[float, list],
221
- wave_direction: Union[float, list],
222
- tp_tspec: float = 1.1,
223
- dll_settings: dict = None,
224
- ) -> Union[float, list]:
225
- """
226
- Calculate the overtopping discharge
227
-
228
- Parameters
229
- ----------
230
- water_level : Union[float, list]
231
- List or float with the water level
232
- significant_wave_height : Union[float, list]
233
- List or float with the significant wave height
234
- spectral_wave_period : Union[float, list]
235
- List or float with the spectral wave period
236
- wave_direction : Union[float, list]
237
- List or float with the wave direction
238
- tp_tspec : float, optional
239
- Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
240
-
241
- Returns
242
- -------
243
- Union[float, list]
244
- List or float with the overtopping discharge
245
- """
246
- # Transform wave conditions
247
- water_level, significant_wave_height, spectral_wave_period, wave_direction = (
248
- self.transform_wave_conditions(
249
- water_level,
250
- significant_wave_height,
251
- spectral_wave_period,
252
- wave_direction,
253
- tp_tspec,
254
- force_array=True,
255
- )
256
- )
257
-
258
- # Create profile loading
259
- profile_loading = ProfileLoading(self, dll_settings)
260
-
261
- # Calculate
262
- qov = []
263
- for _h, _hs, _tspec, _dir in zip(
264
- water_level, significant_wave_height, spectral_wave_period, wave_direction
265
- ):
266
- qov.append(profile_loading.calculate_discharge(_h, _hs, _tspec, _dir))
267
-
268
- # Return
269
- return qov[0] if len(qov) == 1 else qov
270
-
271
- def calculate_runup(
272
- self,
273
- water_level: Union[float, list],
274
- significant_wave_height: Union[float, list],
275
- spectral_wave_period: Union[float, list],
276
- wave_direction: Union[float, list],
277
- tp_tspec: float = 1.1,
278
- dll_settings: dict = None,
279
- ) -> Union[float, list]:
280
- """
281
- Calculate the runup height
282
-
283
- Parameters
284
- ----------
285
- water_level : Union[float, list]
286
- List or float with the water level
287
- significant_wave_height : Union[float, list]
288
- List or float with the significant wave height
289
- spectral_wave_period : Union[float, list]
290
- List or float with the spectral wave period
291
- wave_direction : Union[float, list]
292
- List or float with the wave direction
293
- tp_tspec : float, optional
294
- Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
295
-
296
- Returns
297
- -------
298
- Union[float, list]
299
- List or float with the runup height
300
- """
301
- # Transform wave conditions
302
- water_level, significant_wave_height, spectral_wave_period, wave_direction = (
303
- self.transform_wave_conditions(
304
- water_level,
305
- significant_wave_height,
306
- spectral_wave_period,
307
- wave_direction,
308
- tp_tspec,
309
- force_array=True,
310
- )
311
- )
312
-
313
- # Create profile loading
314
- profile_loading = ProfileLoading(self, dll_settings)
315
-
316
- # Calculate
317
- ru2p = []
318
- for _h, _hs, _tspec, _dir in zip(
319
- water_level, significant_wave_height, spectral_wave_period, wave_direction
320
- ):
321
- ru2p.append(profile_loading.calculate_runup(_h, _hs, _tspec, _dir))
322
-
323
- # Return
324
- return ru2p[0] if len(ru2p) == 1 else ru2p
325
-
326
- def calculate_crest_level(
327
- self,
328
- q_overtopping: float,
329
- water_level: Union[float, list],
330
- significant_wave_height: Union[float, list],
331
- spectral_wave_period: Union[float, list],
332
- wave_direction: Union[float, list],
333
- tp_tspec: float = 1.1,
334
- dll_settings: dict = None,
335
- ) -> Union[float, list]:
336
- """
337
- Calculate the crest level for a given overtopping discharge
338
-
339
- Parameters
340
- ----------
341
- q_overtopping : float
342
- Critical overtopping discharge
343
- water_level : Union[float, list]
344
- List or float with the water level
345
- significant_wave_height : Union[float, list]
346
- List or float with the significant wave height
347
- spectral_wave_period : Union[float, list]
348
- List or float with the spectral wave period
349
- wave_direction : Union[float, list]
350
- List or float with the wave direction
351
- tp_tspec : float, optional
352
- Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
353
-
354
- Returns
355
- -------
356
- Union[float, list]
357
- List or float with the crest level
358
- """
359
- # Transform wave conditions
360
- water_level, significant_wave_height, spectral_wave_period, wave_direction = (
361
- self.transform_wave_conditions(
362
- water_level,
363
- significant_wave_height,
364
- spectral_wave_period,
365
- wave_direction,
366
- tp_tspec,
367
- force_array=True,
368
- )
369
- )
370
-
371
- # Length of the list
372
- n_q = 1 if isinstance(q_overtopping, (float, int)) else len(q_overtopping)
373
-
374
- # If q_overtopping is an int or float
375
- if isinstance(q_overtopping, (float, int)):
376
- q_overtopping = [q_overtopping] * len(water_level)
377
-
378
- # If q_overtopping is a list and water_level has length 1
379
- elif n_q > 1 and len(water_level) == 1:
380
- water_level = [water_level] * n_q
381
- significant_wave_height = [significant_wave_height] * n_q
382
- spectral_wave_period = [spectral_wave_period] * n_q
383
- wave_direction = [wave_direction] * n_q
384
-
385
- # Uneven length of arrays
386
- else:
387
- raise ValueError("[ERROR] Uneven length of arrays")
388
-
389
- # To numpy
390
- q_overtopping = np.array(q_overtopping)
391
- water_level = np.array(water_level)
392
- significant_wave_height = np.array(significant_wave_height)
393
- spectral_wave_period = np.array(spectral_wave_period)
394
- wave_direction = np.array(wave_direction)
395
-
396
- # Create profile loading
397
- profile_loading = ProfileLoading(self, dll_settings)
398
-
399
- # Calculate crest level
400
- hbn = []
401
- for _q, _h, _hs, _tspec, _dir in zip(
402
- q_overtopping,
403
- water_level,
404
- significant_wave_height,
405
- spectral_wave_period,
406
- wave_direction,
407
- ):
408
- hbn.append(profile_loading.calculate_crest_level(_q, _h, _hs, _tspec, _dir))
409
-
410
- # Return
411
- return hbn[0] if len(hbn) == 1 else hbn
412
-
413
- def transform_wave_conditions(
414
- self,
415
- water_level: Union[float, list],
416
- significant_wave_height: Union[float, list],
417
- spectral_wave_period: Union[float, list],
418
- wave_direction: Union[float, list],
419
- tp_tspec: float = 1.1,
420
- force_array: bool = False,
421
- ) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
422
- """
423
- Transform the wave conditions for the schematized foreland
424
-
425
- Parameters
426
- ----------
427
- water_level : Union[float, list]
428
- Water level
429
- significant_wave_height : Union[float, list]
430
- Significant wave height
431
- spectral_wave_period : Union[float, list]
432
- Spectral wave period
433
- wave_direction : Union[float, list]
434
- Wave direction
435
- tp_tspec : float, optional
436
- Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
437
- force_array : bool, optional
438
- Always force to return an array
439
-
440
- Returns
441
- -------
442
- Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]
443
- Water level and transformed wave conditions (h, hs, tp, dir)
444
- """
445
- # Length of the lists
446
- n_h = 1 if isinstance(water_level, (float, int)) else len(water_level)
447
- n_hs = (
448
- 1
449
- if isinstance(significant_wave_height, (float, int))
450
- else len(significant_wave_height)
451
- )
452
- n_tspec = (
453
- 1
454
- if isinstance(spectral_wave_period, (float, int))
455
- else len(spectral_wave_period)
456
- )
457
- n_dir = 1 if isinstance(wave_direction, (float, int)) else len(wave_direction)
458
- n_max = np.max([n_h, n_hs, n_tspec, n_dir])
459
-
460
- # Make lists
461
- if isinstance(water_level, (float, int)):
462
- water_level = [water_level] * n_max
463
- elif len(water_level) != n_max:
464
- raise ValueError("[ERROR] Uneven length of arrays")
465
-
466
- if isinstance(significant_wave_height, (float, int)):
467
- significant_wave_height = [significant_wave_height] * n_max
468
- elif len(significant_wave_height) != n_max:
469
- raise ValueError("[ERROR] Uneven length of arrays")
470
-
471
- if isinstance(spectral_wave_period, (float, int)):
472
- spectral_wave_period = [spectral_wave_period] * n_max
473
- elif len(spectral_wave_period) != n_max:
474
- raise ValueError("[ERROR] Uneven length of arrays")
475
-
476
- if isinstance(wave_direction, (float, int)):
477
- wave_direction = [wave_direction] * n_max
478
- elif len(wave_direction) != n_max:
479
- raise ValueError("[ERROR] Uneven length of arrays")
480
-
481
- # To numpy
482
- water_level = np.array(water_level)
483
- significant_wave_height = np.array(significant_wave_height)
484
- spectral_wave_period = np.array(spectral_wave_period)
485
- wave_direction = np.array(wave_direction)
486
-
487
- # Correct for foreland
488
- if self.has_foreland():
489
- fl = Foreland(self)
490
- water_level, significant_wave_height, peak_wave_period, wave_direction = (
491
- fl.transform_wave_conditions(
492
- water_level,
493
- significant_wave_height,
494
- spectral_wave_period * tp_tspec,
495
- wave_direction,
496
- )
497
- )
498
- spectral_wave_period = peak_wave_period / tp_tspec
499
-
500
- # Return array or floats?
501
- if len(water_level.ravel()) == 1 and not force_array:
502
- return (
503
- water_level.ravel()[0],
504
- significant_wave_height.ravel()[0],
505
- spectral_wave_period.ravel()[0],
506
- wave_direction.ravel()[0],
507
- )
508
- else:
509
- return (
510
- water_level,
511
- significant_wave_height,
512
- spectral_wave_period,
513
- wave_direction,
514
- )
515
-
516
- def to_prfl(
517
- self, export_path: str, id: str = "Onbekend000", memo: str = ""
518
- ) -> None:
519
- """
520
- Export to a prfl file
521
-
522
- export_path : str
523
- Path to where the profile has to be exported
524
- id : str
525
- Id used in RisKeer
526
- memo : str
527
- Memo to be added to the prfl file
528
- """
529
- # Check required info
530
- if (
531
- (self.dike_x_coordinates is None)
532
- or (self.dike_crest_level is None)
533
- or (self.dike_orientation is None)
534
- ):
535
- raise ValueError(
536
- f"[ERROR] Cannot generate .prfl for profile '{self.profile_name}', geometry, crest level or orientation is missing."
537
- )
538
-
539
- # Version
540
- breakwater_level = (
541
- self.breakwater_level if self.breakwater_level is not None else 0.0
542
- )
543
- n_foreland = (
544
- len(self.foreland_x_coordinates)
545
- if self.foreland_x_coordinates is not None
546
- else 0
547
- )
548
- n_dike = (
549
- len(self.dike_x_coordinates) if self.dike_x_coordinates is not None else 0
550
- )
551
- export = f"VERSIE 4.0\nID {id}\n\nRICHTING {self.dike_orientation}\n\nDAM {int(self.breakwater_type.value)}\nDAMHOOGTE {breakwater_level}\n\nVOORLAND {n_foreland}\n[FORELAND]\nDAMWAND 0\nKRUINHOOGTE {self.dike_crest_level}\nDIJK {n_dike}\n[DIKE]\nMEMO\nGenerated with Pydra for profile '{self.profile_name}'\n{memo}\n"
552
-
553
- # Foreland
554
- foreland = ""
555
- if n_foreland > 0:
556
- for foreland_x, foreland_y in zip(
557
- self.foreland_x_coordinates, self.foreland_y_coordinates
558
- ):
559
- foreland = (
560
- foreland
561
- + f"{round(foreland_x,3):.3f}\t{round(foreland_y,3):.3f}\t1.000\n"
562
- )
563
- export = export.replace("[FORELAND]", foreland)
564
-
565
- # Dike
566
- dike = ""
567
- if n_dike > 0:
568
- for dike_x, dike_y, dike_r in zip(
569
- self.dike_x_coordinates, self.dike_y_coordinates, self.dike_roughness
570
- ):
571
- dike = (
572
- dike
573
- + f"{round(dike_x,3):.3f}\t{round(dike_y,3):.3f}\t{round(dike_r,3):.3f}\n"
574
- )
575
- export = export.replace("[DIKE]", dike)
576
-
577
- # Export .prfl
578
- if not export_path.lower().endswith(".prfl"):
579
- export_path = export_path + ".prfl"
580
- prfl_file = open(export_path, "w")
581
- prfl_file.write(export)
582
- prfl_file.close()
583
-
584
- def to_dict(self) -> dict:
585
- """
586
- Export Profile to dictionary
587
-
588
- Returns
589
- -------
590
- dictionary
591
- Dictionary with all profile settings
592
- """
593
- # Create an empty dictionary
594
- profile = {}
595
-
596
- # Add all settings to the dictionary
597
- for setting in dir(self):
598
- if not str(setting).startswith("__") and not callable(
599
- getattr(self, setting)
600
- ):
601
- profile[setting] = getattr(self, setting)
602
-
603
- return profile
604
-
605
- def draw_profile(self) -> None:
606
- """
607
- Draw a cross-section of the profile
608
- """
609
- # Init plot
610
- plt.figure(figsize=[8, 5])
611
-
612
- # Foreland
613
- if self.foreland_x_coordinates is not None:
614
- plt.plot(
615
- self.foreland_x_coordinates,
616
- self.foreland_y_coordinates,
617
- color="orange",
618
- label="Foreland",
619
- zorder=1,
620
- )
621
-
622
- # Geometry
623
- for i in range(len(self.dike_x_coordinates) - 1):
624
- r = self.dike_roughness[i]
625
- plt.plot(
626
- self.dike_x_coordinates[i : i + 2],
627
- self.dike_y_coordinates[i : i + 2],
628
- color="black" if r != 1.0 else "green",
629
- label=f"Roughness: {r}",
630
- zorder=1,
631
- )
632
-
633
- # Breakwater
634
- if isinstance(self.breakwater_type, Breakwater):
635
- # Where should we draw the breakwater?
636
- if self.foreland_x_coordinates is not None:
637
- x_orig, y_orig = (
638
- self.foreland_x_coordinates[0],
639
- self.foreland_y_coordinates[0],
640
- )
641
- else:
642
- x_orig, y_orig = self.dike_x_coordinates[0], self.dike_y_coordinates[0]
643
-
644
- # Draw
645
- bw_height = self.breakwater_level
646
- if self.breakwater_type == Breakwater.CAISSON:
647
- plt.fill_between(
648
- [x_orig - 10, x_orig],
649
- [bw_height, bw_height],
650
- [y_orig, y_orig],
651
- color="dimgrey",
652
- label="Caisson",
653
- zorder=2,
654
- )
655
- elif self.breakwater_type == Breakwater.VERTICAL_WALL:
656
- plt.plot(
657
- [x_orig, x_orig],
658
- [y_orig, bw_height],
659
- color="black",
660
- lw=3,
661
- label="Vertical wall",
662
- zorder=2,
663
- )
664
- elif self.breakwater_type == Breakwater.RUBBLE_MOUND:
665
- diff = bw_height - y_orig
666
- plt.fill_between(
667
- [
668
- x_orig - (3 * diff) - 2,
669
- x_orig - (1.5 * diff) - 2,
670
- x_orig - (1.5 * diff),
671
- x_orig,
672
- ],
673
- [y_orig, bw_height, bw_height, y_orig],
674
- [y_orig, y_orig, y_orig, y_orig],
675
- color="grey",
676
- label="Rubble mound",
677
- zorder=2,
678
- )
679
-
680
- # Crest height
681
- plt.axhline(
682
- self.dike_crest_level,
683
- linestyle=":",
684
- color="grey",
685
- label="Crest height",
686
- zorder=1,
687
- )
688
-
689
- # Legend, labels, etc
690
- handles, labels = plt.gca().get_legend_handles_labels()
691
- by_label = dict(zip(labels, handles))
692
- plt.legend(by_label.values(), by_label.keys(), loc="upper left")
693
- plt.title(f"{self.profile_name} ({self.dike_orientation}°)", fontweight="bold")
694
- plt.xlabel("Distance [m]")
695
- plt.ylabel("Level [NAP+m]")
696
- plt.show()
697
-
698
- @classmethod
699
- def from_prfl(cls, prfl_path: str, profile_name: str = "Profile"):
700
- """
701
- Import a profile from a .prfl file
702
-
703
- Parameters
704
- ----------
705
- prfl_path : str
706
- Path to the '.prfl' file
707
- profile_name : str
708
- Name of the profile (default: 'Profile')
709
-
710
- Returns
711
- -------
712
- Profile
713
- Profile object
714
- """
715
- # Check if the file extension if .prfl
716
- if not prfl_path.lower().endswith(".prfl"):
717
- raise FileNotFoundError(
718
- f"[ERROR] Input file: {prfl_path} should be a .prfl file."
719
- )
720
-
721
- # Check if the provided path exists
722
- if not os.path.exists(prfl_path):
723
- raise FileNotFoundError(f"[ERROR] Input file: {prfl_path} not found.")
724
-
725
- # Read the file
726
- with open(prfl_path, "r") as file:
727
- prfl = file.read()
728
- prfl = prfl.replace("\t", " ")
729
-
730
- # Split the SQL commands by a line break (\n) and remove empty lines, stop before 'memo'
731
- prfl = [entry.lower().strip() for entry in prfl.split("\n") if entry.strip()]
732
- prfl = prfl[: prfl.index("memo")]
733
-
734
- # Create a new profile
735
- profile = cls(profile_name)
736
-
737
- # Version
738
- version = float([entry for entry in prfl if "versie" in entry][0].split(" ")[1])
739
- if version != 4.0:
740
- raise NotImplementedError(
741
- f"[ERROR] Prfl version {version} is not supported."
742
- )
743
-
744
- # Sheet pile
745
- sheetpile = (
746
- True
747
- if float([entry for entry in prfl if "damwand" in entry][0].split(" ")[1])
748
- == 1.0
749
- else False
750
- )
751
- if sheetpile:
752
- raise NotImplementedError("[ERROR] Sheet piles are not implemented.")
753
-
754
- # Breakwater
755
- breakwater = Breakwater(
756
- int([entry for entry in prfl if "dam" in entry][0].split(" ")[1])
757
- )
758
- breakwater_level = float(
759
- [entry for entry in prfl if "damhoogte" in entry][0].split(" ")[1]
760
- )
761
- profile.set_breakwater(breakwater, breakwater_level)
762
-
763
- # Foreland
764
- n_foreland = int(
765
- [entry for entry in prfl if "voorland" in entry][0].split(" ")[1]
766
- )
767
- idx_foreland = prfl.index(f"voorland {n_foreland}") + 1
768
- foreland_x = []
769
- foreland_y = []
770
- for row in range(idx_foreland, idx_foreland + n_foreland):
771
- foreland_x.extend([float(prfl[row].split(" ")[0])])
772
- foreland_y.extend([float(prfl[row].split(" ")[1])])
773
- if n_foreland > 0:
774
- profile.set_foreland_geometry(foreland_x, foreland_y)
775
-
776
- # Dike
777
- n_dike = int([entry for entry in prfl if "dijk" in entry][0].split(" ")[1])
778
- idx_dike = prfl.index(f"dijk {n_dike}") + 1
779
- dike_x = []
780
- dike_y = []
781
- dike_r = []
782
- for row in range(idx_dike, idx_dike + n_dike):
783
- dike_x.extend([float(prfl[row].split(" ")[0])])
784
- dike_y.extend([float(prfl[row].split(" ")[1])])
785
- dike_r.extend([float(prfl[row].split(" ")[2])])
786
- profile.set_dike_geometry(dike_x, dike_y, dike_r)
787
-
788
- # Crest height
789
- dike_crest_level = float(
790
- [entry for entry in prfl if "kruinhoogte" in entry][0].split(" ")[1]
791
- )
792
- profile.set_dike_crest_level(dike_crest_level)
793
-
794
- # Dike orientation
795
- dike_orientation = float(
796
- [entry for entry in prfl if "richting" in entry][0].split(" ")[1]
797
- )
798
- profile.set_dike_orientation(dike_orientation)
799
-
800
- # Return the class
801
- return profile
802
-
803
- @classmethod
804
- def from_dictionary(cls, dictionary: dict):
805
- """
806
- Create a profile from a dictionary
807
-
808
- Parameters
809
- ----------
810
- dictionary: dict
811
- Dictionary with all profile settings
812
- """
813
- # Create a new profile
814
- profile = cls(dictionary["profile_name"])
815
-
816
- # Add settings from dictionary to profile
817
- for setting in dictionary.keys():
818
- setattr(profile, setting, dictionary[setting])
819
-
820
- # Validate
821
- profile.validate_profile()
822
-
823
- return profile
824
-
825
- @classmethod
826
- def from_gebugekb_tool(
827
- cls, sql_path: str, profile_name: str = "Profile", berm_slope: float = 1 / 100
828
- ):
829
- """
830
- Import a profile from the GEBUGEKB plugin.
831
-
832
- Parameters
833
- ----------
834
- sql_path : str
835
- Path to the '1.sql' file
836
- profile_name : str
837
- Name of the profile (default: 'Profile')
838
- berm_slope : float
839
- If applicable: slope of the berm (default : 1/100)
840
-
841
- Returns
842
- -------
843
- Profile
844
- Profile object
845
- """
846
- # Check if the file extension if .prfl
847
- if not sql_path.lower().endswith(".sql"):
848
- raise FileNotFoundError(
849
- f"[ERROR] Input file: {sql_path} should be a .sql file."
850
- )
851
-
852
- # Check if the provided path exists
853
- if not os.path.exists(sql_path):
854
- raise FileNotFoundError(f"[ERROR] Input file: {sql_path} not found.")
855
-
856
- # Check if the berm slope is not too steep or shallow
857
- if berm_slope < 1 / 100 or berm_slope > 1 / 15:
858
- raise ValueError(
859
- f"[ERROR] The slope of the berm cannot be steeper than 1/15 or shallower than 1/100 (Given: 1/{1/berm_slope})."
860
- )
861
-
862
- # Read the file
863
- with open(sql_path, "r") as file:
864
- sql_commands = file.read()
865
-
866
- # Split the SQL commands by a line break (\n)
867
- commands = sql_commands.split("\n")
868
-
869
- # Remove all lines starting with 'DELETE FROM', '--' or is empty. Remove comments (by splitting at the semicolumn)
870
- commands = [
871
- entry.split(";")[0]
872
- for entry in commands
873
- if not entry.startswith("DELETE FROM")
874
- and not entry.startswith("--")
875
- and not entry == ""
876
- ]
877
-
878
- # Create a new profile
879
- profile = cls(profile_name)
880
-
881
- # Breakwater
882
- breakwater = [entry for entry in commands if "Breakwaters" in entry]
883
- breakwater = np.array(
884
- [ast.literal_eval(entry.split("VALUES ")[-1]) for entry in breakwater]
885
- )
886
- if len(breakwater) > 1:
887
- raise ValueError(
888
- "[ERROR] Multiple breakwaters are defined. Only one can be defined at a time."
889
- )
890
- elif len(breakwater) == 1:
891
- profile.set_breakwater(Breakwater(int(breakwater[0][1])), breakwater[0][2])
892
-
893
- # Foreland
894
- foreland = [entry for entry in commands if "Forelands" in entry]
895
- foreland = np.array(
896
- [ast.literal_eval(entry.split("VALUES ")[-1]) for entry in foreland]
897
- )
898
- if len(foreland) > 0:
899
- profile.set_foreland_geometry(foreland[:, 2], foreland[:, 3])
900
-
901
- # Dike geometry
902
- dike = [
903
- entry.replace("NULL", "-999")
904
- for entry in commands
905
- if "VariableDatas" in entry
906
- ]
907
- dike = np.array(
908
- [ast.literal_eval(entry.split("VALUES ")[-1]) for entry in dike]
909
- )[:, 4:]
910
-
911
- # Dike geometry
912
- slope_lower = dike[dike[:, 0] == 10][0][1]
913
- slope_upper = dike[dike[:, 0] == 11][0][1]
914
- toe_level = dike[dike[:, 0] == 12][0][1]
915
- berm_level = dike[dike[:, 0] == 13][0][1]
916
- berm_length = dike[dike[:, 0] == 14][0][1]
917
- crest_level = dike[dike[:, 0] == 15][0][1]
918
- dike_orientation = dike[dike[:, 0] == 16][0][1]
919
- roughness = dike[dike[:, 0] == 17][0][1]
920
- zone_roughness = dike[dike[:, 0] == 50][0][1]
921
- zone_ymin = dike[dike[:, 0] == 51][0][1]
922
- zone_ymax = dike[dike[:, 0] == 52][0][1]
923
-
924
- # Calculate coordinates
925
- dike_x = [0]
926
- dike_y = [toe_level]
927
-
928
- # If there is no berm
929
- if berm_length <= 0:
930
- dike_x.extend([(berm_level - toe_level) / slope_lower])
931
- dike_y.extend([berm_level])
932
- else:
933
- berm_difference = berm_slope * berm_length
934
- dike_x.extend(
935
- [(berm_level - 0.5 * berm_difference - toe_level) / slope_lower]
936
- )
937
- dike_y.extend([berm_level - 0.5 * berm_difference])
938
- dike_x.extend([dike_x[-1] + berm_length])
939
- dike_y.extend([berm_level + 0.5 * berm_difference])
940
-
941
- # Crest
942
- dike_x.extend([dike_x[-1] + (crest_level - dike_y[-1]) / slope_upper])
943
- dike_y.extend([crest_level])
944
-
945
- # Roughness
946
- dike_r = np.ones([len(dike_x)]) * roughness
947
- dike_r[(dike_y >= zone_ymin) & (dike_y < zone_ymax)] = zone_roughness
948
-
949
- # Do we need to add an extra point for zone_ymin?
950
- if (zone_ymin >= np.min(dike_y)) and (zone_ymin not in dike_y):
951
- x_int = Interpolate.inextrp1d(zone_ymin, dike_y, dike_x)
952
- idx = np.searchsorted(dike_x, x_int)
953
- dike_x = np.insert(dike_x, idx, x_int)
954
- dike_y = np.insert(dike_y, idx, zone_ymin)
955
- dike_r = np.insert(dike_r, idx, zone_roughness)
956
-
957
- # Do we need to add an extra point for zone_ymax?
958
- if (zone_ymax <= np.max(dike_y)) and (zone_ymax not in dike_y):
959
- x_int = Interpolate.inextrp1d(zone_ymax, dike_y, dike_x)
960
- idx = np.searchsorted(dike_x, x_int)
961
- dike_x = np.insert(dike_x, idx, x_int)
962
- dike_y = np.insert(dike_y, idx, zone_ymax)
963
- dike_r = np.insert(dike_r, idx, roughness)
964
-
965
- # Dike orientation, crest and geometry
966
- profile.set_dike_orientation(dike_orientation)
967
- profile.set_dike_geometry(dike_x, dike_y, dike_r)
968
- profile.set_dike_crest_level(crest_level)
969
-
970
- # Return the class
971
- return profile
1
+ import ast
2
+ import matplotlib.pyplot as plt
3
+ import numpy as np
4
+ import os
5
+
6
+ from typing import Tuple, Union
7
+
8
+ from .foreland import Foreland
9
+ from .profile_loading import ProfileLoading
10
+ from ...common.enum import Breakwater
11
+ from ...common.interpolate import Interpolate
12
+
13
+
14
+ class Profile:
15
+ """
16
+ Profile class
17
+
18
+ TODO: Implement support for sheet piles
19
+ """
20
+
21
+ # Profile name
22
+ profile_name = None
23
+
24
+ # Breakwater
25
+ breakwater_type = Breakwater.NO_BREAKWATER
26
+ breakwater_level = 0.0
27
+
28
+ # Foreland
29
+ foreland_x_coordinates: None | list = None
30
+ foreland_y_coordinates: None | list = None
31
+
32
+ # Dike schematisation
33
+ dike_orientation: None | float = None
34
+ dike_crest_level: None | float = None
35
+ dike_x_coordinates: None | list = None
36
+ dike_y_coordinates: None | list = None
37
+ dike_roughness: None | list = None
38
+
39
+ def __init__(self, profile_name: str = "Profile"):
40
+ """
41
+ Create a new profile
42
+
43
+ Parameters
44
+ ----------
45
+ profile_name: str
46
+ Name of the profile (default: 'Profile')
47
+ """
48
+ # Save the profile name
49
+ self.profile_name = profile_name
50
+
51
+ def validate_profile(self) -> bool:
52
+ """
53
+ Function to validate the profile.
54
+
55
+ Returns
56
+ -------
57
+ bool
58
+ True if the profile is OK
59
+ """
60
+ # TODO: Improve validation
61
+ # Check necessary components
62
+ # Orientation
63
+ if self.dike_orientation is None:
64
+ return False
65
+
66
+ # Crest height
67
+ if self.dike_crest_level is None:
68
+ return False
69
+
70
+ # Geometry
71
+ if (
72
+ (self.dike_x_coordinates is None)
73
+ or (self.dike_y_coordinates is None)
74
+ or (self.dike_roughness is None)
75
+ ):
76
+ return False
77
+
78
+ return True
79
+
80
+ def set_dike_orientation(self, dike_orientation: float):
81
+ """
82
+ Change the dike orientation
83
+
84
+ Parameters
85
+ ----------
86
+ dike_orientation : float
87
+ The dike orientation
88
+ """
89
+ self.dike_orientation = dike_orientation
90
+
91
+ def set_dike_crest_level(self, dike_crest_level: float):
92
+ """
93
+ Change the crest level
94
+
95
+ Parameters
96
+ ----------
97
+ dike_crest_level : float
98
+ The crest level of the dike
99
+ """
100
+ self.dike_crest_level = dike_crest_level
101
+
102
+ def set_dike_geometry(
103
+ self,
104
+ dike_x_coordinates: list,
105
+ dike_y_coordinates: list,
106
+ dike_roughness: list = None,
107
+ ):
108
+ """
109
+ Change the geometry of the outer slope of the dike
110
+
111
+ Parameters
112
+ ----------
113
+ dike_x_coordinates : list
114
+ A list with the x coordinates of the profile
115
+ dike_y_coordinates : list
116
+ A list with the y coordinates of the profile
117
+ dike_roughness : list, optional
118
+ A list with the roughness of the profile (default : all parts 1.0)
119
+ """
120
+ # Make sure the dike geometry starts at (x = 0)
121
+ min_x = np.min(dike_x_coordinates)
122
+
123
+ # If dike roughness is None, the roughness of every part is 1.0
124
+ if dike_roughness is None:
125
+ dike_roughness = [1.0] * len(dike_x_coordinates)
126
+
127
+ # Save the dike geometry coordinates
128
+ self.dike_x_coordinates = dike_x_coordinates - min_x
129
+ self.dike_y_coordinates = dike_y_coordinates
130
+ self.dike_roughness = dike_roughness
131
+
132
+ def has_foreland(self) -> bool:
133
+ """
134
+ Returns whether the profile has a foreland or breakwater
135
+
136
+ Returns
137
+ -------
138
+ bool
139
+ True if the profile has a foreland or breakwater
140
+ """
141
+ # Check for a breakwater
142
+ if self.breakwater_type != Breakwater.NO_BREAKWATER:
143
+ return True
144
+
145
+ # Check for a foreland
146
+ if self.foreland_x_coordinates is not None:
147
+ return True
148
+
149
+ # No foreland or breakwater
150
+ return False
151
+
152
+ def set_foreland_geometry(
153
+ self, foreland_x_coordinates: list = None, foreland_y_coordinates: list = None
154
+ ):
155
+ """
156
+ Change the geometry of the foreland
157
+ Setting the foreland x and y coordinates to None will remove the foreland.
158
+
159
+ Parameters
160
+ ----------
161
+ foreland_x_coordinates : list
162
+ A list with the x coordinates of the foreland (default: None)
163
+ foreland_y_coordinates : list
164
+ A list with the y coordinates of the foreland (default: None)
165
+ """
166
+ # Add foreland
167
+ if foreland_x_coordinates is not None:
168
+ # Make sure the foreland ends at (x = 0)
169
+ max_x = np.max(foreland_x_coordinates)
170
+
171
+ # Save the foreland coordinates
172
+ self.foreland_x_coordinates = foreland_x_coordinates - max_x
173
+ self.foreland_y_coordinates = foreland_y_coordinates
174
+
175
+ # Delete foreland
176
+ else:
177
+ self.foreland_x_coordinates = None
178
+ self.foreland_y_coordinates = None
179
+
180
+ def remove_foreland(self) -> None:
181
+ """
182
+ Remove the foreland
183
+ Wrapper for set_foreland_geometry()
184
+ """
185
+ self.set_foreland_geometry(
186
+ foreland_x_coordinates=None, foreland_y_coordinates=None
187
+ )
188
+
189
+ def set_breakwater(
190
+ self, breakwater_type: Breakwater = None, breakwater_level: float = 0.0
191
+ ):
192
+ """
193
+ Change the breakwater
194
+ """
195
+ # None equals no breakwater
196
+ if breakwater_type is None:
197
+ breakwater_type = Breakwater.NO_BREAKWATER
198
+
199
+ # If there is no breakwater, the height will be set to None
200
+ if breakwater_type == Breakwater.NO_BREAKWATER:
201
+ breakwater_level = 0.0
202
+
203
+ # Apply settings
204
+ self.breakwater_type = breakwater_type
205
+ self.breakwater_level = breakwater_level
206
+
207
+ def remove_breakwater(self) -> None:
208
+ """
209
+ Remove the breakwater
210
+ Wrapper for set_breakwater()
211
+ """
212
+ self.set_breakwater(
213
+ breakwater_type=Breakwater.NO_BREAKWATER, breakwater_level=0.0
214
+ )
215
+
216
+ def calculate_overtopping(
217
+ self,
218
+ water_level: Union[float, list],
219
+ significant_wave_height: Union[float, list],
220
+ spectral_wave_period: Union[float, list],
221
+ wave_direction: Union[float, list],
222
+ tp_tspec: float = 1.1,
223
+ dll_settings: dict = None,
224
+ ) -> Union[float, list]:
225
+ """
226
+ Calculate the overtopping discharge
227
+
228
+ Parameters
229
+ ----------
230
+ water_level : Union[float, list]
231
+ List or float with the water level
232
+ significant_wave_height : Union[float, list]
233
+ List or float with the significant wave height
234
+ spectral_wave_period : Union[float, list]
235
+ List or float with the spectral wave period
236
+ wave_direction : Union[float, list]
237
+ List or float with the wave direction
238
+ tp_tspec : float, optional
239
+ Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
240
+
241
+ Returns
242
+ -------
243
+ Union[float, list]
244
+ List or float with the overtopping discharge
245
+ """
246
+ # Transform wave conditions
247
+ water_level, significant_wave_height, spectral_wave_period, wave_direction = (
248
+ self.transform_wave_conditions(
249
+ water_level,
250
+ significant_wave_height,
251
+ spectral_wave_period,
252
+ wave_direction,
253
+ tp_tspec,
254
+ force_array=True,
255
+ )
256
+ )
257
+
258
+ # Create profile loading
259
+ profile_loading = ProfileLoading(self, dll_settings)
260
+
261
+ # Calculate
262
+ qov = []
263
+ for _h, _hs, _tspec, _dir in zip(
264
+ water_level, significant_wave_height, spectral_wave_period, wave_direction
265
+ ):
266
+ qov.append(profile_loading.calculate_discharge(_h, _hs, _tspec, _dir))
267
+
268
+ # Return
269
+ return qov[0] if len(qov) == 1 else qov
270
+
271
+ def calculate_runup(
272
+ self,
273
+ water_level: Union[float, list],
274
+ significant_wave_height: Union[float, list],
275
+ spectral_wave_period: Union[float, list],
276
+ wave_direction: Union[float, list],
277
+ tp_tspec: float = 1.1,
278
+ dll_settings: dict = None,
279
+ ) -> Union[float, list]:
280
+ """
281
+ Calculate the runup height
282
+
283
+ Parameters
284
+ ----------
285
+ water_level : Union[float, list]
286
+ List or float with the water level
287
+ significant_wave_height : Union[float, list]
288
+ List or float with the significant wave height
289
+ spectral_wave_period : Union[float, list]
290
+ List or float with the spectral wave period
291
+ wave_direction : Union[float, list]
292
+ List or float with the wave direction
293
+ tp_tspec : float, optional
294
+ Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
295
+
296
+ Returns
297
+ -------
298
+ Union[float, list]
299
+ List or float with the runup height
300
+ """
301
+ # Transform wave conditions
302
+ water_level, significant_wave_height, spectral_wave_period, wave_direction = (
303
+ self.transform_wave_conditions(
304
+ water_level,
305
+ significant_wave_height,
306
+ spectral_wave_period,
307
+ wave_direction,
308
+ tp_tspec,
309
+ force_array=True,
310
+ )
311
+ )
312
+
313
+ # Create profile loading
314
+ profile_loading = ProfileLoading(self, dll_settings)
315
+
316
+ # Calculate
317
+ ru2p = []
318
+ for _h, _hs, _tspec, _dir in zip(
319
+ water_level, significant_wave_height, spectral_wave_period, wave_direction
320
+ ):
321
+ ru2p.append(profile_loading.calculate_runup(_h, _hs, _tspec, _dir))
322
+
323
+ # Return
324
+ return ru2p[0] if len(ru2p) == 1 else ru2p
325
+
326
+ def calculate_crest_level(
327
+ self,
328
+ q_overtopping: float,
329
+ water_level: Union[float, list],
330
+ significant_wave_height: Union[float, list],
331
+ spectral_wave_period: Union[float, list],
332
+ wave_direction: Union[float, list],
333
+ tp_tspec: float = 1.1,
334
+ dll_settings: dict = None,
335
+ ) -> Union[float, list]:
336
+ """
337
+ Calculate the crest level for a given overtopping discharge
338
+
339
+ Parameters
340
+ ----------
341
+ q_overtopping : float
342
+ Critical overtopping discharge
343
+ water_level : Union[float, list]
344
+ List or float with the water level
345
+ significant_wave_height : Union[float, list]
346
+ List or float with the significant wave height
347
+ spectral_wave_period : Union[float, list]
348
+ List or float with the spectral wave period
349
+ wave_direction : Union[float, list]
350
+ List or float with the wave direction
351
+ tp_tspec : float, optional
352
+ Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
353
+
354
+ Returns
355
+ -------
356
+ Union[float, list]
357
+ List or float with the crest level
358
+ """
359
+ # Transform wave conditions
360
+ water_level, significant_wave_height, spectral_wave_period, wave_direction = (
361
+ self.transform_wave_conditions(
362
+ water_level,
363
+ significant_wave_height,
364
+ spectral_wave_period,
365
+ wave_direction,
366
+ tp_tspec,
367
+ force_array=True,
368
+ )
369
+ )
370
+
371
+ # Length of the list
372
+ n_q = 1 if isinstance(q_overtopping, (float, int)) else len(q_overtopping)
373
+
374
+ # If q_overtopping is an int or float
375
+ if isinstance(q_overtopping, (float, int)):
376
+ q_overtopping = [q_overtopping] * len(water_level)
377
+
378
+ # If q_overtopping is a list and water_level has length 1
379
+ elif n_q > 1 and len(water_level) == 1:
380
+ water_level = [water_level] * n_q
381
+ significant_wave_height = [significant_wave_height] * n_q
382
+ spectral_wave_period = [spectral_wave_period] * n_q
383
+ wave_direction = [wave_direction] * n_q
384
+
385
+ # Uneven length of arrays
386
+ else:
387
+ raise ValueError("[ERROR] Uneven length of arrays")
388
+
389
+ # To numpy
390
+ q_overtopping = np.array(q_overtopping)
391
+ water_level = np.array(water_level)
392
+ significant_wave_height = np.array(significant_wave_height)
393
+ spectral_wave_period = np.array(spectral_wave_period)
394
+ wave_direction = np.array(wave_direction)
395
+
396
+ # Create profile loading
397
+ profile_loading = ProfileLoading(self, dll_settings)
398
+
399
+ # Calculate crest level
400
+ hbn = []
401
+ for _q, _h, _hs, _tspec, _dir in zip(
402
+ q_overtopping,
403
+ water_level,
404
+ significant_wave_height,
405
+ spectral_wave_period,
406
+ wave_direction,
407
+ ):
408
+ hbn.append(profile_loading.calculate_crest_level(_q, _h, _hs, _tspec, _dir))
409
+
410
+ # Return
411
+ return hbn[0] if len(hbn) == 1 else hbn
412
+
413
+ def transform_wave_conditions(
414
+ self,
415
+ water_level: Union[float, list],
416
+ significant_wave_height: Union[float, list],
417
+ spectral_wave_period: Union[float, list],
418
+ wave_direction: Union[float, list],
419
+ tp_tspec: float = 1.1,
420
+ force_array: bool = False,
421
+ ) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
422
+ """
423
+ Transform the wave conditions for the schematized foreland
424
+
425
+ Parameters
426
+ ----------
427
+ water_level : Union[float, list]
428
+ Water level
429
+ significant_wave_height : Union[float, list]
430
+ Significant wave height
431
+ spectral_wave_period : Union[float, list]
432
+ Spectral wave period
433
+ wave_direction : Union[float, list]
434
+ Wave direction
435
+ tp_tspec : float, optional
436
+ Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
437
+ force_array : bool, optional
438
+ Always force to return an array
439
+
440
+ Returns
441
+ -------
442
+ Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]
443
+ Water level and transformed wave conditions (h, hs, tp, dir)
444
+ """
445
+ # Length of the lists
446
+ n_h = 1 if isinstance(water_level, (float, int)) else len(water_level)
447
+ n_hs = (
448
+ 1
449
+ if isinstance(significant_wave_height, (float, int))
450
+ else len(significant_wave_height)
451
+ )
452
+ n_tspec = (
453
+ 1
454
+ if isinstance(spectral_wave_period, (float, int))
455
+ else len(spectral_wave_period)
456
+ )
457
+ n_dir = 1 if isinstance(wave_direction, (float, int)) else len(wave_direction)
458
+ n_max = np.max([n_h, n_hs, n_tspec, n_dir])
459
+
460
+ # Make lists
461
+ if isinstance(water_level, (float, int)):
462
+ water_level = [water_level] * n_max
463
+ elif len(water_level) != n_max:
464
+ raise ValueError("[ERROR] Uneven length of arrays")
465
+
466
+ if isinstance(significant_wave_height, (float, int)):
467
+ significant_wave_height = [significant_wave_height] * n_max
468
+ elif len(significant_wave_height) != n_max:
469
+ raise ValueError("[ERROR] Uneven length of arrays")
470
+
471
+ if isinstance(spectral_wave_period, (float, int)):
472
+ spectral_wave_period = [spectral_wave_period] * n_max
473
+ elif len(spectral_wave_period) != n_max:
474
+ raise ValueError("[ERROR] Uneven length of arrays")
475
+
476
+ if isinstance(wave_direction, (float, int)):
477
+ wave_direction = [wave_direction] * n_max
478
+ elif len(wave_direction) != n_max:
479
+ raise ValueError("[ERROR] Uneven length of arrays")
480
+
481
+ # To numpy
482
+ water_level = np.array(water_level)
483
+ significant_wave_height = np.array(significant_wave_height)
484
+ spectral_wave_period = np.array(spectral_wave_period)
485
+ wave_direction = np.array(wave_direction)
486
+
487
+ # Correct for foreland
488
+ if self.has_foreland():
489
+ fl = Foreland(self)
490
+ water_level, significant_wave_height, peak_wave_period, wave_direction = (
491
+ fl.transform_wave_conditions(
492
+ water_level,
493
+ significant_wave_height,
494
+ spectral_wave_period * tp_tspec,
495
+ wave_direction,
496
+ )
497
+ )
498
+ spectral_wave_period = peak_wave_period / tp_tspec
499
+
500
+ # Return array or floats?
501
+ if len(water_level.ravel()) == 1 and not force_array:
502
+ return (
503
+ water_level.ravel()[0],
504
+ significant_wave_height.ravel()[0],
505
+ spectral_wave_period.ravel()[0],
506
+ wave_direction.ravel()[0],
507
+ )
508
+ else:
509
+ return (
510
+ water_level,
511
+ significant_wave_height,
512
+ spectral_wave_period,
513
+ wave_direction,
514
+ )
515
+
516
+ def to_prfl(
517
+ self, export_path: str, id: str = "Onbekend000", memo: str = ""
518
+ ) -> None:
519
+ """
520
+ Export to a prfl file
521
+
522
+ export_path : str
523
+ Path to where the profile has to be exported
524
+ id : str
525
+ Id used in RisKeer
526
+ memo : str
527
+ Memo to be added to the prfl file
528
+ """
529
+ # Check required info
530
+ if (
531
+ (self.dike_x_coordinates is None)
532
+ or (self.dike_crest_level is None)
533
+ or (self.dike_orientation is None)
534
+ ):
535
+ raise ValueError(
536
+ f"[ERROR] Cannot generate .prfl for profile '{self.profile_name}', geometry, crest level or orientation is missing."
537
+ )
538
+
539
+ # Version
540
+ breakwater_level = (
541
+ self.breakwater_level if self.breakwater_level is not None else 0.0
542
+ )
543
+ n_foreland = (
544
+ len(self.foreland_x_coordinates)
545
+ if self.foreland_x_coordinates is not None
546
+ else 0
547
+ )
548
+ n_dike = (
549
+ len(self.dike_x_coordinates) if self.dike_x_coordinates is not None else 0
550
+ )
551
+ export = f"VERSIE 4.0\nID {id}\n\nRICHTING {self.dike_orientation}\n\nDAM {int(self.breakwater_type.value)}\nDAMHOOGTE {breakwater_level}\n\nVOORLAND {n_foreland}\n[FORELAND]\nDAMWAND 0\nKRUINHOOGTE {self.dike_crest_level}\nDIJK {n_dike}\n[DIKE]\nMEMO\nGenerated with Pydra for profile '{self.profile_name}'\n{memo}\n"
552
+
553
+ # Foreland
554
+ foreland = ""
555
+ if n_foreland > 0:
556
+ for foreland_x, foreland_y in zip(
557
+ self.foreland_x_coordinates, self.foreland_y_coordinates
558
+ ):
559
+ foreland = (
560
+ foreland
561
+ + f"{round(foreland_x,3):.3f}\t{round(foreland_y,3):.3f}\t1.000\n"
562
+ )
563
+ export = export.replace("[FORELAND]", foreland)
564
+
565
+ # Dike
566
+ dike = ""
567
+ if n_dike > 0:
568
+ for dike_x, dike_y, dike_r in zip(
569
+ self.dike_x_coordinates, self.dike_y_coordinates, self.dike_roughness
570
+ ):
571
+ dike = (
572
+ dike
573
+ + f"{round(dike_x,3):.3f}\t{round(dike_y,3):.3f}\t{round(dike_r,3):.3f}\n"
574
+ )
575
+ export = export.replace("[DIKE]", dike)
576
+
577
+ # Export .prfl
578
+ if not export_path.lower().endswith(".prfl"):
579
+ export_path = export_path + ".prfl"
580
+ prfl_file = open(export_path, "w")
581
+ prfl_file.write(export)
582
+ prfl_file.close()
583
+
584
+ def to_dict(self) -> dict:
585
+ """
586
+ Export Profile to dictionary
587
+
588
+ Returns
589
+ -------
590
+ dictionary
591
+ Dictionary with all profile settings
592
+ """
593
+ # Create an empty dictionary
594
+ profile = {}
595
+
596
+ # Add all settings to the dictionary
597
+ for setting in dir(self):
598
+ if not str(setting).startswith("__") and not callable(
599
+ getattr(self, setting)
600
+ ):
601
+ profile[setting] = getattr(self, setting)
602
+
603
+ return profile
604
+
605
+ def draw_profile(self) -> None:
606
+ """
607
+ Draw a cross-section of the profile
608
+ """
609
+ # Init plot
610
+ plt.figure(figsize=[8, 5])
611
+
612
+ # Foreland
613
+ if self.foreland_x_coordinates is not None:
614
+ plt.plot(
615
+ self.foreland_x_coordinates,
616
+ self.foreland_y_coordinates,
617
+ color="orange",
618
+ label="Foreland",
619
+ zorder=1,
620
+ )
621
+
622
+ # Geometry
623
+ for i in range(len(self.dike_x_coordinates) - 1):
624
+ r = self.dike_roughness[i]
625
+ plt.plot(
626
+ self.dike_x_coordinates[i : i + 2],
627
+ self.dike_y_coordinates[i : i + 2],
628
+ color="black" if r != 1.0 else "green",
629
+ label=f"Roughness: {r}",
630
+ zorder=1,
631
+ )
632
+
633
+ # Breakwater
634
+ if isinstance(self.breakwater_type, Breakwater):
635
+ # Where should we draw the breakwater?
636
+ if self.foreland_x_coordinates is not None:
637
+ x_orig, y_orig = (
638
+ self.foreland_x_coordinates[0],
639
+ self.foreland_y_coordinates[0],
640
+ )
641
+ else:
642
+ x_orig, y_orig = self.dike_x_coordinates[0], self.dike_y_coordinates[0]
643
+
644
+ # Draw
645
+ bw_height = self.breakwater_level
646
+ if self.breakwater_type == Breakwater.CAISSON:
647
+ plt.fill_between(
648
+ [x_orig - 10, x_orig],
649
+ [bw_height, bw_height],
650
+ [y_orig, y_orig],
651
+ color="dimgrey",
652
+ label="Caisson",
653
+ zorder=2,
654
+ )
655
+ elif self.breakwater_type == Breakwater.VERTICAL_WALL:
656
+ plt.plot(
657
+ [x_orig, x_orig],
658
+ [y_orig, bw_height],
659
+ color="black",
660
+ lw=3,
661
+ label="Vertical wall",
662
+ zorder=2,
663
+ )
664
+ elif self.breakwater_type == Breakwater.RUBBLE_MOUND:
665
+ diff = bw_height - y_orig
666
+ plt.fill_between(
667
+ [
668
+ x_orig - (3 * diff) - 2,
669
+ x_orig - (1.5 * diff) - 2,
670
+ x_orig - (1.5 * diff),
671
+ x_orig,
672
+ ],
673
+ [y_orig, bw_height, bw_height, y_orig],
674
+ [y_orig, y_orig, y_orig, y_orig],
675
+ color="grey",
676
+ label="Rubble mound",
677
+ zorder=2,
678
+ )
679
+
680
+ # Crest height
681
+ plt.axhline(
682
+ self.dike_crest_level,
683
+ linestyle=":",
684
+ color="grey",
685
+ label="Crest height",
686
+ zorder=1,
687
+ )
688
+
689
+ # Legend, labels, etc
690
+ handles, labels = plt.gca().get_legend_handles_labels()
691
+ by_label = dict(zip(labels, handles))
692
+ plt.legend(by_label.values(), by_label.keys(), loc="upper left")
693
+ plt.title(f"{self.profile_name} ({self.dike_orientation}°)", fontweight="bold")
694
+ plt.xlabel("Distance [m]")
695
+ plt.ylabel("Level [NAP+m]")
696
+ plt.show()
697
+
698
+ @classmethod
699
+ def from_prfl(cls, prfl_path: str, profile_name: str = "Profile"):
700
+ """
701
+ Import a profile from a .prfl file
702
+
703
+ Parameters
704
+ ----------
705
+ prfl_path : str
706
+ Path to the '.prfl' file
707
+ profile_name : str
708
+ Name of the profile (default: 'Profile')
709
+
710
+ Returns
711
+ -------
712
+ Profile
713
+ Profile object
714
+ """
715
+ # Check if the file extension if .prfl
716
+ if not prfl_path.lower().endswith(".prfl"):
717
+ raise FileNotFoundError(
718
+ f"[ERROR] Input file: {prfl_path} should be a .prfl file."
719
+ )
720
+
721
+ # Check if the provided path exists
722
+ if not os.path.exists(prfl_path):
723
+ raise FileNotFoundError(f"[ERROR] Input file: {prfl_path} not found.")
724
+
725
+ # Read the file
726
+ with open(prfl_path, "r") as file:
727
+ prfl = file.read()
728
+ prfl = prfl.replace("\t", " ")
729
+
730
+ # Split the SQL commands by a line break (\n) and remove empty lines, stop before 'memo'
731
+ prfl = [entry.lower().strip() for entry in prfl.split("\n") if entry.strip()]
732
+ prfl = prfl[: prfl.index("memo")]
733
+
734
+ # Create a new profile
735
+ profile = cls(profile_name)
736
+
737
+ # Version
738
+ version = float([entry for entry in prfl if "versie" in entry][0].split(" ")[1])
739
+ if version != 4.0:
740
+ raise NotImplementedError(
741
+ f"[ERROR] Prfl version {version} is not supported."
742
+ )
743
+
744
+ # Sheet pile
745
+ sheetpile = (
746
+ True
747
+ if float([entry for entry in prfl if "damwand" in entry][0].split(" ")[1])
748
+ == 1.0
749
+ else False
750
+ )
751
+ if sheetpile:
752
+ raise NotImplementedError("[ERROR] Sheet piles are not implemented.")
753
+
754
+ # Breakwater
755
+ breakwater = Breakwater(
756
+ int([entry for entry in prfl if "dam" in entry][0].split(" ")[1])
757
+ )
758
+ breakwater_level = float(
759
+ [entry for entry in prfl if "damhoogte" in entry][0].split(" ")[1]
760
+ )
761
+ profile.set_breakwater(breakwater, breakwater_level)
762
+
763
+ # Foreland
764
+ n_foreland = int(
765
+ [entry for entry in prfl if "voorland" in entry][0].split(" ")[1]
766
+ )
767
+ idx_foreland = prfl.index(f"voorland {n_foreland}") + 1
768
+ foreland_x = []
769
+ foreland_y = []
770
+ for row in range(idx_foreland, idx_foreland + n_foreland):
771
+ foreland_x.extend([float(prfl[row].split(" ")[0])])
772
+ foreland_y.extend([float(prfl[row].split(" ")[1])])
773
+ if n_foreland > 0:
774
+ profile.set_foreland_geometry(foreland_x, foreland_y)
775
+
776
+ # Dike
777
+ n_dike = int([entry for entry in prfl if "dijk" in entry][0].split(" ")[1])
778
+ idx_dike = prfl.index(f"dijk {n_dike}") + 1
779
+ dike_x = []
780
+ dike_y = []
781
+ dike_r = []
782
+ for row in range(idx_dike, idx_dike + n_dike):
783
+ dike_x.extend([float(prfl[row].split(" ")[0])])
784
+ dike_y.extend([float(prfl[row].split(" ")[1])])
785
+ dike_r.extend([float(prfl[row].split(" ")[2])])
786
+ profile.set_dike_geometry(dike_x, dike_y, dike_r)
787
+
788
+ # Crest height
789
+ dike_crest_level = float(
790
+ [entry for entry in prfl if "kruinhoogte" in entry][0].split(" ")[1]
791
+ )
792
+ profile.set_dike_crest_level(dike_crest_level)
793
+
794
+ # Dike orientation
795
+ dike_orientation = float(
796
+ [entry for entry in prfl if "richting" in entry][0].split(" ")[1]
797
+ )
798
+ profile.set_dike_orientation(dike_orientation)
799
+
800
+ # Return the class
801
+ return profile
802
+
803
+ @classmethod
804
+ def from_dictionary(cls, dictionary: dict):
805
+ """
806
+ Create a profile from a dictionary
807
+
808
+ Parameters
809
+ ----------
810
+ dictionary: dict
811
+ Dictionary with all profile settings
812
+ """
813
+ # Create a new profile
814
+ profile = cls(dictionary["profile_name"])
815
+
816
+ # Add settings from dictionary to profile
817
+ for setting in dictionary.keys():
818
+ setattr(profile, setting, dictionary[setting])
819
+
820
+ # Validate
821
+ profile.validate_profile()
822
+
823
+ return profile
824
+
825
+ @classmethod
826
+ def from_gebugekb_tool(
827
+ cls, sql_path: str, profile_name: str = "Profile", berm_slope: float = 1 / 100
828
+ ):
829
+ """
830
+ Import a profile from the GEBUGEKB plugin.
831
+
832
+ Parameters
833
+ ----------
834
+ sql_path : str
835
+ Path to the '1.sql' file
836
+ profile_name : str
837
+ Name of the profile (default: 'Profile')
838
+ berm_slope : float
839
+ If applicable: slope of the berm (default : 1/100)
840
+
841
+ Returns
842
+ -------
843
+ Profile
844
+ Profile object
845
+ """
846
+ # Check if the file extension if .prfl
847
+ if not sql_path.lower().endswith(".sql"):
848
+ raise FileNotFoundError(
849
+ f"[ERROR] Input file: {sql_path} should be a .sql file."
850
+ )
851
+
852
+ # Check if the provided path exists
853
+ if not os.path.exists(sql_path):
854
+ raise FileNotFoundError(f"[ERROR] Input file: {sql_path} not found.")
855
+
856
+ # Check if the berm slope is not too steep or shallow
857
+ if berm_slope < 1 / 100 or berm_slope > 1 / 15:
858
+ raise ValueError(
859
+ f"[ERROR] The slope of the berm cannot be steeper than 1/15 or shallower than 1/100 (Given: 1/{1/berm_slope})."
860
+ )
861
+
862
+ # Read the file
863
+ with open(sql_path, "r") as file:
864
+ sql_commands = file.read()
865
+
866
+ # Split the SQL commands by a line break (\n)
867
+ commands = sql_commands.split("\n")
868
+
869
+ # Remove all lines starting with 'DELETE FROM', '--' or is empty. Remove comments (by splitting at the semicolumn)
870
+ commands = [
871
+ entry.split(";")[0]
872
+ for entry in commands
873
+ if not entry.startswith("DELETE FROM")
874
+ and not entry.startswith("--")
875
+ and not entry == ""
876
+ ]
877
+
878
+ # Create a new profile
879
+ profile = cls(profile_name)
880
+
881
+ # Breakwater
882
+ breakwater = [entry for entry in commands if "Breakwaters" in entry]
883
+ breakwater = np.array(
884
+ [ast.literal_eval(entry.split("VALUES ")[-1]) for entry in breakwater]
885
+ )
886
+ if len(breakwater) > 1:
887
+ raise ValueError(
888
+ "[ERROR] Multiple breakwaters are defined. Only one can be defined at a time."
889
+ )
890
+ elif len(breakwater) == 1:
891
+ profile.set_breakwater(Breakwater(int(breakwater[0][1])), breakwater[0][2])
892
+
893
+ # Foreland
894
+ foreland = [entry for entry in commands if "Forelands" in entry]
895
+ foreland = np.array(
896
+ [ast.literal_eval(entry.split("VALUES ")[-1]) for entry in foreland]
897
+ )
898
+ if len(foreland) > 0:
899
+ profile.set_foreland_geometry(foreland[:, 2], foreland[:, 3])
900
+
901
+ # Dike geometry
902
+ dike = [
903
+ entry.replace("NULL", "-999")
904
+ for entry in commands
905
+ if "VariableDatas" in entry
906
+ ]
907
+ dike = np.array(
908
+ [ast.literal_eval(entry.split("VALUES ")[-1]) for entry in dike]
909
+ )[:, 4:]
910
+
911
+ # Dike geometry
912
+ slope_lower = dike[dike[:, 0] == 10][0][1]
913
+ slope_upper = dike[dike[:, 0] == 11][0][1]
914
+ toe_level = dike[dike[:, 0] == 12][0][1]
915
+ berm_level = dike[dike[:, 0] == 13][0][1]
916
+ berm_length = dike[dike[:, 0] == 14][0][1]
917
+ crest_level = dike[dike[:, 0] == 15][0][1]
918
+ dike_orientation = dike[dike[:, 0] == 16][0][1]
919
+ roughness = dike[dike[:, 0] == 17][0][1]
920
+ zone_roughness = dike[dike[:, 0] == 50][0][1]
921
+ zone_ymin = dike[dike[:, 0] == 51][0][1]
922
+ zone_ymax = dike[dike[:, 0] == 52][0][1]
923
+
924
+ # Calculate coordinates
925
+ dike_x = [0]
926
+ dike_y = [toe_level]
927
+
928
+ # If there is no berm
929
+ if berm_length <= 0:
930
+ dike_x.extend([(berm_level - toe_level) / slope_lower])
931
+ dike_y.extend([berm_level])
932
+ else:
933
+ berm_difference = berm_slope * berm_length
934
+ dike_x.extend(
935
+ [(berm_level - 0.5 * berm_difference - toe_level) / slope_lower]
936
+ )
937
+ dike_y.extend([berm_level - 0.5 * berm_difference])
938
+ dike_x.extend([dike_x[-1] + berm_length])
939
+ dike_y.extend([berm_level + 0.5 * berm_difference])
940
+
941
+ # Crest
942
+ dike_x.extend([dike_x[-1] + (crest_level - dike_y[-1]) / slope_upper])
943
+ dike_y.extend([crest_level])
944
+
945
+ # Roughness
946
+ dike_r = np.ones([len(dike_x)]) * roughness
947
+ dike_r[(dike_y >= zone_ymin) & (dike_y < zone_ymax)] = zone_roughness
948
+
949
+ # Do we need to add an extra point for zone_ymin?
950
+ if (zone_ymin >= np.min(dike_y)) and (zone_ymin not in dike_y):
951
+ x_int = Interpolate.inextrp1d(zone_ymin, dike_y, dike_x)
952
+ idx = np.searchsorted(dike_x, x_int)
953
+ dike_x = np.insert(dike_x, idx, x_int)
954
+ dike_y = np.insert(dike_y, idx, zone_ymin)
955
+ dike_r = np.insert(dike_r, idx, zone_roughness)
956
+
957
+ # Do we need to add an extra point for zone_ymax?
958
+ if (zone_ymax <= np.max(dike_y)) and (zone_ymax not in dike_y):
959
+ x_int = Interpolate.inextrp1d(zone_ymax, dike_y, dike_x)
960
+ idx = np.searchsorted(dike_x, x_int)
961
+ dike_x = np.insert(dike_x, idx, x_int)
962
+ dike_y = np.insert(dike_y, idx, zone_ymax)
963
+ dike_r = np.insert(dike_r, idx, roughness)
964
+
965
+ # Dike orientation, crest and geometry
966
+ profile.set_dike_orientation(dike_orientation)
967
+ profile.set_dike_geometry(dike_x, dike_y, dike_r)
968
+ profile.set_dike_crest_level(crest_level)
969
+
970
+ # Return the class
971
+ return profile