roms-tools 1.4.1__py3-none-any.whl → 1.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 (252) hide show
  1. roms_tools/_version.py +1 -1
  2. roms_tools/setup/boundary_forcing.py +350 -166
  3. roms_tools/setup/datasets.py +57 -74
  4. roms_tools/setup/download.py +3 -6
  5. roms_tools/setup/fill.py +46 -18
  6. roms_tools/setup/grid.py +74 -113
  7. roms_tools/setup/initial_conditions.py +209 -76
  8. roms_tools/setup/regrid.py +198 -0
  9. roms_tools/setup/surface_forcing.py +167 -80
  10. roms_tools/setup/tides.py +135 -67
  11. roms_tools/setup/topography.py +9 -17
  12. roms_tools/setup/utils.py +251 -77
  13. roms_tools/setup/vertical_coordinate.py +4 -6
  14. roms_tools/tests/test_setup/test_boundary_forcing.py +6 -13
  15. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zattrs +1 -1
  16. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zmetadata +1 -1
  17. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_east/0.0.0 +0 -0
  18. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_north/0.0.0 +0 -0
  19. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_south/0.0.0 +0 -0
  20. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/0.0.0 +0 -0
  21. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_east/0.0.0 +0 -0
  22. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_north/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_north/0.0.0 +0 -0
  27. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_south/0.0.0 +0 -0
  28. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/0.0.0 +0 -0
  29. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_east/0.0.0 +0 -0
  30. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_north/0.0.0 +0 -0
  31. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_south/0.0.0 +0 -0
  32. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/0.0.0 +0 -0
  33. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_east/0.0.0 +0 -0
  34. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_north/0.0.0 +0 -0
  35. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_south/0.0.0 +0 -0
  36. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/0.0.0 +0 -0
  37. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_east/0.0.0 +0 -0
  38. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_north/0.0.0 +0 -0
  39. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_south/0.0.0 +0 -0
  40. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/0.0.0 +0 -0
  41. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_east/0.0.0 +0 -0
  42. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_north/0.0.0 +0 -0
  43. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_south/0.0.0 +0 -0
  44. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/0.0.0 +0 -0
  45. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_east/0.0.0 +0 -0
  46. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_north/0.0.0 +0 -0
  47. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_south/0.0.0 +0 -0
  48. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/0.0.0 +0 -0
  49. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_east/0.0.0 +0 -0
  50. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_north/0.0.0 +0 -0
  51. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_south/0.0.0 +0 -0
  52. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/0.0.0 +0 -0
  53. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_east/0.0.0 +0 -0
  54. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_north/0.0.0 +0 -0
  55. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_south/0.0.0 +0 -0
  56. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/0.0.0 +0 -0
  57. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_east/0.0.0 +0 -0
  58. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_north/0.0.0 +0 -0
  59. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_south/0.0.0 +0 -0
  60. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/0.0.0 +0 -0
  61. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_east/0.0.0 +0 -0
  62. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_north/0.0.0 +0 -0
  63. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_south/0.0.0 +0 -0
  64. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/0.0.0 +0 -0
  65. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_east/0.0.0 +0 -0
  66. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_north/0.0.0 +0 -0
  67. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_south/0.0.0 +0 -0
  68. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/0.0.0 +0 -0
  69. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_east/0.0.0 +0 -0
  70. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_north/0.0.0 +0 -0
  71. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_south/0.0.0 +0 -0
  72. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/0.0.0 +0 -0
  73. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_east/0.0.0 +0 -0
  74. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_north/0.0.0 +0 -0
  75. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_south/0.0.0 +0 -0
  76. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/0.0.0 +0 -0
  77. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_east/0.0.0 +0 -0
  78. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_north/0.0.0 +0 -0
  79. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_south/0.0.0 +0 -0
  80. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/0.0.0 +0 -0
  81. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_east/0.0.0 +0 -0
  82. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_north/0.0.0 +0 -0
  83. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_south/0.0.0 +0 -0
  84. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/0.0.0 +0 -0
  85. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_east/0.0.0 +0 -0
  86. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_north/0.0.0 +0 -0
  87. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_south/0.0.0 +0 -0
  88. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/0.0.0 +0 -0
  89. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_east/0.0.0 +0 -0
  90. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_north/0.0.0 +0 -0
  91. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_south/0.0.0 +0 -0
  92. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/0.0.0 +0 -0
  93. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_east/0.0.0 +0 -0
  94. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_north/0.0.0 +0 -0
  95. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_south/0.0.0 +0 -0
  96. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/0.0.0 +0 -0
  97. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_east/0.0.0 +0 -0
  98. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_north/0.0.0 +0 -0
  99. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_south/0.0.0 +0 -0
  100. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/0.0.0 +0 -0
  101. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_east/0.0.0 +0 -0
  102. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_north/0.0.0 +0 -0
  103. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_south/0.0.0 +0 -0
  104. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/0.0.0 +0 -0
  105. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_east/0.0.0 +0 -0
  106. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_north/0.0.0 +0 -0
  107. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_south/0.0.0 +0 -0
  108. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/0.0.0 +0 -0
  109. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_east/0.0.0 +0 -0
  110. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_north/0.0.0 +0 -0
  111. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_south/0.0.0 +0 -0
  112. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/0.0.0 +0 -0
  113. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_east/0.0.0 +0 -0
  114. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_north/0.0.0 +0 -0
  115. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_south/0.0.0 +0 -0
  116. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/0.0.0 +0 -0
  117. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_east/0.0.0 +0 -0
  118. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_north/0.0.0 +0 -0
  119. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_south/0.0.0 +0 -0
  120. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/0.0.0 +0 -0
  121. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_east/0.0.0 +0 -0
  122. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_north/0.0.0 +0 -0
  123. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_south/0.0.0 +0 -0
  124. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/0.0.0 +0 -0
  125. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_east/0.0.0 +0 -0
  126. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_north/0.0.0 +0 -0
  127. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_south/0.0.0 +0 -0
  128. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/0.0.0 +0 -0
  129. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_east/0.0.0 +0 -0
  130. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_north/0.0.0 +0 -0
  131. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_south/0.0.0 +0 -0
  132. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/0.0.0 +0 -0
  133. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_east/0.0.0 +0 -0
  134. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_north/0.0.0 +0 -0
  135. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_south/0.0.0 +0 -0
  136. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/0.0.0 +0 -0
  137. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_east/0.0.0 +0 -0
  138. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_north/0.0.0 +0 -0
  139. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_south/0.0.0 +0 -0
  140. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/0.0.0 +0 -0
  141. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_east/0.0.0 +0 -0
  142. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_north/0.0.0 +0 -0
  143. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_south/0.0.0 +0 -0
  144. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/0.0.0 +0 -0
  145. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zattrs +1 -1
  146. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zmetadata +1 -1
  147. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air_alt/0.0.0 +0 -0
  148. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zattrs +1 -1
  149. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zmetadata +1 -1
  150. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air_alt/0.0.0 +0 -0
  151. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zattrs +1 -1
  152. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +1 -1
  153. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/0.0.0 +0 -0
  154. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/0.0.0 +0 -0
  155. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/0.0.0 +0 -0
  156. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/0.0.0 +0 -0
  157. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/0.0.0 +0 -0
  158. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/0.0.0 +0 -0
  159. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/0.0.0 +0 -0
  160. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/0.0.0 +0 -0
  161. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/0.0.0 +0 -0
  162. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/0.0.0 +0 -0
  163. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/0.0.0 +0 -0
  164. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/0.0.0 +0 -0
  165. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/0.0 +0 -0
  166. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/0.0 +0 -0
  167. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/0.0 +0 -0
  168. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/0.0 +0 -0
  169. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/0.0.0 +0 -0
  170. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/0.0.0 +0 -0
  171. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/0.0.0 +0 -0
  172. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/0.0.0 +0 -0
  173. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/0.0 +0 -0
  174. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/0.0 +0 -0
  175. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/0.0 +0 -0
  176. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/0.0 +0 -0
  177. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/0.0 +0 -0
  178. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
  179. roms_tools/tests/test_setup/test_data/grid.zarr/.zattrs +2 -2
  180. roms_tools/tests/test_setup/test_data/grid.zarr/.zmetadata +2 -62
  181. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zattrs +2 -2
  182. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zmetadata +2 -62
  183. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zattrs +1 -1
  184. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zmetadata +1 -1
  185. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK/0.0.0.0 +0 -0
  186. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK_ALT_CO2/0.0.0.0 +0 -0
  187. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC/0.0.0.0 +0 -0
  188. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC_ALT_CO2/0.0.0.0 +0 -0
  189. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOC/0.0.0.0 +0 -0
  190. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOCr/0.0.0.0 +0 -0
  191. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DON/0.0.0.0 +0 -0
  192. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DONr/0.0.0.0 +0 -0
  193. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOP/0.0.0.0 +0 -0
  194. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOPr/0.0.0.0 +0 -0
  195. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Fe/0.0.0.0 +0 -0
  196. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Lig/0.0.0.0 +0 -0
  197. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NH4/0.0.0.0 +0 -0
  198. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NO3/0.0.0.0 +0 -0
  199. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/O2/0.0.0.0 +0 -0
  200. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/PO4/0.0.0.0 +0 -0
  201. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/SiO3/0.0.0.0 +0 -0
  202. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatC/0.0.0.0 +0 -0
  203. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatChl/0.0.0.0 +0 -0
  204. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatFe/0.0.0.0 +0 -0
  205. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatP/0.0.0.0 +0 -0
  206. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatSi/0.0.0.0 +0 -0
  207. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazC/0.0.0.0 +0 -0
  208. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazChl/0.0.0.0 +0 -0
  209. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazFe/0.0.0.0 +0 -0
  210. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazP/0.0.0.0 +0 -0
  211. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/salt/0.0.0.0 +0 -0
  212. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spC/0.0.0.0 +0 -0
  213. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spCaCO3/0.0.0.0 +0 -0
  214. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spChl/0.0.0.0 +0 -0
  215. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spFe/0.0.0.0 +0 -0
  216. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spP/0.0.0.0 +0 -0
  217. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/temp/0.0.0.0 +0 -0
  218. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/u/0.0.0.0 +0 -0
  219. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ubar/0.0.0 +0 -0
  220. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/v/0.0.0.0 +0 -0
  221. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/vbar/0.0.0 +0 -0
  222. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zeta/0.0.0 +0 -0
  223. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zooC/0.0.0.0 +0 -0
  224. roms_tools/tests/test_setup/test_datasets.py +8 -18
  225. roms_tools/tests/test_setup/test_fill.py +43 -14
  226. roms_tools/tests/test_setup/test_grid.py +9 -9
  227. roms_tools/tests/test_setup/test_initial_conditions.py +4 -7
  228. roms_tools/tests/test_setup/test_regrid.py +59 -0
  229. roms_tools/tests/test_setup/test_surface_forcing.py +74 -56
  230. roms_tools/tests/test_setup/test_tides.py +6 -10
  231. roms_tools/tests/test_setup/test_topography.py +2 -4
  232. roms_tools/tests/test_setup/test_vertical_coordinate.py +2 -6
  233. roms_tools/tests/test_utils.py +30 -30
  234. roms_tools/utils.py +6 -7
  235. {roms_tools-1.4.1.dist-info → roms_tools-1.5.0.dist-info}/METADATA +2 -2
  236. {roms_tools-1.4.1.dist-info → roms_tools-1.5.0.dist-info}/RECORD +239 -250
  237. roms_tools/setup/mixins.py +0 -231
  238. roms_tools/tests/test_setup/test_data/grid.zarr/lat_psi/.zarray +0 -22
  239. roms_tools/tests/test_setup/test_data/grid.zarr/lat_psi/.zattrs +0 -8
  240. roms_tools/tests/test_setup/test_data/grid.zarr/lat_psi/0.0 +0 -0
  241. roms_tools/tests/test_setup/test_data/grid.zarr/lon_psi/.zarray +0 -22
  242. roms_tools/tests/test_setup/test_data/grid.zarr/lon_psi/.zattrs +0 -8
  243. roms_tools/tests/test_setup/test_data/grid.zarr/lon_psi/0.0 +0 -0
  244. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_psi/.zarray +0 -22
  245. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_psi/.zattrs +0 -8
  246. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_psi/0.0 +0 -0
  247. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_psi/.zarray +0 -22
  248. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_psi/.zattrs +0 -8
  249. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_psi/0.0 +0 -0
  250. {roms_tools-1.4.1.dist-info → roms_tools-1.5.0.dist-info}/LICENSE +0 -0
  251. {roms_tools-1.4.1.dist-info → roms_tools-1.5.0.dist-info}/WHEEL +0 -0
  252. {roms_tools-1.4.1.dist-info → roms_tools-1.5.0.dist-info}/top_level.txt +0 -0
@@ -12,17 +12,23 @@ from roms_tools.setup.utils import (
12
12
  substitute_nans_by_fillvalue,
13
13
  get_variable_metadata,
14
14
  save_datasets,
15
+ get_target_coords,
16
+ rotate_velocities,
17
+ compute_barotropic_velocity,
18
+ _extrapolate_deepest_to_bottom,
19
+ transpose_dimensions,
15
20
  )
16
- from roms_tools.setup.mixins import ROMSToolsMixins
21
+ from roms_tools.setup.fill import _lateral_fill
22
+ from roms_tools.setup.regrid import _lateral_regrid, _vertical_regrid
17
23
  from roms_tools.setup.plot import _plot, _section_plot, _profile_plot, _line_plot
18
24
  import matplotlib.pyplot as plt
19
25
  from pathlib import Path
20
26
 
21
27
 
22
28
  @dataclass(frozen=True, kw_only=True)
23
- class InitialConditions(ROMSToolsMixins):
24
- """
25
- Represents initial conditions for ROMS, including physical and biogeochemical data.
29
+ class InitialConditions:
30
+ """Represents initial conditions for ROMS, including physical and biogeochemical
31
+ data.
26
32
 
27
33
  Parameters
28
34
  ----------
@@ -32,27 +38,33 @@ class InitialConditions(ROMSToolsMixins):
32
38
  The date and time at which the initial conditions are set.
33
39
  If no exact match is found, the closest time entry to `ini_time` within the time range [ini_time, ini_time + 24 hours] is selected.
34
40
  source : Dict[str, Union[str, Path, List[Union[str, Path]]], bool]
35
- Dictionary specifying the source of the physical initial condition data:
36
- - "name" (str): Name of the data source (e.g., "GLORYS").
37
- - "path" (Union[str, Path, List[Union[str, Path]]]): The path to the raw data file(s). Can be a single string (with or without wildcards),
38
- a single Path object, or a list of strings or Path objects containing multiple files.
39
- - "climatology" (bool): Indicates if the physical data is climatology data. Defaults to False.
40
- bgc_source : Optional[Dict[str, Union[str, Path, List[Union[str, Path]]], bool]]
41
- Dictionary specifying the source of the biogeochemical (BGC) initial condition data:
42
- - "name" (str): Name of the BGC data source (e.g., "CESM_REGRIDDED").
43
- - "path" (Union[str, Path, List[Union[str, Path]]]): The path to the raw data file(s). Can be a single string (with or without wildcards),
44
- a single Path object, or a list of strings or Path objects containing multiple files.
45
- - "climatology" (bool): Indicates if the BGC data is climatology data. Defaults to False.
41
+
42
+ Dictionary specifying the source of the physical initial condition data. Keys include:
43
+
44
+ - "name" (str): Name of the data source (e.g., "GLORYS").
45
+ - "path" (Union[str, Path, List[Union[str, Path]]]): The path to the raw data file(s). This can be:
46
+
47
+ - A single string (with or without wildcards).
48
+ - A single Path object.
49
+ - A list of strings or Path objects containing multiple files.
50
+ - "climatology" (bool): Indicates if the data is climatology data. Defaults to False.
51
+
52
+ bgc_source : Dict[str, Union[str, Path, List[Union[str, Path]]], bool]
53
+ Dictionary specifying the source of the biogeochemical (BGC) initial condition data. Keys include:
54
+
55
+ - "name" (str): Name of the data source (e.g., "CESM_REGRIDDED").
56
+ - "path" (Union[str, Path, List[Union[str, Path]]]): The path to the raw data file(s). This can be:
57
+
58
+ - A single string (with or without wildcards).
59
+ - A single Path object.
60
+ - A list of strings or Path objects containing multiple files.
61
+ - "climatology" (bool): Indicates if the data is climatology data. Defaults to False.
62
+
46
63
  model_reference_date : datetime, optional
47
64
  The reference date for the model. Defaults to January 1, 2000.
48
65
  use_dask: bool, optional
49
66
  Indicates whether to use dask for processing. If True, data is processed with dask; if False, data is processed eagerly. Defaults to False.
50
67
 
51
- Attributes
52
- ----------
53
- ds : xr.Dataset
54
- Xarray Dataset containing the initial condition data loaded from the specified files.
55
-
56
68
  Examples
57
69
  --------
58
70
  >>> initial_conditions = InitialConditions(
@@ -79,42 +91,15 @@ class InitialConditions(ROMSToolsMixins):
79
91
  def __post_init__(self):
80
92
 
81
93
  self._input_checks()
82
- lon, lat, angle, straddle = super().get_target_lon_lat()
83
94
 
84
- data = self._get_data()
85
- data.choose_subdomain(
86
- latitude_range=[lat.min().values, lat.max().values],
87
- longitude_range=[lon.min().values, lon.max().values],
88
- margin=2,
89
- straddle=straddle,
90
- )
91
-
92
- vars_2d = ["zeta"]
93
- vars_3d = ["temp", "salt", "u", "v"]
94
- data_vars = super().regrid_data(data, vars_2d, vars_3d, lon, lat)
95
- data_vars = super().process_velocities(data_vars, angle, "u", "v")
95
+ data_vars = {}
96
+ data_vars = self._process_data(data_vars, type="physics")
96
97
 
97
98
  if self.bgc_source is not None:
98
- bgc_data = self._get_bgc_data()
99
- bgc_data.choose_subdomain(
100
- latitude_range=[lat.min().values, lat.max().values],
101
- longitude_range=[lon.min().values, lon.max().values],
102
- margin=2,
103
- straddle=straddle,
104
- )
105
-
106
- vars_2d = []
107
- vars_3d = bgc_data.var_names.keys()
108
- bgc_data_vars = super().regrid_data(bgc_data, vars_2d, vars_3d, lon, lat)
109
-
110
- # Ensure time coordinate matches that of physical variables
111
- for var in bgc_data_vars.keys():
112
- bgc_data_vars[var] = bgc_data_vars[var].assign_coords(
113
- {"time": data_vars["temp"]["time"]}
114
- )
99
+ data_vars = self._process_data(data_vars, type="bgc")
115
100
 
116
- # Combine data variables from physical and biogeochemical sources
117
- data_vars.update(bgc_data_vars)
101
+ for var in data_vars.keys():
102
+ data_vars[var] = transpose_dimensions(data_vars[var])
118
103
 
119
104
  d_meta = get_variable_metadata()
120
105
  ds = self._write_into_dataset(data_vars, d_meta)
@@ -131,6 +116,80 @@ class InitialConditions(ROMSToolsMixins):
131
116
 
132
117
  object.__setattr__(self, "ds", ds)
133
118
 
119
+ def _process_data(self, data_vars, type="physics"):
120
+
121
+ target_coords = get_target_coords(self.grid)
122
+
123
+ if type == "physics":
124
+ data = self._get_data()
125
+ else:
126
+ data = self._get_bgc_data()
127
+
128
+ data.choose_subdomain(
129
+ latitude_range=[
130
+ target_coords["lat"].min().values,
131
+ target_coords["lat"].max().values,
132
+ ],
133
+ longitude_range=[
134
+ target_coords["lon"].min().values,
135
+ target_coords["lon"].max().values,
136
+ ],
137
+ margin=2,
138
+ straddle=target_coords["straddle"],
139
+ )
140
+
141
+ variable_info = self._set_variable_info(data, type=type)
142
+
143
+ data_vars = _extrapolate_deepest_to_bottom(data_vars, data)
144
+
145
+ data_vars = _lateral_fill(data_vars, data)
146
+
147
+ # lateral regridding
148
+ var_names = variable_info.keys()
149
+ data_vars = _lateral_regrid(
150
+ data, target_coords["lon"], target_coords["lat"], data_vars, var_names
151
+ )
152
+
153
+ # rotation of velocities and interpolation to u/v points
154
+ if "u" in variable_info and "v" in variable_info:
155
+ (data_vars["u"], data_vars["v"],) = rotate_velocities(
156
+ data_vars["u"],
157
+ data_vars["v"],
158
+ target_coords["angle"],
159
+ interpolate=True,
160
+ )
161
+
162
+ # vertical regridding
163
+ for location in ["rho", "u", "v"]:
164
+ var_names = [
165
+ name
166
+ for name, info in variable_info.items()
167
+ if info["location"] == location and info["is_3d"]
168
+ ]
169
+ if len(var_names) > 0:
170
+ data_vars = _vertical_regrid(
171
+ data,
172
+ self.grid.ds[f"layer_depth_{location}"],
173
+ data_vars,
174
+ var_names,
175
+ )
176
+
177
+ # compute barotropic velocities
178
+ if "u" in variable_info and "v" in variable_info:
179
+ for var in ["u", "v"]:
180
+ data_vars[f"{var}bar"] = compute_barotropic_velocity(
181
+ data_vars[var], self.grid.ds[f"interface_depth_{var}"]
182
+ )
183
+
184
+ if type == "bgc":
185
+ # Ensure time coordinate matches that of physical variables
186
+ for var in variable_info.keys():
187
+ data_vars[var] = data_vars[var].assign_coords(
188
+ {"time": data_vars["temp"]["time"]}
189
+ )
190
+
191
+ return data_vars
192
+
134
193
  def _input_checks(self):
135
194
 
136
195
  if "name" not in self.source.keys():
@@ -195,6 +254,71 @@ class InitialConditions(ROMSToolsMixins):
195
254
 
196
255
  return data
197
256
 
257
+ def _set_variable_info(self, data, type="physics"):
258
+ """Sets up a dictionary with metadata for variables based on the type.
259
+
260
+ The dictionary contains the following information:
261
+ - `location`: Where the variable resides in the grid (e.g., rho, u, or v points).
262
+ - `is_vector`: Whether the variable is part of a vector (True for velocity components like 'u' and 'v').
263
+ - `vector_pair`: For vector variables, this indicates the associated variable that forms the vector (e.g., 'u' and 'v').
264
+ - `is_3d`: Indicates whether the variable is 3D (True for variables like 'temp' and 'salt') or 2D (False for 'zeta').
265
+
266
+ Returns
267
+ -------
268
+ dict
269
+ A dictionary where the keys are variable names and the values are dictionaries of metadata
270
+ about each variable, including 'location', 'is_vector', 'vector_pair', and 'is_3d'.
271
+ """
272
+ default_info = {
273
+ "location": "rho",
274
+ "is_vector": False,
275
+ "vector_pair": None,
276
+ "is_3d": True,
277
+ }
278
+
279
+ # Define a dictionary for variable names and their associated information
280
+ if type == "physics":
281
+ variable_info = {
282
+ "zeta": {
283
+ "location": "rho",
284
+ "is_vector": False,
285
+ "vector_pair": None,
286
+ "is_3d": False,
287
+ },
288
+ "temp": default_info,
289
+ "salt": default_info,
290
+ "u": {
291
+ "location": "u",
292
+ "is_vector": True,
293
+ "vector_pair": "v",
294
+ "is_3d": True,
295
+ },
296
+ "v": {
297
+ "location": "v",
298
+ "is_vector": True,
299
+ "vector_pair": "u",
300
+ "is_3d": True,
301
+ },
302
+ "ubar": {
303
+ "location": "u",
304
+ "is_vector": True,
305
+ "vector_pair": "vbar",
306
+ "is_3d": False,
307
+ },
308
+ "vbar": {
309
+ "location": "v",
310
+ "is_vector": True,
311
+ "vector_pair": "ubar",
312
+ "is_3d": False,
313
+ },
314
+ }
315
+ elif type == "bgc":
316
+ variable_info = {}
317
+ for var in data.var_names.keys():
318
+ variable_info[var] = default_info
319
+
320
+ return variable_info
321
+
198
322
  def _write_into_dataset(self, data_vars, d_meta):
199
323
 
200
324
  # save in new dataset
@@ -216,12 +340,16 @@ class InitialConditions(ROMSToolsMixins):
216
340
  "s_rho",
217
341
  "lat_rho",
218
342
  "lon_rho",
219
- "layer_depth_rho",
220
- "interface_depth_rho",
221
343
  "lat_u",
222
344
  "lon_u",
223
345
  "lat_v",
224
346
  "lon_v",
347
+ "layer_depth_rho",
348
+ "interface_depth_rho",
349
+ "layer_depth_u",
350
+ "interface_depth_u",
351
+ "layer_depth_v",
352
+ "interface_depth_v",
225
353
  ]
226
354
  existing_vars = [var for var in variables_to_drop if var in ds]
227
355
  ds = ds.drop_vars(existing_vars)
@@ -277,13 +405,13 @@ class InitialConditions(ROMSToolsMixins):
277
405
  depth_contours=False,
278
406
  layer_contours=False,
279
407
  ) -> None:
280
- """
281
- Plot the initial conditions field for a given eta-, xi-, or s_rho-slice.
408
+ """Plot the initial conditions field for a given eta-, xi-, or s_rho- slice.
282
409
 
283
410
  Parameters
284
411
  ----------
285
412
  varname : str
286
413
  The name of the initial conditions field to plot. Options include:
414
+
287
415
  - "temp": Potential temperature.
288
416
  - "salt": Salinity.
289
417
  - "zeta": Free surface.
@@ -324,6 +452,7 @@ class InitialConditions(ROMSToolsMixins):
324
452
  - "diazC": Diazotroph Carbon (mmol/m³).
325
453
  - "diazP": Diazotroph Phosphorus (mmol/m³).
326
454
  - "diazFe": Diazotroph Iron (mmol/m³).
455
+
327
456
  s : int, optional
328
457
  The index of the vertical layer (`s_rho`) to plot. If not specified, the plot
329
458
  will represent a horizontal slice (eta- or xi- plane). Default is None.
@@ -354,7 +483,6 @@ class InitialConditions(ROMSToolsMixins):
354
483
  If the specified `varname` is not one of the valid options.
355
484
  If the field specified by `varname` is 3D and none of `s`, `eta`, or `xi` are specified.
356
485
  If the field specified by `varname` is 2D and both `eta` and `xi` are specified.
357
-
358
486
  """
359
487
 
360
488
  if len(self.ds[varname].squeeze().dims) == 3 and not any(
@@ -375,7 +503,7 @@ class InitialConditions(ROMSToolsMixins):
375
503
  if all(dim in field.dims for dim in ["eta_rho", "xi_rho"]):
376
504
  interface_depth = self.grid.ds.interface_depth_rho
377
505
  layer_depth = self.grid.ds.layer_depth_rho
378
- field = field.where(self.grid.ds.mask_rho)
506
+ mask = self.grid.ds.mask_rho
379
507
  field = field.assign_coords(
380
508
  {"lon": self.grid.ds.lon_rho, "lat": self.grid.ds.lat_rho}
381
509
  )
@@ -383,7 +511,7 @@ class InitialConditions(ROMSToolsMixins):
383
511
  elif all(dim in field.dims for dim in ["eta_rho", "xi_u"]):
384
512
  interface_depth = self.grid.ds.interface_depth_u
385
513
  layer_depth = self.grid.ds.layer_depth_u
386
- field = field.where(self.grid.ds.mask_u)
514
+ mask = self.grid.ds.mask_u
387
515
  field = field.assign_coords(
388
516
  {"lon": self.grid.ds.lon_u, "lat": self.grid.ds.lat_u}
389
517
  )
@@ -391,7 +519,7 @@ class InitialConditions(ROMSToolsMixins):
391
519
  elif all(dim in field.dims for dim in ["eta_v", "xi_rho"]):
392
520
  interface_depth = self.grid.ds.interface_depth_v
393
521
  layer_depth = self.grid.ds.layer_depth_v
394
- field = field.where(self.grid.ds.mask_v)
522
+ mask = self.grid.ds.mask_v
395
523
  field = field.assign_coords(
396
524
  {"lon": self.grid.ds.lon_v, "lat": self.grid.ds.lat_v}
397
525
  )
@@ -413,14 +541,16 @@ class InitialConditions(ROMSToolsMixins):
413
541
  title = title + f", eta_rho = {field.eta_rho[eta].item()}"
414
542
  field = field.isel(eta_rho=eta)
415
543
  layer_depth = layer_depth.isel(eta_rho=eta)
416
- field = field.assign_coords({"layer_depth": layer_depth})
417
544
  interface_depth = interface_depth.isel(eta_rho=eta)
545
+ if "s_rho" in field.dims:
546
+ field = field.assign_coords({"layer_depth": layer_depth})
418
547
  elif "eta_v" in field.dims:
419
548
  title = title + f", eta_v = {field.eta_v[eta].item()}"
420
549
  field = field.isel(eta_v=eta)
421
550
  layer_depth = layer_depth.isel(eta_v=eta)
422
- field = field.assign_coords({"layer_depth": layer_depth})
423
551
  interface_depth = interface_depth.isel(eta_v=eta)
552
+ if "s_rho" in field.dims:
553
+ field = field.assign_coords({"layer_depth": layer_depth})
424
554
  else:
425
555
  raise ValueError(
426
556
  f"None of the expected dimensions (eta_rho, eta_v) found in ds[{varname}]."
@@ -430,14 +560,16 @@ class InitialConditions(ROMSToolsMixins):
430
560
  title = title + f", xi_rho = {field.xi_rho[xi].item()}"
431
561
  field = field.isel(xi_rho=xi)
432
562
  layer_depth = layer_depth.isel(xi_rho=xi)
433
- field = field.assign_coords({"layer_depth": layer_depth})
434
563
  interface_depth = interface_depth.isel(xi_rho=xi)
564
+ if "s_rho" in field.dims:
565
+ field = field.assign_coords({"layer_depth": layer_depth})
435
566
  elif "xi_u" in field.dims:
436
567
  title = title + f", xi_u = {field.xi_u[xi].item()}"
437
568
  field = field.isel(xi_u=xi)
438
569
  layer_depth = layer_depth.isel(xi_u=xi)
439
- field = field.assign_coords({"layer_depth": layer_depth})
440
570
  interface_depth = interface_depth.isel(xi_u=xi)
571
+ if "s_rho" in field.dims:
572
+ field = field.assign_coords({"layer_depth": layer_depth})
441
573
  else:
442
574
  raise ValueError(
443
575
  f"None of the expected dimensions (xi_rho, xi_u) found in ds[{varname}]."
@@ -461,7 +593,7 @@ class InitialConditions(ROMSToolsMixins):
461
593
  if eta is None and xi is None:
462
594
  _plot(
463
595
  self.grid.ds,
464
- field=field,
596
+ field=field.where(mask),
465
597
  straddle=self.grid.straddle,
466
598
  depth_contours=depth_contours,
467
599
  title=title,
@@ -492,17 +624,19 @@ class InitialConditions(ROMSToolsMixins):
492
624
  def save(
493
625
  self, filepath: Union[str, Path], np_eta: int = None, np_xi: int = None
494
626
  ) -> None:
495
- """
496
- Save the initial conditions information to a netCDF4 file.
627
+ """Save the initial conditions information to a netCDF4 file.
497
628
 
498
629
  This method supports saving the dataset in two modes:
499
630
 
500
- 1. **Single File Mode (default)**:
501
- - If both `np_eta` and `np_xi` are `None`, the entire dataset is saved as a single file at the specified `filepath.nc`.
631
+ 1. **Single File Mode (default)**:
502
632
 
503
- 2. **Partitioned Mode**:
504
- - If either `np_eta` or `np_xi` is specified, the dataset is divided into spatial tiles along the eta-axis and xi-axis.
505
- - The files are saved as `filepath.0.nc`, `filepath.1.nc`, ..., where the numbering corresponds to the partition index.
633
+ If both `np_eta` and `np_xi` are `None`, the entire dataset is saved as a single netCDF4 file
634
+ with the base filename specified by `filepath.nc`.
635
+
636
+ 2. **Partitioned Mode**:
637
+
638
+ - If either `np_eta` or `np_xi` is specified, the dataset is divided into spatial tiles along the eta-axis and xi-axis.
639
+ - Each spatial tile is saved as a separate netCDF4 file.
506
640
 
507
641
  Parameters
508
642
  ----------
@@ -536,8 +670,8 @@ class InitialConditions(ROMSToolsMixins):
536
670
  return saved_filenames
537
671
 
538
672
  def to_yaml(self, filepath: Union[str, Path]) -> None:
539
- """
540
- Export the parameters of the class to a YAML file, including the version of roms-tools.
673
+ """Export the parameters of the class to a YAML file, including the version of
674
+ roms-tools.
541
675
 
542
676
  Parameters
543
677
  ----------
@@ -588,8 +722,7 @@ class InitialConditions(ROMSToolsMixins):
588
722
  def from_yaml(
589
723
  cls, filepath: Union[str, Path], use_dask: bool = False
590
724
  ) -> "InitialConditions":
591
- """
592
- Create an instance of the InitialConditions class from a YAML file.
725
+ """Create an instance of the InitialConditions class from a YAML file.
593
726
 
594
727
  Parameters
595
728
  ----------
@@ -0,0 +1,198 @@
1
+ import xarray as xr
2
+
3
+
4
+ class LateralRegrid:
5
+ """Applies lateral fill and regridding to data.
6
+
7
+ This class fills missing values in ocean data and interpolates it onto a new grid
8
+ defined by the provided longitude and latitude.
9
+
10
+ Parameters
11
+ ----------
12
+ data : DataContainer
13
+ Container with variables to be interpolated, including a `mask` and dimension names.
14
+ lon : xarray.DataArray
15
+ Target longitude coordinates.
16
+ lat : xarray.DataArray
17
+ Target latitude coordinates.
18
+ """
19
+
20
+ def __init__(self, data, lon, lat):
21
+ """Initializes the lateral fill and target grid coordinates.
22
+
23
+ Parameters
24
+ ----------
25
+ data : DataContainer
26
+ Data with dimensions and mask for filling.
27
+ lon : xarray.DataArray
28
+ Longitude for new grid.
29
+ lat : xarray.DataArray
30
+ Latitude for new grid.
31
+ """
32
+
33
+ self.coords = {
34
+ data.dim_names["latitude"]: lat,
35
+ data.dim_names["longitude"]: lon,
36
+ }
37
+
38
+ def apply(self, var):
39
+ """Fills missing values and regrids the variable.
40
+
41
+ Parameters
42
+ ----------
43
+ var : xarray.DataArray
44
+ Input data to fill and regrid.
45
+
46
+ Returns
47
+ -------
48
+ xarray.DataArray
49
+ Regridded data with filled values.
50
+ """
51
+ regridded = var.interp(self.coords, method="linear").drop_vars(
52
+ list(self.coords.keys())
53
+ )
54
+ return regridded
55
+
56
+
57
+ class VerticalRegrid:
58
+ """Performs vertical interpolation of data onto new depth coordinates.
59
+
60
+ Parameters
61
+ ----------
62
+ data : DataContainer
63
+ Container holding the data to be regridded, with relevant dimension names.
64
+ target_depth : xarray.DataArray
65
+ Target depth coordinates for interpolation.
66
+ """
67
+
68
+ def __init__(self, data, target_depth):
69
+ """Initializes vertical regridding with specified depth coordinates.
70
+
71
+ Parameters
72
+ ----------
73
+ data : DataContainer
74
+ Container holding the data to be regridded, with relevant dimension names.
75
+ target_depth : xarray.DataArray
76
+ Target depth coordinates for interpolation.
77
+ """
78
+
79
+ self.depth_dim = data.dim_names["depth"]
80
+ dims = {"dim": self.depth_dim}
81
+
82
+ dlev = data.ds[data.dim_names["depth"]] - target_depth
83
+ is_below = dlev == dlev.where(dlev >= 0).min(**dims)
84
+ is_above = dlev == dlev.where(dlev <= 0).max(**dims)
85
+ p_below = dlev.where(is_below).sum(**dims)
86
+ p_above = -dlev.where(is_above).sum(**dims)
87
+ denominator = p_below + p_above
88
+ denominator = denominator.where(denominator > 1e-6, 1e-6)
89
+ factor = p_below / denominator
90
+
91
+ upper_mask = is_above.sum(**dims) > 0
92
+ lower_mask = is_below.sum(**dims) > 0
93
+
94
+ self.coeff = xr.Dataset(
95
+ {
96
+ "is_below": is_below,
97
+ "is_above": is_above,
98
+ "upper_mask": upper_mask,
99
+ "lower_mask": lower_mask,
100
+ "factor": factor,
101
+ }
102
+ )
103
+
104
+ def apply(self, var, fill_nans=True):
105
+ """Interpolates the variable onto the new depth grid using precomputed
106
+ coefficients for linear interpolation between layers.
107
+
108
+ Parameters
109
+ ----------
110
+ var : xarray.DataArray
111
+ The input data to be regridded along the depth dimension. This should be
112
+ an array with the same depth coordinates as the original grid.
113
+ fill_nans : bool, optional
114
+ Whether to fill NaN values in the regridded data. If True (default),
115
+ forward-fill and backward-fill are applied along the 's_rho' dimension to
116
+ ensure there are no NaNs after interpolation.
117
+
118
+ Returns
119
+ -------
120
+ xarray.DataArray
121
+ The regridded data array, interpolated onto the new depth grid. NaN values
122
+ are replaced if `fill_nans=True`, with extrapolation allowed at the surface
123
+ and bottom layers to minimize gaps.
124
+ """
125
+
126
+ dims = {"dim": self.depth_dim}
127
+
128
+ var_below = var.where(self.coeff["is_below"]).sum(**dims)
129
+ var_above = var.where(self.coeff["is_above"]).sum(**dims)
130
+
131
+ result = var_below + (var_above - var_below) * self.coeff["factor"]
132
+ if fill_nans:
133
+ result = result.where(self.coeff["upper_mask"], var.isel({dims["dim"]: 0}))
134
+ result = result.where(self.coeff["lower_mask"], var.isel({dims["dim"]: -1}))
135
+ else:
136
+ result = result.where(self.coeff["upper_mask"]).where(
137
+ self.coeff["lower_mask"]
138
+ )
139
+
140
+ return result
141
+
142
+
143
+ def _lateral_regrid(data, lon, lat, data_vars, var_names):
144
+ """Laterally regrid specified variables onto new latitude and longitude coordinates.
145
+
146
+ Parameters
147
+ ----------
148
+ data : Dataset
149
+ Input data containing the information about source dimensions.
150
+ lon : xarray.DataArray
151
+ Target longitude coordinates.
152
+ lat : xarray.DataArray
153
+ Target latitude coordinates.
154
+ data_vars : dict of str : xarray.DataArray
155
+ Dictionary of variables to regrid.
156
+ var_names : list of str
157
+ Names of variables to regrid.
158
+
159
+ Returns
160
+ -------
161
+ dict of str : xarray.DataArray
162
+ Updated data_vars with regridded variables.
163
+ """
164
+ lateral_regrid = LateralRegrid(data, lon, lat)
165
+
166
+ for var_name in var_names:
167
+ if var_name in data_vars:
168
+ data_vars[var_name] = lateral_regrid.apply(data_vars[var_name])
169
+
170
+ return data_vars
171
+
172
+
173
+ def _vertical_regrid(data, target_depth, data_vars, var_names):
174
+ """Vertically regrid specified variables onto new depth coordinates.
175
+
176
+ Parameters
177
+ ----------
178
+ data : Dataset
179
+ Input dataset containing the variables and source depth information.
180
+ target_depth : xarray.DataArray
181
+ Target depth coordinates for regridding.
182
+ data_vars : dict of str : xarray.DataArray
183
+ Dictionary of variables to be regridded.
184
+ var_names : list of str
185
+ Names of variables to regrid.
186
+
187
+ Returns
188
+ -------
189
+ dict of str : xarray.DataArray
190
+ Updated data_vars with variables regridded onto the target depth coordinates.
191
+ """
192
+ vertical_regrid = VerticalRegrid(data, target_depth)
193
+
194
+ for var_name in var_names:
195
+ if var_name in data_vars:
196
+ data_vars[var_name] = vertical_regrid.apply(data_vars[var_name])
197
+
198
+ return data_vars