roms-tools 1.5.0__py3-none-any.whl → 1.6.1__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 (239) hide show
  1. roms_tools/_version.py +1 -1
  2. roms_tools/setup/boundary_forcing.py +263 -100
  3. roms_tools/setup/datasets.py +169 -39
  4. roms_tools/setup/fill.py +0 -36
  5. roms_tools/setup/grid.py +1 -1
  6. roms_tools/setup/initial_conditions.py +108 -73
  7. roms_tools/setup/regrid.py +43 -98
  8. roms_tools/setup/surface_forcing.py +104 -82
  9. roms_tools/setup/tides.py +76 -48
  10. roms_tools/setup/utils.py +25 -53
  11. roms_tools/tests/test_setup/test_boundary_forcing.py +84 -47
  12. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_east/0.0.0 +0 -0
  13. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_south/0.0.0 +0 -0
  14. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/0.0.0 +0 -0
  15. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_east/0.0.0 +0 -0
  16. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_south/0.0.0 +0 -0
  17. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/0.0.0 +0 -0
  18. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_east/0.0.0 +0 -0
  19. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_south/0.0.0 +0 -0
  20. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/0.0.0 +0 -0
  21. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_east/0.0.0 +0 -0
  22. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_south/0.0.0 +0 -0
  23. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/0.0.0 +0 -0
  24. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_east/0.0.0 +0 -0
  25. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_south/0.0.0 +0 -0
  26. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/0.0.0 +0 -0
  27. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_east/0.0.0 +0 -0
  28. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_south/0.0.0 +0 -0
  29. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/0.0.0 +0 -0
  30. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_east/0.0.0 +0 -0
  31. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_south/0.0.0 +0 -0
  32. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/0.0.0 +0 -0
  33. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_east/0.0.0 +0 -0
  34. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_south/0.0.0 +0 -0
  35. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/0.0.0 +0 -0
  36. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_east/0.0.0 +0 -0
  37. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_south/0.0.0 +0 -0
  38. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/0.0.0 +0 -0
  39. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_east/0.0.0 +0 -0
  40. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_south/0.0.0 +0 -0
  41. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/0.0.0 +0 -0
  42. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_east/0.0.0 +0 -0
  43. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_south/0.0.0 +0 -0
  44. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/0.0.0 +0 -0
  45. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_east/0.0.0 +0 -0
  46. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_south/0.0.0 +0 -0
  47. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/0.0.0 +0 -0
  48. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_east/0.0.0 +0 -0
  49. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_south/0.0.0 +0 -0
  50. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/0.0.0 +0 -0
  51. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_east/0.0.0 +0 -0
  52. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_south/0.0.0 +0 -0
  53. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/0.0.0 +0 -0
  54. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_east/0.0.0 +0 -0
  55. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_south/0.0.0 +0 -0
  56. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/0.0.0 +0 -0
  57. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_east/0.0.0 +0 -0
  58. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_south/0.0.0 +0 -0
  59. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/0.0.0 +0 -0
  60. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_east/0.0.0 +0 -0
  61. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_south/0.0.0 +0 -0
  62. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/0.0.0 +0 -0
  63. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_east/0.0.0 +0 -0
  64. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_south/0.0.0 +0 -0
  65. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/0.0.0 +0 -0
  66. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_east/0.0.0 +0 -0
  67. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_south/0.0.0 +0 -0
  68. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/0.0.0 +0 -0
  69. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_east/0.0.0 +0 -0
  70. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_south/0.0.0 +0 -0
  71. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/0.0.0 +0 -0
  72. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_east/0.0.0 +0 -0
  73. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_south/0.0.0 +0 -0
  74. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/0.0.0 +0 -0
  75. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_east/0.0.0 +0 -0
  76. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_south/0.0.0 +0 -0
  77. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/0.0.0 +0 -0
  78. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_east/0.0.0 +0 -0
  79. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_south/0.0.0 +0 -0
  80. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/0.0.0 +0 -0
  81. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_east/0.0.0 +0 -0
  82. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_south/0.0.0 +0 -0
  83. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/0.0.0 +0 -0
  84. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_east/0.0.0 +0 -0
  85. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_south/0.0.0 +0 -0
  86. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/0.0.0 +0 -0
  87. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_east/0.0.0 +0 -0
  88. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_south/0.0.0 +0 -0
  89. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/0.0.0 +0 -0
  90. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_east/0.0.0 +0 -0
  91. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_south/0.0.0 +0 -0
  92. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/0.0.0 +0 -0
  93. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_east/0.0.0 +0 -0
  94. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_south/0.0.0 +0 -0
  95. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/0.0.0 +0 -0
  96. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_east/0.0.0 +0 -0
  97. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_south/0.0.0 +0 -0
  98. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/0.0.0 +0 -0
  99. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_east/0.0.0 +0 -0
  100. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_south/0.0.0 +0 -0
  101. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/0.0.0 +0 -0
  102. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_east/0.0.0 +0 -0
  103. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_south/0.0.0 +0 -0
  104. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/0.0.0 +0 -0
  105. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_east/0.0.0 +0 -0
  106. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_south/0.0.0 +0 -0
  107. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/0.0.0 +0 -0
  108. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zattrs +1 -1
  109. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zmetadata +1 -1
  110. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/dust/0.0.0 +0 -0
  111. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/iron/0.0.0 +0 -0
  112. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nhy/0.0.0 +0 -0
  113. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nox/0.0.0 +0 -0
  114. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air/0.0.0 +0 -0
  115. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air_alt/0.0.0 +0 -0
  116. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zattrs +1 -1
  117. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zmetadata +1 -1
  118. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/dust/0.0.0 +0 -0
  119. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/iron/0.0.0 +0 -0
  120. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nhy/0.0.0 +0 -0
  121. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nox/0.0.0 +0 -0
  122. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air/0.0.0 +0 -0
  123. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air_alt/0.0.0 +0 -0
  124. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +7 -0
  125. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zattrs +3 -0
  126. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/0.0.0 +0 -0
  127. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/0.0.0 +0 -0
  128. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/0.0.0 +0 -0
  129. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/0.0.0 +0 -0
  130. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/0.0.0 +0 -0
  131. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/0.0.0 +0 -0
  132. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/0.0.0 +0 -0
  133. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/0.0.0 +0 -0
  134. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/0.0 +0 -0
  135. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/0.0 +0 -0
  136. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/0.0 +0 -0
  137. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/0.0 +0 -0
  138. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/0.0.0 +0 -0
  139. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/0.0.0 +0 -0
  140. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/0.0.0 +0 -0
  141. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/0.0.0 +0 -0
  142. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/0.0 +0 -0
  143. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/0.0 +0 -0
  144. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/0.0 +0 -0
  145. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/0.0 +0 -0
  146. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/.zattrs +1 -0
  147. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/0.0 +0 -0
  148. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/.zattrs +1 -0
  149. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zattrs +1 -0
  150. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
  151. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/.zattrs +1 -0
  152. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/.zattrs +1 -1
  153. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/.zmetadata +1 -1
  154. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/Tair/0.0.0 +0 -0
  155. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/lwrad/0.0.0 +0 -0
  156. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/qair/0.0.0 +0 -0
  157. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/rain/0.0.0 +0 -0
  158. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/swrad/0.0.0 +0 -0
  159. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/uwnd/0.0.0 +0 -0
  160. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/vwnd/0.0.0 +0 -0
  161. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/.zattrs +1 -1
  162. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/.zmetadata +1 -1
  163. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/Tair/0.0.0 +0 -0
  164. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/lwrad/0.0.0 +0 -0
  165. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/qair/0.0.0 +0 -0
  166. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/rain/0.0.0 +0 -0
  167. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/swrad/0.0.0 +0 -0
  168. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/uwnd/0.0.0 +0 -0
  169. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/vwnd/0.0.0 +0 -0
  170. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK/0.0.0.0 +0 -0
  171. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK_ALT_CO2/0.0.0.0 +0 -0
  172. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC/0.0.0.0 +0 -0
  173. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC_ALT_CO2/0.0.0.0 +0 -0
  174. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOC/0.0.0.0 +0 -0
  175. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOCr/0.0.0.0 +0 -0
  176. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DON/0.0.0.0 +0 -0
  177. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DONr/0.0.0.0 +0 -0
  178. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOP/0.0.0.0 +0 -0
  179. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOPr/0.0.0.0 +0 -0
  180. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Fe/0.0.0.0 +0 -0
  181. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Lig/0.0.0.0 +0 -0
  182. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NH4/0.0.0.0 +0 -0
  183. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NO3/0.0.0.0 +0 -0
  184. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/O2/0.0.0.0 +0 -0
  185. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/PO4/0.0.0.0 +0 -0
  186. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/SiO3/0.0.0.0 +0 -0
  187. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatC/0.0.0.0 +0 -0
  188. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatChl/0.0.0.0 +0 -0
  189. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatFe/0.0.0.0 +0 -0
  190. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatP/0.0.0.0 +0 -0
  191. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatSi/0.0.0.0 +0 -0
  192. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazC/0.0.0.0 +0 -0
  193. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazChl/0.0.0.0 +0 -0
  194. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazFe/0.0.0.0 +0 -0
  195. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazP/0.0.0.0 +0 -0
  196. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/salt/0.0.0.0 +0 -0
  197. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spC/0.0.0.0 +0 -0
  198. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spCaCO3/0.0.0.0 +0 -0
  199. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spChl/0.0.0.0 +0 -0
  200. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spFe/0.0.0.0 +0 -0
  201. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spP/0.0.0.0 +0 -0
  202. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/temp/0.0.0.0 +0 -0
  203. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/u/0.0.0.0 +0 -0
  204. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ubar/0.0.0 +0 -0
  205. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/v/0.0.0.0 +0 -0
  206. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/vbar/0.0.0 +0 -0
  207. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zeta/0.0.0 +0 -0
  208. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zooC/0.0.0.0 +0 -0
  209. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/.zattrs +1 -1
  210. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/.zmetadata +1 -1
  211. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/Tair/0.0.0 +0 -0
  212. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/lwrad/0.0.0 +0 -0
  213. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/qair/0.0.0 +0 -0
  214. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/rain/0.0.0 +0 -0
  215. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/swrad/0.0.0 +0 -0
  216. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/uwnd/0.0.0 +0 -0
  217. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/vwnd/0.0.0 +0 -0
  218. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/.zattrs +1 -1
  219. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/.zmetadata +4 -2
  220. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/omega/.zattrs +3 -1
  221. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/pot_Im/0.0.0 +0 -0
  222. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/pot_Re/0.0.0 +0 -0
  223. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/ssh_Im/0.0.0 +0 -0
  224. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/ssh_Re/0.0.0 +0 -0
  225. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/u_Im/0.0.0 +0 -0
  226. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/u_Re/0.0.0 +0 -0
  227. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/v_Im/0.0.0 +0 -0
  228. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/v_Re/0.0.0 +0 -0
  229. roms_tools/tests/test_setup/test_datasets.py +79 -21
  230. roms_tools/tests/test_setup/test_fill.py +18 -105
  231. roms_tools/tests/test_setup/test_initial_conditions.py +29 -25
  232. roms_tools/tests/test_setup/test_regrid.py +2 -8
  233. roms_tools/tests/test_setup/test_surface_forcing.py +49 -29
  234. roms_tools/tests/test_setup/test_tides.py +7 -5
  235. {roms_tools-1.5.0.dist-info → roms_tools-1.6.1.dist-info}/METADATA +13 -3
  236. {roms_tools-1.5.0.dist-info → roms_tools-1.6.1.dist-info}/RECORD +239 -239
  237. {roms_tools-1.5.0.dist-info → roms_tools-1.6.1.dist-info}/WHEEL +1 -1
  238. {roms_tools-1.5.0.dist-info → roms_tools-1.6.1.dist-info}/LICENSE +0 -0
  239. {roms_tools-1.5.0.dist-info → roms_tools-1.6.1.dist-info}/top_level.txt +0 -0
@@ -7,8 +7,7 @@ from roms_tools.setup.grid import Grid
7
7
  from datetime import datetime
8
8
  import numpy as np
9
9
  from typing import Dict, Union, List
10
- from roms_tools.setup.fill import _lateral_fill, LateralFill
11
- from roms_tools.setup.regrid import _lateral_regrid, LateralRegrid
10
+ from roms_tools.setup.regrid import LateralRegrid
12
11
  from roms_tools.setup.datasets import (
13
12
  ERA5Dataset,
14
13
  ERA5Correction,
@@ -99,51 +98,40 @@ class SurfaceForcing:
99
98
 
100
99
  data = self._get_data()
101
100
  data.choose_subdomain(
102
- latitude_range=[
103
- target_coords["lat"].min().values,
104
- target_coords["lat"].max().values,
105
- ],
106
- longitude_range=[
107
- target_coords["lon"].min().values,
108
- target_coords["lon"].max().values,
109
- ],
110
- margin=2,
111
- straddle=target_coords["straddle"],
101
+ target_coords,
102
+ buffer_points=20, # lateral fill needs some buffer from data margin
112
103
  )
113
104
 
114
- variable_info = self._set_variable_info(data)
105
+ data.apply_lateral_fill()
115
106
 
116
- data_vars = {}
117
- for var_name in data.var_names:
118
- if var_name != "mask":
119
- data_vars[var_name] = data.ds[data.var_names[var_name]]
120
-
121
- data_vars = _lateral_fill(data_vars, data)
107
+ variable_info = self._set_variable_info(data)
108
+ var_names = variable_info.keys()
122
109
 
110
+ processed_fields = {}
123
111
  # lateral regridding
124
- var_names = variable_info.keys()
125
- data_vars = _lateral_regrid(
126
- data, target_coords["lon"], target_coords["lat"], data_vars, var_names
127
- )
112
+ lateral_regrid = LateralRegrid(target_coords, data.dim_names)
113
+ for var_name in var_names:
114
+ if var_name in data.var_names.keys():
115
+ processed_fields[var_name] = lateral_regrid.apply(
116
+ data.ds[data.var_names[var_name]]
117
+ )
128
118
 
129
119
  # rotation of velocities and interpolation to u/v points
130
120
  if "uwnd" in variable_info and "vwnd" in variable_info:
131
- data_vars["uwnd"], data_vars["vwnd"] = rotate_velocities(
132
- data_vars["uwnd"],
133
- data_vars["vwnd"],
121
+ processed_fields["uwnd"], processed_fields["vwnd"] = rotate_velocities(
122
+ processed_fields["uwnd"],
123
+ processed_fields["vwnd"],
134
124
  target_coords["angle"],
135
125
  interpolate=False,
136
126
  )
137
127
 
138
128
  # correct radiation
139
129
  if self.type == "physics" and self.correct_radiation:
140
- data_vars = self._apply_correction(data_vars, data)
141
-
142
- object.__setattr__(data, "data_vars", data_vars)
130
+ processed_fields = self._apply_correction(processed_fields, data)
143
131
 
144
132
  d_meta = get_variable_metadata()
145
133
 
146
- ds = self._write_into_dataset(data, d_meta)
134
+ ds = self._write_into_dataset(processed_fields, data, d_meta)
147
135
 
148
136
  if self.use_coarse_grid:
149
137
  mask = self.grid.ds["mask_coarse"].rename(
@@ -152,13 +140,11 @@ class SurfaceForcing:
152
140
  else:
153
141
  mask = self.grid.ds["mask_rho"]
154
142
 
155
- # NaN values at wet points indicate that the raw data did not cover the domain, and the following will raise a ValueError
156
- for var in ds.data_vars:
157
- nan_check(ds[var].isel(time=0), mask)
143
+ self._validate(ds, mask)
158
144
 
159
145
  # substitute NaNs over land by a fill value to avoid blow-up of ROMS
160
- for var in ds.data_vars:
161
- ds[var] = substitute_nans_by_fillvalue(ds[var])
146
+ for var_name in ds.data_vars:
147
+ ds[var_name] = substitute_nans_by_fillvalue(ds[var_name])
162
148
 
163
149
  object.__setattr__(self, "ds", ds)
164
150
 
@@ -272,7 +258,7 @@ class SurfaceForcing:
272
258
 
273
259
  return variable_info
274
260
 
275
- def _apply_correction(self, data_vars, data):
261
+ def _apply_correction(self, processed_fields, data):
276
262
 
277
263
  correction_data = self._get_correction_data()
278
264
  # choose same subdomain as forcing data so that we can use same mask
@@ -285,44 +271,34 @@ class SurfaceForcing:
285
271
  correction_data.choose_subdomain(
286
272
  coords_correction, straddle=self.target_coords["straddle"]
287
273
  )
288
-
274
+ correction_data.ds["mask"] = data.ds["mask"] # use mask from ERA5 data
275
+ correction_data.apply_lateral_fill()
289
276
  # regrid
290
- lateral_fill = LateralFill(
291
- data.ds["mask"], # use mask from ERA5 data
292
- [
293
- correction_data.dim_names["latitude"],
294
- correction_data.dim_names["longitude"],
295
- ],
296
- )
297
- lateral_regrid = LateralRegrid(
298
- correction_data, self.target_coords["lon"], self.target_coords["lat"]
299
- )
300
-
301
- filled = lateral_fill.apply(
277
+ lateral_regrid = LateralRegrid(self.target_coords, correction_data.dim_names)
278
+ corr_factor = lateral_regrid.apply(
302
279
  correction_data.ds[correction_data.var_names["swr_corr"]]
303
280
  )
304
- corr_factor = lateral_regrid.apply(filled)
305
281
 
306
282
  # temporal interpolation
307
283
  corr_factor = interpolate_from_climatology(
308
284
  corr_factor,
309
285
  correction_data.dim_names["time"],
310
- time=data_vars["swrad"].time,
286
+ time=processed_fields["swrad"].time,
311
287
  )
312
288
 
313
- data_vars["swrad"] = data_vars["swrad"] * corr_factor
289
+ processed_fields["swrad"] = processed_fields["swrad"] * corr_factor
314
290
 
315
- return data_vars
291
+ return processed_fields
316
292
 
317
- def _write_into_dataset(self, data, d_meta):
293
+ def _write_into_dataset(self, processed_fields, data, d_meta):
318
294
 
319
295
  # save in new dataset
320
296
  ds = xr.Dataset()
321
297
 
322
- for var in data.data_vars.keys():
323
- ds[var] = data.data_vars[var].astype(np.float32)
324
- ds[var].attrs["long_name"] = d_meta[var]["long_name"]
325
- ds[var].attrs["units"] = d_meta[var]["units"]
298
+ for var_name in processed_fields.keys():
299
+ ds[var_name] = processed_fields[var_name].astype(np.float32)
300
+ ds[var_name].attrs["long_name"] = d_meta[var_name]["long_name"]
301
+ ds[var_name].attrs["units"] = d_meta[var_name]["units"]
326
302
 
327
303
  if self.use_coarse_grid:
328
304
  ds = ds.rename({"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"})
@@ -388,11 +364,36 @@ class SurfaceForcing:
388
364
  ds = ds.drop_vars(["time"])
389
365
 
390
366
  variables_to_drop = ["lat_rho", "lon_rho", "lat_coarse", "lon_coarse"]
391
- existing_vars = [var for var in variables_to_drop if var in ds]
367
+ existing_vars = [var_name for var_name in variables_to_drop if var_name in ds]
392
368
  ds = ds.drop_vars(existing_vars)
393
369
 
394
370
  return ds
395
371
 
372
+ def _validate(self, ds, mask):
373
+ """Validates the dataset by checking for NaN values at wet points, which would
374
+ indicate missing raw data coverage over the target domain.
375
+
376
+ Parameters
377
+ ----------
378
+ ds : xarray.Dataset
379
+ The dataset to validate.
380
+ mask : xarray.DataArray
381
+ Land mask (1=ocean, 0=land) to determine wet points in the domain.
382
+
383
+ Raises
384
+ ------
385
+ ValueError
386
+ If NaN values are found in any of the specified variables at wet points,
387
+ indicating incomplete data coverage.
388
+
389
+ Notes
390
+ -----
391
+ This check is applied to the first time step (`time=0`) of each variable in the provided dataset.
392
+ """
393
+
394
+ for var_name in ds.data_vars:
395
+ nan_check(ds[var_name].isel(time=0), mask)
396
+
396
397
  def _add_global_metadata(self, ds=None):
397
398
 
398
399
  if ds is None:
@@ -416,12 +417,12 @@ class SurfaceForcing:
416
417
 
417
418
  return ds
418
419
 
419
- def plot(self, varname, time=0) -> None:
420
+ def plot(self, var_name, time=0) -> None:
420
421
  """Plot the specified surface forcing field for a given time slice.
421
422
 
422
423
  Parameters
423
424
  ----------
424
- varname : str
425
+ var_name : str
425
426
  The name of the surface forcing field to plot. Options include:
426
427
 
427
428
  - "uwnd": 10 meter wind in x-direction.
@@ -450,7 +451,7 @@ class SurfaceForcing:
450
451
  Raises
451
452
  ------
452
453
  ValueError
453
- If the specified varname is not found in dataset.
454
+ If the specified var_name is not found in dataset.
454
455
 
455
456
 
456
457
  Examples
@@ -458,10 +459,16 @@ class SurfaceForcing:
458
459
  >>> atm_forcing.plot("uwnd", time=0)
459
460
  """
460
461
 
461
- if varname not in self.ds:
462
- raise ValueError(f"Variable '{varname}' is not found in dataset.")
462
+ if var_name not in self.ds:
463
+ raise ValueError(f"Variable '{var_name}' is not found in dataset.")
464
+
465
+ field = self.ds[var_name].isel(time=time)
466
+ if self.use_dask:
467
+ from dask.diagnostics import ProgressBar
468
+
469
+ with ProgressBar():
470
+ field = field.load()
463
471
 
464
- field = self.ds[varname].isel(time=time).load()
465
472
  title = field.long_name
466
473
 
467
474
  # assign lat / lon
@@ -476,14 +483,14 @@ class SurfaceForcing:
476
483
  )
477
484
 
478
485
  # choose colorbar
479
- if varname in ["uwnd", "vwnd"]:
486
+ if var_name in ["uwnd", "vwnd"]:
480
487
  vmax = max(field.max().values, -field.min().values)
481
488
  vmin = -vmax
482
489
  cmap = plt.colormaps.get_cmap("RdBu_r")
483
490
  else:
484
491
  vmax = field.max().values
485
492
  vmin = field.min().values
486
- if varname in ["swrad", "lwrad", "Tair", "qair"]:
493
+ if var_name in ["swrad", "lwrad", "Tair", "qair"]:
487
494
  cmap = plt.colormaps.get_cmap("YlOrRd")
488
495
  else:
489
496
  cmap = plt.colormaps.get_cmap("YlGnBu")
@@ -501,24 +508,26 @@ class SurfaceForcing:
501
508
  )
502
509
 
503
510
  def save(
504
- self, filepath: Union[str, Path], np_eta: int = None, np_xi: int = None
511
+ self,
512
+ filepath: Union[str, Path],
513
+ np_eta: int = None,
514
+ np_xi: int = None,
515
+ group: bool = False,
505
516
  ) -> None:
506
- """Save the surface forcing fields to netCDF4 files.
507
-
508
- This method saves the dataset by grouping it into subsets based on the data frequency. The subsets are then written
509
- to one or more netCDF4 files. The filenames of the output files reflect the temporal coverage of the data.
510
-
511
- There are two modes of saving the dataset:
517
+ """Save the surface forcing fields to one or more netCDF4 files.
512
518
 
513
- 1. **Single File Mode (default)**:
519
+ This method saves the dataset either as a single file or as multiple files depending on the partitioning and grouping options.
520
+ The dataset can be saved in two modes:
514
521
 
515
- If both `np_eta` and `np_xi` are `None`, the entire dataset, divided by temporal subsets, is saved as a single netCDF4 file
516
- with the base filename specified by `filepath.nc`.
522
+ 1. **Single File Mode (default)**:
523
+ - If both `np_eta` and `np_xi` are `None`, the entire dataset is saved as a single netCDF4 file.
524
+ - The file is named based on the `filepath`, with `.nc` automatically appended.
517
525
 
518
- 2. **Partitioned Mode**:
526
+ 2. **Partitioned Mode**:
527
+ - If either `np_eta` or `np_xi` is specified, the dataset is partitioned into spatial tiles along the `eta` and `xi` axes.
528
+ - Each tile is saved as a separate netCDF4 file, and filenames are modified with an index (e.g., `"filepath_YYYYMM.0.nc"`, `"filepath_YYYYMM.1.nc"`).
519
529
 
520
- - If either `np_eta` or `np_xi` is specified, the dataset is divided into spatial tiles along the eta-axis and xi-axis.
521
- - Each spatial tile is saved as a separate netCDF4 file.
530
+ Additionally, if `group` is set to `True`, the dataset is first grouped into temporal subsets, resulting in multiple grouped files before partitioning and saving.
522
531
 
523
532
  Parameters
524
533
  ----------
@@ -530,6 +539,8 @@ class SurfaceForcing:
530
539
  The number of partitions along the `eta` direction. If `None`, no spatial partitioning is performed.
531
540
  np_xi : int, optional
532
541
  The number of partitions along the `xi` direction. If `None`, no spatial partitioning is performed.
542
+ group: bool, optional
543
+ If `True`, groups the dataset into multiple files based on temporal data frequency. Defaults to `False`.
533
544
 
534
545
  Returns
535
546
  -------
@@ -544,7 +555,18 @@ class SurfaceForcing:
544
555
  if filepath.suffix == ".nc":
545
556
  filepath = filepath.with_suffix("")
546
557
 
547
- dataset_list, output_filenames = group_dataset(self.ds.load(), str(filepath))
558
+ if self.use_dask:
559
+ from dask.diagnostics import ProgressBar
560
+
561
+ with ProgressBar():
562
+ self.ds.load()
563
+
564
+ if group:
565
+ dataset_list, output_filenames = group_dataset(self.ds, str(filepath))
566
+ else:
567
+ dataset_list = [self.ds]
568
+ output_filenames = [str(filepath)]
569
+
548
570
  saved_filenames = save_datasets(
549
571
  dataset_list, output_filenames, np_eta=np_eta, np_xi=np_xi
550
572
  )
@@ -602,7 +624,7 @@ class SurfaceForcing:
602
624
  # Write header
603
625
  file.write(header)
604
626
  # Write YAML data
605
- yaml.dump(yaml_data, file, default_flow_style=False)
627
+ yaml.dump(yaml_data, file, default_flow_style=False, sort_keys=False)
606
628
 
607
629
  @classmethod
608
630
  def from_yaml(
roms_tools/setup/tides.py CHANGED
@@ -20,8 +20,7 @@ from roms_tools.setup.utils import (
20
20
  rotate_velocities,
21
21
  get_vector_pairs,
22
22
  )
23
- from roms_tools.setup.fill import _lateral_fill
24
- from roms_tools.setup.regrid import _lateral_regrid
23
+ from roms_tools.setup.regrid import LateralRegrid
25
24
  import matplotlib.pyplot as plt
26
25
  from pathlib import Path
27
26
 
@@ -77,71 +76,64 @@ class TidalForcing:
77
76
  data = self._get_data()
78
77
  data.check_number_constituents(self.ntides)
79
78
  data.choose_subdomain(
80
- latitude_range=[
81
- target_coords["lat"].min().values,
82
- target_coords["lat"].max().values,
83
- ],
84
- longitude_range=[
85
- target_coords["lon"].min().values,
86
- target_coords["lon"].max().values,
87
- ],
88
- margin=2,
89
- straddle=target_coords["straddle"],
79
+ target_coords,
80
+ buffer_points=20,
90
81
  )
91
82
  # select desired number of constituents
92
83
  object.__setattr__(data, "ds", data.ds.isel(ntides=slice(None, self.ntides)))
93
84
  self._correct_tides(data)
94
85
 
95
- variable_info = self._set_variable_info()
96
-
97
- data_vars = {}
98
- for var_name in data.var_names:
99
- data_vars[var_name] = data.ds[data.var_names[var_name]]
86
+ data.apply_lateral_fill()
100
87
 
101
- data_vars = _lateral_fill(data_vars, data)
88
+ variable_info = self._set_variable_info()
89
+ var_names = variable_info.keys()
102
90
 
91
+ processed_fields = {}
103
92
  # lateral regridding
104
- var_names = variable_info.keys()
105
- data_vars = _lateral_regrid(
106
- data, target_coords["lon"], target_coords["lat"], data_vars, var_names
107
- )
93
+ lateral_regrid = LateralRegrid(target_coords, data.dim_names)
94
+ for var_name in var_names:
95
+ if var_name in data.var_names.keys():
96
+ processed_fields[var_name] = lateral_regrid.apply(
97
+ data.ds[data.var_names[var_name]]
98
+ )
108
99
 
109
100
  # rotation of velocities and interpolation to u/v points
110
101
  vector_pairs = get_vector_pairs(variable_info)
111
102
  for pair in vector_pairs:
112
103
  u_component = pair[0]
113
104
  v_component = pair[1]
114
- if u_component in data_vars and v_component in data_vars:
115
- (data_vars[u_component], data_vars[v_component],) = rotate_velocities(
116
- data_vars[u_component],
117
- data_vars[v_component],
105
+ if u_component in processed_fields and v_component in processed_fields:
106
+ (
107
+ processed_fields[u_component],
108
+ processed_fields[v_component],
109
+ ) = rotate_velocities(
110
+ processed_fields[u_component],
111
+ processed_fields[v_component],
118
112
  target_coords["angle"],
119
113
  interpolate=False,
120
114
  )
121
115
 
122
116
  # convert to barotropic velocity
123
- for varname in ["u_Re", "v_Re", "u_Im", "v_Im"]:
124
- data_vars[varname] = data_vars[varname] / self.grid.ds.h
117
+ for var_name in ["u_Re", "v_Re", "u_Im", "v_Im"]:
118
+ processed_fields[var_name] = processed_fields[var_name] / self.grid.ds.h
125
119
 
126
120
  # interpolate from rho- to velocity points
127
121
  for uname in ["u_Re", "u_Im"]:
128
- data_vars[uname] = interpolate_from_rho_to_u(data_vars[uname])
122
+ processed_fields[uname] = interpolate_from_rho_to_u(processed_fields[uname])
129
123
  for vname in ["v_Re", "v_Im"]:
130
- data_vars[vname] = interpolate_from_rho_to_v(data_vars[vname])
124
+ processed_fields[vname] = interpolate_from_rho_to_v(processed_fields[vname])
131
125
 
132
126
  d_meta = get_variable_metadata()
133
- ds = self._write_into_dataset(data_vars, d_meta)
127
+ ds = self._write_into_dataset(processed_fields, d_meta)
134
128
  ds["omega"] = data.ds["omega"]
135
129
 
136
130
  ds = self._add_global_metadata(ds)
137
131
 
138
- # NaN values at wet points indicate that the raw data did not cover the domain, and the following will raise a ValueError
139
- for var in ["ssh_Re", "u_Re", "v_Im"]:
140
- nan_check(ds[var].isel(ntides=0), self.grid.ds.mask_rho)
132
+ self._validate(ds)
141
133
 
142
134
  # substitute NaNs over land by a fill value to avoid blow-up of ROMS
143
- for var in ds.data_vars:
144
- ds[var] = substitute_nans_by_fillvalue(ds[var])
135
+ for var_name in ds.data_vars:
136
+ ds[var_name] = substitute_nans_by_fillvalue(ds[var_name])
145
137
 
146
138
  object.__setattr__(self, "ds", ds)
147
139
 
@@ -216,15 +208,15 @@ class TidalForcing:
216
208
 
217
209
  return variable_info
218
210
 
219
- def _write_into_dataset(self, data_vars, d_meta):
211
+ def _write_into_dataset(self, processed_fields, d_meta):
220
212
 
221
213
  # save in new dataset
222
214
  ds = xr.Dataset()
223
215
 
224
- for var in data_vars.keys():
225
- ds[var] = data_vars[var].astype(np.float32)
226
- ds[var].attrs["long_name"] = d_meta[var]["long_name"]
227
- ds[var].attrs["units"] = d_meta[var]["units"]
216
+ for var_name in processed_fields.keys():
217
+ ds[var_name] = processed_fields[var_name].astype(np.float32)
218
+ ds[var_name].attrs["long_name"] = d_meta[var_name]["long_name"]
219
+ ds[var_name].attrs["units"] = d_meta[var_name]["units"]
228
220
 
229
221
  ds = ds.drop_vars(["lat_rho", "lon_rho"])
230
222
 
@@ -247,12 +239,35 @@ class TidalForcing:
247
239
 
248
240
  return ds
249
241
 
250
- def plot(self, varname, ntides=0) -> None:
242
+ def _validate(self, ds):
243
+ """Validates the dataset by checking for NaN values at wet points, which would
244
+ indicate missing raw data coverage over the target domain.
245
+
246
+ Parameters
247
+ ----------
248
+ ds : xarray.Dataset
249
+ The dataset to validate, containing tidal variables and a mask for wet points.
250
+
251
+ Raises
252
+ ------
253
+ ValueError
254
+ If NaN values are found in any of the specified variables at wet points,
255
+ indicating incomplete data coverage.
256
+
257
+ Notes
258
+ -----
259
+ This check is applied to the first constituent (`ntides=0`) of each variable in the dataset.
260
+ The method utilizes `self.grid.ds.mask_rho` to determine the wet points in the domain.
261
+ """
262
+ for var_name in ds.data_vars:
263
+ nan_check(ds[var_name].isel(ntides=0), self.grid.ds.mask_rho)
264
+
265
+ def plot(self, var_name, ntides=0) -> None:
251
266
  """Plot the specified tidal forcing variable for a given tidal constituent.
252
267
 
253
268
  Parameters
254
269
  ----------
255
- varname : str
270
+ var_name : str
256
271
  The tidal forcing variable to plot. Options include:
257
272
 
258
273
  - "ssh_Re": Real part of tidal elevation.
@@ -285,7 +300,14 @@ class TidalForcing:
285
300
  >>> tidal_forcing.plot("ssh_Re", nc=0)
286
301
  """
287
302
 
288
- field = self.ds[varname].isel(ntides=ntides).compute()
303
+ field = self.ds[var_name].isel(ntides=ntides)
304
+
305
+ if self.use_dask:
306
+ from dask.diagnostics import ProgressBar
307
+
308
+ with ProgressBar():
309
+ field = field.load()
310
+
289
311
  if all(dim in field.dims for dim in ["eta_rho", "xi_rho"]):
290
312
  field = field.where(self.grid.ds.mask_rho)
291
313
  field = field.assign_coords(
@@ -306,7 +328,7 @@ class TidalForcing:
306
328
  else:
307
329
  ValueError("provided field does not have two horizontal dimension")
308
330
 
309
- title = "%s, ntides = %i" % (field.long_name, self.ds[varname].ntides[ntides])
331
+ title = "%s, ntides = %i" % (field.long_name, self.ds[var_name].ntides[ntides])
310
332
 
311
333
  vmax = max(field.max(), -field.min())
312
334
  vmin = -vmax
@@ -363,7 +385,13 @@ class TidalForcing:
363
385
  if filepath.suffix == ".nc":
364
386
  filepath = filepath.with_suffix("")
365
387
 
366
- dataset_list = [self.ds.load()]
388
+ if self.use_dask:
389
+ from dask.diagnostics import ProgressBar
390
+
391
+ with ProgressBar():
392
+ self.ds.load()
393
+
394
+ dataset_list = [self.ds]
367
395
  output_filenames = [str(filepath)]
368
396
 
369
397
  saved_filenames = save_datasets(
@@ -404,8 +432,8 @@ class TidalForcing:
404
432
  "TidalForcing": {
405
433
  "source": self.source,
406
434
  "ntides": self.ntides,
407
- "model_reference_date": self.model_reference_date.isoformat(),
408
435
  "allan_factor": self.allan_factor,
436
+ "model_reference_date": self.model_reference_date.isoformat(),
409
437
  }
410
438
  }
411
439
 
@@ -416,7 +444,7 @@ class TidalForcing:
416
444
  # Write header
417
445
  file.write(header)
418
446
  # Write YAML data
419
- yaml.dump(yaml_data, file, default_flow_style=False)
447
+ yaml.dump(yaml_data, file, default_flow_style=False, sort_keys=False)
420
448
 
421
449
  @classmethod
422
450
  def from_yaml(