roms-tools 2.3.0__py3-none-any.whl → 2.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 (303) hide show
  1. ci/environment.yml +1 -0
  2. roms_tools/__init__.py +2 -1
  3. roms_tools/analysis/roms_output.py +81 -98
  4. roms_tools/plot.py +4 -2
  5. roms_tools/setup/boundary_forcing.py +207 -208
  6. roms_tools/setup/datasets.py +149 -33
  7. roms_tools/setup/grid.py +35 -102
  8. roms_tools/setup/initial_conditions.py +179 -132
  9. roms_tools/setup/nesting.py +239 -86
  10. roms_tools/setup/river_forcing.py +266 -128
  11. roms_tools/setup/surface_forcing.py +137 -76
  12. roms_tools/setup/tides.py +10 -36
  13. roms_tools/setup/topography.py +25 -2
  14. roms_tools/setup/utils.py +52 -82
  15. roms_tools/tests/test_analysis/test_roms_output.py +233 -70
  16. roms_tools/tests/test_setup/test_boundary_forcing.py +283 -57
  17. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zattrs +3 -1
  18. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zmetadata +3 -1
  19. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_east/0.0.0 +0 -0
  20. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_south/0.0.0 +0 -0
  21. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/0.0.0 +0 -0
  22. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_east/0.0.0 +0 -0
  23. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_south/0.0.0 +0 -0
  24. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/0.0.0 +0 -0
  25. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_east/0.0.0 +0 -0
  26. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_south/0.0.0 +0 -0
  27. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/0.0.0 +0 -0
  28. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_east/0.0.0 +0 -0
  29. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_south/0.0.0 +0 -0
  30. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/0.0.0 +0 -0
  31. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_east/0.0.0 +0 -0
  32. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_south/0.0.0 +0 -0
  33. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/0.0.0 +0 -0
  34. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_east/0.0.0 +0 -0
  35. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_south/0.0.0 +0 -0
  36. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/0.0.0 +0 -0
  37. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_east/0.0.0 +0 -0
  38. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_south/0.0.0 +0 -0
  39. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/0.0.0 +0 -0
  40. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_east/0.0.0 +0 -0
  41. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_south/0.0.0 +0 -0
  42. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/0.0.0 +0 -0
  43. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_east/0.0.0 +0 -0
  44. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_south/0.0.0 +0 -0
  45. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/0.0.0 +0 -0
  46. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_east/0.0.0 +0 -0
  47. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_south/0.0.0 +0 -0
  48. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/0.0.0 +0 -0
  49. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_east/0.0.0 +0 -0
  50. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_south/0.0.0 +0 -0
  51. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/0.0.0 +0 -0
  52. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_east/0.0.0 +0 -0
  53. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_south/0.0.0 +0 -0
  54. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/0.0.0 +0 -0
  55. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_east/0.0.0 +0 -0
  56. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_north/0.0.0 +0 -0
  57. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_south/0.0.0 +0 -0
  58. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/0.0.0 +0 -0
  59. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_east/0.0.0 +0 -0
  60. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_south/0.0.0 +0 -0
  61. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/0.0.0 +0 -0
  62. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_east/0.0.0 +0 -0
  63. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_south/0.0.0 +0 -0
  64. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/0.0.0 +0 -0
  65. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_east/0.0.0 +0 -0
  66. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_south/0.0.0 +0 -0
  67. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/0.0.0 +0 -0
  68. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_east/0.0.0 +0 -0
  69. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_south/0.0.0 +0 -0
  70. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/0.0.0 +0 -0
  71. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_east/0.0.0 +0 -0
  72. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_north/0.0.0 +0 -0
  73. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_south/0.0.0 +0 -0
  74. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/0.0.0 +0 -0
  75. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_east/0.0.0 +0 -0
  76. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_north/0.0.0 +0 -0
  77. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_south/0.0.0 +0 -0
  78. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/0.0.0 +0 -0
  79. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_east/0.0.0 +0 -0
  80. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_north/0.0.0 +0 -0
  81. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_south/0.0.0 +0 -0
  82. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/0.0.0 +0 -0
  83. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_east/0.0.0 +0 -0
  84. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_north/0.0.0 +0 -0
  85. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_south/0.0.0 +0 -0
  86. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/0.0.0 +0 -0
  87. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_east/0.0.0 +0 -0
  88. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_north/0.0.0 +0 -0
  89. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_south/0.0.0 +0 -0
  90. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/0.0.0 +0 -0
  91. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_east/0.0.0 +0 -0
  92. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_north/0.0.0 +0 -0
  93. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_south/0.0.0 +0 -0
  94. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/0.0.0 +0 -0
  95. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_east/0.0.0 +0 -0
  96. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_north/0.0.0 +0 -0
  97. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_south/0.0.0 +0 -0
  98. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/0.0.0 +0 -0
  99. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_east/0.0.0 +0 -0
  100. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_north/0.0.0 +0 -0
  101. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_south/0.0.0 +0 -0
  102. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/0.0.0 +0 -0
  103. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_east/0.0.0 +0 -0
  104. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_north/0.0.0 +0 -0
  105. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_south/0.0.0 +0 -0
  106. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/0.0.0 +0 -0
  107. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_east/0.0.0 +0 -0
  108. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_north/0.0.0 +0 -0
  109. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_south/0.0.0 +0 -0
  110. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/0.0.0 +0 -0
  111. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_east/0.0.0 +0 -0
  112. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_north/0.0.0 +0 -0
  113. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_south/0.0.0 +0 -0
  114. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/0.0.0 +0 -0
  115. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_east/0.0.0 +0 -0
  116. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_north/0.0.0 +0 -0
  117. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_south/0.0.0 +0 -0
  118. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/0.0.0 +0 -0
  119. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_east/0.0.0 +0 -0
  120. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_north/0.0.0 +0 -0
  121. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_south/0.0.0 +0 -0
  122. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/0.0.0 +0 -0
  123. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_east/0.0.0 +0 -0
  124. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_north/0.0.0 +0 -0
  125. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_south/0.0.0 +0 -0
  126. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/0.0.0 +0 -0
  127. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_east/0.0.0 +0 -0
  128. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_north/0.0.0 +0 -0
  129. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_south/0.0.0 +0 -0
  130. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/0.0.0 +0 -0
  131. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zattrs +2 -2
  132. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zmetadata +8 -7
  133. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/abs_time/.zattrs +1 -0
  134. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/dust/0.0.0 +0 -0
  135. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/dust_time/.zattrs +1 -1
  136. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/iron/0.0.0 +0 -0
  137. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/iron_time/.zattrs +1 -1
  138. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nhy/0.0.0 +0 -0
  139. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nhy_time/.zattrs +1 -1
  140. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nox/0.0.0 +0 -0
  141. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nox_time/.zattrs +1 -1
  142. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air/0.0.0 +0 -0
  143. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air_alt/0.0.0 +0 -0
  144. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_time/.zattrs +1 -1
  145. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zattrs +2 -2
  146. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zmetadata +2 -2
  147. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/dust/0.0.0 +0 -0
  148. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/iron/0.0.0 +0 -0
  149. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nhy/0.0.0 +0 -0
  150. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nox/0.0.0 +0 -0
  151. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air/0.0.0 +0 -0
  152. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air_alt/0.0.0 +0 -0
  153. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zattrs +5 -3
  154. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +156 -121
  155. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zarray +2 -2
  156. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zattrs +2 -1
  157. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/0 +0 -0
  158. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/.zarray +2 -2
  159. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/.zattrs +1 -1
  160. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/0 +0 -0
  161. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/.zarray +4 -4
  162. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/0.0.0 +0 -0
  163. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/.zarray +4 -4
  164. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/0.0.0 +0 -0
  165. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/.zarray +4 -4
  166. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/0.0.0 +0 -0
  167. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/.zarray +4 -4
  168. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/0.0.0 +0 -0
  169. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/.zarray +4 -4
  170. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/0.0.0 +0 -0
  171. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/.zarray +4 -4
  172. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/0.0.0 +0 -0
  173. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/.zarray +4 -4
  174. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/0.0.0 +0 -0
  175. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/.zarray +4 -4
  176. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/0.0.0 +0 -0
  177. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/.zarray +4 -4
  178. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/0.0.0 +0 -0
  179. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/.zarray +4 -4
  180. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/0.0.0 +0 -0
  181. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/.zarray +4 -4
  182. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/0.0.0 +0 -0
  183. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/.zarray +4 -4
  184. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/0.0.0 +0 -0
  185. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/.zarray +4 -4
  186. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/0.0 +0 -0
  187. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/.zarray +4 -4
  188. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/0.0 +0 -0
  189. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/.zarray +4 -4
  190. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/0.0 +0 -0
  191. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/.zarray +4 -4
  192. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/0.0 +0 -0
  193. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/.zarray +4 -4
  194. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/0.0.0 +0 -0
  195. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/.zarray +4 -4
  196. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/0.0.0 +0 -0
  197. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/.zarray +4 -4
  198. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/0.0.0 +0 -0
  199. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/.zarray +4 -4
  200. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/0.0.0 +0 -0
  201. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/.zarray +4 -4
  202. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/0.0 +0 -0
  203. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/.zarray +4 -4
  204. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/0.0 +0 -0
  205. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/.zarray +4 -4
  206. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/0.0 +0 -0
  207. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/.zarray +4 -4
  208. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/0.0 +0 -0
  209. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/.zarray +4 -4
  210. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/.zattrs +8 -0
  211. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/0.0 +0 -0
  212. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/.zarray +4 -4
  213. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/.zattrs +8 -0
  214. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/0.0 +0 -0
  215. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zarray +4 -4
  216. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zattrs +8 -0
  217. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
  218. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/.zarray +4 -4
  219. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/.zattrs +8 -0
  220. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/0.0 +0 -0
  221. roms_tools/tests/test_setup/test_data/grid.zarr/.zattrs +1 -1
  222. roms_tools/tests/test_setup/test_data/grid.zarr/.zmetadata +2 -2
  223. roms_tools/tests/test_setup/test_data/grid.zarr/angle/0.0 +0 -0
  224. roms_tools/tests/test_setup/test_data/grid.zarr/angle_coarse/0.0 +0 -0
  225. roms_tools/tests/test_setup/test_data/grid.zarr/f/0.0 +0 -0
  226. roms_tools/tests/test_setup/test_data/grid.zarr/h/.zattrs +1 -1
  227. roms_tools/tests/test_setup/test_data/grid.zarr/h/0.0 +0 -0
  228. roms_tools/tests/test_setup/test_data/grid.zarr/lat_coarse/0.0 +0 -0
  229. roms_tools/tests/test_setup/test_data/grid.zarr/lat_rho/0.0 +0 -0
  230. roms_tools/tests/test_setup/test_data/grid.zarr/lat_u/0.0 +0 -0
  231. roms_tools/tests/test_setup/test_data/grid.zarr/lat_v/0.0 +0 -0
  232. roms_tools/tests/test_setup/test_data/grid.zarr/pm/0.0 +0 -0
  233. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zattrs +4 -4
  234. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zmetadata +4 -4
  235. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/angle/0.0 +0 -0
  236. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/angle_coarse/0.0 +0 -0
  237. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/f/0.0 +0 -0
  238. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/h/0.0 +0 -0
  239. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_coarse/0.0 +0 -0
  240. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_rho/0.0 +0 -0
  241. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_u/0.0 +0 -0
  242. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_v/0.0 +0 -0
  243. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_coarse/0.0 +0 -0
  244. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_rho/0.0 +0 -0
  245. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_u/0.0 +0 -0
  246. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_v/0.0 +0 -0
  247. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_coarse/0.0 +0 -0
  248. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_rho/0.0 +0 -0
  249. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_u/0.0 +0 -0
  250. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_v/0.0 +0 -0
  251. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/pm/0.0 +0 -0
  252. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/pn/0.0 +0 -0
  253. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zattrs +2 -1
  254. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zmetadata +6 -4
  255. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Cs_r/.zattrs +1 -1
  256. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Cs_w/.zattrs +1 -1
  257. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NH4/0.0.0.0 +0 -0
  258. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NO3/0.0.0.0 +0 -0
  259. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/PO4/0.0.0.0 +0 -0
  260. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/abs_time/.zattrs +1 -0
  261. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatSi/0.0.0.0 +0 -0
  262. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ocean_time/.zattrs +1 -1
  263. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/salt/0.0.0.0 +0 -0
  264. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spC/0.0.0.0 +0 -0
  265. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spCaCO3/0.0.0.0 +0 -0
  266. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spFe/0.0.0.0 +0 -0
  267. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/temp/0.0.0.0 +0 -0
  268. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/u/0.0.0.0 +0 -0
  269. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ubar/0.0.0 +0 -0
  270. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/v/0.0.0.0 +0 -0
  271. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/vbar/0.0.0 +0 -0
  272. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zeta/0.0.0 +0 -0
  273. roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/.zmetadata +56 -0
  274. roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/nriver/.zarray +20 -0
  275. roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/nriver/.zattrs +6 -0
  276. roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/nriver/0 +0 -0
  277. roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/.zarray +22 -0
  278. roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/.zattrs +8 -0
  279. roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/0.0 +0 -0
  280. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/.zmetadata +56 -0
  281. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/.zarray +20 -0
  282. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/.zattrs +6 -0
  283. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/0 +0 -0
  284. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/.zarray +22 -0
  285. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/.zattrs +8 -0
  286. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/0.0 +0 -0
  287. roms_tools/tests/test_setup/test_grid.py +0 -13
  288. roms_tools/tests/test_setup/test_initial_conditions.py +220 -66
  289. roms_tools/tests/test_setup/test_nesting.py +139 -118
  290. roms_tools/tests/test_setup/test_river_forcing.py +583 -293
  291. roms_tools/tests/test_setup/test_surface_forcing.py +149 -73
  292. roms_tools/tests/test_setup/test_tides.py +4 -16
  293. roms_tools/tests/test_setup/test_utils.py +1 -0
  294. roms_tools/tests/test_setup/test_validation.py +34 -2
  295. roms_tools/tests/{test_utils.py → test_tiling/test_partition.py} +1 -1
  296. roms_tools/tiling/partition.py +338 -0
  297. roms_tools/utils.py +66 -333
  298. roms_tools/vertical_coordinate.py +54 -133
  299. {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/METADATA +1 -1
  300. {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/RECORD +303 -290
  301. {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/WHEEL +1 -1
  302. {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/LICENSE +0 -0
  303. {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/top_level.txt +0 -0
roms_tools/utils.py CHANGED
@@ -1,340 +1,8 @@
1
- from numbers import Integral
2
-
3
- import numpy as np
4
1
  import xarray as xr
5
- from typing import Union
6
2
  from pathlib import Path
7
3
  import re
8
4
  import glob
9
-
10
-
11
- def partition(
12
- ds: xr.Dataset, np_eta: int = 1, np_xi: int = 1
13
- ) -> tuple[list[int], list[xr.Dataset]]:
14
- """Partition a ROMS (Regional Ocean Modeling System) dataset into smaller spatial
15
- tiles.
16
-
17
- This function divides the input dataset into `np_eta` by `np_xi` tiles, where each tile
18
- represents a subdomain of the original dataset. The partitioning is performed along
19
- the spatial dimensions `eta_rho`, `xi_rho`, `eta_v`, `xi_u`, `eta_psi`, `xi_psi`, `eta_coarse`, and `xi_coarse`,
20
- depending on which dimensions are present in the dataset.
21
-
22
- Parameters
23
- ----------
24
- ds : xr.Dataset
25
- The input ROMS dataset that is to be partitioned.
26
-
27
- np_eta : int, optional
28
- The number of partitions along the `eta` direction. Must be a positive integer. Default is 1.
29
-
30
- np_xi : int, optional
31
- The number of partitions along the `xi` direction. Must be a positive integer. Default is 1.
32
-
33
- Returns
34
- -------
35
- tuple[list[int], list[xr.Dataset]]
36
- A tuple containing two elements:
37
-
38
- - A list of integers representing the file numbers associated with each partition.
39
- - A list of `xarray.Dataset` objects, each representing a partitioned subdomain of the original dataset.
40
-
41
- Raises
42
- ------
43
- ValueError
44
- If `np_eta` or `np_xi` is not a positive integer, or if the dataset cannot be evenly partitioned
45
- into the specified number of tiles.
46
-
47
-
48
- Example
49
- -------
50
- >>> partitioned_file_numbers, partitioned_datasets = partition(
51
- ... ds, np_eta=2, np_xi=3
52
- ... )
53
- >>> print(partitioned_file_numbers)
54
- [0, 1, 2, 3, 4, 5]
55
- >>> print([ds.sizes for ds in partitioned_datasets])
56
- [{'eta_rho': 50, 'xi_rho': 50}, {'eta_rho': 50, 'xi_rho': 50}, ...]
57
-
58
- This example partitions the dataset into 2 tiles along the `eta` direction and 3 tiles
59
- along the `xi` direction, resulting in a total of 6 partitions.
60
- """
61
-
62
- if (
63
- not isinstance(np_eta, Integral)
64
- or np_eta < 1
65
- or not isinstance(np_xi, Integral)
66
- or np_xi < 1
67
- ):
68
- raise ValueError("np_eta and np_xi must be positive integers")
69
-
70
- partitionable_dims_maybe_present = [
71
- "eta_rho",
72
- "xi_rho",
73
- "eta_v",
74
- "xi_u",
75
- "eta_psi",
76
- "xi_psi",
77
- "eta_coarse",
78
- "xi_coarse",
79
- ]
80
- dims_to_partition = [d for d in partitionable_dims_maybe_present if d in ds.dims]
81
-
82
- # if eta is periodic there are no ghost cells along those dimensions
83
- if "eta_v" in ds.sizes and ds.sizes["eta_rho"] == ds.sizes["eta_v"]:
84
- # TODO how are we supposed to know if eta is periodic if eta_v doesn't appear? partit.F doesn't say...
85
- n_eta_ghost_cells = 0
86
- else:
87
- n_eta_ghost_cells = 1
88
-
89
- # if xi is periodic there are no ghost cells along those dimensions
90
- if "xi_u" in ds.sizes and ds.sizes["xi_rho"] == ds.sizes["xi_u"]:
91
- n_xi_ghost_cells = 0
92
- else:
93
- n_xi_ghost_cells = 1
94
-
95
- def integer_division_or_raise(a: int, b: int, dimension: str) -> int:
96
- """Perform integer division and ensure that the division is exact.
97
-
98
- Parameters
99
- ----------
100
- a : int
101
- The numerator for the division.
102
- b : int
103
- The denominator for the division.
104
- dimension : str
105
- The name of the dimension being partitioned, used for error reporting.
106
-
107
- Returns
108
- -------
109
- int
110
- The result of the integer division.
111
-
112
- Raises
113
- ------
114
- ValueError
115
- If the division is not exact, indicating that the domain cannot be evenly divided
116
- along the specified dimension.
117
- """
118
- remainder = a % b
119
- if remainder == 0:
120
- return a // b
121
- else:
122
- raise ValueError(
123
- f"Dimension '{dimension}' of size {a} cannot be evenly divided into {b} partitions."
124
- )
125
-
126
- if "eta_rho" in dims_to_partition:
127
- eta_rho_domain_size = integer_division_or_raise(
128
- ds.sizes["eta_rho"] - 2 * n_eta_ghost_cells, np_eta, "eta_rho"
129
- )
130
-
131
- if "xi_rho" in dims_to_partition:
132
- xi_rho_domain_size = integer_division_or_raise(
133
- ds.sizes["xi_rho"] - 2 * n_xi_ghost_cells, np_xi, "xi_rho"
134
- )
135
-
136
- if "eta_v" in dims_to_partition:
137
- eta_v_domain_size = integer_division_or_raise(
138
- ds.sizes["eta_v"] - 1 * n_eta_ghost_cells, np_eta, "eta_v"
139
- )
140
-
141
- if "xi_u" in dims_to_partition:
142
- xi_u_domain_size = integer_division_or_raise(
143
- ds.sizes["xi_u"] - 1 * n_xi_ghost_cells, np_xi, "xi_u"
144
- )
145
-
146
- if "eta_psi" in dims_to_partition:
147
- eta_psi_domain_size = integer_division_or_raise(
148
- ds.sizes["eta_psi"] - 3 * n_eta_ghost_cells, np_eta, "eta_psi"
149
- )
150
-
151
- if "xi_psi" in dims_to_partition:
152
- xi_psi_domain_size = integer_division_or_raise(
153
- ds.sizes["xi_psi"] - 3 * n_xi_ghost_cells, np_xi, "xi_psi"
154
- )
155
-
156
- if "eta_coarse" in dims_to_partition:
157
- eta_coarse_domain_size = integer_division_or_raise(
158
- ds.sizes["eta_coarse"] - 2 * n_eta_ghost_cells, np_eta, "eta_coarse"
159
- )
160
- if "xi_coarse" in dims_to_partition:
161
- xi_coarse_domain_size = integer_division_or_raise(
162
- ds.sizes["xi_coarse"] - 2 * n_xi_ghost_cells, np_xi, "xi_coarse"
163
- )
164
-
165
- # unpartitioned dimensions should have sizes unchanged
166
- partitioned_sizes = {
167
- dim: [size] for dim, size in ds.sizes.items() if dim in dims_to_partition
168
- }
169
-
170
- # TODO refactor to use two functions for odd- and even-length dimensions
171
- if "eta_v" in dims_to_partition:
172
- partitioned_sizes["eta_v"] = [eta_v_domain_size] * (np_eta - 1) + [
173
- eta_v_domain_size + n_eta_ghost_cells
174
- ]
175
- if "xi_u" in dims_to_partition:
176
- partitioned_sizes["xi_u"] = [xi_u_domain_size] * (np_xi - 1) + [
177
- xi_u_domain_size + n_xi_ghost_cells
178
- ]
179
-
180
- if np_eta > 1:
181
- if "eta_rho" in dims_to_partition:
182
- partitioned_sizes["eta_rho"] = (
183
- [eta_rho_domain_size + n_eta_ghost_cells]
184
- + [eta_rho_domain_size] * (np_eta - 2)
185
- + [eta_rho_domain_size + n_eta_ghost_cells]
186
- )
187
- if "eta_psi" in dims_to_partition:
188
- partitioned_sizes["eta_psi"] = (
189
- [n_eta_ghost_cells + eta_psi_domain_size]
190
- + [eta_psi_domain_size] * (np_eta - 2)
191
- + [eta_psi_domain_size + 2 * n_eta_ghost_cells]
192
- )
193
- if "eta_coarse" in dims_to_partition:
194
- partitioned_sizes["eta_coarse"] = (
195
- [eta_coarse_domain_size + n_eta_ghost_cells]
196
- + [eta_coarse_domain_size] * (np_eta - 2)
197
- + [eta_coarse_domain_size + n_eta_ghost_cells]
198
- )
199
-
200
- if np_xi > 1:
201
- if "xi_rho" in dims_to_partition:
202
- partitioned_sizes["xi_rho"] = (
203
- [xi_rho_domain_size + n_xi_ghost_cells]
204
- + [xi_rho_domain_size] * (np_xi - 2)
205
- + [xi_rho_domain_size + n_xi_ghost_cells]
206
- )
207
- if "xi_psi" in dims_to_partition:
208
- partitioned_sizes["xi_psi"] = (
209
- [n_xi_ghost_cells + xi_psi_domain_size]
210
- + [xi_psi_domain_size] * (np_xi - 2)
211
- + [xi_psi_domain_size + 2 * n_xi_ghost_cells]
212
- )
213
- if "xi_coarse" in dims_to_partition:
214
- partitioned_sizes["xi_coarse"] = (
215
- [xi_coarse_domain_size + n_xi_ghost_cells]
216
- + [xi_coarse_domain_size] * (np_xi - 2)
217
- + [xi_coarse_domain_size + n_xi_ghost_cells]
218
- )
219
-
220
- def cumsum(pmf):
221
- """Implementation of cumsum which ensures the result starts with zero."""
222
- cdf = np.empty(len(pmf) + 1, dtype=int)
223
- cdf[0] = 0
224
- np.cumsum(pmf, out=cdf[1:])
225
- return cdf
226
-
227
- file_numbers = []
228
- partitioned_datasets = []
229
- for i in range(np_eta):
230
- for j in range(np_xi):
231
- file_number = j + (i * np_xi)
232
- file_numbers.append(file_number)
233
-
234
- indexers = {}
235
-
236
- if "eta_rho" in dims_to_partition:
237
- eta_rho_partition_indices = cumsum(partitioned_sizes["eta_rho"])
238
- indexers["eta_rho"] = slice(
239
- int(eta_rho_partition_indices[i]),
240
- int(eta_rho_partition_indices[i + 1]),
241
- )
242
- if "xi_rho" in dims_to_partition:
243
- xi_rho_partition_indices = cumsum(partitioned_sizes["xi_rho"])
244
- indexers["xi_rho"] = slice(
245
- int(xi_rho_partition_indices[j]),
246
- int(xi_rho_partition_indices[j + 1]),
247
- )
248
-
249
- if "eta_v" in dims_to_partition:
250
- eta_v_partition_indices = cumsum(partitioned_sizes["eta_v"])
251
- indexers["eta_v"] = slice(
252
- int(eta_v_partition_indices[i]),
253
- int(eta_v_partition_indices[i + 1]),
254
- )
255
- if "xi_u" in dims_to_partition:
256
- xi_u_partition_indices = cumsum(partitioned_sizes["xi_u"])
257
- indexers["xi_u"] = slice(
258
- int(xi_u_partition_indices[j]), int(xi_u_partition_indices[j + 1])
259
- )
260
- if "eta_psi" in dims_to_partition:
261
- eta_psi_partition_indices = cumsum(partitioned_sizes["eta_psi"])
262
- indexers["eta_psi"] = slice(
263
- int(eta_psi_partition_indices[i]),
264
- int(eta_psi_partition_indices[i + 1]),
265
- )
266
- if "xi_psi" in dims_to_partition:
267
- xi_psi_partition_indices = cumsum(partitioned_sizes["xi_psi"])
268
- indexers["xi_psi"] = slice(
269
- int(xi_psi_partition_indices[j]),
270
- int(xi_psi_partition_indices[j + 1]),
271
- )
272
-
273
- if "eta_coarse" in dims_to_partition:
274
- eta_coarse_partition_indices = cumsum(partitioned_sizes["eta_coarse"])
275
- indexers["eta_coarse"] = slice(
276
- int(eta_coarse_partition_indices[i]),
277
- int(eta_coarse_partition_indices[i + 1]),
278
- )
279
-
280
- if "xi_coarse" in dims_to_partition:
281
- xi_coarse_partition_indices = cumsum(partitioned_sizes["xi_coarse"])
282
- indexers["xi_coarse"] = slice(
283
- int(xi_coarse_partition_indices[j]),
284
- int(xi_coarse_partition_indices[j + 1]),
285
- )
286
-
287
- partitioned_ds = ds.isel(**indexers)
288
-
289
- partitioned_datasets.append(partitioned_ds)
290
-
291
- return file_numbers, partitioned_datasets
292
-
293
-
294
- def partition_netcdf(
295
- filepath: Union[str, Path], np_eta: int = 1, np_xi: int = 1
296
- ) -> None:
297
- """Partition a ROMS NetCDF file into smaller spatial tiles and save them to disk.
298
-
299
- This function divides the dataset in the specified NetCDF file into `np_eta` by `np_xi` tiles.
300
- Each tile is saved as a separate NetCDF file.
301
-
302
- Parameters
303
- ----------
304
- filepath : Union[str, Path]
305
- The path to the input NetCDF file.
306
-
307
- np_eta : int, optional
308
- The number of partitions along the `eta` direction. Must be a positive integer. Default is 1.
309
-
310
- np_xi : int, optional
311
- The number of partitions along the `xi` direction. Must be a positive integer. Default is 1.
312
-
313
- Returns
314
- -------
315
- List[Path]
316
- A list of Path objects for the filenames that were saved.
317
- """
318
-
319
- # Ensure filepath is a Path object
320
- filepath = Path(filepath)
321
-
322
- # Open the dataset
323
- ds = xr.open_dataset(filepath.with_suffix(".nc"))
324
-
325
- # Partition the dataset
326
- file_numbers, partitioned_datasets = partition(ds, np_eta=np_eta, np_xi=np_xi)
327
-
328
- # Generate paths to the partitioned files
329
- base_filepath = filepath.with_suffix("")
330
- paths_to_partitioned_files = [
331
- Path(f"{base_filepath}.{file_number}.nc") for file_number in file_numbers
332
- ]
333
-
334
- # Save the partitioned datasets to files
335
- xr.save_mfdataset(partitioned_datasets, paths_to_partitioned_files)
336
-
337
- return paths_to_partitioned_files
5
+ import logging
338
6
 
339
7
 
340
8
  def _load_data(
@@ -634,3 +302,68 @@ def transpose_dimensions(da: xr.DataArray) -> xr.DataArray:
634
302
  transposed_da = da.transpose(*new_order)
635
303
 
636
304
  return transposed_da
305
+
306
+
307
+ def save_datasets(dataset_list, output_filenames, use_dask=False, verbose=True):
308
+ """Save the list of datasets to netCDF4 files.
309
+
310
+ Parameters
311
+ ----------
312
+ dataset_list : list
313
+ List of datasets to be saved.
314
+ output_filenames : list
315
+ List of filenames for the output files.
316
+ use_dask : bool, optional
317
+ Whether to use Dask diagnostics (e.g., progress bars) when saving the datasets, by default False.
318
+ verbose : bool, optional
319
+ Whether to log information about the files being written. If True, logs the output filenames.
320
+ Defaults to True.
321
+
322
+ Returns
323
+ -------
324
+ List[Path]
325
+ A list of Path objects for the filenames that were saved.
326
+ """
327
+
328
+ saved_filenames = []
329
+
330
+ output_filenames = [f"{filename}.nc" for filename in output_filenames]
331
+ if verbose:
332
+ logging.info(
333
+ "Writing the following NetCDF files:\n%s", "\n".join(output_filenames)
334
+ )
335
+
336
+ if use_dask:
337
+ from dask.diagnostics import ProgressBar
338
+
339
+ with ProgressBar():
340
+ xr.save_mfdataset(dataset_list, output_filenames)
341
+ else:
342
+ xr.save_mfdataset(dataset_list, output_filenames)
343
+
344
+ saved_filenames.extend(Path(f) for f in output_filenames)
345
+
346
+ return saved_filenames
347
+
348
+
349
+ def get_dask_chunks(location, chunk_size):
350
+ """Returns the appropriate Dask chunking dictionary based on grid location.
351
+
352
+ Parameters
353
+ ----------
354
+ location : str
355
+ The grid location, one of "rho", "u", or "v".
356
+ chunk_size : int
357
+ The chunk size to apply.
358
+
359
+ Returns
360
+ -------
361
+ dict
362
+ Dictionary specifying the chunking strategy.
363
+ """
364
+ chunk_mapping = {
365
+ "rho": {"eta_rho": chunk_size, "xi_rho": chunk_size},
366
+ "u": {"eta_rho": chunk_size, "xi_u": chunk_size},
367
+ "v": {"eta_v": chunk_size, "xi_rho": chunk_size},
368
+ }
369
+ return chunk_mapping.get(location, {})
@@ -113,191 +113,112 @@ def compute_depth(zeta, h, hc, cs, sigma):
113
113
  return z
114
114
 
115
115
 
116
- def add_depth_coordinates_to_dataset(
117
- ds: "xr.Dataset",
118
- grid_ds: "xr.Dataset",
119
- depth_type: str,
120
- locations: list[str] = ["rho", "u", "v"],
121
- ) -> None:
122
- """Add computed vertical depth coordinates to a dataset for specified grid
123
- locations.
124
-
125
- This function computes vertical depth coordinates (layer or interface) and updates
126
- the provided dataset with these coordinates for the specified grid locations. If
127
- the dataset already contains depth coordinates for all specified locations, the function
128
- does nothing.
129
-
130
- Parameters
131
- ----------
132
- ds : xr.Dataset
133
- Target dataset to which computed depth coordinates will be added.
134
- If the `zeta` variable is not present, static vertical coordinates are used.
135
-
136
- grid_ds : xr.Dataset
137
- Grid dataset containing bathymetry, stretching curves, and parameters.
138
-
139
- depth_type : str
140
- Type of depth coordinates to compute. Options are:
141
- - "layer": Layer depth coordinates.
142
- - "interface": Interface depth coordinates.
143
-
144
- locations : list of str, optional
145
- List of locations for which to compute depth coordinates. Default is ["rho", "u", "v"].
146
- """
147
- required_vars = [f"{depth_type}_depth_{loc}" for loc in locations]
148
-
149
- if all(var in ds for var in required_vars):
150
- return # Depth coordinates already exist
151
-
152
- # Compute or interpolate depth coordinates
153
- if f"{depth_type}_depth_rho" in ds:
154
- depth_rho = ds[f"{depth_type}_depth_rho"]
155
- else:
156
- h = grid_ds["h"]
157
- zeta = ds.get("zeta", 0)
158
- if depth_type == "layer":
159
- Cs = grid_ds["Cs_r"]
160
- sigma = grid_ds["sigma_r"]
161
- elif depth_type == "interface":
162
- Cs = grid_ds["Cs_w"]
163
- sigma = grid_ds["sigma_w"]
164
- depth_rho = compute_depth(zeta, h, grid_ds.attrs["hc"], Cs, sigma)
165
- depth_rho.attrs.update(
166
- {"long_name": f"{depth_type} depth at rho-points", "units": "m"}
167
- )
168
- ds[f"{depth_type}_depth_rho"] = depth_rho
169
-
170
- # Interpolate depth to other locations
171
- for loc in locations:
172
- if loc == "rho":
173
- continue
174
-
175
- interp_func = (
176
- interpolate_from_rho_to_u if loc == "u" else interpolate_from_rho_to_v
177
- )
178
- depth_loc = interp_func(depth_rho)
179
- depth_loc.attrs.update(
180
- {"long_name": f"{depth_type} depth at {loc}-points", "units": "m"}
181
- )
182
- ds[f"{depth_type}_depth_{loc}"] = depth_loc
183
-
184
-
185
116
  def compute_depth_coordinates(
186
- ds: "xr.Dataset",
187
117
  grid_ds: "xr.Dataset",
188
- depth_type: str,
189
- location: str,
190
- s: int = None,
118
+ zeta: xr.DataArray | float = 0,
119
+ depth_type: str = "layer",
120
+ location: str = "rho",
191
121
  eta: int = None,
192
122
  xi: int = None,
193
123
  ) -> "xr.DataArray":
194
- """Compute vertical depth coordinates efficiently for a specified grid location and
195
- optional indices.
124
+ """Compute vertical depth coordinates for a given ROMS grid location.
196
125
 
197
- This function calculates vertical depth coordinates (layer or interface) for a given grid
198
- location (`rho`, `u`, or `v`). It performs spatial slicing (meridional or zonal) on the
199
- bathymetry and free-surface elevation (`zeta`) before computing depth coordinates. This
200
- approach minimizes computational overhead by reducing the dataset size before performing
201
- vertical coordinate calculations.
126
+ This function calculates depth coordinates (layer or interface) at a specified grid
127
+ location (`rho`, `u`, or `v`). It optimizes computations by slicing the bathymetry (`h`)
128
+ and free-surface elevation (`zeta`) before performing vertical coordinate calculations,
129
+ reducing memory usage and improving efficiency.
202
130
 
203
131
  Parameters
204
132
  ----------
205
- ds : xr.Dataset
206
- Dataset containing optional `zeta` (free-surface elevation). If `zeta` is not present,
207
- static vertical coordinates are computed.
208
-
209
133
  grid_ds : xr.Dataset
210
- Grid dataset containing bathymetry (`h`), stretching curves (`Cs`), and sigma-layer
211
- parameters (`sigma`). The attributes of this dataset should include the critical depth (`hc`).
134
+ ROMS grid dataset containing bathymetry (`h`), stretching curves (`Cs`),
135
+ and sigma-layer parameters (`sigma`). The dataset's attributes should include
136
+ the critical depth parameter (`hc`).
212
137
 
213
- depth_type : str
138
+ zeta : xr.DataArray or float, optional
139
+ Free-surface elevation. If set to `0` (default), the static sea level is assumed.
140
+
141
+ depth_type : str, optional
214
142
  Type of depth coordinates to compute:
215
- - `"layer"`: Depth at the center of layers.
143
+ - `"layer"` (default): Depth at the center of vertical layers.
216
144
  - `"interface"`: Depth at layer interfaces.
217
145
 
218
- location : str
219
- Grid location for the computation. Options are:
220
- - `"rho"`: Depth at rho points (cell centers).
221
- - `"u"`: Depth at u points (eastward velocity points).
222
- - `"v"`: Depth at v points (northward velocity points).
223
-
224
- s : int, optional
225
- Vertical index to extract a single layer or interface slice. If not provided, all vertical
226
- layers are included.
146
+ location : str, optional
147
+ Grid location for depth computation:
148
+ - `"rho"` (default): Depth at cell centers (rho points).
149
+ - `"u"`: Depth at eastward velocity points (u points).
150
+ - `"v"`: Depth at northward velocity points (v points).
227
151
 
228
152
  eta : int, optional
229
- Meridional (north-south) index to extract a slice. If not provided, all meridional indices
230
- are included.
153
+ Meridional (north-south) index to extract a zonal slice. If not provided,
154
+ all meridional indices are included.
231
155
 
232
156
  xi : int, optional
233
- Zonal (east-west) index to extract a slice. If not provided, all zonal indices are included.
157
+ Zonal (east-west) index to extract a meridional slice. If not provided,
158
+ all zonal indices are included.
234
159
 
235
160
  Returns
236
161
  -------
237
162
  xr.DataArray
238
- A DataArray containing the computed depth coordinates. If no indices are specified, the
239
- array will have the full dimensionality of the depth coordinates. The dimensions of the
240
- output depend on the provided indices:
241
- - Full 3D (or 4D if `zeta` includes time) depth coordinates if no indices are provided.
242
- - Reduced dimensionality for specified slices (e.g., 2D for a single vertical slice).
163
+ Computed depth coordinates. The shape of the output depends on the given indices:
164
+ - Full 3D (or 4D if `zeta` includes time) depth field if no indices are specified.
165
+ - 2D (or 3D if `zeta` includes time) slice if either `eta` or `xi` are specified.
166
+ - 1D (or 2D if `zeta` includes time) slice if both `eta` and `xi` are specified.
243
167
 
244
168
  Notes
245
169
  -----
246
- - To ensure computational efficiency, spatial slicing (based on `eta` and `xi`) is performed
247
- before computing depth coordinates. This reduces memory usage and processing time.
248
- - Depth coordinates are interpolated to the specified grid location (`rho`, `u`, or `v`) if
249
- necessary.
250
- - If depth coordinates for the specified location and configuration already exist in `ds`,
251
- they are not recomputed.
170
+ - The function first interpolates `h` and `zeta` to the specified grid location (`rho`, `u`, or `v`).
171
+ - Spatial slicing (`eta`, `xi`) is performed before depth computation to optimize efficiency.
172
+ - Depth calculations rely on the ROMS vertical stretching curves (`Cs`) and sigma-layers.
252
173
  """
253
174
 
175
+ # Select the appropriate depth computation parameters
176
+ if depth_type == "layer":
177
+ Cs = grid_ds["Cs_r"]
178
+ sigma = grid_ds["sigma_r"]
179
+ elif depth_type == "interface":
180
+ Cs = grid_ds["Cs_w"]
181
+ sigma = grid_ds["sigma_w"]
182
+ else:
183
+ raise ValueError(
184
+ f"Invalid depth_type: {depth_type}. Choose 'layer' or 'interface'."
185
+ )
186
+
254
187
  h = grid_ds["h"]
255
- zeta = ds.get("zeta", None)
256
188
 
257
189
  # Interpolate h and zeta to the specified location
258
190
  if location == "u":
259
191
  h = interpolate_from_rho_to_u(h)
260
- if zeta is not None:
192
+ if isinstance(zeta, xr.DataArray):
261
193
  zeta = interpolate_from_rho_to_u(zeta)
262
194
  elif location == "v":
263
195
  h = interpolate_from_rho_to_v(h)
264
- if zeta is not None:
196
+ if isinstance(zeta, xr.DataArray):
265
197
  zeta = interpolate_from_rho_to_v(zeta)
266
198
 
267
- # Slice spatially based on the location's specific dimensions
199
+ # Slice spatially based on indices
268
200
  if eta is not None:
269
201
  if location == "v":
270
202
  h = h.isel(eta_v=eta)
271
- if zeta is not None:
203
+ if isinstance(zeta, xr.DataArray):
272
204
  zeta = zeta.isel(eta_v=eta)
273
- else: # Default to "rho" or "u"
205
+ else: # Applies to "rho" or "u"
274
206
  h = h.isel(eta_rho=eta)
275
- if zeta is not None:
207
+ if isinstance(zeta, xr.DataArray):
276
208
  zeta = zeta.isel(eta_rho=eta)
209
+
277
210
  if xi is not None:
278
211
  if location == "u":
279
212
  h = h.isel(xi_u=xi)
280
- if zeta is not None:
213
+ if isinstance(zeta, xr.DataArray):
281
214
  zeta = zeta.isel(xi_u=xi)
282
- else: # Default to "rho" or "v"
215
+ else: # Applies to "rho" or "v"
283
216
  h = h.isel(xi_rho=xi)
284
- if zeta is not None:
217
+ if isinstance(zeta, xr.DataArray):
285
218
  zeta = zeta.isel(xi_rho=xi)
286
219
 
287
- # Compute depth
288
- if depth_type == "layer":
289
- Cs = grid_ds["Cs_r"]
290
- sigma = grid_ds["sigma_r"]
291
- elif depth_type == "interface":
292
- Cs = grid_ds["Cs_w"]
293
- sigma = grid_ds["sigma_w"]
294
220
  depth = compute_depth(zeta, h, grid_ds.attrs["hc"], Cs, sigma)
295
221
 
296
- # Slice vertically
297
- if s is not None:
298
- vertical_dim = "s_rho" if "s_rho" in depth.dims else "s_w"
299
- depth = depth.isel({vertical_dim: s})
300
-
301
222
  # Add metadata
302
223
  depth.attrs.update(
303
224
  {"long_name": f"{depth_type} depth at {location}-points", "units": "m"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: roms-tools
3
- Version: 2.3.0
3
+ Version: 2.5.0
4
4
  Summary: Tools for running and analysing UCLA-ROMS simulations
5
5
  Author-email: Nora Loose <nora.loose@gmail.com>, Thomas Nicholas <tom@cworthy.org>
6
6
  License: Apache-2