roms-tools 3.3.0__py3-none-any.whl → 3.5.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 (246) 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 +88 -64
  6. roms_tools/{setup → datasets}/river_datasets.py +9 -4
  7. roms_tools/datasets/roms_dataset.py +854 -0
  8. roms_tools/datasets/utils.py +487 -0
  9. roms_tools/{setup/fill.py → fill.py} +110 -13
  10. roms_tools/plot.py +4 -4
  11. roms_tools/regrid.py +76 -0
  12. roms_tools/setup/boundary_forcing.py +53 -45
  13. roms_tools/setup/cdr_release.py +2 -4
  14. roms_tools/setup/grid.py +46 -15
  15. roms_tools/setup/initial_conditions.py +330 -71
  16. roms_tools/setup/mask.py +2 -5
  17. roms_tools/setup/nesting.py +13 -6
  18. roms_tools/setup/river_forcing.py +4 -4
  19. roms_tools/setup/surface_forcing.py +15 -11
  20. roms_tools/setup/tides.py +7 -6
  21. roms_tools/setup/topography.py +10 -2
  22. roms_tools/setup/utils.py +292 -666
  23. roms_tools/tests/test_analysis/test_cdr_ensemble.py +4 -6
  24. roms_tools/tests/test_analysis/test_roms_output.py +1 -220
  25. roms_tools/tests/{test_setup → test_datasets}/test_lat_lon_datasets.py +4 -4
  26. roms_tools/tests/{test_setup → test_datasets}/test_river_datasets.py +1 -1
  27. roms_tools/tests/test_datasets/test_roms_dataset.py +743 -0
  28. roms_tools/tests/test_datasets/test_utils.py +527 -0
  29. roms_tools/tests/{test_setup/test_fill.py → test_fill.py} +72 -9
  30. roms_tools/tests/test_regrid.py +120 -1
  31. roms_tools/tests/test_setup/test_boundary_forcing.py +57 -138
  32. roms_tools/tests/test_setup/test_cdr_release.py +4 -5
  33. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zarr.json +293 -2021
  34. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zarr.json +294 -2022
  35. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ALK/c/0/0/0/0 +0 -0
  36. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/ALK_west → initial_conditions_from_roms.zarr/ALK}/zarr.json +11 -8
  37. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ALK_ALT_CO2/c/0/0/0/0 +0 -0
  38. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west → initial_conditions_from_roms.zarr/ALK_ALT_CO2}/zarr.json +11 -8
  39. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Cs_r/c/0 +0 -0
  40. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west → initial_conditions_from_roms.zarr/Cs_r}/zarr.json +5 -12
  41. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Cs_w/c/0 +0 -0
  42. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/diatFe_west → initial_conditions_from_roms.zarr/Cs_w}/zarr.json +3 -10
  43. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DIC/c/0/0/0/0 +0 -0
  44. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DOCr_west → initial_conditions_from_roms.zarr/DIC}/zarr.json +11 -8
  45. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DIC_ALT_CO2/c/0/0/0/0 +0 -0
  46. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DIC_ALT_CO2/zarr.json +57 -0
  47. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOC/c/0/0/0/0 +0 -0
  48. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOC/zarr.json +57 -0
  49. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOCr/c/0/0/0/0 +0 -0
  50. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west → initial_conditions_from_roms.zarr/DOCr}/zarr.json +11 -8
  51. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DON/c/0/0/0/0 +0 -0
  52. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DON/zarr.json +57 -0
  53. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DONr/c/0/0/0/0 +0 -0
  54. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DONr/zarr.json +57 -0
  55. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOP/c/0/0/0/0 +0 -0
  56. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOP/zarr.json +57 -0
  57. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOPr/c/0/0/0/0 +0 -0
  58. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOPr/zarr.json +57 -0
  59. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Fe/c/0/0/0/0 +0 -0
  60. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Fe/zarr.json +57 -0
  61. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Lig/c/0/0/0/0 +0 -0
  62. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DOP_west → initial_conditions_from_roms.zarr/Lig}/zarr.json +11 -8
  63. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/NH4/c/0/0/0/0 +0 -0
  64. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DON_west → initial_conditions_from_roms.zarr/NH4}/zarr.json +11 -8
  65. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/NO3/c/0/0/0/0 +0 -0
  66. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/NO3/zarr.json +57 -0
  67. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/O2/c/0/0/0/0 +0 -0
  68. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/Lig_west → initial_conditions_from_roms.zarr/O2}/zarr.json +11 -8
  69. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/PO4/c/0/0/0/0 +0 -0
  70. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/PO4/zarr.json +57 -0
  71. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/SiO3/c/0/0/0/0 +0 -0
  72. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/SiO3/zarr.json +57 -0
  73. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/abs_time/zarr.json +47 -0
  74. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatC/c/0/0/0/0 +0 -0
  75. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/diatC_west → initial_conditions_from_roms.zarr/diatC}/zarr.json +11 -8
  76. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatChl/c/0/0/0/0 +0 -0
  77. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/diatChl_west → initial_conditions_from_roms.zarr/diatChl}/zarr.json +11 -8
  78. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatFe/c/0/0/0/0 +0 -0
  79. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/O2_west → initial_conditions_from_roms.zarr/diatFe}/zarr.json +11 -8
  80. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatP/c/0/0/0/0 +0 -0
  81. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DIC_west → initial_conditions_from_roms.zarr/diatP}/zarr.json +11 -8
  82. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatSi/c/0/0/0/0 +0 -0
  83. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DOC_west → initial_conditions_from_roms.zarr/diatSi}/zarr.json +11 -8
  84. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazC/c/0/0/0/0 +0 -0
  85. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazC/zarr.json +57 -0
  86. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazChl/c/0/0/0/0 +0 -0
  87. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/diazChl_west → initial_conditions_from_roms.zarr/diazChl}/zarr.json +11 -8
  88. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazFe/c/0/0/0/0 +0 -0
  89. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/Fe_west → initial_conditions_from_roms.zarr/diazFe}/zarr.json +11 -8
  90. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazP/c/0/0/0/0 +0 -0
  91. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazP/zarr.json +57 -0
  92. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ocean_time/c/0 +0 -0
  93. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ocean_time/zarr.json +47 -0
  94. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/salt/c/0/0/0/0 +0 -0
  95. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west → initial_conditions_from_roms.zarr/salt}/zarr.json +12 -9
  96. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spC/c/0/0/0/0 +0 -0
  97. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spC/zarr.json +57 -0
  98. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spCaCO3/c/0/0/0/0 +0 -0
  99. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spCaCO3/zarr.json +57 -0
  100. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spChl/c/0/0/0/0 +0 -0
  101. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/spChl_west → initial_conditions_from_roms.zarr/spChl}/zarr.json +11 -8
  102. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spFe/c/0/0/0/0 +0 -0
  103. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spFe/zarr.json +57 -0
  104. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spP/c/0/0/0/0 +0 -0
  105. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spP/zarr.json +57 -0
  106. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/temp/c/0/0/0/0 +0 -0
  107. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/temp/zarr.json +57 -0
  108. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/u/c/0/0/0/0 +0 -0
  109. roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/NH4_west → initial_conditions_from_roms.zarr/u}/zarr.json +12 -9
  110. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ubar/c/0/0/0 +0 -0
  111. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ubar/zarr.json +54 -0
  112. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/v/c/0/0/0/0 +0 -0
  113. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/v/zarr.json +57 -0
  114. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/vbar/c/0/0/0 +0 -0
  115. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/vbar/zarr.json +54 -0
  116. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/w/zarr.json +57 -0
  117. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zarr.json +2481 -0
  118. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zeta/c/0/0/0 +0 -0
  119. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zeta/zarr.json +54 -0
  120. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zooC/c/0/0/0/0 +0 -0
  121. roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zooC/zarr.json +57 -0
  122. roms_tools/tests/test_setup/test_grid.py +66 -1
  123. roms_tools/tests/test_setup/test_initial_conditions.py +130 -104
  124. roms_tools/tests/test_setup/test_nesting.py +2 -1
  125. roms_tools/tests/test_setup/test_surface_forcing.py +1 -1
  126. roms_tools/tests/test_setup/test_tides.py +1 -1
  127. roms_tools/tests/test_setup/test_utils.py +100 -15
  128. roms_tools/tests/test_setup/test_validation.py +15 -0
  129. roms_tools/tests/test_tiling/test_partition.py +63 -15
  130. roms_tools/tests/test_utils.py +365 -0
  131. roms_tools/tiling/partition.py +81 -211
  132. roms_tools/utils.py +360 -62
  133. {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/METADATA +2 -3
  134. {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/RECORD +137 -174
  135. {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/WHEEL +1 -1
  136. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/c/0/0/0 +0 -0
  137. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/c/0/0/0 +0 -0
  138. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/c/0/0/0 +0 -0
  139. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/c/0/0/0 +0 -0
  140. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/c/0/0/0 +0 -0
  141. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/c/0/0/0 +0 -0
  142. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/c/0/0/0 +0 -0
  143. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/c/0/0/0 +0 -0
  144. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/zarr.json +0 -54
  145. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/c/0/0/0 +0 -0
  146. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/c/0/0/0 +0 -0
  147. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/zarr.json +0 -54
  148. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/c/0/0/0 +0 -0
  149. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/c/0/0/0 +0 -0
  150. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/c/0/0/0 +0 -0
  151. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/c/0/0/0 +0 -0
  152. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/zarr.json +0 -54
  153. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/c/0/0/0 +0 -0
  154. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/c/0/0/0 +0 -0
  155. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/zarr.json +0 -54
  156. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/c/0/0/0 +0 -0
  157. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/zarr.json +0 -54
  158. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/c/0/0/0 +0 -0
  159. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/c/0/0/0 +0 -0
  160. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/c/0/0/0 +0 -0
  161. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/c/0/0/0 +0 -0
  162. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/zarr.json +0 -54
  163. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/c/0/0/0 +0 -0
  164. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/zarr.json +0 -54
  165. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/c/0/0/0 +0 -0
  166. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/zarr.json +0 -54
  167. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/c/0/0/0 +0 -0
  168. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/c/0/0/0 +0 -0
  169. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/zarr.json +0 -54
  170. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/c/0/0/0 +0 -0
  171. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/zarr.json +0 -54
  172. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/c/0/0/0 +0 -0
  173. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/zarr.json +0 -54
  174. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/c/0/0/0 +0 -0
  175. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/zarr.json +0 -54
  176. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/c/0/0/0 +0 -0
  177. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/c/0/0/0 +0 -0
  178. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/zarr.json +0 -54
  179. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/c/0/0/0 +0 -0
  180. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/zarr.json +0 -54
  181. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/c/0/0/0 +0 -0
  182. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/zarr.json +0 -54
  183. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/c/0/0/0 +0 -0
  184. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/zarr.json +0 -54
  185. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/c/0/0/0 +0 -0
  186. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/c/0/0/0 +0 -0
  187. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/zarr.json +0 -54
  188. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/c/0/0/0 +0 -0
  189. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/zarr.json +0 -54
  190. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/c/0/0/0 +0 -0
  191. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/zarr.json +0 -54
  192. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/c/0/0/0 +0 -0
  193. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/zarr.json +0 -54
  194. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/c/0/0/0 +0 -0
  195. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/zarr.json +0 -54
  196. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/c/0/0/0 +0 -0
  197. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/zarr.json +0 -54
  198. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/c/0/0/0 +0 -0
  199. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/zarr.json +0 -54
  200. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/c/0/0/0 +0 -0
  201. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/zarr.json +0 -54
  202. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/c/0/0/0 +0 -0
  203. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/zarr.json +0 -54
  204. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/c/0/0/0 +0 -0
  205. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/zarr.json +0 -54
  206. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/c/0/0/0 +0 -0
  207. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/zarr.json +0 -54
  208. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/c/0/0/0 +0 -0
  209. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/zarr.json +0 -54
  210. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/c/0/0/0 +0 -0
  211. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/zarr.json +0 -54
  212. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/c/0/0/0 +0 -0
  213. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/zarr.json +0 -54
  214. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/c/0/0/0 +0 -0
  215. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/zarr.json +0 -54
  216. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/c/0/0/0 +0 -0
  217. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/zarr.json +0 -54
  218. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/c/0/0/0 +0 -0
  219. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/zarr.json +0 -54
  220. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/c/0/0/0 +0 -0
  221. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/c/0/0/0 +0 -0
  222. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/zarr.json +0 -54
  223. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/c/0/0/0 +0 -0
  224. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/zarr.json +0 -54
  225. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/c/0/0/0 +0 -0
  226. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/zarr.json +0 -54
  227. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/c/0/0/0 +0 -0
  228. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/zarr.json +0 -54
  229. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/c/0/0/0 +0 -0
  230. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/zarr.json +0 -54
  231. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/c/0/0/0 +0 -0
  232. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/zarr.json +0 -54
  233. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/c/0/0/0 +0 -0
  234. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/zarr.json +0 -54
  235. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/c/0/0/0 +0 -0
  236. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/zarr.json +0 -54
  237. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/c/0/0/0 +0 -0
  238. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/zarr.json +0 -54
  239. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/c/0/0/0 +0 -0
  240. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/zarr.json +0 -54
  241. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/c/0/0/0 +0 -0
  242. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/zarr.json +0 -54
  243. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/c/0/0/0 +0 -0
  244. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/zarr.json +0 -54
  245. {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/licenses/LICENSE +0 -0
  246. {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/top_level.txt +0 -0
roms_tools/regrid.py CHANGED
@@ -295,3 +295,79 @@ class VerticalRegridFromROMS:
295
295
  )
296
296
 
297
297
  return transformed
298
+
299
+
300
+ class VerticalRegrid:
301
+ """Regrid ROMS variables along the vertical, using spatially varying coordinates.
302
+
303
+ This class uses the `xgcm` package to transform data from a ROMS vertical coordinate
304
+ system (`s_rho`) to a user-defined set of target depth levels, where both the source
305
+ and target coordinates can vary spatially (i.e., 2D fields in horizontal space).
306
+
307
+ Attributes
308
+ ----------
309
+ grid : xgcm.Grid
310
+ The XGCM grid object used for vertical regridding, initialized with the input dataset `ds`.
311
+ """
312
+
313
+ def __init__(self, ds: "xr.Dataset"):
314
+ """Initialize the VerticalRegrid object with a ROMS dataset.
315
+
316
+ Parameters
317
+ ----------
318
+ ds : xarray.Dataset
319
+ The ROMS dataset containing the vertical coordinate `s_rho` and the variable(s)
320
+ to be regridded.
321
+ """
322
+ self.grid = xgcm.Grid(
323
+ ds,
324
+ coords={"s_rho": {"center": "s_rho"}},
325
+ periodic=False,
326
+ autoparse_metadata=False,
327
+ )
328
+
329
+ def apply(
330
+ self,
331
+ da: "xr.DataArray",
332
+ source_depth_coords: "xr.DataArray",
333
+ target_depth_coords: "xr.DataArray",
334
+ mask_edges: bool = True,
335
+ ) -> "xr.DataArray":
336
+ """Regrid a ROMS variable from source vertical coordinates to target vertical coordinates.
337
+
338
+ This method supports spatially varying vertical coordinates for both source and target,
339
+ meaning that the depth levels can vary across the horizontal grid.
340
+
341
+ Parameters
342
+ ----------
343
+ da : xarray.DataArray
344
+ The data array to regrid. Must have a vertical dimension corresponding to `s_rho`.
345
+
346
+ source_depth_coords : array-like (1D or 2D)
347
+ Depth coordinates of the source data. Can be a 1D array (same for all horizontal points)
348
+ or a 2D array (varying in horizontal space).
349
+
350
+ target_depth_coords : array-like (1D or 2D)
351
+ Desired depth coordinates of the regridded data. Can also be 1D or 2D.
352
+
353
+ mask_edges : bool, optional
354
+ If True, target values outside the range of source depth coordinates are masked with NaN.
355
+ Defaults to True.
356
+
357
+ Returns
358
+ -------
359
+ xarray.DataArray
360
+ A new `DataArray` containing the regridded variable at the target depth coordinates.
361
+ """
362
+ with warnings.catch_warnings():
363
+ warnings.filterwarnings("ignore", category=FutureWarning, module="xgcm")
364
+ transformed = self.grid.transform(
365
+ da,
366
+ "s_rho",
367
+ target=target_depth_coords,
368
+ target_data=source_depth_coords,
369
+ target_dim="s_rho",
370
+ mask_edges=mask_edges,
371
+ )
372
+
373
+ return transformed
@@ -11,17 +11,19 @@ import xarray as xr
11
11
  from scipy.ndimage import label
12
12
 
13
13
  from roms_tools import Grid
14
- from roms_tools.plot import line_plot, section_plot
15
- from roms_tools.regrid import LateralRegridToROMS, VerticalRegridToROMS
16
- from roms_tools.setup.lat_lon_datasets import (
14
+ from roms_tools.datasets.lat_lon_datasets import (
17
15
  CESMBGCDataset,
18
16
  GLORYSDataset,
19
17
  GLORYSDefaultDataset,
20
18
  UnifiedBGCDataset,
21
19
  )
20
+ from roms_tools.fill import one_dim_fill
21
+ from roms_tools.plot import line_plot, section_plot
22
+ from roms_tools.regrid import LateralRegridToROMS, VerticalRegridToROMS
22
23
  from roms_tools.setup.utils import (
23
24
  RawDataSource,
24
25
  add_time_info_to_ds,
26
+ check_and_set_boundaries,
25
27
  compute_barotropic_velocity,
26
28
  compute_missing_bgc_variables,
27
29
  from_yaml,
@@ -30,8 +32,6 @@ from roms_tools.setup.utils import (
30
32
  get_variable_metadata,
31
33
  group_dataset,
32
34
  nan_check,
33
- one_dim_fill,
34
- rotate_velocities,
35
35
  substitute_nans_by_fillvalue,
36
36
  to_dict,
37
37
  write_to_yaml,
@@ -39,6 +39,7 @@ from roms_tools.setup.utils import (
39
39
  from roms_tools.utils import (
40
40
  interpolate_from_rho_to_u,
41
41
  interpolate_from_rho_to_v,
42
+ rotate_velocities,
42
43
  save_datasets,
43
44
  transpose_dimensions,
44
45
  )
@@ -61,8 +62,9 @@ class BoundaryForcing:
61
62
  The end time of the desired surface forcing data. This time is used to filter the dataset
62
63
  to include only records on or before this time, with a single record at or after this time.
63
64
  If no time filtering is desired, set it to None. Default is None.
64
- boundaries : Dict[str, bool], optional
65
- Dictionary specifying which boundaries are forced (south, east, north, west). Default is all True.
65
+ boundaries : dict[str, bool], optional
66
+ Specifies which grid boundaries ('south', 'east', 'north', 'west') are active and to be processed.
67
+ if not provided, valid (non-land) boundaries are enabled automatically.
66
68
  source : RawDataSource
67
69
  Dictionary specifying the source of the boundary forcing data. Keys include:
68
70
 
@@ -86,10 +88,6 @@ class BoundaryForcing:
86
88
  Indicates whether to perform a two-dimensional horizontal fill on the source data prior to regridding to boundaries.
87
89
  If `False`, a one-dimensional horizontal fill is performed separately on each of the four regridded boundaries.
88
90
  Defaults to `False`.
89
- adjust_depth_for_sea_surface_height : bool, optional
90
- Whether to account for sea surface height (`zeta`) variations when computing depth coordinates.
91
- This adjustment is only applicable for `type="physics"`, as for biogeochemical fields usually `zeta` is not available.
92
- Defaults to `False`.
93
91
  model_reference_date : datetime, optional
94
92
  Reference date for the model. Default is January 1, 2000.
95
93
  use_dask: bool, optional
@@ -117,14 +115,7 @@ class BoundaryForcing:
117
115
  """The start time of the desired surface forcing data."""
118
116
  end_time: datetime | None = None
119
117
  """The end time of the desired surface forcing data."""
120
- boundaries: dict[str, bool] = field(
121
- default_factory=lambda: {
122
- "south": True,
123
- "east": True,
124
- "north": True,
125
- "west": True,
126
- }
127
- )
118
+ boundaries: dict[str, bool] | None = None
128
119
  """Dictionary specifying which boundaries are forced (south, east, north, west)."""
129
120
  source: RawDataSource
130
121
  """Dictionary specifying the source of the boundary forcing data."""
@@ -133,9 +124,6 @@ class BoundaryForcing:
133
124
  apply_2d_horizontal_fill: bool = False
134
125
  """Whether to perform a two-dimensional horizontal fill on the source data prior to
135
126
  regridding to boundaries."""
136
- adjust_depth_for_sea_surface_height: bool = False
137
- """Whether to account for sea surface height (`zeta`) variations when computing
138
- depth coordinates."""
139
127
  model_reference_date: datetime = datetime(2000, 1, 1)
140
128
  """Reference date for the model."""
141
129
  use_dask: bool = False
@@ -146,12 +134,18 @@ class BoundaryForcing:
146
134
  ds: xr.Dataset = field(init=False, repr=False)
147
135
  """An xarray Dataset containing post-processed variables ready for input into
148
136
  ROMS."""
137
+ adjust_depth_for_sea_surface_height: bool = field(init=False)
138
+ """Whether to account for sea surface height when computing depth coordinates."""
139
+ ds_depth_coords: xr.Dataset = field(init=False, repr=False)
140
+ """An xarray Dataset containing the depth coordinates."""
149
141
 
150
142
  def __post_init__(self):
151
- self._input_checks()
152
- # Dataset for depth coordinates
143
+ # Initialize depth coordinates
144
+ self.adjust_depth_for_sea_surface_height = False
153
145
  self.ds_depth_coords = xr.Dataset()
154
146
 
147
+ self._input_checks()
148
+
155
149
  target_coords = get_target_coords(self.grid)
156
150
 
157
151
  data = self._get_data()
@@ -279,7 +273,7 @@ class BoundaryForcing:
279
273
  processed_fields["u"],
280
274
  processed_fields["v"],
281
275
  angle,
282
- interpolate=True,
276
+ interpolate_after=True,
283
277
  )
284
278
  if self.adjust_depth_for_sea_surface_height:
285
279
  zeta_u = interpolate_from_rho_to_u(zeta_vector)
@@ -388,51 +382,58 @@ class BoundaryForcing:
388
382
 
389
383
  self.ds = ds
390
384
 
391
- def _input_checks(self):
392
- # Check that start_time and end_time are both None or none of them is
385
+ def _input_checks(self) -> None:
386
+ """Validate and normalize user-provided input parameters."""
387
+ # -------------------------------------------------------
388
+ # Time range checks
389
+ # -------------------------------------------------------
393
390
  if (self.start_time is None) != (self.end_time is None):
394
391
  raise ValueError(
395
392
  "Both `start_time` and `end_time` must be provided together as datetime objects or both should be None."
396
393
  )
397
394
 
398
- # Trigger a warning if both are None
399
395
  if self.start_time is None and self.end_time is None:
400
396
  logging.warning(
401
397
  "Both `start_time` and `end_time` are None. No time filtering will be applied to the source data."
402
398
  )
403
399
 
404
- # Validate the 'type' parameter
405
- if self.type not in ["physics", "bgc"]:
400
+ # -------------------------------------------------------
401
+ # Type check
402
+ # -------------------------------------------------------
403
+ if self.type not in {"physics", "bgc"}:
406
404
  raise ValueError("`type` must be either 'physics' or 'bgc'.")
407
405
 
408
- # Ensure 'source' dictionary contains required keys
406
+ # -------------------------------------------------------
407
+ # Source configuration checks
408
+ # -------------------------------------------------------
409
409
  if "name" not in self.source:
410
410
  raise ValueError("`source` must include a 'name'.")
411
+
411
412
  if "path" not in self.source:
412
413
  if self.source["name"] != "GLORYS":
413
414
  raise ValueError("`source` must include a 'path'.")
414
-
415
415
  self.source["path"] = GLORYSDefaultDataset.dataset_name
416
416
 
417
- # Set 'climatology' to False if not provided in 'source'
418
- self.source = {
419
- **self.source,
420
- "climatology": self.source.get("climatology", False),
421
- }
417
+ # Assign default value
418
+ self.source["climatology"] = self.source.get("climatology", False)
419
+
420
+ # -------------------------------------------------------
421
+ # Boundary selection defaults and validation
422
+ # -------------------------------------------------------
423
+
424
+ self.boundaries = check_and_set_boundaries(
425
+ self.boundaries, self.grid.ds.mask_rho
426
+ )
422
427
 
423
- # Ensure adjust_depth_for_sea_surface_height is only used with type="physics"
428
+ # -------------------------------------------------------
429
+ # Depth adjustment checks
430
+ # -------------------------------------------------------
424
431
  if self.type == "bgc" and self.adjust_depth_for_sea_surface_height:
425
432
  logging.warning(
426
433
  "adjust_depth_for_sea_surface_height is not applicable for BGC fields. "
427
434
  "Setting it to False."
428
435
  )
429
436
  self.adjust_depth_for_sea_surface_height = False
430
- elif self.adjust_depth_for_sea_surface_height:
431
- logging.info("Sea surface height will be used to adjust depth coordinates.")
432
- else:
433
- logging.info(
434
- "Sea surface height will NOT be used to adjust depth coordinates."
435
- )
436
437
 
437
438
  def _get_data(
438
439
  self,
@@ -1061,7 +1062,14 @@ class BoundaryForcing:
1061
1062
  filepath : Union[str, Path]
1062
1063
  The path to the YAML file where the parameters will be saved.
1063
1064
  """
1064
- forcing_dict = to_dict(self, exclude=["use_dask"])
1065
+ forcing_dict = to_dict(
1066
+ self,
1067
+ exclude=[
1068
+ "ds_depth_coords",
1069
+ "adjust_depth_for_sea_surface_height",
1070
+ "use_dask",
1071
+ ],
1072
+ )
1065
1073
  write_to_yaml(forcing_dict, filepath)
1066
1074
 
1067
1075
  @classmethod
@@ -573,7 +573,7 @@ class TracerPerturbation(Release):
573
573
 
574
574
  tracer_fluxes : dict, optional
575
575
 
576
- Dictionary of tracer names and their non-negative flux values. The flux values can be either
576
+ Dictionary of tracer names and their flux values. The flux values can be either
577
577
  a float (constant in time) or a list of float (time-varying).
578
578
 
579
579
  - Constant: applies uniformly across the entire simulation period.
@@ -589,9 +589,7 @@ class TracerPerturbation(Release):
589
589
  """
590
590
 
591
591
  times: list[datetime] = Field([])
592
- tracer_fluxes: dict[str, Flux | NonNegativeFloat | list[NonNegativeFloat]] = Field(
593
- {}
594
- )
592
+ tracer_fluxes: dict[str, Flux | float | list[float]] = Field({})
595
593
  """Dictionary of tracer names and their non-negative flux values."""
596
594
 
597
595
  release_type: Literal[ReleaseType.tracer_perturbation] = (
roms_tools/setup/grid.py CHANGED
@@ -1,3 +1,4 @@
1
+ import copy
1
2
  import importlib.metadata
2
3
  import logging
3
4
  import re
@@ -19,12 +20,14 @@ from roms_tools.setup.utils import (
19
20
  extract_single_value,
20
21
  gc_dist,
21
22
  get_target_coords,
22
- interpolate_from_rho_to_u,
23
- interpolate_from_rho_to_v,
24
23
  pop_grid_data,
25
24
  write_to_yaml,
26
25
  )
27
- from roms_tools.utils import save_datasets
26
+ from roms_tools.utils import (
27
+ interpolate_from_rho_to_u,
28
+ interpolate_from_rho_to_v,
29
+ save_datasets,
30
+ )
28
31
  from roms_tools.vertical_coordinate import compute_depth_coordinates, sigma_stretch
29
32
 
30
33
 
@@ -206,7 +209,8 @@ class Grid:
206
209
  hmin: float | None = None,
207
210
  verbose: bool = False,
208
211
  ) -> None:
209
- """Update the grid dataset with processed topography.
212
+ """
213
+ Update the grid dataset with processed topography.
210
214
 
211
215
  This method performs the following operations:
212
216
 
@@ -218,29 +222,45 @@ class Grid:
218
222
  Parameters
219
223
  ----------
220
224
  topography_source : dict, optional
221
- A dictionary specifying the source of the topography data. The dictionary should
222
- contain the following keys:
223
- - "name" (str): The name of the topography data source (e.g., "SRTM15").
224
- - "path" (Union[str, Path): The path to the raw data file.
225
+ Dictionary specifying the topography data source with keys:
226
+
227
+ - ``"name"`` (str): Name of the topography dataset (e.g. ``"SRTM15"``)
228
+ - ``"path"`` (str or pathlib.Path): Path to the raw data file
225
229
 
226
230
  If not provided, `topography_source` will remain unchanged (i.e., the existing value will not be overwritten).
227
231
 
228
232
  hmin : float, optional
229
- The minimum ocean depth (in meters).
233
+ Minimum ocean depth in meters.
230
234
  If not provided, `hmin` will remain unchanged (i.e., the existing value will not be overwritten).
231
235
 
232
236
  verbose : bool, optional
233
- If True, the method will print detailed information about the grid generation process,
234
- including the timing of each step. Defaults to False.
237
+ If True, print detailed information about the processing steps and timing.
238
+ Defaults to False.
235
239
 
236
240
  Returns
237
241
  -------
238
242
  None
239
- This method updates the internal dataset (`self.ds`) in place by adding or overwriting the
240
- topography variable. It does not return any value.
243
+ Updates ``self.ds`` in place.
241
244
  """
242
- topography_source = topography_source or self.topography_source
243
- hmin = hmin or self.hmin
245
+ if topography_source is None:
246
+ topography_source = self.topography_source
247
+
248
+ if hmin is None:
249
+ hmin = self.hmin
250
+
251
+ # This can only happen for externally generated grids read via Grid.from_file()
252
+ if topography_source is None:
253
+ raise ValueError(
254
+ "Topography source information is not available. "
255
+ "Please provide `topography_source` explicitly when calling "
256
+ "`update_topography()`."
257
+ )
258
+ # This can only happen for externally generated grids read via Grid.from_file()
259
+ if hmin is None:
260
+ raise ValueError(
261
+ "Minimal ocean depth is not available. "
262
+ "Please provide `hmin` explicitly when calling `update_topography()`."
263
+ )
244
264
 
245
265
  name = topography_source["name"] # type: ignore[index]
246
266
 
@@ -1249,6 +1269,17 @@ class Grid:
1249
1269
 
1250
1270
  return z_centers, z_faces
1251
1271
 
1272
+ def copy_with_ds(self, ds: xr.Dataset) -> "Grid":
1273
+ """
1274
+ Return a copy of this Grid with the given Dataset.
1275
+
1276
+ Grid metadata is preserved; only the backing xarray Dataset
1277
+ is replaced. The original Grid is not modified.
1278
+ """
1279
+ new = copy.copy(self) # shallow copy of metadata
1280
+ new.ds = ds
1281
+ return new
1282
+
1252
1283
 
1253
1284
  def _rotate(coords, rot):
1254
1285
  """Rotate grid counterclockwise relative to surface of Earth by rot degrees."""