roms-tools 3.3.0__py3-none-any.whl → 3.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. roms_tools/__init__.py +1 -1
  2. roms_tools/analysis/cdr_ensemble.py +10 -13
  3. roms_tools/analysis/roms_output.py +5 -304
  4. roms_tools/{download.py → datasets/download.py} +1 -0
  5. roms_tools/{setup → datasets}/lat_lon_datasets.py +76 -64
  6. roms_tools/{setup → datasets}/river_datasets.py +9 -4
  7. roms_tools/datasets/roms_dataset.py +767 -0
  8. roms_tools/datasets/utils.py +475 -0
  9. roms_tools/{setup/fill.py → fill.py} +110 -13
  10. roms_tools/plot.py +4 -4
  11. roms_tools/setup/boundary_forcing.py +51 -43
  12. roms_tools/setup/cdr_release.py +2 -4
  13. roms_tools/setup/grid.py +29 -12
  14. roms_tools/setup/initial_conditions.py +19 -19
  15. roms_tools/setup/nesting.py +8 -4
  16. roms_tools/setup/river_forcing.py +4 -4
  17. roms_tools/setup/surface_forcing.py +14 -9
  18. roms_tools/setup/tides.py +1 -1
  19. roms_tools/setup/topography.py +10 -2
  20. roms_tools/setup/utils.py +72 -524
  21. roms_tools/tests/test_analysis/test_cdr_ensemble.py +4 -6
  22. roms_tools/tests/test_analysis/test_roms_output.py +1 -220
  23. roms_tools/tests/{test_setup → test_datasets}/test_lat_lon_datasets.py +4 -4
  24. roms_tools/tests/{test_setup → test_datasets}/test_river_datasets.py +1 -1
  25. roms_tools/tests/test_datasets/test_roms_dataset.py +539 -0
  26. roms_tools/tests/test_datasets/test_utils.py +527 -0
  27. roms_tools/tests/{test_setup/test_fill.py → test_fill.py} +72 -9
  28. roms_tools/tests/test_setup/test_boundary_forcing.py +57 -138
  29. roms_tools/tests/test_setup/test_cdr_release.py +4 -5
  30. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zarr.json +293 -2021
  31. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zarr.json +294 -2022
  32. roms_tools/tests/test_setup/test_grid.py +42 -1
  33. roms_tools/tests/test_setup/test_initial_conditions.py +3 -94
  34. roms_tools/tests/test_setup/test_nesting.py +2 -1
  35. roms_tools/tests/test_setup/test_surface_forcing.py +1 -1
  36. roms_tools/tests/test_setup/test_tides.py +1 -1
  37. roms_tools/tests/test_setup/test_utils.py +100 -15
  38. roms_tools/tests/test_tiling/test_partition.py +63 -15
  39. roms_tools/tests/test_utils.py +78 -0
  40. roms_tools/tiling/partition.py +81 -211
  41. roms_tools/utils.py +193 -0
  42. {roms_tools-3.3.0.dist-info → roms_tools-3.4.0.dist-info}/METADATA +1 -1
  43. {roms_tools-3.3.0.dist-info → roms_tools-3.4.0.dist-info}/RECORD +46 -170
  44. {roms_tools-3.3.0.dist-info → roms_tools-3.4.0.dist-info}/WHEEL +1 -1
  45. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/c/0/0/0 +0 -0
  46. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/zarr.json +0 -54
  47. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/c/0/0/0 +0 -0
  48. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/zarr.json +0 -54
  49. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/c/0/0/0 +0 -0
  50. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/zarr.json +0 -54
  51. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/c/0/0/0 +0 -0
  52. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/zarr.json +0 -54
  53. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/c/0/0/0 +0 -0
  54. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/zarr.json +0 -54
  55. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/c/0/0/0 +0 -0
  56. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/zarr.json +0 -54
  57. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/c/0/0/0 +0 -0
  58. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/zarr.json +0 -54
  59. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/c/0/0/0 +0 -0
  60. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/zarr.json +0 -54
  61. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/c/0/0/0 +0 -0
  62. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/zarr.json +0 -54
  63. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/c/0/0/0 +0 -0
  64. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/zarr.json +0 -54
  65. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/c/0/0/0 +0 -0
  66. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/zarr.json +0 -54
  67. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/c/0/0/0 +0 -0
  68. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/zarr.json +0 -54
  69. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/c/0/0/0 +0 -0
  70. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/zarr.json +0 -54
  71. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/c/0/0/0 +0 -0
  72. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/zarr.json +0 -54
  73. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/c/0/0/0 +0 -0
  74. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/zarr.json +0 -54
  75. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/c/0/0/0 +0 -0
  76. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/zarr.json +0 -54
  77. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/c/0/0/0 +0 -0
  78. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/zarr.json +0 -54
  79. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/c/0/0/0 +0 -0
  80. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/zarr.json +0 -54
  81. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/c/0/0/0 +0 -0
  82. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/zarr.json +0 -54
  83. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/c/0/0/0 +0 -0
  84. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/zarr.json +0 -54
  85. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/c/0/0/0 +0 -0
  86. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/zarr.json +0 -54
  87. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/c/0/0/0 +0 -0
  88. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/zarr.json +0 -54
  89. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/c/0/0/0 +0 -0
  90. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/zarr.json +0 -54
  91. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/c/0/0/0 +0 -0
  92. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/zarr.json +0 -54
  93. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/c/0/0/0 +0 -0
  94. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/zarr.json +0 -54
  95. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/c/0/0/0 +0 -0
  96. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/zarr.json +0 -54
  97. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/c/0/0/0 +0 -0
  98. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/zarr.json +0 -54
  99. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/c/0/0/0 +0 -0
  100. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/zarr.json +0 -54
  101. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/c/0/0/0 +0 -0
  102. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/zarr.json +0 -54
  103. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/c/0/0/0 +0 -0
  104. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/zarr.json +0 -54
  105. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/c/0/0/0 +0 -0
  106. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/zarr.json +0 -54
  107. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/c/0/0/0 +0 -0
  108. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/zarr.json +0 -54
  109. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/c/0/0/0 +0 -0
  110. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/zarr.json +0 -54
  111. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/c/0/0/0 +0 -0
  112. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/zarr.json +0 -54
  113. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/c/0/0/0 +0 -0
  114. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/zarr.json +0 -54
  115. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/c/0/0/0 +0 -0
  116. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/zarr.json +0 -54
  117. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/c/0/0/0 +0 -0
  118. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/zarr.json +0 -54
  119. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/c/0/0/0 +0 -0
  120. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/zarr.json +0 -54
  121. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/c/0/0/0 +0 -0
  122. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/zarr.json +0 -54
  123. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/c/0/0/0 +0 -0
  124. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/zarr.json +0 -54
  125. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/c/0/0/0 +0 -0
  126. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/zarr.json +0 -54
  127. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/c/0/0/0 +0 -0
  128. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/zarr.json +0 -54
  129. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/c/0/0/0 +0 -0
  130. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/zarr.json +0 -54
  131. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/c/0/0/0 +0 -0
  132. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/zarr.json +0 -54
  133. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/c/0/0/0 +0 -0
  134. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/zarr.json +0 -54
  135. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/c/0/0/0 +0 -0
  136. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/zarr.json +0 -54
  137. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/c/0/0/0 +0 -0
  138. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/zarr.json +0 -54
  139. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/c/0/0/0 +0 -0
  140. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/zarr.json +0 -54
  141. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/c/0/0/0 +0 -0
  142. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/zarr.json +0 -54
  143. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/c/0/0/0 +0 -0
  144. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/zarr.json +0 -54
  145. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/c/0/0/0 +0 -0
  146. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/zarr.json +0 -54
  147. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/c/0/0/0 +0 -0
  148. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/zarr.json +0 -54
  149. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/c/0/0/0 +0 -0
  150. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/zarr.json +0 -54
  151. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/c/0/0/0 +0 -0
  152. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/zarr.json +0 -54
  153. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/c/0/0/0 +0 -0
  154. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/zarr.json +0 -54
  155. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/c/0/0/0 +0 -0
  156. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/zarr.json +0 -54
  157. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/c/0/0/0 +0 -0
  158. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/zarr.json +0 -54
  159. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/c/0/0/0 +0 -0
  160. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/zarr.json +0 -54
  161. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/c/0/0/0 +0 -0
  162. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/zarr.json +0 -54
  163. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/c/0/0/0 +0 -0
  164. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/zarr.json +0 -54
  165. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/c/0/0/0 +0 -0
  166. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/zarr.json +0 -54
  167. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/c/0/0/0 +0 -0
  168. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/zarr.json +0 -54
  169. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/c/0/0/0 +0 -0
  170. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/zarr.json +0 -54
  171. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/c/0/0/0 +0 -0
  172. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/zarr.json +0 -54
  173. {roms_tools-3.3.0.dist-info → roms_tools-3.4.0.dist-info}/licenses/LICENSE +0 -0
  174. {roms_tools-3.3.0.dist-info → roms_tools-3.4.0.dist-info}/top_level.txt +0 -0
@@ -18,7 +18,7 @@ from roms_tools.constants import (
18
18
  UPPER_BOUND_THETA_B,
19
19
  UPPER_BOUND_THETA_S,
20
20
  )
21
- from roms_tools.download import download_test_data
21
+ from roms_tools.datasets.download import download_test_data
22
22
  from roms_tools.setup.topography import _compute_rfactor
23
23
 
24
24
  try:
@@ -121,6 +121,25 @@ def grid_that_straddles_180_degree_meridian_with_global_srtm15_data():
121
121
  return grid
122
122
 
123
123
 
124
+ @pytest.fixture()
125
+ def grid_with_emod_data():
126
+ grid = Grid(
127
+ nx=2,
128
+ ny=2,
129
+ size_x=32,
130
+ size_y=19.2,
131
+ center_lon=-21.68,
132
+ center_lat=64.325,
133
+ rot=0,
134
+ topography_source={
135
+ "name": "EMOD",
136
+ "path": download_test_data("EMODnet_C2_coarse100.nc"),
137
+ },
138
+ )
139
+
140
+ return grid
141
+
142
+
124
143
  @pytest.fixture()
125
144
  def grid_with_gshhs_coastlines():
126
145
  iceland_fjord_kwargs = {
@@ -203,6 +222,7 @@ def test_coords_relation(grid_fixture, request):
203
222
  "grid_that_straddles_dateline_with_global_srtm15_data",
204
223
  "grid_that_straddles_180_degree_meridian_with_global_srtm15_data",
205
224
  "grid_with_gshhs_coastlines",
225
+ "grid_with_emod_data",
206
226
  ],
207
227
  )
208
228
  def test_successful_initialization_with_topography(grid_fixture, request):
@@ -344,6 +364,7 @@ def test_grid_straddle_crosses_meridian():
344
364
  "grid_that_straddles_dateline_with_shifted_global_etopo_data",
345
365
  "grid_that_straddles_dateline_with_global_srtm15_data",
346
366
  "grid_with_gshhs_coastlines",
367
+ "grid_with_emod_data",
347
368
  ],
348
369
  )
349
370
  def test_roundtrip_netcdf(grid_fixture, tmp_path, request):
@@ -379,6 +400,7 @@ def test_roundtrip_netcdf(grid_fixture, tmp_path, request):
379
400
  "grid_that_straddles_dateline_with_shifted_global_etopo_data",
380
401
  "grid_that_straddles_dateline_with_global_srtm15_data",
381
402
  "grid_with_gshhs_coastlines",
403
+ "grid_with_emod_data",
382
404
  ],
383
405
  )
384
406
  def test_roundtrip_yaml(grid_fixture, tmp_path, request):
@@ -411,6 +433,7 @@ def test_roundtrip_yaml(grid_fixture, tmp_path, request):
411
433
  "grid_that_straddles_dateline_with_shifted_global_etopo_data",
412
434
  "grid_that_straddles_dateline_with_global_srtm15_data",
413
435
  "grid_with_gshhs_coastlines",
436
+ "grid_with_emod_data",
414
437
  ],
415
438
  )
416
439
  def test_roundtrip_from_file_yaml(grid_fixture, tmp_path, request):
@@ -441,6 +464,7 @@ def test_roundtrip_from_file_yaml(grid_fixture, tmp_path, request):
441
464
  "grid_that_straddles_dateline_with_shifted_global_etopo_data",
442
465
  "grid_that_straddles_dateline_with_global_srtm15_data",
443
466
  "grid_with_gshhs_coastlines",
467
+ "grid_with_emod_data",
444
468
  ],
445
469
  )
446
470
  def test_files_have_same_hash(grid_fixture, tmp_path, request):
@@ -741,6 +765,23 @@ def test_hmin_criterion_and_update_topography():
741
765
  assert np.less_equal(grid.hmin, grid.ds.h.min())
742
766
 
743
767
 
768
+ def test_update_topography_raises_if_grid_loaded_from_file_has_no_source_info():
769
+ fname = download_test_data("grid_created_with_matlab.nc")
770
+ grid = Grid.from_file(fname)
771
+
772
+ with pytest.raises(
773
+ ValueError,
774
+ match="Topography source information is not available",
775
+ ):
776
+ grid.update_topography(hmin=15)
777
+
778
+ with pytest.raises(
779
+ ValueError,
780
+ match="Minimal ocean depth is not available",
781
+ ):
782
+ grid.update_topography(topography_source={"name": "ETOPO5"})
783
+
784
+
744
785
  # Mask tests
745
786
 
746
787
 
@@ -1,4 +1,3 @@
1
- import logging
2
1
  import textwrap
3
2
  from datetime import datetime
4
3
  from pathlib import Path
@@ -10,8 +9,8 @@ import xarray as xr
10
9
 
11
10
  from conftest import calculate_data_hash
12
11
  from roms_tools import Grid, InitialConditions
13
- from roms_tools.download import download_test_data
14
- from roms_tools.setup.lat_lon_datasets import (
12
+ from roms_tools.datasets.download import download_test_data
13
+ from roms_tools.datasets.lat_lon_datasets import (
15
14
  CESMBGCDataset,
16
15
  UnifiedBGCDataset,
17
16
  )
@@ -46,9 +45,7 @@ def example_grid():
46
45
  "ic_fixture",
47
46
  [
48
47
  "initial_conditions",
49
- "initial_conditions_adjusted_for_zeta",
50
48
  "initial_conditions_with_bgc",
51
- "initial_conditions_with_bgc_adjusted_for_zeta",
52
49
  "initial_conditions_with_bgc_from_climatology",
53
50
  "initial_conditions_with_unified_bgc_from_climatology",
54
51
  ],
@@ -66,6 +63,7 @@ def test_initial_conditions_creation_with_nondefault_glorys_dataset(
66
63
  "climatology": False,
67
64
  }
68
65
  assert hasattr(ic.ds, "adjust_depth_for_sea_surface_height")
66
+ assert ic.ds.attrs["adjust_depth_for_sea_surface_height"] == "False"
69
67
  assert isinstance(ic.ds, xr.Dataset)
70
68
  assert ic.ds.coords["ocean_time"].attrs["units"] == "seconds"
71
69
  expected_vars = {"temp", "salt", "u", "v", "zeta", "ubar", "vbar"}
@@ -171,7 +169,6 @@ def test_initial_conditions_creation_with_duplicates(use_dask: bool) -> None:
171
169
  "ic_fixture",
172
170
  [
173
171
  "initial_conditions_with_bgc",
174
- "initial_conditions_with_bgc_adjusted_for_zeta",
175
172
  "initial_conditions_with_bgc_from_climatology",
176
173
  "initial_conditions_with_unified_bgc_from_climatology",
177
174
  ],
@@ -303,90 +300,6 @@ def test_initial_conditions_default_bgc_climatology(example_grid, use_dask):
303
300
  assert initial_conditions.bgc_source["climatology"] is False
304
301
 
305
302
 
306
- def test_info_depth(caplog, use_dask):
307
- grid = Grid(
308
- nx=2,
309
- ny=2,
310
- size_x=500,
311
- size_y=1000,
312
- center_lon=0,
313
- center_lat=55,
314
- rot=10,
315
- N=3, # number of vertical levels
316
- theta_s=5.0, # surface control parameter
317
- theta_b=2.0, # bottom control parameter
318
- hc=250.0, # critical depth
319
- )
320
-
321
- fname = Path(download_test_data("GLORYS_coarse_test_data.nc"))
322
-
323
- with caplog.at_level(logging.INFO):
324
- InitialConditions(
325
- grid=grid,
326
- ini_time=datetime(2021, 6, 29),
327
- source={"path": fname, "name": "GLORYS"},
328
- adjust_depth_for_sea_surface_height=True,
329
- use_dask=use_dask,
330
- )
331
- # Verify the warning message in the log
332
- assert "Sea surface height will be used to adjust depth coordinates." in caplog.text
333
-
334
- # Clear the log before the next test
335
- caplog.clear()
336
-
337
- with caplog.at_level(logging.INFO):
338
- InitialConditions(
339
- grid=grid,
340
- ini_time=datetime(2021, 6, 29),
341
- source={"path": fname, "name": "GLORYS"},
342
- adjust_depth_for_sea_surface_height=False,
343
- use_dask=use_dask,
344
- )
345
- # Verify the warning message in the log
346
- assert (
347
- "Sea surface height will NOT be used to adjust depth coordinates."
348
- in caplog.text
349
- )
350
-
351
-
352
- @pytest.mark.parametrize(
353
- "initial_conditions_fixture",
354
- [
355
- "initial_conditions_adjusted_for_zeta",
356
- "initial_conditions_with_bgc_adjusted_for_zeta",
357
- ],
358
- )
359
- def test_correct_depth_coords_adjusted_for_zeta(
360
- initial_conditions_fixture, request, use_dask
361
- ):
362
- initial_conditions = request.getfixturevalue(initial_conditions_fixture)
363
-
364
- # compute interface depth at rho-points and write it into .ds_depth_coords
365
- zeta = initial_conditions.ds.zeta
366
- initial_conditions._get_depth_coordinates(
367
- zeta, location="rho", depth_type="interface"
368
- )
369
- # Test that lowermost interface coincides with topography
370
- assert np.allclose(
371
- initial_conditions.ds_depth_coords["interface_depth_rho"]
372
- .isel(s_w=0)
373
- .squeeze()
374
- .values, # Extract raw NumPy array
375
- initial_conditions.grid.ds.h.values,
376
- atol=1e-6, # Adjust tolerance as needed
377
- )
378
-
379
- # Test that uppermost interface coincides with sea surface height
380
- assert np.allclose(
381
- initial_conditions.ds_depth_coords["interface_depth_rho"]
382
- .isel(s_w=-1)
383
- .squeeze()
384
- .values,
385
- -zeta.values,
386
- atol=1e-6,
387
- )
388
-
389
-
390
303
  @pytest.mark.parametrize(
391
304
  "initial_conditions_fixture",
392
305
  [
@@ -498,7 +411,6 @@ def test_computed_missing_optional_fields(
498
411
  @pytest.mark.parametrize(
499
412
  "initial_conditions_fixture",
500
413
  [
501
- "initial_conditions_with_bgc_adjusted_for_zeta",
502
414
  "initial_conditions_with_bgc_from_climatology",
503
415
  "initial_conditions_with_unified_bgc_from_climatology",
504
416
  ],
@@ -546,7 +458,6 @@ def test_initial_conditions_plot(initial_conditions_fixture, request):
546
458
  "initial_conditions_fixture",
547
459
  [
548
460
  "initial_conditions",
549
- "initial_conditions_adjusted_for_zeta",
550
461
  "initial_conditions_with_bgc_from_climatology",
551
462
  "initial_conditions_with_unified_bgc_from_climatology",
552
463
  ],
@@ -574,7 +485,6 @@ def test_initial_conditions_save(initial_conditions_fixture, request, tmp_path):
574
485
  "initial_conditions_fixture",
575
486
  [
576
487
  "initial_conditions",
577
- "initial_conditions_adjusted_for_zeta",
578
488
  "initial_conditions_with_bgc_from_climatology",
579
489
  "initial_conditions_with_unified_bgc_from_climatology",
580
490
  ],
@@ -607,7 +517,6 @@ def test_roundtrip_yaml(initial_conditions_fixture, request, tmp_path, use_dask)
607
517
  "initial_conditions_fixture",
608
518
  [
609
519
  "initial_conditions",
610
- "initial_conditions_adjusted_for_zeta",
611
520
  "initial_conditions_with_bgc_from_climatology",
612
521
  "initial_conditions_with_unified_bgc_from_climatology",
613
522
  ],
@@ -14,7 +14,8 @@ from roms_tools.setup.nesting import (
14
14
  modify_child_mask,
15
15
  modify_child_topography,
16
16
  )
17
- from roms_tools.setup.utils import get_boundary_coords, wrap_longitudes
17
+ from roms_tools.setup.utils import get_boundary_coords
18
+ from roms_tools.utils import wrap_longitudes
18
19
 
19
20
 
20
21
  @pytest.fixture()
@@ -9,7 +9,7 @@ import xarray as xr
9
9
 
10
10
  from conftest import calculate_data_hash
11
11
  from roms_tools import Grid, SurfaceForcing
12
- from roms_tools.download import download_test_data
12
+ from roms_tools.datasets.download import download_test_data
13
13
  from roms_tools.setup.utils import RawDataSource
14
14
 
15
15
 
@@ -6,7 +6,7 @@ import xarray as xr
6
6
 
7
7
  from conftest import calculate_data_hash
8
8
  from roms_tools import Grid, TidalForcing
9
- from roms_tools.download import download_test_data
9
+ from roms_tools.datasets.download import download_test_data
10
10
 
11
11
 
12
12
  @pytest.fixture(scope="session")
@@ -7,11 +7,11 @@ import pytest
7
7
  import xarray as xr
8
8
 
9
9
  from roms_tools import BoundaryForcing, Grid
10
- from roms_tools.download import download_test_data
11
- from roms_tools.setup.lat_lon_datasets import ERA5Correction
10
+ from roms_tools.datasets.download import download_test_data
12
11
  from roms_tools.setup.utils import (
12
+ _infer_valid_boundaries_from_mask,
13
+ check_and_set_boundaries,
13
14
  get_target_coords,
14
- interpolate_from_climatology,
15
15
  validate_names,
16
16
  )
17
17
 
@@ -101,18 +101,6 @@ class TestGetTargetCoords:
101
101
  assert "mask" in result
102
102
 
103
103
 
104
- def test_interpolate_from_climatology(use_dask):
105
- fname = download_test_data("ERA5_regional_test_data.nc")
106
- era5_times = xr.open_dataset(fname).time
107
-
108
- climatology = ERA5Correction(use_dask=use_dask)
109
- field = climatology.ds["ssr_corr"]
110
- field["time"] = field["time"].dt.days
111
-
112
- interpolated_field = interpolate_from_climatology(field, "time", era5_times)
113
- assert len(interpolated_field.time) == len(era5_times)
114
-
115
-
116
104
  # Test yaml roundtrip with multiple source files
117
105
  @pytest.fixture()
118
106
  def boundary_forcing_from_multiple_source_files(request, use_dask):
@@ -210,3 +198,100 @@ def test_non_string_elements_in_list_raises():
210
198
  def test_custom_label_in_errors():
211
199
  with pytest.raises(ValueError, match="Invalid foozs: z"):
212
200
  validate_names(["z"], VALID_NAMES, SENTINEL, MAX_TO_PLOT, label="fooz")
201
+
202
+
203
+ # test _infer_valid_boundaries_from_mask
204
+ @pytest.fixture
205
+ def simple_mask():
206
+ data = np.array(
207
+ [
208
+ [0, 0, 0, 0], # south
209
+ [1, 0, 0, 0],
210
+ [1, 0, 0, 0],
211
+ [1, 1, 1, 1], # north
212
+ ]
213
+ )
214
+ return xr.DataArray(data, dims=("eta_rho", "xi_rho"))
215
+
216
+
217
+ def test_infer_valid_boundaries_partial(simple_mask):
218
+ out = _infer_valid_boundaries_from_mask(simple_mask)
219
+
220
+ assert out == {
221
+ "south": False,
222
+ "north": True,
223
+ "west": True,
224
+ "east": True,
225
+ }
226
+
227
+
228
+ def test_infer_valid_boundaries_all_ocean():
229
+ mask = xr.DataArray(np.ones((3, 3)), dims=("eta_rho", "xi_rho"))
230
+
231
+ out = _infer_valid_boundaries_from_mask(mask)
232
+ assert all(out.values())
233
+
234
+
235
+ # test check_and_set_boundaries
236
+
237
+
238
+ def test_check_and_set_default_boundaries(simple_mask, monkeypatch):
239
+ monkeypatch.setattr(
240
+ "roms_tools.setup.utils._infer_valid_boundaries_from_mask",
241
+ lambda mask: {
242
+ "south": True,
243
+ "north": False,
244
+ "west": True,
245
+ "east": False,
246
+ },
247
+ )
248
+
249
+ result = check_and_set_boundaries(None, simple_mask)
250
+
251
+ assert result == {
252
+ "south": True,
253
+ "north": False,
254
+ "west": True,
255
+ "east": False,
256
+ }
257
+
258
+
259
+ def test_check_and_set_partial_boundaries(simple_mask, monkeypatch):
260
+ monkeypatch.setattr(
261
+ "roms_tools.setup.utils._infer_valid_boundaries_from_mask",
262
+ lambda mask: {
263
+ "south": True,
264
+ "north": False,
265
+ "west": True,
266
+ "east": False,
267
+ },
268
+ )
269
+
270
+ user = {"south": False} # user overrides south → False
271
+
272
+ result = check_and_set_boundaries(user, simple_mask)
273
+
274
+ assert result == {
275
+ "south": False, # user-preserved
276
+ "north": False, # inferred
277
+ "west": True, # inferred
278
+ "east": False, # inferred
279
+ }
280
+
281
+
282
+ def test_check_and_set_type_error(simple_mask):
283
+ with pytest.raises(TypeError):
284
+ check_and_set_boundaries({"south": "yes"}, simple_mask)
285
+
286
+
287
+ def test_check_and_set_invalid_key(simple_mask):
288
+ with pytest.raises(ValueError):
289
+ check_and_set_boundaries({"northeast": True}, simple_mask)
290
+
291
+
292
+ def test_check_and_set_full_user_boundaries(simple_mask):
293
+ boundaries = {"south": False, "north": True, "east": False, "west": True}
294
+
295
+ result = check_and_set_boundaries(boundaries, simple_mask)
296
+
297
+ assert result == boundaries # unchanged
@@ -1,6 +1,8 @@
1
1
  from pathlib import Path
2
2
 
3
+ import numpy as np
3
4
  import pytest
5
+ import xarray as xr
4
6
  import xarray.testing as xrt
5
7
 
6
8
  from roms_tools import Grid
@@ -18,7 +20,7 @@ class TestPartitionGrid:
18
20
  def test_partition_grid_along_x(self, grid):
19
21
  _, [ds1, ds2, ds3] = partition(grid.ds, np_eta=3, np_xi=1)
20
22
 
21
- assert ds1.sizes == {
23
+ assert dict(ds1.sizes) == {
22
24
  "eta_rho": 11,
23
25
  "xi_rho": 32,
24
26
  "xi_u": 31,
@@ -30,7 +32,7 @@ class TestPartitionGrid:
30
32
  "s_rho": 100,
31
33
  "s_w": 101,
32
34
  }
33
- assert ds2.sizes == {
35
+ assert dict(ds2.sizes) == {
34
36
  "eta_rho": 10,
35
37
  "xi_rho": 32,
36
38
  "xi_u": 31,
@@ -42,7 +44,7 @@ class TestPartitionGrid:
42
44
  "s_rho": 100,
43
45
  "s_w": 101,
44
46
  }
45
- assert ds3.sizes == {
47
+ assert dict(ds3.sizes) == {
46
48
  "eta_rho": 11,
47
49
  "xi_rho": 32,
48
50
  "xi_u": 31,
@@ -58,7 +60,7 @@ class TestPartitionGrid:
58
60
  def test_partition_grid_along_y(self, grid):
59
61
  _, [ds1, ds2, ds3] = partition(grid.ds, np_eta=1, np_xi=3)
60
62
 
61
- assert ds1.sizes == {
63
+ assert dict(ds1.sizes) == {
62
64
  "eta_rho": 32,
63
65
  "xi_rho": 11,
64
66
  "xi_u": 10,
@@ -70,7 +72,7 @@ class TestPartitionGrid:
70
72
  "s_rho": 100,
71
73
  "s_w": 101,
72
74
  }
73
- assert ds2.sizes == {
75
+ assert dict(ds2.sizes) == {
74
76
  "eta_rho": 32,
75
77
  "xi_rho": 10,
76
78
  "xi_u": 10,
@@ -82,7 +84,7 @@ class TestPartitionGrid:
82
84
  "s_rho": 100,
83
85
  "s_w": 101,
84
86
  }
85
- assert ds3.sizes == {
87
+ assert dict(ds3.sizes) == {
86
88
  "eta_rho": 32,
87
89
  "xi_rho": 11,
88
90
  "xi_u": 11,
@@ -103,7 +105,7 @@ class TestPartitionGrid:
103
105
  ds7, ds8, ds9] = partition(grid.ds, np_eta=3, np_xi=3)
104
106
  # fmt: on
105
107
 
106
- assert ds1.sizes == {
108
+ assert dict(ds1.sizes) == {
107
109
  "eta_rho": 11,
108
110
  "xi_rho": 11,
109
111
  "xi_u": 10,
@@ -115,7 +117,7 @@ class TestPartitionGrid:
115
117
  "s_rho": 100,
116
118
  "s_w": 101,
117
119
  }
118
- assert ds4.sizes == {
120
+ assert dict(ds4.sizes) == {
119
121
  "eta_rho": 10,
120
122
  "xi_rho": 11,
121
123
  "xi_u": 10,
@@ -127,7 +129,7 @@ class TestPartitionGrid:
127
129
  "s_rho": 100,
128
130
  "s_w": 101,
129
131
  }
130
- assert ds7.sizes == {
132
+ assert dict(ds7.sizes) == {
131
133
  "eta_rho": 11,
132
134
  "xi_rho": 11,
133
135
  "xi_u": 10,
@@ -139,7 +141,7 @@ class TestPartitionGrid:
139
141
  "s_rho": 100,
140
142
  "s_w": 101,
141
143
  }
142
- assert ds2.sizes == {
144
+ assert dict(ds2.sizes) == {
143
145
  "eta_rho": 11,
144
146
  "xi_rho": 10,
145
147
  "xi_u": 10,
@@ -151,7 +153,7 @@ class TestPartitionGrid:
151
153
  "s_rho": 100,
152
154
  "s_w": 101,
153
155
  }
154
- assert ds5.sizes == {
156
+ assert dict(ds5.sizes) == {
155
157
  "eta_rho": 10,
156
158
  "xi_rho": 10,
157
159
  "xi_u": 10,
@@ -163,7 +165,7 @@ class TestPartitionGrid:
163
165
  "s_rho": 100,
164
166
  "s_w": 101,
165
167
  }
166
- assert ds8.sizes == {
168
+ assert dict(ds8.sizes) == {
167
169
  "eta_rho": 11,
168
170
  "xi_rho": 10,
169
171
  "xi_u": 10,
@@ -175,7 +177,7 @@ class TestPartitionGrid:
175
177
  "s_rho": 100,
176
178
  "s_w": 101,
177
179
  }
178
- assert ds3.sizes == {
180
+ assert dict(ds3.sizes) == {
179
181
  "eta_rho": 11,
180
182
  "xi_rho": 11,
181
183
  "xi_u": 11,
@@ -187,7 +189,7 @@ class TestPartitionGrid:
187
189
  "s_rho": 100,
188
190
  "s_w": 101,
189
191
  }
190
- assert ds6.sizes == {
192
+ assert dict(ds6.sizes) == {
191
193
  "eta_rho": 10,
192
194
  "xi_rho": 11,
193
195
  "xi_u": 11,
@@ -199,7 +201,7 @@ class TestPartitionGrid:
199
201
  "s_rho": 100,
200
202
  "s_w": 101,
201
203
  }
202
- assert ds9.sizes == {
204
+ assert dict(ds9.sizes) == {
203
205
  "eta_rho": 11,
204
206
  "xi_rho": 11,
205
207
  "xi_u": 11,
@@ -246,6 +248,52 @@ class TestPartitionGrid:
246
248
  assert ds.sizes["xi_coarse"] == grid.ds.sizes["xi_coarse"]
247
249
 
248
250
 
251
+ class TestPartitionGridWithExtraDims:
252
+ @pytest.fixture
253
+ def ds_with_extra_dims(self):
254
+ # Base dims
255
+ eta_rho = 10
256
+ xi_rho = 12
257
+ s_rho = 5
258
+ eta_v = eta_rho - 1
259
+ xi_u = xi_rho - 1
260
+
261
+ # Extra dims
262
+ eta_u = eta_rho
263
+ xi_v = xi_rho
264
+
265
+ ds = xr.Dataset(
266
+ {
267
+ "zeta": (("eta_rho", "xi_rho"), np.zeros((eta_rho, xi_rho))),
268
+ "u": (("s_rho", "eta_u", "xi_u"), np.zeros((s_rho, eta_u, xi_u))),
269
+ "v": (("s_rho", "eta_v", "xi_v"), np.zeros((s_rho, eta_v, xi_v))),
270
+ },
271
+ coords={
272
+ "eta_rho": np.arange(eta_rho),
273
+ "eta_u": np.arange(eta_u),
274
+ "eta_v": np.arange(eta_v),
275
+ "xi_rho": np.arange(xi_rho),
276
+ "xi_u": np.arange(xi_u),
277
+ "xi_v": np.arange(xi_v),
278
+ "s_rho": np.arange(s_rho),
279
+ },
280
+ )
281
+
282
+ return ds
283
+
284
+ def test_partition_with_extra_dims(self, ds_with_extra_dims):
285
+ file_numbers, parts = partition(ds_with_extra_dims, np_eta=2, np_xi=2)
286
+
287
+ # Test that partitioned datasets contain eta_u and xi_v
288
+ for ds_part in parts:
289
+ assert "eta_u" in ds_part.dims
290
+ assert "xi_v" in ds_part.dims
291
+ assert ds_part.sizes["eta_u"] < ds_with_extra_dims.sizes["eta_u"]
292
+ assert ds_part.sizes["xi_v"] < ds_with_extra_dims.sizes["xi_v"]
293
+ assert ds_part.sizes["eta_u"] > 0
294
+ assert ds_part.sizes["xi_v"] > 0
295
+
296
+
249
297
  class TestPartitionMissingDims:
250
298
  def test_partition_missing_dims(self, grid):
251
299
  dims_to_drop = ["xi_u", "eta_v", "eta_coarse", "xi_coarse"]