roms-tools 1.4.2__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 (223) hide show
  1. roms_tools/_version.py +1 -1
  2. roms_tools/setup/boundary_forcing.py +276 -99
  3. roms_tools/setup/datasets.py +19 -15
  4. roms_tools/setup/fill.py +38 -2
  5. roms_tools/setup/initial_conditions.py +170 -44
  6. roms_tools/setup/regrid.py +198 -0
  7. roms_tools/setup/surface_forcing.py +136 -51
  8. roms_tools/setup/tides.py +103 -31
  9. roms_tools/setup/utils.py +235 -40
  10. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zattrs +1 -1
  11. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zmetadata +1 -1
  12. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_east/0.0.0 +0 -0
  13. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_north/0.0.0 +0 -0
  14. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_south/0.0.0 +0 -0
  15. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/0.0.0 +0 -0
  16. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_east/0.0.0 +0 -0
  17. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_north/0.0.0 +0 -0
  18. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_south/0.0.0 +0 -0
  19. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/0.0.0 +0 -0
  20. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_east/0.0.0 +0 -0
  21. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_north/0.0.0 +0 -0
  22. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_south/0.0.0 +0 -0
  23. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/0.0.0 +0 -0
  24. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_east/0.0.0 +0 -0
  25. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_north/0.0.0 +0 -0
  26. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_south/0.0.0 +0 -0
  27. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/0.0.0 +0 -0
  28. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_east/0.0.0 +0 -0
  29. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_north/0.0.0 +0 -0
  30. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_south/0.0.0 +0 -0
  31. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/0.0.0 +0 -0
  32. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_east/0.0.0 +0 -0
  33. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_north/0.0.0 +0 -0
  34. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_south/0.0.0 +0 -0
  35. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/0.0.0 +0 -0
  36. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_east/0.0.0 +0 -0
  37. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_north/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_north/0.0.0 +0 -0
  42. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_south/0.0.0 +0 -0
  43. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/0.0.0 +0 -0
  44. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_east/0.0.0 +0 -0
  45. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_north/0.0.0 +0 -0
  46. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_south/0.0.0 +0 -0
  47. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/0.0.0 +0 -0
  48. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_east/0.0.0 +0 -0
  49. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_north/0.0.0 +0 -0
  50. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_south/0.0.0 +0 -0
  51. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/0.0.0 +0 -0
  52. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_east/0.0.0 +0 -0
  53. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_north/0.0.0 +0 -0
  54. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_south/0.0.0 +0 -0
  55. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/0.0.0 +0 -0
  56. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_east/0.0.0 +0 -0
  57. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_north/0.0.0 +0 -0
  58. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_south/0.0.0 +0 -0
  59. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/0.0.0 +0 -0
  60. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_east/0.0.0 +0 -0
  61. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_north/0.0.0 +0 -0
  62. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_south/0.0.0 +0 -0
  63. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/0.0.0 +0 -0
  64. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_east/0.0.0 +0 -0
  65. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_north/0.0.0 +0 -0
  66. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_south/0.0.0 +0 -0
  67. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/0.0.0 +0 -0
  68. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_east/0.0.0 +0 -0
  69. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_north/0.0.0 +0 -0
  70. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_south/0.0.0 +0 -0
  71. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/0.0.0 +0 -0
  72. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_east/0.0.0 +0 -0
  73. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_north/0.0.0 +0 -0
  74. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_south/0.0.0 +0 -0
  75. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/0.0.0 +0 -0
  76. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_east/0.0.0 +0 -0
  77. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_north/0.0.0 +0 -0
  78. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_south/0.0.0 +0 -0
  79. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/0.0.0 +0 -0
  80. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_east/0.0.0 +0 -0
  81. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_north/0.0.0 +0 -0
  82. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_south/0.0.0 +0 -0
  83. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/0.0.0 +0 -0
  84. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_east/0.0.0 +0 -0
  85. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_north/0.0.0 +0 -0
  86. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_south/0.0.0 +0 -0
  87. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/0.0.0 +0 -0
  88. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_east/0.0.0 +0 -0
  89. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_north/0.0.0 +0 -0
  90. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_south/0.0.0 +0 -0
  91. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/0.0.0 +0 -0
  92. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_east/0.0.0 +0 -0
  93. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_north/0.0.0 +0 -0
  94. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_south/0.0.0 +0 -0
  95. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/0.0.0 +0 -0
  96. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_east/0.0.0 +0 -0
  97. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_north/0.0.0 +0 -0
  98. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_south/0.0.0 +0 -0
  99. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/0.0.0 +0 -0
  100. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_east/0.0.0 +0 -0
  101. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_north/0.0.0 +0 -0
  102. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_south/0.0.0 +0 -0
  103. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/0.0.0 +0 -0
  104. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_east/0.0.0 +0 -0
  105. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_north/0.0.0 +0 -0
  106. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_south/0.0.0 +0 -0
  107. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/0.0.0 +0 -0
  108. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_east/0.0.0 +0 -0
  109. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_north/0.0.0 +0 -0
  110. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_south/0.0.0 +0 -0
  111. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/0.0.0 +0 -0
  112. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_east/0.0.0 +0 -0
  113. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_north/0.0.0 +0 -0
  114. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_south/0.0.0 +0 -0
  115. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/0.0.0 +0 -0
  116. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_east/0.0.0 +0 -0
  117. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_north/0.0.0 +0 -0
  118. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_south/0.0.0 +0 -0
  119. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/0.0.0 +0 -0
  120. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_east/0.0.0 +0 -0
  121. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_north/0.0.0 +0 -0
  122. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_south/0.0.0 +0 -0
  123. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/0.0.0 +0 -0
  124. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_east/0.0.0 +0 -0
  125. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_north/0.0.0 +0 -0
  126. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_south/0.0.0 +0 -0
  127. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/0.0.0 +0 -0
  128. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_east/0.0.0 +0 -0
  129. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_north/0.0.0 +0 -0
  130. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_south/0.0.0 +0 -0
  131. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/0.0.0 +0 -0
  132. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_east/0.0.0 +0 -0
  133. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_north/0.0.0 +0 -0
  134. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_south/0.0.0 +0 -0
  135. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/0.0.0 +0 -0
  136. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_east/0.0.0 +0 -0
  137. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_north/0.0.0 +0 -0
  138. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_south/0.0.0 +0 -0
  139. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/0.0.0 +0 -0
  140. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zattrs +1 -1
  141. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zmetadata +1 -1
  142. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air_alt/0.0.0 +0 -0
  143. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zattrs +1 -1
  144. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zmetadata +1 -1
  145. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air_alt/0.0.0 +0 -0
  146. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zattrs +1 -1
  147. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +1 -1
  148. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/0.0.0 +0 -0
  149. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/0.0.0 +0 -0
  150. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/0.0.0 +0 -0
  151. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/0.0.0 +0 -0
  152. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/0.0.0 +0 -0
  153. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/0.0.0 +0 -0
  154. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/0.0.0 +0 -0
  155. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/0.0.0 +0 -0
  156. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/0.0.0 +0 -0
  157. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/0.0.0 +0 -0
  158. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/0.0.0 +0 -0
  159. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/0.0.0 +0 -0
  160. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/0.0 +0 -0
  161. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/0.0 +0 -0
  162. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/0.0 +0 -0
  163. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/0.0 +0 -0
  164. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/0.0.0 +0 -0
  165. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/0.0.0 +0 -0
  166. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/0.0.0 +0 -0
  167. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/0.0.0 +0 -0
  168. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/0.0 +0 -0
  169. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/0.0 +0 -0
  170. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/0.0 +0 -0
  171. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/0.0 +0 -0
  172. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/0.0 +0 -0
  173. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
  174. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zattrs +1 -1
  175. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zmetadata +1 -1
  176. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK/0.0.0.0 +0 -0
  177. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK_ALT_CO2/0.0.0.0 +0 -0
  178. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC/0.0.0.0 +0 -0
  179. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC_ALT_CO2/0.0.0.0 +0 -0
  180. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOC/0.0.0.0 +0 -0
  181. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOCr/0.0.0.0 +0 -0
  182. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DON/0.0.0.0 +0 -0
  183. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DONr/0.0.0.0 +0 -0
  184. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOP/0.0.0.0 +0 -0
  185. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOPr/0.0.0.0 +0 -0
  186. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Fe/0.0.0.0 +0 -0
  187. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Lig/0.0.0.0 +0 -0
  188. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NH4/0.0.0.0 +0 -0
  189. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NO3/0.0.0.0 +0 -0
  190. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/O2/0.0.0.0 +0 -0
  191. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/PO4/0.0.0.0 +0 -0
  192. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/SiO3/0.0.0.0 +0 -0
  193. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatC/0.0.0.0 +0 -0
  194. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatChl/0.0.0.0 +0 -0
  195. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatFe/0.0.0.0 +0 -0
  196. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatP/0.0.0.0 +0 -0
  197. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatSi/0.0.0.0 +0 -0
  198. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazC/0.0.0.0 +0 -0
  199. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazChl/0.0.0.0 +0 -0
  200. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazFe/0.0.0.0 +0 -0
  201. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazP/0.0.0.0 +0 -0
  202. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/salt/0.0.0.0 +0 -0
  203. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spC/0.0.0.0 +0 -0
  204. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spCaCO3/0.0.0.0 +0 -0
  205. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spChl/0.0.0.0 +0 -0
  206. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spFe/0.0.0.0 +0 -0
  207. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spP/0.0.0.0 +0 -0
  208. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/temp/0.0.0.0 +0 -0
  209. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/u/0.0.0.0 +0 -0
  210. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ubar/0.0.0 +0 -0
  211. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/v/0.0.0.0 +0 -0
  212. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/vbar/0.0.0 +0 -0
  213. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zeta/0.0.0 +0 -0
  214. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zooC/0.0.0.0 +0 -0
  215. roms_tools/tests/test_setup/test_fill.py +43 -14
  216. roms_tools/tests/test_setup/test_regrid.py +59 -0
  217. roms_tools/tests/test_setup/test_surface_forcing.py +18 -0
  218. {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/METADATA +2 -2
  219. {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/RECORD +222 -221
  220. roms_tools/setup/mixins.py +0 -227
  221. {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/LICENSE +0 -0
  222. {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/WHEEL +0 -0
  223. {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/top_level.txt +0 -0
roms_tools/_version.py CHANGED
@@ -1,2 +1,2 @@
1
1
  # Do not change! Do not track in version control!
2
- __version__ = "1.4.2"
2
+ __version__ = "1.5.0"
@@ -6,16 +6,21 @@ import importlib.metadata
6
6
  from typing import Dict, Union, List
7
7
  from dataclasses import dataclass, field, asdict
8
8
  from roms_tools.setup.grid import Grid
9
- from roms_tools.setup.mixins import ROMSToolsMixins
9
+ from roms_tools.setup.fill import _lateral_fill
10
+ from roms_tools.setup.regrid import _lateral_regrid, _vertical_regrid
10
11
  from datetime import datetime
11
12
  from roms_tools.setup.datasets import GLORYSDataset, CESMBGCDataset
12
13
  from roms_tools.setup.utils import (
13
14
  nan_check,
14
15
  substitute_nans_by_fillvalue,
15
16
  get_variable_metadata,
16
- get_boundary_info,
17
17
  group_dataset,
18
18
  save_datasets,
19
+ get_target_coords,
20
+ rotate_velocities,
21
+ compute_barotropic_velocity,
22
+ _extrapolate_deepest_to_bottom,
23
+ transpose_dimensions,
19
24
  )
20
25
  from roms_tools.setup.plot import _section_plot, _line_plot
21
26
  import matplotlib.pyplot as plt
@@ -23,7 +28,7 @@ from pathlib import Path
23
28
 
24
29
 
25
30
  @dataclass(frozen=True, kw_only=True)
26
- class BoundaryForcing(ROMSToolsMixins):
31
+ class BoundaryForcing:
27
32
  """Represents boundary forcing input data for ROMS.
28
33
 
29
34
  Parameters
@@ -91,33 +96,115 @@ class BoundaryForcing(ROMSToolsMixins):
91
96
  def __post_init__(self):
92
97
 
93
98
  self._input_checks()
94
- lon, lat, angle, straddle = super()._get_target_lon_lat()
99
+ target_coords = get_target_coords(self.grid)
95
100
 
96
101
  data = self._get_data()
97
102
  data.choose_subdomain(
98
- latitude_range=[lat.min().values, lat.max().values],
99
- longitude_range=[lon.min().values, lon.max().values],
103
+ latitude_range=[
104
+ target_coords["lat"].min().values,
105
+ target_coords["lat"].max().values,
106
+ ],
107
+ longitude_range=[
108
+ target_coords["lon"].min().values,
109
+ target_coords["lon"].max().values,
110
+ ],
100
111
  margin=2,
101
- straddle=straddle,
112
+ straddle=target_coords["straddle"],
102
113
  )
103
114
 
104
- if self.type == "physics":
105
- vars_2d = ["zeta"]
106
- vars_3d = ["temp", "salt", "u", "v"]
107
- elif self.type == "bgc":
108
- vars_2d = []
109
- vars_3d = data.var_names.keys()
115
+ variable_info = self._set_variable_info(data)
110
116
 
111
- data_vars = super()._regrid_data(data, vars_2d, vars_3d, lon, lat)
117
+ data_vars = {}
118
+ data_vars = _extrapolate_deepest_to_bottom(data_vars, data)
119
+ data_vars = _lateral_fill(data_vars, data)
112
120
 
113
- if self.type == "physics":
114
- data_vars = super()._process_velocities(data_vars, angle, "u", "v")
115
- object.__setattr__(data, "data_vars", data_vars)
116
-
117
- d_meta = get_variable_metadata()
118
121
  bdry_coords = get_boundary_info()
122
+ ds = xr.Dataset()
123
+ for direction in ["south", "east", "north", "west"]:
124
+ if self.boundaries[direction]:
125
+
126
+ bdry_data_vars = data_vars.copy()
127
+
128
+ # lateral regridding of vector fields
129
+ vector_var_names = [
130
+ name for name, info in variable_info.items() if info["is_vector"]
131
+ ]
132
+ if len(vector_var_names) > 0:
133
+ lon = target_coords["lon"].isel(**bdry_coords["vector"][direction])
134
+ lat = target_coords["lat"].isel(**bdry_coords["vector"][direction])
135
+ bdry_data_vars = _lateral_regrid(
136
+ data, lon, lat, bdry_data_vars, vector_var_names
137
+ )
138
+ # lateral regridding of tracer fields
139
+ tracer_var_names = [
140
+ name
141
+ for name, info in variable_info.items()
142
+ if not info["is_vector"]
143
+ ]
144
+ if len(tracer_var_names) > 0:
145
+ lon = target_coords["lon"].isel(**bdry_coords["rho"][direction])
146
+ lat = target_coords["lat"].isel(**bdry_coords["rho"][direction])
147
+ bdry_data_vars = _lateral_regrid(
148
+ data, lon, lat, bdry_data_vars, tracer_var_names
149
+ )
150
+
151
+ # rotation of velocities and interpolation to u/v points
152
+ if "u" in variable_info and "v" in variable_info:
153
+ angle = target_coords["angle"].isel(
154
+ **bdry_coords["vector"][direction]
155
+ )
156
+ (bdry_data_vars["u"], bdry_data_vars["v"],) = rotate_velocities(
157
+ bdry_data_vars["u"],
158
+ bdry_data_vars["v"],
159
+ angle,
160
+ interpolate=True,
161
+ )
162
+
163
+ # selection of outermost margin for u/v variables
164
+ for var in variable_info.keys():
165
+ if var in bdry_data_vars:
166
+ location = variable_info[var]["location"]
167
+ if location in ["u", "v"]:
168
+ bdry_data_vars[var] = bdry_data_vars[var].isel(
169
+ **bdry_coords[location][direction]
170
+ )
171
+
172
+ # vertical regridding
173
+ for location in ["rho", "u", "v"]:
174
+ var_names = [
175
+ name
176
+ for name, info in variable_info.items()
177
+ if info["location"] == location and info["is_3d"]
178
+ ]
179
+ if len(var_names) > 0:
180
+ bdry_data_vars = _vertical_regrid(
181
+ data,
182
+ self.grid.ds[f"layer_depth_{location}"].isel(
183
+ **bdry_coords[location][direction],
184
+ ),
185
+ bdry_data_vars,
186
+ var_names,
187
+ )
188
+
189
+ # compute barotropic velocities
190
+ if "u" in variable_info and "v" in variable_info:
191
+ for var in ["u", "v"]:
192
+ bdry_data_vars[f"{var}bar"] = compute_barotropic_velocity(
193
+ bdry_data_vars[var],
194
+ self.grid.ds[f"interface_depth_{var}"].isel(
195
+ **bdry_coords[var][direction]
196
+ ),
197
+ )
119
198
 
120
- ds = self._write_into_dataset(data, d_meta, bdry_coords)
199
+ # Reorder dimensions
200
+ for var in bdry_data_vars.keys():
201
+ bdry_data_vars[var] = transpose_dimensions(bdry_data_vars[var])
202
+
203
+ # Write the boundary data into dataset
204
+ ds = self._write_into_dataset(direction, bdry_data_vars, ds)
205
+
206
+ # Add global information
207
+ ds = self._add_global_metadata(data, ds)
121
208
 
122
209
  # NaN values at wet points indicate that the raw data did not cover the domain, and the following will raise a ValueError
123
210
  # this check works only for 2D fields because for 3D I extrapolate to bottom which eliminates NaNs
@@ -187,37 +274,86 @@ class BoundaryForcing(ROMSToolsMixins):
187
274
 
188
275
  return data
189
276
 
190
- def _write_into_dataset(self, data, d_meta, bdry_coords):
277
+ def _set_variable_info(self, data):
278
+ """Sets up a dictionary with metadata for variables based on the type of data
279
+ (physics or BGC).
191
280
 
192
- # save in new dataset
193
- ds = xr.Dataset()
281
+ The dictionary contains the following information:
282
+ - `location`: Where the variable resides in the grid (e.g., rho, u, or v points).
283
+ - `is_vector`: Whether the variable is part of a vector (True for velocity components like 'u' and 'v').
284
+ - `vector_pair`: For vector variables, this indicates the associated variable that forms the vector (e.g., 'u' and 'v').
285
+ - `is_3d`: Indicates whether the variable is 3D (True for variables like 'temp' and 'salt') or 2D (False for 'zeta').
194
286
 
195
- for direction in ["south", "east", "north", "west"]:
196
- if self.boundaries[direction]:
287
+ Returns
288
+ -------
289
+ dict
290
+ A dictionary where the keys are variable names and the values are dictionaries of metadata
291
+ about each variable, including 'location', 'is_vector', 'vector_pair', and 'is_3d'.
292
+ """
293
+ default_info = {
294
+ "location": "rho",
295
+ "is_vector": False,
296
+ "vector_pair": None,
297
+ "is_3d": True,
298
+ }
197
299
 
198
- for var in data.data_vars.keys():
199
- if var in ["u", "ubar"]:
200
- ds[f"{var}_{direction}"] = (
201
- data.data_vars[var]
202
- .isel(**bdry_coords["u"][direction])
203
- .astype(np.float32)
204
- )
205
- elif var in ["v", "vbar"]:
206
- ds[f"{var}_{direction}"] = (
207
- data.data_vars[var]
208
- .isel(**bdry_coords["v"][direction])
209
- .astype(np.float32)
210
- )
211
- else:
212
- ds[f"{var}_{direction}"] = (
213
- data.data_vars[var]
214
- .isel(**bdry_coords["rho"][direction])
215
- .astype(np.float32)
216
- )
217
- ds[f"{var}_{direction}"].attrs[
218
- "long_name"
219
- ] = f"{direction}ern boundary {d_meta[var]['long_name']}"
220
- ds[f"{var}_{direction}"].attrs["units"] = d_meta[var]["units"]
300
+ # Define a dictionary for variable names and their associated information
301
+ if self.type == "physics":
302
+ variable_info = {
303
+ "zeta": {
304
+ "location": "rho",
305
+ "is_vector": False,
306
+ "vector_pair": None,
307
+ "is_3d": False,
308
+ },
309
+ "temp": default_info,
310
+ "salt": default_info,
311
+ "u": {
312
+ "location": "u",
313
+ "is_vector": True,
314
+ "vector_pair": "v",
315
+ "is_3d": True,
316
+ },
317
+ "v": {
318
+ "location": "v",
319
+ "is_vector": True,
320
+ "vector_pair": "u",
321
+ "is_3d": True,
322
+ },
323
+ "ubar": {
324
+ "location": "u",
325
+ "is_vector": True,
326
+ "vector_pair": "vbar",
327
+ "is_3d": False,
328
+ },
329
+ "vbar": {
330
+ "location": "v",
331
+ "is_vector": True,
332
+ "vector_pair": "ubar",
333
+ "is_3d": False,
334
+ },
335
+ }
336
+ elif self.type == "bgc":
337
+ variable_info = {}
338
+ for var in data.var_names.keys():
339
+ variable_info[var] = default_info
340
+
341
+ return variable_info
342
+
343
+ def _write_into_dataset(self, direction, data_vars, ds=None):
344
+ if ds is None:
345
+ ds = xr.Dataset()
346
+
347
+ d_meta = get_variable_metadata()
348
+
349
+ for var in data_vars.keys():
350
+ ds[f"{var}_{direction}"] = data_vars[var].astype(np.float32)
351
+
352
+ ds[f"{var}_{direction}"].attrs[
353
+ "long_name"
354
+ ] = f"{direction}ern boundary {d_meta[var]['long_name']}"
355
+
356
+ ds[f"{var}_{direction}"].attrs["units"] = d_meta[var]["units"]
221
357
 
222
358
  # Gracefully handle dropping variables that might not be present
223
359
  variables_to_drop = [
@@ -238,56 +374,6 @@ class BoundaryForcing(ROMSToolsMixins):
238
374
  existing_vars = [var for var in variables_to_drop if var in ds]
239
375
  ds = ds.drop_vars(existing_vars)
240
376
 
241
- ds = self._add_global_metadata(ds)
242
-
243
- # Convert the time coordinate to the format expected by ROMS
244
- if data.climatology:
245
- ds.attrs["climatology"] = str(True)
246
- # Preserve absolute time coordinate for readability
247
- ds = ds.assign_coords(
248
- {"abs_time": np.datetime64(self.model_reference_date) + ds["time"]}
249
- )
250
- # Convert to pandas TimedeltaIndex
251
- timedelta_index = pd.to_timedelta(ds["time"].values)
252
-
253
- # Determine the start of the year for the base_datetime
254
- start_of_year = datetime(self.model_reference_date.year, 1, 1)
255
-
256
- # Calculate the offset from midnight of the new year
257
- offset = self.model_reference_date - start_of_year
258
-
259
- # Convert the timedelta to nanoseconds first, then to days
260
- bry_time = xr.DataArray(
261
- (timedelta_index - offset).view("int64") / 3600 / 24 * 1e-9,
262
- dims="time",
263
- )
264
-
265
- else:
266
- # Preserve absolute time coordinate for readability
267
- ds = ds.assign_coords({"abs_time": ds["time"]})
268
- # TODO: Check if we need to convert from 12:00:00 to 00:00:00 as in matlab scripts
269
- bry_time = (
270
- (ds["time"] - np.datetime64(self.model_reference_date)).astype(
271
- "float64"
272
- )
273
- / 3600
274
- / 24
275
- * 1e-9
276
- )
277
-
278
- ds = ds.assign_coords({"bry_time": bry_time})
279
- ds["bry_time"].attrs[
280
- "long_name"
281
- ] = f"days since {str(self.model_reference_date)}"
282
- ds["bry_time"].encoding["units"] = "days"
283
- ds["bry_time"].attrs["units"] = "days"
284
- ds = ds.swap_dims({"time": "bry_time"})
285
- ds = ds.drop_vars("time")
286
- ds.encoding["unlimited_dims"] = "bry_time"
287
-
288
- if data.climatology:
289
- ds["bry_time"].attrs["cycle_length"] = 365.25
290
-
291
377
  return ds
292
378
 
293
379
  def _get_coordinates(self, direction, point):
@@ -325,7 +411,7 @@ class BoundaryForcing(ROMSToolsMixins):
325
411
 
326
412
  return layer_depth, interface_depth
327
413
 
328
- def _add_global_metadata(self, ds=None):
414
+ def _add_global_metadata(self, data, ds=None):
329
415
 
330
416
  if ds is None:
331
417
  ds = xr.Dataset()
@@ -345,6 +431,53 @@ class BoundaryForcing(ROMSToolsMixins):
345
431
  ds.attrs["theta_b"] = self.grid.ds.attrs["theta_b"]
346
432
  ds.attrs["hc"] = self.grid.ds.attrs["hc"]
347
433
 
434
+ # Convert the time coordinate to the format expected by ROMS
435
+ if data.climatology:
436
+ ds.attrs["climatology"] = str(True)
437
+ # Preserve absolute time coordinate for readability
438
+ ds = ds.assign_coords(
439
+ {"abs_time": np.datetime64(self.model_reference_date) + ds["time"]}
440
+ )
441
+ # Convert to pandas TimedeltaIndex
442
+ timedelta_index = pd.to_timedelta(ds["time"].values)
443
+
444
+ # Determine the start of the year for the base_datetime
445
+ start_of_year = datetime(self.model_reference_date.year, 1, 1)
446
+
447
+ # Calculate the offset from midnight of the new year
448
+ offset = self.model_reference_date - start_of_year
449
+
450
+ # Convert the timedelta to nanoseconds first, then to days
451
+ bry_time = xr.DataArray(
452
+ (timedelta_index - offset).view("int64") / 3600 / 24 * 1e-9,
453
+ dims="time",
454
+ )
455
+
456
+ else:
457
+ # Preserve absolute time coordinate for readability
458
+ ds = ds.assign_coords({"abs_time": ds["time"]})
459
+ bry_time = (
460
+ (ds["time"] - np.datetime64(self.model_reference_date)).astype(
461
+ "float64"
462
+ )
463
+ / 3600
464
+ / 24
465
+ * 1e-9
466
+ )
467
+
468
+ ds = ds.assign_coords({"bry_time": bry_time})
469
+ ds["bry_time"].attrs[
470
+ "long_name"
471
+ ] = f"days since {str(self.model_reference_date)}"
472
+ ds["bry_time"].encoding["units"] = "days"
473
+ ds["bry_time"].attrs["units"] = "days"
474
+ ds = ds.swap_dims({"time": "bry_time"})
475
+ ds = ds.drop_vars("time")
476
+ ds.encoding["unlimited_dims"] = "bry_time"
477
+
478
+ if data.climatology:
479
+ ds["bry_time"].attrs["cycle_length"] = 365.25
480
+
348
481
  return ds
349
482
 
350
483
  def plot(
@@ -621,3 +754,47 @@ class BoundaryForcing(ROMSToolsMixins):
621
754
 
622
755
  # Create and return an instance of InitialConditions
623
756
  return cls(grid=grid, **boundary_forcing_data, use_dask=use_dask)
757
+
758
+
759
+ def get_boundary_info():
760
+ """This function provides information about the boundary points for the rho, u, and
761
+ v variables on the grid, specifying the indices for the south, east, north, and west
762
+ boundaries.
763
+
764
+ Returns
765
+ -------
766
+ dict
767
+ A dictionary where keys are variable types ("rho", "u", "v"), and values
768
+ are nested dictionaries mapping directions ("south", "east", "north", "west")
769
+ to the corresponding boundary coordinates.
770
+ """
771
+
772
+ # Boundary coordinates
773
+ bdry_coords = {
774
+ "rho": {
775
+ "south": {"eta_rho": 0},
776
+ "east": {"xi_rho": -1},
777
+ "north": {"eta_rho": -1},
778
+ "west": {"xi_rho": 0},
779
+ },
780
+ "u": {
781
+ "south": {"eta_rho": 0},
782
+ "east": {"xi_u": -1},
783
+ "north": {"eta_rho": -1},
784
+ "west": {"xi_u": 0},
785
+ },
786
+ "v": {
787
+ "south": {"eta_v": 0},
788
+ "east": {"xi_rho": -1},
789
+ "north": {"eta_v": -1},
790
+ "west": {"xi_rho": 0},
791
+ },
792
+ "vector": {
793
+ "south": {"eta_rho": [0, 1]},
794
+ "east": {"xi_rho": [-2, -1]},
795
+ "north": {"eta_rho": [-2, -1]},
796
+ "west": {"xi_rho": [0, 1]},
797
+ },
798
+ }
799
+
800
+ return bdry_coords
@@ -805,11 +805,13 @@ class TPXODataset(Dataset):
805
805
  if "depth" in self.var_names.keys():
806
806
  mask = xr.where(self.ds["depth"] > 0, 1, 0)
807
807
 
808
- for var in self.ds.data_vars:
809
- self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
810
-
811
808
  self.ds["mask"] = mask
812
809
 
810
+ # Remove "depth" from var_names
811
+ updated_var_names = {**self.var_names} # Create a copy of the dictionary
812
+ updated_var_names.pop("depth", None) # Remove "depth" if it exists
813
+ object.__setattr__(self, "var_names", updated_var_names)
814
+
813
815
 
814
816
  @dataclass(frozen=True, kw_only=True)
815
817
  class GLORYSDataset(Dataset):
@@ -878,11 +880,16 @@ class GLORYSDataset(Dataset):
878
880
  0,
879
881
  1,
880
882
  )
881
-
882
- for var in self.ds.data_vars:
883
- self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
883
+ mask_vel = xr.where(
884
+ self.ds[self.var_names["u"]]
885
+ .isel({self.dim_names["time"]: 0, self.dim_names["depth"]: 0})
886
+ .isnull(),
887
+ 0,
888
+ 1,
889
+ )
884
890
 
885
891
  self.ds["mask"] = mask
892
+ self.ds["mask_vel"] = mask_vel
886
893
 
887
894
 
888
895
  @dataclass(frozen=True, kw_only=True)
@@ -1088,9 +1095,6 @@ class CESMBGCDataset(CESMDataset):
1088
1095
  1,
1089
1096
  )
1090
1097
 
1091
- for var in self.ds.data_vars:
1092
- self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
1093
-
1094
1098
  self.ds["mask"] = mask
1095
1099
 
1096
1100
 
@@ -1160,9 +1164,6 @@ class CESMBGCSurfaceForcingDataset(CESMDataset):
1160
1164
  1,
1161
1165
  )
1162
1166
 
1163
- for var in self.ds.data_vars:
1164
- self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
1165
-
1166
1167
  self.ds["mask"] = mask
1167
1168
 
1168
1169
 
@@ -1266,16 +1267,19 @@ class ERA5Dataset(Dataset):
1266
1267
 
1267
1268
  # Update var_names dictionary
1268
1269
  var_names = {**self.var_names, "qair": "qair"}
1270
+ var_names.pop("d2m")
1269
1271
  object.__setattr__(self, "var_names", var_names)
1270
1272
 
1271
1273
  if "mask" in self.var_names.keys():
1272
1274
  mask = xr.where(self.ds[self.var_names["mask"]].isel(time=0).isnull(), 0, 1)
1273
1275
 
1274
- for var in self.ds.data_vars:
1275
- self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
1276
-
1277
1276
  self.ds["mask"] = mask
1278
1277
 
1278
+ # Remove mask from var_names dictionary
1279
+ var_names = self.var_names
1280
+ var_names.pop("mask")
1281
+ object.__setattr__(self, "var_names", var_names)
1282
+
1279
1283
 
1280
1284
  @dataclass(frozen=True, kw_only=True)
1281
1285
  class ERA5Correction(Dataset):
roms_tools/setup/fill.py CHANGED
@@ -15,7 +15,7 @@ class LateralFill:
15
15
  A 2D boolean mask indicating valid points (True) and land points (False).
16
16
  Boundary points are automatically set to land (True).
17
17
  dims : list of str
18
- Dimensions along which to perform the lateral fill. Defaults to ["latitude", "longitude"].
18
+ Dimensions along which to perform the lateral fill.
19
19
  tol : float, optional
20
20
  Tolerance for the iterative solver, determining convergence. Default is 1.0e-4.
21
21
 
@@ -65,7 +65,7 @@ class LateralFill:
65
65
  non-NaN values.
66
66
  """
67
67
  # Apply fill to anomaly field
68
- mean = var.mean(dim=self.dims, skipna=True)
68
+ mean = var.where(self.mask).mean(dim=self.dims, skipna=True)
69
69
  var = var - mean
70
70
 
71
71
  # Setup the right-hand side (RHS): ocean points take their original values, land points are set to 0
@@ -301,3 +301,39 @@ def stencil_grid_mod(S, grid, msk, dtype=None, format=None):
301
301
  data[4, i + diags[4]] = 0
302
302
 
303
303
  return sparse.dia_matrix((data, diags), shape=(N_v, N_v)).asformat(format)
304
+
305
+
306
+ def _lateral_fill(data_vars, data):
307
+ """Wrapper function to apply lateral fill to variables using the dataset's mask and
308
+ grid dimensions.
309
+
310
+ Parameters
311
+ ----------
312
+ data_vars : dict of str : xarray.DataArray
313
+ Dictionary of variables to be filled.
314
+ data : Dataset
315
+ Dataset containing the mask and grid dimensions.
316
+
317
+ Returns
318
+ -------
319
+ dict of str : xarray.DataArray
320
+ Dictionary of filled variables.
321
+ """
322
+ lateral_fill = LateralFill(
323
+ data.ds["mask"],
324
+ [data.dim_names["latitude"], data.dim_names["longitude"]],
325
+ )
326
+
327
+ if "mask_vel" in data.ds.data_vars:
328
+ lateral_fill_vel = LateralFill(
329
+ data.ds["mask_vel"],
330
+ [data.dim_names["latitude"], data.dim_names["longitude"]],
331
+ )
332
+
333
+ for var in data.var_names:
334
+ if var in ["u", "v"]:
335
+ data_vars[var] = lateral_fill_vel.apply(data_vars[var])
336
+ else:
337
+ data_vars[var] = lateral_fill.apply(data_vars[var])
338
+
339
+ return data_vars