roms-tools 1.3.0__py3-none-any.whl → 1.4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. ci/environment.yml +1 -8
  2. roms_tools/_version.py +1 -1
  3. roms_tools/setup/boundary_forcing.py +1 -1
  4. roms_tools/setup/datasets.py +278 -105
  5. roms_tools/setup/download.py +5 -0
  6. roms_tools/setup/fill.py +266 -331
  7. roms_tools/setup/grid.py +92 -8
  8. roms_tools/setup/initial_conditions.py +10 -11
  9. roms_tools/setup/mixins.py +29 -21
  10. roms_tools/setup/surface_forcing.py +3 -5
  11. roms_tools/setup/tides.py +44 -46
  12. roms_tools/setup/topography.py +30 -4
  13. roms_tools/setup/utils.py +41 -23
  14. roms_tools/tests/test_setup/test_boundary_forcing.py +1 -1
  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/dust/0.0.0 +0 -0
  148. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/iron/0.0.0 +0 -0
  149. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nhy/0.0.0 +0 -0
  150. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nox/0.0.0 +0 -0
  151. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air/0.0.0 +0 -0
  152. roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air_alt/0.0.0 +0 -0
  153. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zattrs +1 -1
  154. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zmetadata +1 -1
  155. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/dust/0.0.0 +0 -0
  156. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/iron/0.0.0 +0 -0
  157. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nhy/0.0.0 +0 -0
  158. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nox/0.0.0 +0 -0
  159. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air/0.0.0 +0 -0
  160. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air_alt/0.0.0 +0 -0
  161. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zattrs +1 -1
  162. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +1 -1
  163. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/0.0.0 +0 -0
  164. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/0.0.0 +0 -0
  165. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/0.0.0 +0 -0
  166. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/0.0.0 +0 -0
  167. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/0.0.0 +0 -0
  168. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/0.0.0 +0 -0
  169. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/0.0.0 +0 -0
  170. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/0.0.0 +0 -0
  171. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/0.0.0 +0 -0
  172. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/0.0.0 +0 -0
  173. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/0.0.0 +0 -0
  174. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/0.0.0 +0 -0
  175. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/0.0 +0 -0
  176. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/0.0 +0 -0
  177. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/0.0 +0 -0
  178. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/0.0 +0 -0
  179. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/0.0.0 +0 -0
  180. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/0.0.0 +0 -0
  181. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/0.0.0 +0 -0
  182. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/0.0.0 +0 -0
  183. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/0.0 +0 -0
  184. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/0.0 +0 -0
  185. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/0.0 +0 -0
  186. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/0.0 +0 -0
  187. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/0.0 +0 -0
  188. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
  189. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/.zattrs +1 -1
  190. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/.zmetadata +8 -8
  191. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/Tair/.zarray +1 -1
  192. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/Tair/0.0.0 +0 -0
  193. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/lwrad/.zarray +1 -1
  194. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/lwrad/0.0.0 +0 -0
  195. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/qair/.zarray +1 -1
  196. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/qair/0.0.0 +0 -0
  197. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/rain/.zarray +1 -1
  198. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/rain/0.0.0 +0 -0
  199. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/swrad/.zarray +1 -1
  200. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/swrad/0.0.0 +0 -0
  201. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/uwnd/.zarray +1 -1
  202. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/uwnd/0.0.0 +0 -0
  203. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/vwnd/.zarray +1 -1
  204. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/vwnd/0.0.0 +0 -0
  205. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/.zattrs +1 -1
  206. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/.zmetadata +8 -8
  207. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/Tair/.zarray +1 -1
  208. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/Tair/0.0.0 +0 -0
  209. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/lwrad/.zarray +1 -1
  210. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/lwrad/0.0.0 +0 -0
  211. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/qair/.zarray +1 -1
  212. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/qair/0.0.0 +0 -0
  213. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/rain/.zarray +1 -1
  214. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/rain/0.0.0 +0 -0
  215. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/swrad/.zarray +1 -1
  216. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/swrad/0.0.0 +0 -0
  217. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/uwnd/.zarray +1 -1
  218. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/uwnd/0.0.0 +0 -0
  219. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/vwnd/.zarray +1 -1
  220. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/vwnd/0.0.0 +0 -0
  221. roms_tools/tests/test_setup/test_data/grid.zarr/.zattrs +2 -2
  222. roms_tools/tests/test_setup/test_data/grid.zarr/.zmetadata +62 -2
  223. roms_tools/tests/test_setup/test_data/grid.zarr/lat_psi/.zarray +22 -0
  224. roms_tools/tests/test_setup/test_data/grid.zarr/lat_psi/.zattrs +8 -0
  225. roms_tools/tests/test_setup/test_data/grid.zarr/lat_psi/0.0 +0 -0
  226. roms_tools/tests/test_setup/test_data/grid.zarr/lat_u/0.0 +0 -0
  227. roms_tools/tests/test_setup/test_data/grid.zarr/lat_v/0.0 +0 -0
  228. roms_tools/tests/test_setup/test_data/grid.zarr/lon_psi/.zarray +22 -0
  229. roms_tools/tests/test_setup/test_data/grid.zarr/lon_psi/.zattrs +8 -0
  230. roms_tools/tests/test_setup/test_data/grid.zarr/lon_psi/0.0 +0 -0
  231. roms_tools/tests/test_setup/test_data/grid.zarr/lon_u/0.0 +0 -0
  232. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zattrs +2 -2
  233. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zmetadata +62 -2
  234. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_psi/.zarray +22 -0
  235. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_psi/.zattrs +8 -0
  236. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_psi/0.0 +0 -0
  237. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_u/0.0 +0 -0
  238. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_v/0.0 +0 -0
  239. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_psi/.zarray +22 -0
  240. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_psi/.zattrs +8 -0
  241. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_psi/0.0 +0 -0
  242. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_u/0.0 +0 -0
  243. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_v/0.0 +0 -0
  244. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zattrs +1 -1
  245. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zmetadata +1 -1
  246. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK/0.0.0.0 +0 -0
  247. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK_ALT_CO2/0.0.0.0 +0 -0
  248. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC/0.0.0.0 +0 -0
  249. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC_ALT_CO2/0.0.0.0 +0 -0
  250. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOC/0.0.0.0 +0 -0
  251. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOCr/0.0.0.0 +0 -0
  252. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DON/0.0.0.0 +0 -0
  253. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DONr/0.0.0.0 +0 -0
  254. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOP/0.0.0.0 +0 -0
  255. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOPr/0.0.0.0 +0 -0
  256. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Fe/0.0.0.0 +0 -0
  257. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Lig/0.0.0.0 +0 -0
  258. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NH4/0.0.0.0 +0 -0
  259. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NO3/0.0.0.0 +0 -0
  260. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/O2/0.0.0.0 +0 -0
  261. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/PO4/0.0.0.0 +0 -0
  262. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/SiO3/0.0.0.0 +0 -0
  263. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatC/0.0.0.0 +0 -0
  264. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatChl/0.0.0.0 +0 -0
  265. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatFe/0.0.0.0 +0 -0
  266. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatP/0.0.0.0 +0 -0
  267. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatSi/0.0.0.0 +0 -0
  268. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazC/0.0.0.0 +0 -0
  269. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazChl/0.0.0.0 +0 -0
  270. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazFe/0.0.0.0 +0 -0
  271. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazP/0.0.0.0 +0 -0
  272. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/salt/0.0.0.0 +0 -0
  273. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spC/0.0.0.0 +0 -0
  274. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spCaCO3/0.0.0.0 +0 -0
  275. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spChl/0.0.0.0 +0 -0
  276. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spFe/0.0.0.0 +0 -0
  277. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spP/0.0.0.0 +0 -0
  278. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/temp/0.0.0.0 +0 -0
  279. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/u/0.0.0.0 +0 -0
  280. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ubar/0.0.0 +0 -0
  281. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/v/0.0.0.0 +0 -0
  282. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/vbar/0.0.0 +0 -0
  283. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zeta/0.0.0 +0 -0
  284. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zooC/0.0.0.0 +0 -0
  285. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/.zattrs +1 -1
  286. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/.zmetadata +8 -8
  287. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/Tair/.zarray +1 -1
  288. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/Tair/0.0.0 +0 -0
  289. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/lwrad/.zarray +1 -1
  290. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/lwrad/0.0.0 +0 -0
  291. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/qair/.zarray +1 -1
  292. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/qair/0.0.0 +0 -0
  293. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/rain/.zarray +1 -1
  294. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/rain/0.0.0 +0 -0
  295. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/swrad/.zarray +1 -1
  296. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/swrad/0.0.0 +0 -0
  297. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/uwnd/.zarray +1 -1
  298. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/uwnd/0.0.0 +0 -0
  299. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/vwnd/.zarray +1 -1
  300. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/vwnd/0.0.0 +0 -0
  301. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/.zattrs +1 -1
  302. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/.zmetadata +2 -4
  303. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/omega/.zattrs +1 -3
  304. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/pot_Im/0.0.0 +0 -0
  305. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/pot_Re/0.0.0 +0 -0
  306. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/ssh_Im/0.0.0 +0 -0
  307. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/ssh_Re/0.0.0 +0 -0
  308. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/u_Im/0.0.0 +0 -0
  309. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/u_Re/0.0.0 +0 -0
  310. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/v_Im/0.0.0 +0 -0
  311. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/v_Re/0.0.0 +0 -0
  312. roms_tools/tests/test_setup/test_datasets.py +280 -211
  313. roms_tools/tests/test_setup/test_fill.py +177 -0
  314. roms_tools/tests/test_setup/test_grid.py +56 -0
  315. roms_tools/tests/test_setup/test_initial_conditions.py +5 -3
  316. roms_tools/tests/test_setup/test_surface_forcing.py +4 -4
  317. roms_tools/tests/test_setup/test_tides.py +5 -2
  318. roms_tools/tests/test_setup/test_topography.py +40 -0
  319. roms_tools/tests/test_setup/test_validation.py +1 -1
  320. roms_tools/tests/test_utils.py +30 -0
  321. roms_tools/utils.py +39 -3
  322. roms_tools-1.4.1.dist-info/LICENSE +201 -0
  323. {roms_tools-1.3.0.dist-info → roms_tools-1.4.1.dist-info}/METADATA +13 -3
  324. {roms_tools-1.3.0.dist-info → roms_tools-1.4.1.dist-info}/RECORD +326 -334
  325. {roms_tools-1.3.0.dist-info → roms_tools-1.4.1.dist-info}/WHEEL +1 -1
  326. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/Tair/1.0.0 +0 -0
  327. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/lwrad/1.0.0 +0 -0
  328. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/qair/1.0.0 +0 -0
  329. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/rain/1.0.0 +0 -0
  330. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/swrad/1.0.0 +0 -0
  331. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/uwnd/1.0.0 +0 -0
  332. roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/vwnd/1.0.0 +0 -0
  333. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/Tair/1.0.0 +0 -0
  334. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/lwrad/1.0.0 +0 -0
  335. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/qair/1.0.0 +0 -0
  336. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/rain/1.0.0 +0 -0
  337. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/swrad/1.0.0 +0 -0
  338. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/uwnd/1.0.0 +0 -0
  339. roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/vwnd/1.0.0 +0 -0
  340. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/Tair/1.0.0 +0 -0
  341. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/lwrad/1.0.0 +0 -0
  342. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/qair/1.0.0 +0 -0
  343. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/rain/1.0.0 +0 -0
  344. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/swrad/1.0.0 +0 -0
  345. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/uwnd/1.0.0 +0 -0
  346. roms_tools/tests/test_setup/test_data/surface_forcing.zarr/vwnd/1.0.0 +0 -0
  347. roms_tools-1.3.0.dist-info/LICENSE +0 -674
  348. {roms_tools-1.3.0.dist-info → roms_tools-1.4.1.dist-info}/top_level.txt +0 -0
@@ -10,7 +10,7 @@ import warnings
10
10
  from roms_tools.setup.utils import (
11
11
  assign_dates_to_climatology,
12
12
  interpolate_from_climatology,
13
- is_cftime_datetime,
13
+ get_time_type,
14
14
  convert_cftime_to_datetime,
15
15
  )
16
16
  from roms_tools.setup.download import download_correction_data
@@ -39,7 +39,8 @@ class Dataset:
39
39
  Indicates whether the dataset is climatological. Defaults to False.
40
40
  use_dask: bool
41
41
  Indicates whether to use dask for chunking. If True, data is loaded with dask; if False, data is loaded eagerly. Defaults to False.
42
-
42
+ apply_post_processing: bool
43
+ Indicates whether to post-process the dataset for futher use. Defaults to True.
43
44
 
44
45
  Attributes
45
46
  ----------
@@ -55,10 +56,6 @@ class Dataset:
55
56
  ... start_time=datetime(2022, 1, 1),
56
57
  ... end_time=datetime(2022, 12, 31),
57
58
  ... )
58
- >>> dataset.load_data()
59
- >>> print(dataset.ds)
60
- <xarray.Dataset>
61
- Dimensions: ...
62
59
  """
63
60
 
64
61
  filename: Union[str, Path, List[Union[str, Path]]]
@@ -74,6 +71,7 @@ class Dataset:
74
71
  )
75
72
  climatology: Optional[bool] = False
76
73
  use_dask: Optional[bool] = True
74
+ apply_post_processing: Optional[bool] = True
77
75
 
78
76
  is_global: bool = field(init=False, repr=False)
79
77
  ds: xr.Dataset = field(init=False, repr=False)
@@ -84,11 +82,22 @@ class Dataset:
84
82
  1. Loads the dataset from the specified filename.
85
83
  2. Applies time filtering based on start_time and end_time if provided.
86
84
  3. Selects relevant fields as specified by var_names.
87
- 4. Ensures latitude values are in ascending order.
85
+ 4. Ensures latitude values and depth values are in ascending order.
88
86
  5. Checks if the dataset covers the entire globe and adjusts if necessary.
89
87
  """
90
88
 
89
+ # Validate start_time and end_time
90
+ if self.start_time is not None and not isinstance(self.start_time, datetime):
91
+ raise TypeError(
92
+ f"start_time must be a datetime object, but got {type(self.start_time).__name__}."
93
+ )
94
+ if self.end_time is not None and not isinstance(self.end_time, datetime):
95
+ raise TypeError(
96
+ f"end_time must be a datetime object, but got {type(self.end_time).__name__}."
97
+ )
98
+
91
99
  ds = self.load_data()
100
+ ds = self.clean_up(ds)
92
101
  self.check_dataset(ds)
93
102
 
94
103
  # Select relevant times
@@ -96,11 +105,18 @@ class Dataset:
96
105
  ds = self.add_time_info(ds)
97
106
  ds = self.select_relevant_times(ds)
98
107
 
108
+ if self.dim_names["time"] != "time":
109
+ ds = ds.rename({self.dim_names["time"]: "time"})
110
+
99
111
  # Select relevant fields
100
112
  ds = self.select_relevant_fields(ds)
101
113
 
102
114
  # Make sure that latitude is ascending
103
- ds = self.ensure_latitude_ascending(ds)
115
+ ds = self.ensure_dimension_is_ascending(ds, dim="latitude")
116
+
117
+ if "depth" in self.dim_names:
118
+ # Make sure that depth is ascending
119
+ ds = self.ensure_dimension_is_ascending(ds, dim="depth")
104
120
 
105
121
  # Check whether the data covers the entire globe
106
122
  object.__setattr__(self, "is_global", self.check_if_global(ds))
@@ -111,6 +127,9 @@ class Dataset:
111
127
 
112
128
  object.__setattr__(self, "ds", ds)
113
129
 
130
+ if self.apply_post_processing:
131
+ self.post_process()
132
+
114
133
  def load_data(self) -> xr.Dataset:
115
134
  """
116
135
  Load dataset from the specified file.
@@ -125,10 +144,12 @@ class Dataset:
125
144
  FileNotFoundError
126
145
  If the specified file does not exist.
127
146
  ValueError
128
- If wildcards are found in the filename and use_dask=False.
129
147
  If a list of files is provided but self.dim_names["time"] is not available or use_dask=False.
130
148
  """
131
149
 
150
+ # Precompile the regex for matching wildcard characters
151
+ wildcard_regex = re.compile(r"[\*\?\[\]]")
152
+
132
153
  # Convert Path objects to strings
133
154
  if isinstance(self.filename, (str, Path)):
134
155
  filename_str = str(self.filename)
@@ -140,13 +161,10 @@ class Dataset:
140
161
  )
141
162
 
142
163
  # Handle the case when filename is a string
164
+ contains_wildcard = False
143
165
  if isinstance(filename_str, str):
144
- if re.search(r"[\*\?\[\]]", filename_str):
145
- if not self.use_dask:
146
- raise ValueError(
147
- "Wildcards detected in the filename but use_dask=False. "
148
- "Wildcards can only be used when use_dask=True."
149
- )
166
+ contains_wildcard = bool(wildcard_regex.search(filename_str))
167
+ if contains_wildcard:
150
168
  matching_files = glob.glob(filename_str)
151
169
  if not matching_files:
152
170
  raise FileNotFoundError(
@@ -157,12 +175,18 @@ class Dataset:
157
175
 
158
176
  # Handle the case when filename is a list
159
177
  elif isinstance(filename_str, list):
160
- if not self.use_dask:
161
- raise ValueError(
162
- "A list of files is provided, but use_dask=False. "
163
- "Multiple files can only be loaded when use_dask=True."
164
- )
165
- matching_files = filename_str
178
+ contains_wildcard = any(wildcard_regex.search(f) for f in filename_str)
179
+ if contains_wildcard:
180
+ matching_files = []
181
+ for f in filename_str:
182
+ files = glob.glob(f)
183
+ if not files:
184
+ raise FileNotFoundError(
185
+ f"No files found matching the pattern '{f}'."
186
+ )
187
+ matching_files.extend(files)
188
+ else:
189
+ matching_files = filename_str
166
190
 
167
191
  # Check if time dimension is available when multiple files are provided
168
192
  if isinstance(filename_str, list) and "time" not in self.dim_names:
@@ -171,6 +195,21 @@ class Dataset:
171
195
  "A time dimension must be available to concatenate the files."
172
196
  )
173
197
 
198
+ # Determine the kwargs for combining datasets
199
+ if contains_wildcard or len(matching_files) == 1:
200
+ # If there is a wildcard or just one file, use by_coords
201
+ kwargs = {"combine": "by_coords"}
202
+ else:
203
+ # Otherwise, use nested combine based on time
204
+ kwargs = {"combine": "nested", "concat_dim": self.dim_names["time"]}
205
+
206
+ # Base kwargs used for dataset combination
207
+ combine_kwargs = {
208
+ "coords": "minimal",
209
+ "compat": "override",
210
+ "combine_attrs": "override",
211
+ }
212
+
174
213
  if self.use_dask:
175
214
 
176
215
  chunks = {
@@ -182,26 +221,49 @@ class Dataset:
182
221
  if "time" in self.dim_names:
183
222
  chunks[self.dim_names["time"]] = 1
184
223
 
185
- if re.search(r"[\*\?\[\]]", filename_str) or len(matching_files) == 1:
186
- kwargs = {"combine": "by_coords"}
187
- else:
188
- kwargs = {"combine": "nested", "concat_dim": self.dim_names["time"]}
189
-
190
224
  ds = xr.open_mfdataset(
191
225
  matching_files,
192
- coords="minimal",
193
- compat="override",
194
226
  chunks=chunks,
227
+ **combine_kwargs,
195
228
  **kwargs,
196
229
  )
197
230
  else:
198
- ds = xr.open_dataset(matching_files[0], chunks=None)
231
+ ds_list = []
232
+ for file in matching_files:
233
+ ds = xr.open_dataset(file, chunks=None)
234
+ ds_list.append(ds)
235
+
236
+ if kwargs["combine"] == "by_coords":
237
+ ds = xr.combine_by_coords(ds_list, **combine_kwargs)
238
+ elif kwargs["combine"] == "nested":
239
+ ds = xr.combine_nested(
240
+ ds_list, concat_dim=kwargs["concat_dim"], **combine_kwargs
241
+ )
199
242
 
200
243
  if "time" in self.dim_names and self.dim_names["time"] not in ds.dims:
201
244
  ds = ds.expand_dims(self.dim_names["time"])
202
245
 
203
246
  return ds
204
247
 
248
+ def clean_up(self, ds: xr.Dataset) -> xr.Dataset:
249
+ """
250
+ Dummy method to be overridden by child classes to clean up the dataset.
251
+
252
+ This method is intended as a placeholder and should be implemented in subclasses
253
+ to provide specific functionality.
254
+
255
+ Parameters
256
+ ----------
257
+ ds : xr.Dataset
258
+ The xarray Dataset to be cleaned up.
259
+
260
+ Returns
261
+ -------
262
+ xr.Dataset
263
+ The xarray Dataset cleaned up (as implemented by child classes).
264
+ """
265
+ return ds
266
+
205
267
  def check_dataset(self, ds: xr.Dataset) -> None:
206
268
  """
207
269
  Check if the dataset contains the specified variables and dimensions.
@@ -252,8 +314,6 @@ class Dataset:
252
314
 
253
315
  return ds
254
316
 
255
- import xarray as xr
256
-
257
317
  def add_time_info(self, ds: xr.Dataset) -> xr.Dataset:
258
318
  """
259
319
  Dummy method to be overridden by child classes to add time information to the dataset.
@@ -275,25 +335,30 @@ class Dataset:
275
335
 
276
336
  def select_relevant_times(self, ds) -> xr.Dataset:
277
337
  """
278
- Selects and returns the subset of the dataset corresponding to the specified time range.
338
+ Select a subset of the dataset based on the specified time range.
339
+
340
+ This method filters the dataset to include all records between `start_time` and `end_time`.
341
+ Additionally, it ensures that one record at or before `start_time` and one record at or
342
+ after `end_time` are included, even if they fall outside the strict time range.
279
343
 
280
- This function filters the dataset to include all times between `start_time` and `end_time`,
281
- plus exactly one record at or before `start_time`, and exactly one record at or after `end_time`.
344
+ If no `end_time` is specified, the method will select the time range of
345
+ [start_time, start_time + 24 hours] and return the closest time entry to `start_time` within that range.
282
346
 
283
347
  Parameters
284
348
  ----------
285
349
  ds : xr.Dataset
286
- The input dataset to be filtered.
350
+ The input dataset to be filtered. Must contain a time dimension.
287
351
 
288
352
  Returns
289
353
  -------
290
354
  xr.Dataset
291
- A dataset containing the filtered time range.
355
+ A dataset filtered to the specified time range, including the closest entries
356
+ at or before `start_time` and at or after `end_time` if applicable.
292
357
 
293
358
  Raises
294
359
  ------
295
360
  ValueError
296
- If no matching times are found.
361
+ If no matching times are found between `start_time` and `start_time + 24 hours`.
297
362
 
298
363
  Warns
299
364
  -----
@@ -302,26 +367,38 @@ class Dataset:
302
367
  This may indicate that the dataset represents climatology data.
303
368
 
304
369
  UserWarning
305
- If no records at or before `self.start_time` or no records at or after `self.end_time` are found.
370
+ If no records at or before `start_time` or no records at or after `end_time` are found.
306
371
 
372
+ UserWarning
373
+ If the dataset does not contain any time dimension or the time dimension is incorrectly named.
374
+
375
+ Notes
376
+ -----
377
+ - If the `climatology` flag is set and `end_time` is not provided, the method will
378
+ interpolate initial conditions from climatology data.
379
+ - If the dataset uses `cftime` datetime objects, these will be converted to standard
380
+ `np.datetime64` objects before filtering.
307
381
  """
308
382
 
309
383
  time_dim = self.dim_names["time"]
310
384
  if time_dim in ds.variables:
311
385
  if self.climatology:
386
+ if len(ds[time_dim]) != 12:
387
+ raise ValueError(
388
+ f"The dataset contains {len(ds[time_dim])} time steps, but the climatology flag is set to True, which requires exactly 12 time steps."
389
+ )
312
390
  if not self.end_time:
313
391
  # Interpolate from climatology for initial conditions
314
392
  ds = interpolate_from_climatology(
315
393
  ds, self.dim_names["time"], self.start_time
316
394
  )
317
395
  else:
318
- if len(ds[time_dim]) == 12:
319
- warnings.warn(
320
- "The dataset contains exactly 12 time steps. This may indicate that it is "
321
- "climatological data. Please verify if climatology is appropriate for your "
322
- "analysis and set the climatology flag to True."
396
+ time_type = get_time_type(ds[time_dim])
397
+ if time_type == "int":
398
+ raise ValueError(
399
+ "The dataset contains integer time values, which are only supported when the climatology flag is set to True. However, your climatology flag is set to False."
323
400
  )
324
- if is_cftime_datetime(ds[time_dim]):
401
+ if time_type == "cftime":
325
402
  ds = ds.assign_coords(
326
403
  {time_dim: convert_cftime_to_datetime(ds[time_dim])}
327
404
  )
@@ -360,18 +437,25 @@ class Dataset:
360
437
  )
361
438
  ds = ds.sel({time_dim: selected_times})
362
439
  else:
440
+ # Look in time range [self.start_time, self.start_time + 24h]
363
441
  end_time = self.start_time + timedelta(days=1)
364
442
  times = (np.datetime64(self.start_time) <= ds[time_dim]) & (
365
443
  ds[time_dim] < np.datetime64(end_time)
366
444
  )
367
- ds = ds.where(times, drop=True)
368
-
369
- if ds.sizes[time_dim] != 1:
370
- found_times = ds.sizes[time_dim]
445
+ if np.all(~times):
371
446
  raise ValueError(
372
- f"There must be exactly one time matching the start_time. Found {found_times} matching times."
447
+ f"The dataset does not contain any time entries between the specified start_time: {self.start_time} "
448
+ f"and {self.start_time + timedelta(hours=24)}. "
449
+ "Please ensure the dataset includes time entries for that range."
373
450
  )
374
451
 
452
+ ds = ds.where(times, drop=True)
453
+ if ds.sizes[time_dim] > 1:
454
+ # Pick the time closest to self.start_time
455
+ ds = ds.isel({time_dim: 0})
456
+ print(
457
+ f"Selected time entry closest to the specified start_time ({self.start_time}) within the range [{self.start_time}, {self.start_time + timedelta(hours=24)}]: {ds[time_dim].values}"
458
+ )
375
459
  else:
376
460
  warnings.warn(
377
461
  "Dataset does not contain any time information. Please check if the time dimension "
@@ -380,24 +464,34 @@ class Dataset:
380
464
 
381
465
  return ds
382
466
 
383
- def ensure_latitude_ascending(self, ds: xr.Dataset) -> xr.Dataset:
467
+ def ensure_dimension_is_ascending(
468
+ self, ds: xr.Dataset, dim="latitude"
469
+ ) -> xr.Dataset:
384
470
  """
385
- Ensure that the latitude dimension is in ascending order.
471
+ Ensure that the specified dimension in the dataset is in ascending order.
472
+
473
+ If the values along the specified dimension are in descending order, this function reverses the order of the dimension to make it ascending.
386
474
 
387
475
  Parameters
388
476
  ----------
389
477
  ds : xr.Dataset
390
- The xarray Dataset to check.
478
+ The input `xarray.Dataset` whose dimension is to be checked and, if necessary, reordered.
479
+ dim : str, optional
480
+ The name of the dimension to check for ascending order.
481
+ Defaults to "latitude". The dimension is expected to be one of the keys in `self.dim_names`.
391
482
 
392
483
  Returns
393
484
  -------
394
- ds : xr.Dataset
395
- The xarray Dataset with latitude in ascending order.
485
+ xr.Dataset
486
+ A new `xarray.Dataset` with the specified dimension in ascending order.
487
+ If the dimension was already in ascending order, the original dataset is returned unchanged.
488
+ If the dimension was in descending order, the dataset is returned with the dimension reversed.
489
+
396
490
  """
397
491
  # Make sure that latitude is ascending
398
- lat_diff = np.diff(ds[self.dim_names["latitude"]])
399
- if np.all(lat_diff < 0):
400
- ds = ds.isel(**{self.dim_names["latitude"]: slice(None, None, -1)})
492
+ diff = np.diff(ds[self.dim_names[dim]])
493
+ if np.all(diff < 0):
494
+ ds = ds.isel(**{self.dim_names[dim]: slice(None, None, -1)})
401
495
 
402
496
  return ds
403
497
 
@@ -474,6 +568,17 @@ class Dataset:
474
568
 
475
569
  return ds_concatenated
476
570
 
571
+ def post_process(self):
572
+ """
573
+ Placeholder method to be overridden by subclasses for dataset post-processing.
574
+
575
+ Returns
576
+ -------
577
+ None
578
+ This method does not return any value. Subclasses are expected to modify the dataset in-place.
579
+ """
580
+ pass
581
+
477
582
  def choose_subdomain(
478
583
  self, latitude_range, longitude_range, margin, straddle, return_subdomain=False
479
584
  ):
@@ -571,19 +676,6 @@ class Dataset:
571
676
  else:
572
677
  object.__setattr__(self, "ds", subdomain)
573
678
 
574
- def convert_to_negative_depth(self):
575
- """
576
- Converts the depth values in the dataset to negative if they are non-negative.
577
-
578
- This method checks the values in the depth dimension of the dataset (`self.ds[self.dim_names["depth"]]`).
579
- If all values are greater than or equal to zero, it negates them and updates the dataset accordingly.
580
-
581
- """
582
- depth = self.ds[self.dim_names["depth"]]
583
-
584
- if (depth >= 0).all():
585
- self.ds[self.dim_names["depth"]] = -depth
586
-
587
679
 
588
680
  @dataclass(frozen=True, kw_only=True)
589
681
  class TPXODataset(Dataset):
@@ -639,11 +731,29 @@ class TPXODataset(Dataset):
639
731
  ds: xr.Dataset = field(init=False, repr=False)
640
732
  reference_date: datetime = datetime(1992, 1, 1)
641
733
 
642
- def __post_init__(self):
643
- # Perform any necessary dataset initialization or modifications here
644
- ds = super().load_data()
734
+ def clean_up(self, ds: xr.Dataset) -> xr.Dataset:
735
+ """
736
+ Clean up and standardize the dimensions and coordinates of the dataset for further processing.
737
+
738
+ This method performs the following operations:
739
+ - Assigns new coordinate variables for 'omega', 'longitude', and 'latitude' based on existing dataset variables.
740
+ - 'omega' is retained as it is.
741
+ - 'longitude' is derived from 'lon_r', assuming it is constant along the 'ny' dimension.
742
+ - 'latitude' is derived from 'lat_r', assuming it is constant along the 'nx' dimension.
743
+ - Renames the dimensions 'nx' and 'ny' to 'longitude' and 'latitude', respectively, for consistency.
744
+ - Renames the tidal dimension to 'ntides' for standardization.
745
+ - Updates the `dim_names` attribute of the object to reflect the new dimension names: 'longitude', 'latitude', and 'ntides'.
645
746
 
646
- # Clean up dataset
747
+ Parameters
748
+ ----------
749
+ ds : xr.Dataset
750
+ The input dataset to be cleaned and standardized. It should contain the coordinates 'omega', 'lon_r', 'lat_r', and the tidal dimension.
751
+
752
+ Returns
753
+ -------
754
+ ds : xr.Dataset
755
+ A cleaned and standardized `xarray.Dataset` with updated coordinates and dimensions.
756
+ """
647
757
  ds = ds.assign_coords(
648
758
  {
649
759
  "omega": ds["omega"],
@@ -655,7 +765,9 @@ class TPXODataset(Dataset):
655
765
  ), # lat_r is constant along nx, i.e., is only a function of ny
656
766
  }
657
767
  )
658
- ds = ds.rename({"nx": "longitude", "ny": "latitude"})
768
+ ds = ds.rename(
769
+ {"nx": "longitude", "ny": "latitude", self.dim_names["ntides"]: "ntides"}
770
+ )
659
771
 
660
772
  object.__setattr__(
661
773
  self,
@@ -663,25 +775,11 @@ class TPXODataset(Dataset):
663
775
  {
664
776
  "latitude": "latitude",
665
777
  "longitude": "longitude",
666
- "ntides": self.dim_names["ntides"],
778
+ "ntides": "ntides",
667
779
  },
668
780
  )
669
- self.check_dataset(ds)
670
-
671
- # Select relevant fields
672
- ds = super().select_relevant_fields(ds)
673
-
674
- # Make sure that latitude is ascending
675
- ds = super().ensure_latitude_ascending(ds)
676
-
677
- # Check whether the data covers the entire globe
678
- object.__setattr__(self, "is_global", super().check_if_global(ds))
679
-
680
- # If dataset is global concatenate three copies of field along longitude dimension
681
- if self.is_global:
682
- ds = super().concatenate_longitudes(ds)
683
781
 
684
- object.__setattr__(self, "ds", ds)
782
+ return ds
685
783
 
686
784
  def check_number_constituents(self, ntides: int):
687
785
  """
@@ -702,6 +800,29 @@ class TPXODataset(Dataset):
702
800
  f"The dataset contains fewer than {ntides} tidal constituents."
703
801
  )
704
802
 
803
+ def post_process(self):
804
+ """
805
+ Apply a depth-based mask to the dataset, ensuring only positive depths are retained.
806
+
807
+ This method checks if the 'depth' variable is present in the dataset. If found, a mask is created where
808
+ depths greater than 0 are considered valid (mask value of 1). This mask is applied to all data variables
809
+ in the dataset, replacing values at invalid depths (depth ≤ 0) with NaN. The mask itself is also stored
810
+ in the dataset under the variable 'mask'.
811
+
812
+ Returns
813
+ -------
814
+ None
815
+ The dataset is modified in-place by applying the mask to each variable.
816
+ """
817
+
818
+ if "depth" in self.var_names.keys():
819
+ mask = xr.where(self.ds["depth"] > 0, 1, 0)
820
+
821
+ for var in self.ds.data_vars:
822
+ self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
823
+
824
+ self.ds["mask"] = mask
825
+
705
826
 
706
827
  @dataclass(frozen=True, kw_only=True)
707
828
  class GLORYSDataset(Dataset):
@@ -751,6 +872,33 @@ class GLORYSDataset(Dataset):
751
872
 
752
873
  climatology: Optional[bool] = False
753
874
 
875
+ def post_process(self):
876
+ """
877
+ Apply a mask to the dataset based on the 'zeta' variable, with 0 where 'zeta' is NaN.
878
+
879
+ This method creates a mask based on the
880
+ first time step (time=0) of 'zeta'. The mask has 1 for valid data and 0 where 'zeta' is NaN. This mask is applied
881
+ to all data variables, replacing values with NaN where 'zeta' is NaN at time=0.
882
+ The mask itself is stored in the dataset under the variable 'mask'.
883
+
884
+ Returns
885
+ -------
886
+ None
887
+ The dataset is modified in-place by applying the mask to each variable.
888
+
889
+ """
890
+
891
+ mask = xr.where(
892
+ self.ds[self.var_names["zeta"]].isel({self.dim_names["time"]: 0}).isnull(),
893
+ 0,
894
+ 1,
895
+ )
896
+
897
+ for var in self.ds.data_vars:
898
+ self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
899
+
900
+ self.ds["mask"] = mask
901
+
754
902
 
755
903
  @dataclass(frozen=True, kw_only=True)
756
904
  class CESMDataset(Dataset):
@@ -771,7 +919,7 @@ class CESMDataset(Dataset):
771
919
  dim_names: Dict[str, str], optional
772
920
  Dictionary specifying the names of dimensions in the dataset.
773
921
  climatology : bool
774
- Indicates whether the dataset is climatological. Defaults to True.
922
+ Indicates whether the dataset is climatological. Defaults to False.
775
923
 
776
924
  Attributes
777
925
  ----------
@@ -779,24 +927,20 @@ class CESMDataset(Dataset):
779
927
  The xarray Dataset containing the CESM data on its original grid.
780
928
  """
781
929
 
782
- # overwrite load_data method from parent class
783
- def load_data(self) -> xr.Dataset:
930
+ # overwrite clean_up method from parent class
931
+ def clean_up(self, ds: xr.Dataset) -> xr.Dataset:
784
932
  """
785
- Load dataset from the specified file.
933
+ Ensure the dataset's time dimension is correctly defined and standardized.
934
+
935
+ This method verifies that the time dimension exists in the dataset and assigns it appropriately. If the "time" dimension is missing, the method attempts to assign an existing "time" or "month" dimension. If neither exists, it expands the dataset to include a "time" dimension with a size of one.
786
936
 
787
937
  Returns
788
938
  -------
789
939
  ds : xr.Dataset
790
- The loaded xarray Dataset containing the forcing data.
940
+ The xarray Dataset with the correct time dimension assigned or added.
791
941
 
792
- Raises
793
- ------
794
- FileNotFoundError
795
- If the specified file does not exist.
796
942
  """
797
943
 
798
- ds = super().load_data()
799
-
800
944
  if "time" not in self.dim_names:
801
945
  if "time" in ds.dims:
802
946
  self.dim_names["time"] = "time"
@@ -864,7 +1008,7 @@ class CESMBGCDataset(CESMDataset):
864
1008
  dim_names: Dict[str, str], optional
865
1009
  Dictionary specifying the names of dimensions in the dataset.
866
1010
  climatology : bool
867
- Indicates whether the dataset is climatological. Defaults to True.
1011
+ Indicates whether the dataset is climatological. Defaults to False.
868
1012
 
869
1013
  Attributes
870
1014
  ----------
@@ -917,14 +1061,14 @@ class CESMBGCDataset(CESMDataset):
917
1061
  }
918
1062
  )
919
1063
 
920
- climatology: Optional[bool] = True
1064
+ climatology: Optional[bool] = False
921
1065
 
922
1066
  def post_process(self):
923
1067
  """
924
1068
  Processes and converts CESM data values as follows:
925
1069
  - Convert depth values from cm to m.
1070
+ - Apply a mask to the dataset based on the 'P04' variable at the surface.
926
1071
  """
927
-
928
1072
  if self.dim_names["depth"] == "z_t":
929
1073
  # Fill variables that only have data in upper 150m with NaNs below
930
1074
  if (
@@ -955,6 +1099,19 @@ class CESMBGCDataset(CESMDataset):
955
1099
  updated_dim_names["depth"] = "depth"
956
1100
  object.__setattr__(self, "dim_names", updated_dim_names)
957
1101
 
1102
+ mask = xr.where(
1103
+ self.ds[self.var_names["PO4"]]
1104
+ .isel({self.dim_names["time"]: 0, self.dim_names["depth"]: 0})
1105
+ .isnull(),
1106
+ 0,
1107
+ 1,
1108
+ )
1109
+
1110
+ for var in self.ds.data_vars:
1111
+ self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
1112
+
1113
+ self.ds["mask"] = mask
1114
+
958
1115
 
959
1116
  @dataclass(frozen=True, kw_only=True)
960
1117
  class CESMBGCSurfaceForcingDataset(CESMDataset):
@@ -1016,6 +1173,19 @@ class CESMBGCSurfaceForcingDataset(CESMDataset):
1016
1173
  ds = self.ds.drop_vars("z_t")
1017
1174
  object.__setattr__(self, "ds", ds)
1018
1175
 
1176
+ mask = xr.where(
1177
+ self.ds[self.var_names["pco2_air"]]
1178
+ .isel({self.dim_names["time"]: 0})
1179
+ .isnull(),
1180
+ 0,
1181
+ 1,
1182
+ )
1183
+
1184
+ for var in self.ds.data_vars:
1185
+ self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
1186
+
1187
+ self.ds["mask"] = mask
1188
+
1019
1189
 
1020
1190
  @dataclass(frozen=True, kw_only=True)
1021
1191
  class ERA5Dataset(Dataset):
@@ -1074,6 +1244,7 @@ class ERA5Dataset(Dataset):
1074
1244
  - Convert rainfall from meters to cm/day.
1075
1245
  - Convert temperature from Kelvin to Celsius.
1076
1246
  - Compute relative humidity if not present, convert to absolute humidity.
1247
+ - Use SST to create mask.
1077
1248
  """
1078
1249
  # Translate radiation to fluxes. ERA5 stores values integrated over 1 hour.
1079
1250
  # Convert radiation from J/m^2 to W/m^2
@@ -1125,6 +1296,8 @@ class ERA5Dataset(Dataset):
1125
1296
  for var in self.ds.data_vars:
1126
1297
  self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
1127
1298
 
1299
+ self.ds["mask"] = mask
1300
+
1128
1301
 
1129
1302
  @dataclass(frozen=True, kw_only=True)
1130
1303
  class ERA5Correction(Dataset):