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
@@ -1,5 +1,4 @@
1
1
  import importlib.metadata
2
- import logging
3
2
  from collections import defaultdict
4
3
  from dataclasses import dataclass, field
5
4
  from datetime import datetime
@@ -11,15 +10,21 @@ import xarray as xr
11
10
  from matplotlib.axes import Axes
12
11
 
13
12
  from roms_tools import Grid
14
- from roms_tools.plot import plot
15
- from roms_tools.regrid import LateralRegridToROMS, VerticalRegridToROMS
16
- from roms_tools.setup.lat_lon_datasets import (
13
+ from roms_tools.datasets.lat_lon_datasets import (
17
14
  CESMBGCDataset,
18
15
  GLORYSDataset,
19
16
  GLORYSDefaultDataset,
20
17
  LatLonDataset,
21
18
  UnifiedBGCDataset,
22
19
  )
20
+ from roms_tools.datasets.roms_dataset import ROMSDataset, choose_subdomain
21
+ from roms_tools.plot import plot
22
+ from roms_tools.regrid import (
23
+ LateralRegridFromROMS,
24
+ LateralRegridToROMS,
25
+ VerticalRegrid,
26
+ VerticalRegridToROMS,
27
+ )
23
28
  from roms_tools.setup.utils import (
24
29
  RawDataSource,
25
30
  compute_barotropic_velocity,
@@ -28,7 +33,7 @@ from roms_tools.setup.utils import (
28
33
  get_target_coords,
29
34
  get_variable_metadata,
30
35
  nan_check,
31
- rotate_velocities,
36
+ pop_grid_data,
32
37
  substitute_nans_by_fillvalue,
33
38
  to_dict,
34
39
  write_to_yaml,
@@ -36,6 +41,7 @@ from roms_tools.setup.utils import (
36
41
  from roms_tools.utils import (
37
42
  interpolate_from_rho_to_u,
38
43
  interpolate_from_rho_to_v,
44
+ rotate_velocities,
39
45
  save_datasets,
40
46
  transpose_dimensions,
41
47
  )
@@ -81,9 +87,6 @@ class InitialConditions:
81
87
  - A list of strings or Path objects containing multiple files.
82
88
  - "climatology" (bool): Indicates if the data is climatology data. Defaults to False.
83
89
 
84
- adjust_depth_for_sea_surface_height : bool, optional
85
- Whether to account for sea surface height variations when computing depth coordinates.
86
- Defaults to `False`.
87
90
  model_reference_date : datetime, optional
88
91
  The reference date for the model. Defaults to January 1, 2000.
89
92
  use_dask: bool, optional
@@ -116,6 +119,18 @@ class InitialConditions:
116
119
  ... "climatology": False,
117
120
  ... },
118
121
  ... )
122
+
123
+ >>> initial_conditions = InitialConditions(
124
+ ... grid=grid,
125
+ ... ini_time=datetime(2022, 1, 1),
126
+ ... source={"name": "ROMS", "grid": parent_grid, "path": "restart.nc"},
127
+ ... bgc_source={
128
+ ... "name": "ROMS",
129
+ ... "grid": parent_grid,
130
+ ... "path": "restart.nc",
131
+ ... },
132
+ ... )
133
+
119
134
  """
120
135
 
121
136
  grid: Grid
@@ -129,9 +144,6 @@ class InitialConditions:
129
144
  data."""
130
145
  model_reference_date: datetime = datetime(2000, 1, 1)
131
146
  """The reference date for the model."""
132
- adjust_depth_for_sea_surface_height: bool = False
133
- """Whether to account for sea surface height variations when computing depth
134
- coordinates."""
135
147
  allow_flex_time: bool = False
136
148
  """Whether to handle ini_time flexibly."""
137
149
  use_dask: bool = False
@@ -145,12 +157,17 @@ class InitialConditions:
145
157
  ds: xr.Dataset = field(init=False, repr=False)
146
158
  """An xarray Dataset containing post-processed variables ready for input into
147
159
  ROMS."""
160
+ adjust_depth_for_sea_surface_height: bool = field(init=False)
161
+ """Whether to account for sea surface height when computing depth coordinates."""
162
+ ds_depth_coords: xr.Dataset = field(init=False, repr=False)
163
+ """An xarray Dataset containing the depth coordinates."""
148
164
 
149
165
  def __post_init__(self):
150
- self._input_checks()
151
- # Dataset for depth coordinates
166
+ # Initialize depth coordinates
152
167
  self.ds_depth_coords = xr.Dataset()
153
168
 
169
+ self._input_checks()
170
+
154
171
  processed_fields = {}
155
172
  processed_fields = self._process_data(processed_fields, type="physics")
156
173
 
@@ -181,7 +198,6 @@ class InitialConditions:
181
198
  target_coords = get_target_coords(self.grid)
182
199
 
183
200
  data = self._get_data(forcing_type=type)
184
-
185
201
  data.choose_subdomain(
186
202
  target_coords,
187
203
  )
@@ -189,6 +205,7 @@ class InitialConditions:
189
205
  data.convert_to_float64()
190
206
  data.extrapolate_deepest_to_bottom()
191
207
  data.apply_lateral_fill()
208
+ data.rotate_velocities_to_east_and_north()
192
209
 
193
210
  self._set_variable_info(data, type=type)
194
211
  attr_name = f"variable_info_{type}"
@@ -203,6 +220,7 @@ class InitialConditions:
203
220
  var: {
204
221
  "name": data.var_names[var],
205
222
  "location": variable_info[var]["location"],
223
+ "is_3d": variable_info[var]["is_3d"],
206
224
  }
207
225
  for var in data.var_names.keys()
208
226
  if data.var_names[var] in data.ds.data_vars
@@ -213,27 +231,24 @@ class InitialConditions:
213
231
  var: {
214
232
  "name": data.opt_var_names[var],
215
233
  "location": variable_info[var]["location"],
234
+ "is_3d": variable_info[var]["is_3d"],
216
235
  }
217
236
  for var in data.opt_var_names.keys()
218
237
  if data.opt_var_names[var] in data.ds.data_vars
219
238
  }
220
239
  )
221
240
 
222
- # lateral regridding
223
- lateral_regrid = LateralRegridToROMS(target_coords, data.dim_names)
224
-
225
- for var_name in var_names:
226
- processed_fields[var_name] = lateral_regrid.apply(
227
- data.ds[var_names[var_name]["name"]]
228
- )
229
-
230
- # rotation of velocities and interpolation to u/v points
241
+ # Lateral regridding
242
+ processed_fields = self._regrid_laterally(
243
+ data, target_coords, processed_fields, var_names
244
+ )
245
+ # Rotation of velocities and interpolation to u/v points
231
246
  if "u" in var_names and "v" in var_names:
232
247
  processed_fields["u"], processed_fields["v"] = rotate_velocities(
233
248
  processed_fields["u"],
234
249
  processed_fields["v"],
235
250
  target_coords["angle"],
236
- interpolate=True,
251
+ interpolate_after=True,
237
252
  )
238
253
 
239
254
  if type == "bgc":
@@ -247,32 +262,11 @@ class InitialConditions:
247
262
  zeta = (
248
263
  processed_fields["zeta"] if self.adjust_depth_for_sea_surface_height else 0
249
264
  )
250
-
251
265
  for location in ["rho", "u", "v"]:
252
- # Filter var_names by location and check for 3D variables
253
- filtered_vars = [
254
- var_name
255
- for var_name, info in var_names.items()
256
- if info["location"] == location and variable_info[var_name]["is_3d"]
257
- ]
266
+ self._get_depth_coordinates(zeta, location, "layer")
258
267
 
259
- if filtered_vars:
260
- # Handle depth coordinates
261
- self._get_depth_coordinates(zeta, location, "layer")
262
-
263
- # Vertical regridding
264
- vertical_regrid = VerticalRegridToROMS(
265
- self.ds_depth_coords[f"layer_depth_{location}"],
266
- data.ds[data.dim_names["depth"]],
267
- )
268
- for var_name in filtered_vars:
269
- if var_name in processed_fields:
270
- field = processed_fields[var_name]
271
- if self.use_dask:
272
- field = field.chunk(
273
- _set_dask_chunks(location, self.horizontal_chunk_size)
274
- )
275
- processed_fields[var_name] = vertical_regrid.apply(field)
268
+ # Vertical regridding
269
+ processed_fields = self._regrid_vertically(data, processed_fields, var_names)
276
270
 
277
271
  # Compute barotropic velocities
278
272
  if "u" in var_names and "v" in var_names:
@@ -285,13 +279,157 @@ class InitialConditions:
285
279
 
286
280
  return processed_fields
287
281
 
288
- def _input_checks(self):
289
- # Check that ini_time is not None
290
- if self.ini_time is None:
291
- raise ValueError(
292
- "`ini_time` must be a valid datetime object and cannot be None."
282
+ def _regrid_laterally(
283
+ self,
284
+ data: ROMSDataset | LatLonDataset,
285
+ target_coords: dict[str, xr.DataArray],
286
+ processed_fields: dict[str, xr.DataArray],
287
+ var_names: dict[str, dict[str, str]],
288
+ ):
289
+ """Regrid variables in data.ds laterally to target coordinates.
290
+
291
+ Parameters
292
+ ----------
293
+ data : ROMSDataset or LatLonDataset
294
+ The dataset containing variables to regrid.
295
+ target_coords : dict[str, xr.DataArray]
296
+ Dictionary of target coordinates for regridding.
297
+ processed_fields : dict[str, xr.DataArray]
298
+ Dictionary where regridded variables will be stored.
299
+ var_names : dict[str, dict[str, str]]
300
+ Mapping from variable keys to dataset variable names and metadata.
301
+
302
+ Returns
303
+ -------
304
+ processed_fields : dict[str, xr.DataArray]
305
+ Updated dictionary with regridded variables.
306
+ """
307
+ if isinstance(data, ROMSDataset):
308
+ # Compute depth coordinates on source data for rho
309
+ data._get_depth_coordinates(depth_type="layer", locations=["rho"])
310
+ # Subset depth coordinate to target subdomain
311
+ data.ds_depth_coords = choose_subdomain(
312
+ data.ds_depth_coords,
313
+ data.grid.ds,
314
+ target_coords,
315
+ )
316
+
317
+ # Regrid all rho variables
318
+ ds_rho = data.ds[[var_names[var]["name"] for var in var_names]].rename(
319
+ {"lat_rho": "lat", "lon_rho": "lon"}
293
320
  )
321
+ lateral_regrid_from_roms = LateralRegridFromROMS(ds_rho, target_coords)
322
+ ds_rho = lateral_regrid_from_roms.apply(ds_rho)
323
+
324
+ for var_name in var_names:
325
+ processed_fields[var_name] = ds_rho[var_name]
326
+
327
+ # Regrid depth coordinates
328
+ processed_fields["layer_depth_rho"] = lateral_regrid_from_roms.apply(
329
+ data.ds_depth_coords["layer_depth_rho"]
330
+ )
331
+
332
+ else:
333
+ lateral_regrid_to_roms = LateralRegridToROMS(target_coords, data.dim_names)
334
+ for var_name in var_names:
335
+ processed_fields[var_name] = lateral_regrid_to_roms.apply(
336
+ data.ds[var_names[var_name]["name"]]
337
+ )
338
+
339
+ return processed_fields
340
+
341
+ def _regrid_vertically(
342
+ self,
343
+ data: ROMSDataset | LatLonDataset,
344
+ processed_fields: dict[str, xr.DataArray],
345
+ var_names: dict[str, dict[str, str | bool]],
346
+ ) -> dict[str, xr.DataArray]:
347
+ """
348
+ Perform vertical regridding of 3D variables to the model's vertical grid.
349
+
350
+ For each vertical location ('rho', 'u', 'v'), this method regrids variables
351
+ that are flagged as 3D in `var_names`. The regridding procedure differs
352
+ depending on whether the source dataset is a ROMSDataset or a LatLonDataset.
294
353
 
354
+ Parameters
355
+ ----------
356
+ data : ROMSDataset or LatLonDataset
357
+ Dataset containing the variables to regrid.
358
+ processed_fields : dict[str, xarray.DataArray]
359
+ Dictionary containing fields that have already been regridded laterally.
360
+ This method updates the entries in-place with vertically regridded fields.
361
+ var_names : dict[str, dict[str, str | bool]]
362
+ Mapping of variable keys to dataset variable metadata:
363
+ - 'name': dataset variable name
364
+ - 'location': vertical location ('rho', 'u', 'v')
365
+ - 'is_3d': whether the variable is 3D and requires vertical regridding
366
+
367
+ Returns
368
+ -------
369
+ processed_fields : dict[str, xarray.DataArray]
370
+ Dictionary containing the same variables as `processed_fields`, now updated
371
+ with vertically regridded values.
372
+ """
373
+ for location in ["rho", "u", "v"]:
374
+ # Select variables for this vertical location that are 3D
375
+ filtered_vars = [
376
+ var_name
377
+ for var_name, info in var_names.items()
378
+ if info["location"] == location and info["is_3d"]
379
+ ]
380
+
381
+ if not filtered_vars:
382
+ continue
383
+
384
+ if isinstance(data, ROMSDataset):
385
+ # Interpolate depth coordinates from rho to u/v points if needed
386
+ if location == "u":
387
+ processed_fields["layer_depth_u"] = interpolate_from_rho_to_u(
388
+ processed_fields["layer_depth_rho"]
389
+ )
390
+ elif location == "v":
391
+ processed_fields["layer_depth_v"] = interpolate_from_rho_to_v(
392
+ processed_fields["layer_depth_rho"]
393
+ )
394
+
395
+ # Use the first variable to initialize VerticalRegrid
396
+ ds_tmp = xr.Dataset(
397
+ {filtered_vars[0]: processed_fields[filtered_vars[0]]}
398
+ )
399
+ vertical_regrid = VerticalRegrid(ds_tmp)
400
+
401
+ for var_name in filtered_vars:
402
+ if var_name in processed_fields:
403
+ processed_fields[var_name] = vertical_regrid.apply(
404
+ processed_fields[var_name],
405
+ source_depth_coords=processed_fields[
406
+ f"layer_depth_{location}"
407
+ ],
408
+ target_depth_coords=self.ds_depth_coords[
409
+ f"layer_depth_{location}"
410
+ ],
411
+ mask_edges=False,
412
+ )
413
+ else:
414
+ # LatLonDataset: create a regrid object for all variables
415
+ vertical_regrid_to_roms = VerticalRegridToROMS(
416
+ self.ds_depth_coords[f"layer_depth_{location}"],
417
+ data.ds[data.dim_names["depth"]],
418
+ )
419
+
420
+ for var_name in filtered_vars:
421
+ if var_name not in processed_fields:
422
+ continue
423
+ field = processed_fields[var_name]
424
+ if getattr(self, "use_dask", False):
425
+ field = field.chunk(
426
+ _set_dask_chunks(location, self.horizontal_chunk_size)
427
+ )
428
+ processed_fields[var_name] = vertical_regrid_to_roms.apply(field)
429
+
430
+ return processed_fields
431
+
432
+ def _input_checks(self):
295
433
  if "name" not in self.source.keys():
296
434
  raise ValueError("`source` must include a 'name'.")
297
435
  if "path" not in self.source.keys():
@@ -319,14 +457,14 @@ class InitialConditions:
319
457
  **self.bgc_source,
320
458
  "climatology": self.bgc_source.get("climatology", False),
321
459
  }
322
- if self.adjust_depth_for_sea_surface_height:
323
- logging.info("Sea surface height will be used to adjust depth coordinates.")
324
- else:
325
- logging.info(
326
- "Sea surface height will NOT be used to adjust depth coordinates."
460
+ if not isinstance(self.ini_time, datetime):
461
+ raise TypeError(
462
+ f"`ini_time` must be a datetime object, got {type(self.ini_time).__name__} instead."
327
463
  )
328
464
 
329
- def _get_data(self, forcing_type=Literal["physics", "bgc"]) -> LatLonDataset:
465
+ def _get_data(
466
+ self, forcing_type=Literal["physics", "bgc"]
467
+ ) -> LatLonDataset | ROMSDataset:
330
468
  """Determine the correct `Dataset` type and return an instance.
331
469
 
332
470
  forcing_type : str
@@ -337,18 +475,22 @@ class InitialConditions:
337
475
  Returns
338
476
  -------
339
477
  Dataset
340
- The `Dataset` instance
478
+ The `LatLonDataset` or `ROMSDataset` instance
341
479
  """
342
- dataset_map: dict[str, dict[str, dict[str, type[LatLonDataset]]]] = {
480
+ dataset_map: dict[
481
+ str, dict[str, dict[str, type[LatLonDataset | ROMSDataset]]]
482
+ ] = {
343
483
  "physics": {
344
484
  "GLORYS": {
345
485
  "external": GLORYSDataset,
346
486
  "default": GLORYSDefaultDataset,
347
487
  },
488
+ "ROMS": defaultdict(lambda: ROMSDataset),
348
489
  },
349
490
  "bgc": {
350
491
  "CESM_REGRIDDED": defaultdict(lambda: CESMBGCDataset),
351
492
  "UNIFIED": defaultdict(lambda: UnifiedBGCDataset),
493
+ "ROMS": defaultdict(lambda: ROMSDataset),
352
494
  },
353
495
  }
354
496
 
@@ -376,13 +518,31 @@ class InitialConditions:
376
518
  if isinstance(source_dict["path"], bool):
377
519
  raise ValueError('source["path"] cannot be a boolean here')
378
520
 
379
- return data_type(
380
- filename=source_dict["path"],
381
- start_time=self.ini_time,
382
- climatology=source_dict["climatology"], # type: ignore
383
- allow_flex_time=self.allow_flex_time,
384
- use_dask=self.use_dask,
385
- )
521
+ if source_dict["name"] == "ROMS":
522
+ var_names = _set_required_vars(forcing_type)
523
+ self.adjust_depth_for_sea_surface_height = True
524
+
525
+ data = data_type(
526
+ path=source_dict["path"], # type: ignore
527
+ grid=source_dict["grid"], # type: ignore
528
+ var_names=var_names,
529
+ start_time=self.ini_time,
530
+ allow_flex_time=self.allow_flex_time,
531
+ adjust_depth_for_sea_surface_height=True,
532
+ use_dask=self.use_dask,
533
+ )
534
+
535
+ else:
536
+ self.adjust_depth_for_sea_surface_height = False
537
+ data = data_type(
538
+ filename=source_dict["path"], # type: ignore
539
+ start_time=self.ini_time,
540
+ climatology=source_dict["climatology"], # type: ignore
541
+ allow_flex_time=self.allow_flex_time,
542
+ use_dask=self.use_dask,
543
+ )
544
+
545
+ return data
386
546
 
387
547
  def _set_variable_info(self, data, type="physics"):
388
548
  """Sets up a dictionary with metadata for variables based on the type.
@@ -473,7 +633,16 @@ class InitialConditions:
473
633
  if var_name == "ALK":
474
634
  variable_info[var_name] = {**default_info, "validate": True}
475
635
  else:
476
- variable_info[var_name] = {**default_info, "validate": False}
636
+ if var_name == "zeta":
637
+ variable_info[var_name] = {
638
+ "location": "rho",
639
+ "is_vector": False,
640
+ "vector_pair": None,
641
+ "is_3d": False,
642
+ "validate": False,
643
+ }
644
+ else:
645
+ variable_info[var_name] = {**default_info, "validate": False}
477
646
 
478
647
  object.__setattr__(self, f"variable_info_{type}", variable_info)
479
648
 
@@ -586,7 +755,7 @@ class InitialConditions:
586
755
  model_reference_date = np.datetime64(self.model_reference_date)
587
756
 
588
757
  # Convert the time coordinate to the format expected by ROMS (seconds since model reference date)
589
- ocean_time = (ds["time"] - model_reference_date).astype("float64") * 1e-9
758
+ ocean_time = (ds["time"] - model_reference_date).dt.total_seconds()
590
759
  ds = ds.assign_coords(ocean_time=("time", ocean_time.data.astype("float64")))
591
760
  ds["ocean_time"].attrs["long_name"] = (
592
761
  f"relative time: seconds since {self.model_reference_date!s}"
@@ -826,7 +995,14 @@ class InitialConditions:
826
995
  filepath : Union[str, Path]
827
996
  The path to the YAML file where the parameters will be saved.
828
997
  """
829
- forcing_dict = to_dict(self, exclude=["use_dask"])
998
+ forcing_dict = to_dict(
999
+ self,
1000
+ exclude=[
1001
+ "ds_depth_coords",
1002
+ "adjust_depth_for_sea_surface_height",
1003
+ "use_dask",
1004
+ ],
1005
+ )
830
1006
  write_to_yaml(forcing_dict, filepath)
831
1007
 
832
1008
  @classmethod
@@ -853,6 +1029,14 @@ class InitialConditions:
853
1029
 
854
1030
  grid = Grid.from_yaml(filepath)
855
1031
  initial_conditions_params = from_yaml(cls, filepath)
1032
+
1033
+ # Deserialize nested grids inside 'source' and 'bgc_source'
1034
+ for name in ["source", "bgc_source"]:
1035
+ src_dict = initial_conditions_params.get(name)
1036
+ if src_dict and "grid" in src_dict and src_dict["grid"] is not None:
1037
+ grid_data = pop_grid_data(src_dict["grid"])
1038
+ src_dict["grid"] = Grid(**grid_data)
1039
+
856
1040
  return cls(
857
1041
  grid=grid,
858
1042
  **initial_conditions_params,
@@ -881,3 +1065,78 @@ def _set_dask_chunks(location: str, chunk_size: int):
881
1065
  "v": {"eta_v": chunk_size, "xi_rho": chunk_size},
882
1066
  }
883
1067
  return chunk_mapping.get(location, {})
1068
+
1069
+
1070
+ def _set_required_vars(var_type: str = "physics") -> dict[str, str]:
1071
+ """
1072
+ Return the canonical variable-name mapping for a ROMS dataset.
1073
+
1074
+ Parameters
1075
+ ----------
1076
+ var_type : str, optional
1077
+ Category of variables. Supported values:
1078
+ - "physics": physical variables (temperature, salinity, currents, etc.)
1079
+ - "bgc": biogeochemical variables (nutrients, pigments, carbon, etc.)
1080
+ Default is "physics".
1081
+
1082
+ Returns
1083
+ -------
1084
+ dict[str, str]
1085
+ Mapping from logical variable names to dataset variable names.
1086
+
1087
+ Raises
1088
+ ------
1089
+ ValueError
1090
+ If an unsupported `var_type` is provided.
1091
+ """
1092
+ var_mappings = {
1093
+ "physics": {
1094
+ "zeta": "zeta",
1095
+ "temp": "temp",
1096
+ "salt": "salt",
1097
+ "u": "u",
1098
+ "v": "v",
1099
+ },
1100
+ "bgc": {
1101
+ "zeta": "zeta", # to infer vertical coordinate
1102
+ "PO4": "PO4",
1103
+ "NO3": "NO3",
1104
+ "SiO3": "SiO3",
1105
+ "NH4": "NH4",
1106
+ "Fe": "Fe",
1107
+ "Lig": "Lig",
1108
+ "O2": "O2",
1109
+ "DIC": "DIC",
1110
+ "DIC_ALT_CO2": "DIC_ALT_CO2",
1111
+ "ALK": "ALK",
1112
+ "ALK_ALT_CO2": "ALK_ALT_CO2",
1113
+ "DOC": "DOC",
1114
+ "DON": "DON",
1115
+ "DOP": "DOP",
1116
+ "DOPr": "DOPr",
1117
+ "DONr": "DONr",
1118
+ "DOCr": "DOCr",
1119
+ "spChl": "spChl",
1120
+ "spC": "spC",
1121
+ "spP": "spP",
1122
+ "spFe": "spFe",
1123
+ "diatChl": "diatChl",
1124
+ "diatC": "diatC",
1125
+ "diatP": "diatP",
1126
+ "diatFe": "diatFe",
1127
+ "diatSi": "diatSi",
1128
+ "diazChl": "diazChl",
1129
+ "diazC": "diazC",
1130
+ "diazP": "diazP",
1131
+ "diazFe": "diazFe",
1132
+ "spCaCO3": "spCaCO3",
1133
+ "zooC": "zooC",
1134
+ },
1135
+ }
1136
+
1137
+ if var_type not in var_mappings:
1138
+ raise ValueError(
1139
+ f"Unsupported var_type '{var_type}'. Choose from {list(var_mappings.keys())}."
1140
+ )
1141
+
1142
+ return var_mappings[var_type]
roms_tools/setup/mask.py CHANGED
@@ -8,11 +8,8 @@ import regionmask
8
8
  import xarray as xr
9
9
  from scipy.ndimage import label
10
10
 
11
- from roms_tools.setup.utils import (
12
- handle_boundaries,
13
- interpolate_from_rho_to_u,
14
- interpolate_from_rho_to_v,
15
- )
11
+ from roms_tools.setup.utils import handle_boundaries
12
+ from roms_tools.utils import interpolate_from_rho_to_u, interpolate_from_rho_to_v
16
13
 
17
14
 
18
15
  def add_mask(ds: xr.Dataset, shapefile: str | Path | None = None) -> xr.Dataset:
@@ -13,16 +13,19 @@ from roms_tools.plot import plot_nesting
13
13
  from roms_tools.setup.topography import clip_depth
14
14
  from roms_tools.setup.utils import (
15
15
  Timed,
16
+ check_and_set_boundaries,
16
17
  from_yaml,
17
18
  get_boundary_coords,
18
- interpolate_from_rho_to_u,
19
- interpolate_from_rho_to_v,
20
19
  pop_grid_data,
21
20
  to_dict,
22
- wrap_longitudes,
23
21
  write_to_yaml,
24
22
  )
25
- from roms_tools.utils import save_datasets
23
+ from roms_tools.utils import (
24
+ interpolate_from_rho_to_u,
25
+ interpolate_from_rho_to_v,
26
+ save_datasets,
27
+ wrap_longitudes,
28
+ )
26
29
 
27
30
 
28
31
  @dataclass(kw_only=True)
@@ -43,8 +46,8 @@ class ChildGrid(Grid):
43
46
  parent_grid : Grid
44
47
  The parent grid object, providing the reference for the topography and mask of the child grid.
45
48
  boundaries : Dict[str, bool]
46
- Specifies which child grid boundaries (south, east, north, west) should be adjusted for topography/mask
47
- and included in `ds_nesting`. Defaults to all `True`.
49
+ Specifies which child grid boundaries ('south', 'east', 'north', 'west') should be adjusted for topography/mask
50
+ and included in `ds_nesting`. If not provided, valid (non-land) boundaries are enabled automatically.
48
51
  metadata : Dict[str, Any]
49
52
  Dictionary configuring the boundary nesting process, including:
50
53
 
@@ -87,6 +90,10 @@ class ChildGrid(Grid):
87
90
  "=== Mapping the child grid boundary points onto the indices of the parent grid ===",
88
91
  verbose=verbose,
89
92
  ):
93
+ self.boundaries = check_and_set_boundaries(
94
+ self.boundaries, self.ds.mask_rho
95
+ )
96
+
90
97
  # Prepare parent and child grid datasets by adjusting longitudes for dateline crossing
91
98
  parent_grid_ds, child_grid_ds = self._prepare_grid_datasets()
92
99
 
@@ -11,16 +11,16 @@ import xarray as xr
11
11
 
12
12
  from roms_tools import Grid
13
13
  from roms_tools.constants import MAX_DISTINCT_COLORS
14
+ from roms_tools.datasets.river_datasets import (
15
+ DaiRiverDataset,
16
+ get_indices_of_nearest_grid_cell_for_rivers,
17
+ )
14
18
  from roms_tools.plot import (
15
19
  assign_category_colors,
16
20
  get_projection,
17
21
  plot_2d_horizontal_field,
18
22
  plot_location,
19
23
  )
20
- from roms_tools.setup.river_datasets import (
21
- DaiRiverDataset,
22
- get_indices_of_nearest_grid_cell_for_rivers,
23
- )
24
24
  from roms_tools.setup.utils import (
25
25
  RawDataSource,
26
26
  add_time_info_to_ds,