roms-tools 3.1.2__py3-none-any.whl → 3.3.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 (221) hide show
  1. roms_tools/__init__.py +3 -0
  2. roms_tools/analysis/cdr_analysis.py +203 -0
  3. roms_tools/analysis/cdr_ensemble.py +198 -0
  4. roms_tools/analysis/roms_output.py +80 -46
  5. roms_tools/data/grids/GLORYS_global_grid.nc +0 -0
  6. roms_tools/download.py +4 -0
  7. roms_tools/plot.py +113 -51
  8. roms_tools/setup/boundary_forcing.py +45 -20
  9. roms_tools/setup/cdr_forcing.py +122 -8
  10. roms_tools/setup/cdr_release.py +161 -8
  11. roms_tools/setup/grid.py +150 -141
  12. roms_tools/setup/initial_conditions.py +113 -48
  13. roms_tools/setup/{datasets.py → lat_lon_datasets.py} +443 -938
  14. roms_tools/setup/mask.py +63 -7
  15. roms_tools/setup/nesting.py +314 -117
  16. roms_tools/setup/river_datasets.py +527 -0
  17. roms_tools/setup/river_forcing.py +46 -20
  18. roms_tools/setup/surface_forcing.py +7 -9
  19. roms_tools/setup/tides.py +2 -3
  20. roms_tools/setup/topography.py +8 -10
  21. roms_tools/setup/utils.py +396 -23
  22. roms_tools/tests/test_analysis/test_cdr_analysis.py +144 -0
  23. roms_tools/tests/test_analysis/test_cdr_ensemble.py +202 -0
  24. roms_tools/tests/test_analysis/test_roms_output.py +61 -3
  25. roms_tools/tests/test_setup/test_boundary_forcing.py +54 -52
  26. roms_tools/tests/test_setup/test_cdr_forcing.py +54 -0
  27. roms_tools/tests/test_setup/test_cdr_release.py +118 -1
  28. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_east/c/0/0/0 +0 -0
  29. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_north/c/0/0/0 +0 -0
  30. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/c/0/0/0 +0 -0
  31. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_east/c/0/0/0 +0 -0
  32. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_north/c/0/0/0 +0 -0
  33. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/c/0/0/0 +0 -0
  34. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_east/c/0/0/0 +0 -0
  35. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_north/c/0/0/0 +0 -0
  36. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/c/0/0/0 +0 -0
  37. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_east/c/0/0/0 +0 -0
  38. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_north/c/0/0/0 +0 -0
  39. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/c/0/0/0 +0 -0
  40. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_east/c/0/0/0 +0 -0
  41. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_north/c/0/0/0 +0 -0
  42. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/c/0/0/0 +0 -0
  43. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_east/c/0/0/0 +0 -0
  44. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_north/c/0/0/0 +0 -0
  45. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/c/0/0/0 +0 -0
  46. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_east/c/0/0/0 +0 -0
  47. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_north/c/0/0/0 +0 -0
  48. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/c/0/0/0 +0 -0
  49. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_east/c/0/0/0 +0 -0
  50. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_north/c/0/0/0 +0 -0
  51. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/c/0/0/0 +0 -0
  52. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_east/c/0/0/0 +0 -0
  53. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_north/c/0/0/0 +0 -0
  54. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/c/0/0/0 +0 -0
  55. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_east/c/0/0/0 +0 -0
  56. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_north/c/0/0/0 +0 -0
  57. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/c/0/0/0 +0 -0
  58. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_east/c/0/0/0 +0 -0
  59. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_north/c/0/0/0 +0 -0
  60. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/c/0/0/0 +0 -0
  61. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_east/c/0/0/0 +0 -0
  62. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_north/c/0/0/0 +0 -0
  63. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/c/0/0/0 +0 -0
  64. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_east/c/0/0/0 +0 -0
  65. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_north/c/0/0/0 +0 -0
  66. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/c/0/0/0 +0 -0
  67. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_east/c/0/0/0 +0 -0
  68. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_north/c/0/0/0 +0 -0
  69. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/c/0/0/0 +0 -0
  70. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_east/c/0/0/0 +0 -0
  71. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_north/c/0/0/0 +0 -0
  72. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/c/0/0/0 +0 -0
  73. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_east/c/0/0/0 +0 -0
  74. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_north/c/0/0/0 +0 -0
  75. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/c/0/0/0 +0 -0
  76. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_east/c/0/0/0 +0 -0
  77. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_north/c/0/0/0 +0 -0
  78. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/c/0/0/0 +0 -0
  79. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_east/c/0/0/0 +0 -0
  80. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_north/c/0/0/0 +0 -0
  81. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/c/0/0/0 +0 -0
  82. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_east/c/0/0/0 +0 -0
  83. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_north/c/0/0/0 +0 -0
  84. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/c/0/0/0 +0 -0
  85. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_east/c/0/0/0 +0 -0
  86. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_north/c/0/0/0 +0 -0
  87. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/c/0/0/0 +0 -0
  88. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_east/c/0/0/0 +0 -0
  89. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_north/c/0/0/0 +0 -0
  90. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/c/0/0/0 +0 -0
  91. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_east/c/0/0/0 +0 -0
  92. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_north/c/0/0/0 +0 -0
  93. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/c/0/0/0 +0 -0
  94. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_east/c/0/0/0 +0 -0
  95. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_north/c/0/0/0 +0 -0
  96. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/c/0/0/0 +0 -0
  97. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_east/c/0/0/0 +0 -0
  98. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_north/c/0/0/0 +0 -0
  99. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/c/0/0/0 +0 -0
  100. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_east/c/0/0/0 +0 -0
  101. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_north/c/0/0/0 +0 -0
  102. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/c/0/0/0 +0 -0
  103. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_east/c/0/0/0 +0 -0
  104. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_north/c/0/0/0 +0 -0
  105. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/c/0/0/0 +0 -0
  106. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_east/c/0/0/0 +0 -0
  107. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_north/c/0/0/0 +0 -0
  108. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/c/0/0/0 +0 -0
  109. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_east/c/0/0/0 +0 -0
  110. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_north/c/0/0/0 +0 -0
  111. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/c/0/0/0 +0 -0
  112. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_east/c/0/0/0 +0 -0
  113. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_north/c/0/0/0 +0 -0
  114. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/c/0/0/0 +0 -0
  115. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_east/c/0/0/0 +0 -0
  116. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_north/c/0/0/0 +0 -0
  117. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/c/0/0/0 +0 -0
  118. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_east/c/0/0/0 +0 -0
  119. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_north/c/0/0/0 +0 -0
  120. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/c/0/0/0 +0 -0
  121. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zarr.json +406 -406
  122. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_east/c/0/0/0 +0 -0
  123. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_north/c/0/0/0 +0 -0
  124. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/c/0/0/0 +0 -0
  125. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/c/0/0/0 +0 -0
  126. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/c/0/0/0 +0 -0
  127. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/c/0/0/0 +0 -0
  128. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/c/0/0/0 +0 -0
  129. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/c/0/0/0 +0 -0
  130. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/c/0/0/0 +0 -0
  131. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/c/0/0/0 +0 -0
  132. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/c/0/0/0 +0 -0
  133. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/c/0/0/0 +0 -0
  134. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/c/0/0/0 +0 -0
  135. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/c/0/0/0 +0 -0
  136. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/c/0/0/0 +0 -0
  137. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/c/0/0 +0 -0
  138. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/c/0/0 +0 -0
  139. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/c/0/0 +0 -0
  140. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/c/0/0 +0 -0
  141. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/c/0/0/0 +0 -0
  142. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/c/0/0/0 +0 -0
  143. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/c/0/0/0 +0 -0
  144. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/c/0/0/0 +0 -0
  145. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/c/0/0 +0 -0
  146. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/c/0/0 +0 -0
  147. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/c/0/0 +0 -0
  148. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/c/0/0 +0 -0
  149. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zarr.json +182 -182
  150. roms_tools/tests/test_setup/test_data/grid.zarr/h/c/0/0 +0 -0
  151. roms_tools/tests/test_setup/test_data/grid.zarr/zarr.json +191 -191
  152. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/h/c/0/0 +0 -0
  153. roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/zarr.json +210 -210
  154. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK/c/0/0/0/0 +0 -0
  155. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK_ALT_CO2/c/0/0/0/0 +0 -0
  156. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC/c/0/0/0/0 +0 -0
  157. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC_ALT_CO2/c/0/0/0/0 +0 -0
  158. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOC/c/0/0/0/0 +0 -0
  159. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOCr/c/0/0/0/0 +0 -0
  160. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DON/c/0/0/0/0 +0 -0
  161. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DONr/c/0/0/0/0 +0 -0
  162. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOP/c/0/0/0/0 +0 -0
  163. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOPr/c/0/0/0/0 +0 -0
  164. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Fe/c/0/0/0/0 +0 -0
  165. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Lig/c/0/0/0/0 +0 -0
  166. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NH4/c/0/0/0/0 +0 -0
  167. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NO3/c/0/0/0/0 +0 -0
  168. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/O2/c/0/0/0/0 +0 -0
  169. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/PO4/c/0/0/0/0 +0 -0
  170. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/SiO3/c/0/0/0/0 +0 -0
  171. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatC/c/0/0/0/0 +0 -0
  172. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatChl/c/0/0/0/0 +0 -0
  173. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatFe/c/0/0/0/0 +0 -0
  174. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatP/c/0/0/0/0 +0 -0
  175. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatSi/c/0/0/0/0 +0 -0
  176. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazC/c/0/0/0/0 +0 -0
  177. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazChl/c/0/0/0/0 +0 -0
  178. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazFe/c/0/0/0/0 +0 -0
  179. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazP/c/0/0/0/0 +0 -0
  180. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/salt/c/0/0/0/0 +0 -0
  181. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spC/c/0/0/0/0 +0 -0
  182. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spCaCO3/c/0/0/0/0 +0 -0
  183. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spChl/c/0/0/0/0 +0 -0
  184. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spFe/c/0/0/0/0 +0 -0
  185. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spP/c/0/0/0/0 +0 -0
  186. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/temp/c/0/0/0/0 +0 -0
  187. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/u/c/0/0/0/0 +0 -0
  188. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ubar/c/0/0/0 +0 -0
  189. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/v/c/0/0/0/0 +0 -0
  190. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/vbar/c/0/0/0 +0 -0
  191. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zarr.json +182 -182
  192. roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zooC/c/0/0/0/0 +0 -0
  193. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/salt/c/0/0/0/0 +0 -0
  194. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/temp/c/0/0/0/0 +0 -0
  195. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/u/c/0/0/0/0 +0 -0
  196. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ubar/c/0/0/0 +0 -0
  197. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/v/c/0/0/0/0 +0 -0
  198. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/vbar/c/0/0/0 +0 -0
  199. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zarr.json +187 -187
  200. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/u_Im/c/0/0/0 +0 -0
  201. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/u_Re/c/0/0/0 +0 -0
  202. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/v_Im/c/0/0/0 +0 -0
  203. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/v_Re/c/0/0/0 +0 -0
  204. roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/zarr.json +66 -66
  205. roms_tools/tests/test_setup/test_grid.py +236 -115
  206. roms_tools/tests/test_setup/test_initial_conditions.py +94 -41
  207. roms_tools/tests/test_setup/{test_datasets.py → test_lat_lon_datasets.py} +409 -100
  208. roms_tools/tests/test_setup/test_nesting.py +119 -31
  209. roms_tools/tests/test_setup/test_river_datasets.py +48 -0
  210. roms_tools/tests/test_setup/test_surface_forcing.py +2 -1
  211. roms_tools/tests/test_setup/test_utils.py +92 -2
  212. roms_tools/tests/test_setup/utils.py +71 -0
  213. roms_tools/tests/test_tiling/test_join.py +241 -0
  214. roms_tools/tests/test_utils.py +139 -17
  215. roms_tools/tiling/join.py +189 -0
  216. roms_tools/utils.py +131 -99
  217. {roms_tools-3.1.2.dist-info → roms_tools-3.3.0.dist-info}/METADATA +12 -2
  218. {roms_tools-3.1.2.dist-info → roms_tools-3.3.0.dist-info}/RECORD +221 -211
  219. {roms_tools-3.1.2.dist-info → roms_tools-3.3.0.dist-info}/WHEEL +0 -0
  220. {roms_tools-3.1.2.dist-info → roms_tools-3.3.0.dist-info}/licenses/LICENSE +0 -0
  221. {roms_tools-3.1.2.dist-info → roms_tools-3.3.0.dist-info}/top_level.txt +0 -0
@@ -11,9 +11,10 @@ from roms_tools.setup.nesting import (
11
11
  compute_boundary_distance,
12
12
  interpolate_indices,
13
13
  map_child_boundaries_onto_parent_grid_indices,
14
- modify_child_topography_and_mask,
14
+ modify_child_mask,
15
+ modify_child_topography,
15
16
  )
16
- from roms_tools.setup.utils import get_boundary_coords
17
+ from roms_tools.setup.utils import get_boundary_coords, wrap_longitudes
17
18
 
18
19
 
19
20
  @pytest.fixture()
@@ -46,9 +47,7 @@ def big_grid_that_straddles():
46
47
 
47
48
  @pytest.fixture()
48
49
  def small_grid_that_straddles():
49
- return Grid(
50
- nx=10, ny=10, center_lon=10, center_lat=61, rot=-20, size_x=500, size_y=500
51
- )
50
+ return Grid(nx=10, ny=10, center_lon=0, center_lat=61, rot=0, size_x=50, size_y=200)
52
51
 
53
52
 
54
53
  @pytest.fixture()
@@ -71,11 +70,11 @@ def child_grid_that_straddles(big_grid_that_straddles):
71
70
  parent_grid=big_grid_that_straddles,
72
71
  nx=10,
73
72
  ny=10,
74
- center_lon=10,
73
+ center_lon=0,
75
74
  center_lat=61,
76
- rot=-20,
77
- size_x=500,
78
- size_y=500,
75
+ rot=0,
76
+ size_x=50,
77
+ size_y=200,
79
78
  )
80
79
 
81
80
 
@@ -100,13 +99,14 @@ class TestInterpolateIndices:
100
99
  mask = grid.ds[f"mask_{location}"].isel(**bdry_coords)
101
100
 
102
101
  with caplog.at_level(logging.WARNING):
103
- i_eta, i_xi = interpolate_indices(grid.ds, lon, lat, mask)
102
+ i_eta, i_xi = interpolate_indices(grid.ds, lon, lat, mask, direction)
104
103
 
105
- # Verify the warning message in the log
106
- assert (
107
- "Some boundary points of the child grid are very close to the boundary of the parent grid."
108
- in caplog.text
109
- )
104
+ if mask.sum() > 0:
105
+ # Verify the warning message in the log
106
+ assert (
107
+ "boundary of the child grid lie very close to the edges of the parent grid"
108
+ in caplog.text
109
+ )
110
110
 
111
111
  if direction == "south":
112
112
  expected_i_eta = -0.5 * xr.ones_like(grid.ds.xi_rho)
@@ -142,20 +142,27 @@ class TestInterpolateIndices:
142
142
  big_grid = request.getfixturevalue(big_grid_fixture)
143
143
  small_grid = request.getfixturevalue(small_grid_fixture)
144
144
 
145
+ big_grid_ds = wrap_longitudes(big_grid.ds.copy(), straddle=big_grid.straddle)
146
+ small_grid_ds = wrap_longitudes(
147
+ small_grid.ds.copy(), straddle=big_grid.straddle
148
+ )
149
+
145
150
  bdry_coords_dict = get_boundary_coords()
146
151
  for location in ["rho", "u", "v"]:
147
152
  for direction in ["south", "east", "north", "west"]:
148
153
  bdry_coords = bdry_coords_dict[location][direction]
149
- lon = small_grid.ds[f"lon_{location}"].isel(**bdry_coords)
150
- lat = small_grid.ds[f"lat_{location}"].isel(**bdry_coords)
151
- mask = small_grid.ds[f"mask_{location}"].isel(**bdry_coords)
154
+ lon = small_grid_ds[f"lon_{location}"].isel(**bdry_coords)
155
+ lat = small_grid_ds[f"lat_{location}"].isel(**bdry_coords)
156
+ mask = small_grid_ds[f"mask_{location}"].isel(**bdry_coords)
152
157
 
153
- i_eta, i_xi = interpolate_indices(big_grid.ds, lon, lat, mask)
158
+ i_eta, i_xi = interpolate_indices(
159
+ big_grid_ds, lon, lat, mask, direction
160
+ )
154
161
 
155
162
  expected_i_eta_min = -0.5
156
- expected_i_eta_max = big_grid.ds.eta_rho[-1] - 0.5
163
+ expected_i_eta_max = big_grid_ds.eta_rho[-1] - 0.5
157
164
  expected_i_xi_min = -0.5
158
- expected_i_xi_max = big_grid.ds.xi_rho[-1] - 0.5
165
+ expected_i_xi_max = big_grid_ds.xi_rho[-1] - 0.5
159
166
 
160
167
  assert (i_eta >= expected_i_eta_min).all()
161
168
  assert (i_eta <= expected_i_eta_max).all()
@@ -166,11 +173,16 @@ class TestInterpolateIndices:
166
173
  class TestMapChildBoundaries:
167
174
  def test_update_indices_does_nothing_if_no_parent_land(self, small_grid, baby_grid):
168
175
  """Verify no change in indices when parent grid has no land at boundaries."""
176
+ small_grid_ds = wrap_longitudes(
177
+ small_grid.ds.copy(), straddle=small_grid.straddle
178
+ )
179
+ baby_grid_ds = wrap_longitudes(baby_grid.ds.copy(), straddle=baby_grid.straddle)
180
+
169
181
  ds_without_updated_indices = map_child_boundaries_onto_parent_grid_indices(
170
- small_grid.ds, baby_grid.ds, update_land_indices=False
182
+ small_grid_ds, baby_grid_ds, update_land_indices=False
171
183
  )
172
184
  ds_with_updated_indices = map_child_boundaries_onto_parent_grid_indices(
173
- small_grid.ds, baby_grid.ds, update_land_indices=True
185
+ small_grid_ds, baby_grid_ds, update_land_indices=True
174
186
  )
175
187
 
176
188
  xr.testing.assert_allclose(ds_without_updated_indices, ds_with_updated_indices)
@@ -189,7 +201,12 @@ class TestMapChildBoundaries:
189
201
  big_grid = request.getfixturevalue(big_grid_fixture)
190
202
  small_grid = request.getfixturevalue(small_grid_fixture)
191
203
 
192
- ds = map_child_boundaries_onto_parent_grid_indices(big_grid.ds, small_grid.ds)
204
+ big_grid_ds = wrap_longitudes(big_grid.ds.copy(), straddle=big_grid.straddle)
205
+ small_grid_ds = wrap_longitudes(
206
+ small_grid.ds.copy(), straddle=big_grid.straddle
207
+ )
208
+
209
+ ds = map_child_boundaries_onto_parent_grid_indices(big_grid_ds, small_grid_ds)
193
210
  for direction in ["south", "east", "north", "west"]:
194
211
  for location in ["rho", "u", "v"]:
195
212
  if location == "rho":
@@ -224,9 +241,14 @@ class TestMapChildBoundaries:
224
241
  big_grid = request.getfixturevalue(big_grid_fixture)
225
242
  small_grid = request.getfixturevalue(small_grid_fixture)
226
243
 
244
+ big_grid_ds = wrap_longitudes(big_grid.ds.copy(), straddle=big_grid.straddle)
245
+ small_grid_ds = wrap_longitudes(
246
+ small_grid.ds.copy(), straddle=big_grid.straddle
247
+ )
248
+
227
249
  for update_land_indices in [False, True]:
228
250
  ds = map_child_boundaries_onto_parent_grid_indices(
229
- big_grid.ds, small_grid.ds, update_land_indices=update_land_indices
251
+ big_grid_ds, small_grid_ds, update_land_indices=update_land_indices
230
252
  )
231
253
 
232
254
  for direction in ["south", "east", "north", "west"]:
@@ -292,9 +314,7 @@ class TestModifyChid:
292
314
  ):
293
315
  """Confirm child mask remains unchanged if no parent land is at boundaries."""
294
316
  mask_original = baby_grid.ds.mask_rho.copy()
295
- modified_baby_grid_ds = modify_child_topography_and_mask(
296
- small_grid.ds, baby_grid.ds
297
- )
317
+ modified_baby_grid_ds = modify_child_mask(small_grid.ds, baby_grid.ds)
298
318
  xr.testing.assert_allclose(modified_baby_grid_ds.mask_rho, mask_original)
299
319
 
300
320
  @pytest.mark.parametrize(
@@ -311,7 +331,8 @@ class TestModifyChid:
311
331
 
312
332
  h_original = grid.ds.h.copy()
313
333
  mask_original = grid.ds.mask_rho.copy()
314
- modified_grid_ds = modify_child_topography_and_mask(grid.ds, grid.ds)
334
+ modified_grid_ds = modify_child_mask(grid.ds, grid.ds)
335
+ modified_grid_ds = modify_child_topography(grid.ds, modified_grid_ds)
315
336
 
316
337
  xr.testing.assert_allclose(modified_grid_ds.h, h_original)
317
338
  xr.testing.assert_allclose(modified_grid_ds.mask_rho, mask_original)
@@ -325,7 +346,8 @@ class TestModifyChid:
325
346
  mask_original = small_grid.ds.mask_rho.copy()
326
347
 
327
348
  # Apply the modification function
328
- modified_ds = modify_child_topography_and_mask(big_grid.ds, small_grid.ds)
349
+ modified_ds = modify_child_mask(big_grid.ds, small_grid.ds)
350
+ modified_ds = modify_child_topography(big_grid.ds, modified_ds)
329
351
 
330
352
  # Calculate the center indices for the grid
331
353
  eta_center = h_original.sizes["eta_rho"] // 2
@@ -405,9 +427,75 @@ class TestNesting:
405
427
  params = dataclasses.asdict(small_grid)
406
428
  del params["ds"], params["straddle"]
407
429
 
408
- with pytest.raises(ValueError, match="Some points are outside the grid."):
430
+ with pytest.raises(
431
+ ValueError, match="boundary of the child grid lie outside the parent grid"
432
+ ):
409
433
  ChildGrid(parent_grid=big_grid, **params)
410
434
 
435
+ def test_no_error_if_land_child_points_beyond_parent_grid(self):
436
+ # coarse resolution Pacific domain
437
+ parent_grid = Grid(
438
+ nx=50,
439
+ ny=50,
440
+ size_x=23000,
441
+ size_y=12000,
442
+ center_lon=-161,
443
+ center_lat=14.4,
444
+ rot=-3,
445
+ )
446
+
447
+ # California Current System domain, where some land points extend beyond Pacific domain
448
+ child_grid_parameters = {
449
+ "nx": 50,
450
+ "ny": 50,
451
+ "size_x": 2688,
452
+ "size_y": 5280,
453
+ "center_lat": 39.6,
454
+ "center_lon": -134.5,
455
+ "rot": 33.3,
456
+ }
457
+
458
+ child_grid = ChildGrid(
459
+ **child_grid_parameters,
460
+ parent_grid=parent_grid,
461
+ boundaries={"north": True, "west": True, "south": True, "east": False},
462
+ )
463
+ assert isinstance(child_grid.ds, xr.Dataset)
464
+
465
+ def test_no_error_if_child_boundary_entirely_on_land(self):
466
+ parent_grid = Grid(
467
+ nx=7,
468
+ ny=7,
469
+ size_x=240,
470
+ size_y=240,
471
+ center_lon=-4.1,
472
+ center_lat=52.36,
473
+ rot=0,
474
+ )
475
+
476
+ child_grid_parameters = {
477
+ "nx": 5,
478
+ "ny": 5,
479
+ "size_x": 100,
480
+ "size_y": 100,
481
+ "center_lon": -4.1,
482
+ "center_lat": 52.36,
483
+ }
484
+
485
+ child_grid = ChildGrid(
486
+ **child_grid_parameters,
487
+ parent_grid=parent_grid,
488
+ boundaries={
489
+ "south": True,
490
+ "east": True,
491
+ "north": True,
492
+ "west": True,
493
+ },
494
+ )
495
+
496
+ assert isinstance(child_grid.ds, xr.Dataset)
497
+ assert isinstance(child_grid.ds_nesting, xr.Dataset)
498
+
411
499
  @pytest.mark.parametrize(
412
500
  "child_grid_fixture",
413
501
  ["child_grid", "child_grid_that_straddles"],
@@ -0,0 +1,48 @@
1
+ from datetime import datetime
2
+
3
+ import numpy as np
4
+ import xarray as xr
5
+
6
+ from roms_tools.setup.river_datasets import RiverDataset
7
+
8
+
9
+ class TestRiverDataset:
10
+ def test_deduplicate_river_names(self, tmp_path):
11
+ sample_dim_and_var_names = {
12
+ "dim_names": {"station": "station", "time": "time"},
13
+ "var_names": {
14
+ "latitude": "lat",
15
+ "longitude": "lon",
16
+ "flux": "flux",
17
+ "ratio": "ratio",
18
+ "name": "name",
19
+ },
20
+ }
21
+
22
+ data = {
23
+ "lat": (["station"], [10.0, 20.0, 30.0]),
24
+ "lon": (["station"], [100.0, 110.0, 120.0]),
25
+ "flux": (["time", "station"], np.random.rand(1, 3)),
26
+ "ratio": (["time", "station"], np.random.rand(1, 3)),
27
+ "name": (["station"], ["Amazon", "Nile", "Amazon"]), # duplicate
28
+ }
29
+ coords = {"station": [0, 1, 2], "time": [0]}
30
+ ds = xr.Dataset(data, coords=coords)
31
+
32
+ # Write to temporary NetCDF file
33
+ file_path = tmp_path / "rivers.nc"
34
+ ds.to_netcdf(file_path)
35
+
36
+ river_dataset = RiverDataset(
37
+ filename=file_path,
38
+ start_time=datetime(2000, 1, 1),
39
+ end_time=datetime(2000, 1, 2),
40
+ dim_names=sample_dim_and_var_names["dim_names"],
41
+ var_names=sample_dim_and_var_names["var_names"],
42
+ )
43
+
44
+ names = river_dataset.ds["name"].values
45
+ assert "Amazon_1" in names
46
+ assert "Amazon_2" in names
47
+ assert "Nile" in names
48
+ assert len(set(names)) == len(names) # all names must be unique
@@ -10,6 +10,7 @@ import xarray as xr
10
10
  from conftest import calculate_data_hash
11
11
  from roms_tools import Grid, SurfaceForcing
12
12
  from roms_tools.download import download_test_data
13
+ from roms_tools.setup.utils import RawDataSource
13
14
 
14
15
 
15
16
  @pytest.fixture
@@ -159,7 +160,7 @@ def _test_successful_initialization(
159
160
  grid: Grid,
160
161
  start_time: datetime,
161
162
  end_time: datetime,
162
- source: dict[str, str],
163
+ source: RawDataSource,
163
164
  coarse_grid_mode: str,
164
165
  use_dask: bool,
165
166
  caplog,
@@ -2,13 +2,103 @@ import logging
2
2
  from datetime import datetime
3
3
  from pathlib import Path
4
4
 
5
+ import numpy as np
5
6
  import pytest
6
7
  import xarray as xr
7
8
 
8
9
  from roms_tools import BoundaryForcing, Grid
9
10
  from roms_tools.download import download_test_data
10
- from roms_tools.setup.datasets import ERA5Correction
11
- from roms_tools.setup.utils import interpolate_from_climatology, validate_names
11
+ from roms_tools.setup.lat_lon_datasets import ERA5Correction
12
+ from roms_tools.setup.utils import (
13
+ get_target_coords,
14
+ interpolate_from_climatology,
15
+ validate_names,
16
+ )
17
+
18
+
19
+ class DummyGrid:
20
+ """Lightweight grid wrapper mimicking the real Grid API for testing."""
21
+
22
+ def __init__(self, ds: xr.Dataset, straddle: bool):
23
+ """Initialize grid wrapper."""
24
+ self.ds = ds
25
+ self.straddle = straddle
26
+
27
+
28
+ class TestGetTargetCoords:
29
+ def make_rho_grid(self, lons, lats, with_mask=False):
30
+ """Helper to create a minimal rho grid dataset."""
31
+ eta, xi = len(lats), len(lons)
32
+ lon_rho, lat_rho = np.meshgrid(lons, lats)
33
+ ds = xr.Dataset(
34
+ {
35
+ "lon_rho": (("eta_rho", "xi_rho"), lon_rho),
36
+ "lat_rho": (("eta_rho", "xi_rho"), lat_rho),
37
+ "angle": (("eta_rho", "xi_rho"), np.zeros_like(lon_rho)),
38
+ },
39
+ coords={"eta_rho": np.arange(eta), "xi_rho": np.arange(xi)},
40
+ )
41
+ if with_mask:
42
+ ds["mask_rho"] = (("eta_rho", "xi_rho"), np.ones_like(lon_rho))
43
+ return ds
44
+
45
+ def test_basic_rho_grid(self):
46
+ ds = self.make_rho_grid(lons=[-10, -5, 0, 5, 10], lats=[50, 55])
47
+ grid = DummyGrid(ds, straddle=True)
48
+ result = get_target_coords(grid)
49
+ assert "lat" in result and "lon" in result
50
+ assert np.allclose(result["lon"], ds.lon_rho)
51
+
52
+ def test_wrap_longitudes_to_minus180_180(self):
53
+ ds = self.make_rho_grid(lons=[190, 200], lats=[0, 1])
54
+ grid = DummyGrid(ds, straddle=True)
55
+ result = get_target_coords(grid)
56
+ # longitudes >180 should wrap to -170, -160
57
+ expected = np.array([[-170, -160], [-170, -160]])
58
+ assert np.allclose(result["lon"].values, expected)
59
+
60
+ def test_convert_to_0_360_if_far_from_greenwich(self):
61
+ ds = self.make_rho_grid(lons=[-170, -160], lats=[0, 1])
62
+ grid = DummyGrid(ds, straddle=False)
63
+ result = get_target_coords(grid)
64
+ # Should convert to 190, 200 since domain is far from Greenwich
65
+ expected = np.array([[190, 200], [190, 200]])
66
+ assert np.allclose(result["lon"].values, expected)
67
+ assert result["straddle"] is False
68
+
69
+ def test_close_to_greenwich_stays_minus180_180(self):
70
+ ds = self.make_rho_grid(lons=[-2, -1], lats=[0, 1])
71
+ grid = DummyGrid(ds, straddle=False)
72
+ result = get_target_coords(grid)
73
+ # Should remain unchanged (-2, -1), not converted to 358, 359
74
+ expected = np.array([[-2, -1], [-2, -1]])
75
+ assert np.allclose(result["lon"].values, expected)
76
+ assert result["straddle"] is True
77
+
78
+ def test_includes_optional_fields(self):
79
+ ds = self.make_rho_grid(lons=[-10, -5], lats=[0, 1], with_mask=True)
80
+ grid = DummyGrid(ds, straddle=True)
81
+ result = get_target_coords(grid)
82
+ assert result["mask"] is not None
83
+
84
+ def test_coarse_grid_selection(self):
85
+ lon = np.array([[190, 200]])
86
+ lat = np.array([[10, 10]])
87
+ ds = xr.Dataset(
88
+ {
89
+ "lon_coarse": (("eta_coarse", "xi_coarse"), lon),
90
+ "lat_coarse": (("eta_coarse", "xi_coarse"), lat),
91
+ "angle_coarse": (("eta_coarse", "xi_coarse"), np.zeros_like(lon)),
92
+ "mask_coarse": (("eta_coarse", "xi_coarse"), np.ones_like(lon)),
93
+ },
94
+ coords={"eta_coarse": [0], "xi_coarse": [0, 1]},
95
+ )
96
+ grid = DummyGrid(ds, straddle=True)
97
+ result = get_target_coords(grid, use_coarse_grid=True)
98
+ # Should wrap longitudes to -170, -160
99
+ expected = np.array([[-170, -160]])
100
+ assert np.allclose(result["lon"].values, expected)
101
+ assert "mask" in result
12
102
 
13
103
 
14
104
  def test_interpolate_from_climatology(use_dask):
@@ -0,0 +1,71 @@
1
+ from datetime import datetime
2
+ from pathlib import Path
3
+
4
+ from roms_tools import Grid, get_glorys_bounds
5
+
6
+ try:
7
+ import copernicusmarine # type: ignore
8
+ except ImportError:
9
+ copernicusmarine = None
10
+
11
+
12
+ def download_regional_and_bigger(
13
+ tmp_path: Path,
14
+ grid: Grid,
15
+ start_time: datetime,
16
+ variables: list[str] = ["thetao", "so", "uo", "vo", "zos"],
17
+ ) -> tuple[Path, Path]:
18
+ """
19
+ Helper: download minimal and slightly bigger GLORYS subsets.
20
+
21
+ Parameters
22
+ ----------
23
+ tmp_path : Path
24
+ Directory to store the downloaded NetCDF files.
25
+ grid : Grid
26
+ ROMS-Tools Grid object defining the target domain.
27
+ start_time : datetime
28
+ Start time of the requested subset.
29
+ variables : list[str]
30
+ What variables to download.
31
+
32
+ Returns
33
+ -------
34
+ Tuple[Path, Path]
35
+ Paths to the minimal and slightly bigger GLORYS subset files.
36
+ """
37
+ bounds = get_glorys_bounds(grid)
38
+
39
+ # minimal dataset
40
+ regional_file = tmp_path / "regional_GLORYS.nc"
41
+ copernicusmarine.subset(
42
+ dataset_id="cmems_mod_glo_phy_my_0.083deg_P1D-m",
43
+ variables=variables,
44
+ **bounds,
45
+ start_datetime=start_time,
46
+ end_datetime=start_time,
47
+ coordinates_selection_method="outside",
48
+ output_filename=str(regional_file),
49
+ )
50
+
51
+ # slightly bigger dataset
52
+ for key, delta in {
53
+ "minimum_latitude": -1,
54
+ "minimum_longitude": -1,
55
+ "maximum_latitude": +1,
56
+ "maximum_longitude": +1,
57
+ }.items():
58
+ bounds[key] += delta
59
+
60
+ bigger_regional_file = tmp_path / "bigger_regional_GLORYS.nc"
61
+ copernicusmarine.subset(
62
+ dataset_id="cmems_mod_glo_phy_my_0.083deg_P1D-m",
63
+ variables=variables,
64
+ **bounds,
65
+ start_datetime=start_time,
66
+ end_datetime=start_time,
67
+ coordinates_selection_method="outside",
68
+ output_filename=str(bigger_regional_file),
69
+ )
70
+
71
+ return regional_file, bigger_regional_file