roms-tools 1.6.0__py3-none-any.whl → 1.6.2__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 (159) hide show
  1. roms_tools/__init__.py +4 -1
  2. roms_tools/_version.py +1 -1
  3. roms_tools/setup/boundary_forcing.py +155 -52
  4. roms_tools/setup/datasets.py +5 -5
  5. roms_tools/setup/grid.py +9 -11
  6. roms_tools/setup/initial_conditions.py +82 -25
  7. roms_tools/setup/plot.py +68 -10
  8. roms_tools/setup/surface_forcing.py +60 -42
  9. roms_tools/setup/tides.py +35 -13
  10. roms_tools/setup/utils.py +15 -6
  11. roms_tools/tests/test_setup/test_boundary_forcing.py +140 -18
  12. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_east/0.0.0 +0 -0
  13. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_south/0.0.0 +0 -0
  14. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/0.0.0 +0 -0
  15. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_east/0.0.0 +0 -0
  16. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_south/0.0.0 +0 -0
  17. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/0.0.0 +0 -0
  18. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_east/0.0.0 +0 -0
  19. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_south/0.0.0 +0 -0
  20. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/0.0.0 +0 -0
  21. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_east/0.0.0 +0 -0
  22. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_south/0.0.0 +0 -0
  23. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/0.0.0 +0 -0
  24. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_east/0.0.0 +0 -0
  25. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_south/0.0.0 +0 -0
  26. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/0.0.0 +0 -0
  27. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_east/0.0.0 +0 -0
  28. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_south/0.0.0 +0 -0
  29. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/0.0.0 +0 -0
  30. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_east/0.0.0 +0 -0
  31. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_south/0.0.0 +0 -0
  32. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/0.0.0 +0 -0
  33. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_east/0.0.0 +0 -0
  34. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_south/0.0.0 +0 -0
  35. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/0.0.0 +0 -0
  36. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_east/0.0.0 +0 -0
  37. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_south/0.0.0 +0 -0
  38. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/0.0.0 +0 -0
  39. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_east/0.0.0 +0 -0
  40. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_south/0.0.0 +0 -0
  41. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/0.0.0 +0 -0
  42. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_east/0.0.0 +0 -0
  43. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_south/0.0.0 +0 -0
  44. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/0.0.0 +0 -0
  45. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_east/0.0.0 +0 -0
  46. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_south/0.0.0 +0 -0
  47. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/0.0.0 +0 -0
  48. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_east/0.0.0 +0 -0
  49. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_north/0.0.0 +0 -0
  50. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_south/0.0.0 +0 -0
  51. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/0.0.0 +0 -0
  52. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_east/0.0.0 +0 -0
  53. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_south/0.0.0 +0 -0
  54. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/0.0.0 +0 -0
  55. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_east/0.0.0 +0 -0
  56. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_south/0.0.0 +0 -0
  57. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/0.0.0 +0 -0
  58. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_east/0.0.0 +0 -0
  59. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_south/0.0.0 +0 -0
  60. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/0.0.0 +0 -0
  61. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_east/0.0.0 +0 -0
  62. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_south/0.0.0 +0 -0
  63. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/0.0.0 +0 -0
  64. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_east/0.0.0 +0 -0
  65. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_north/0.0.0 +0 -0
  66. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_south/0.0.0 +0 -0
  67. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/0.0.0 +0 -0
  68. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_east/0.0.0 +0 -0
  69. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_north/0.0.0 +0 -0
  70. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_south/0.0.0 +0 -0
  71. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/0.0.0 +0 -0
  72. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_east/0.0.0 +0 -0
  73. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_north/0.0.0 +0 -0
  74. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_south/0.0.0 +0 -0
  75. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/0.0.0 +0 -0
  76. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_east/0.0.0 +0 -0
  77. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_north/0.0.0 +0 -0
  78. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_south/0.0.0 +0 -0
  79. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/0.0.0 +0 -0
  80. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_east/0.0.0 +0 -0
  81. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_north/0.0.0 +0 -0
  82. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_south/0.0.0 +0 -0
  83. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/0.0.0 +0 -0
  84. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_east/0.0.0 +0 -0
  85. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_north/0.0.0 +0 -0
  86. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_south/0.0.0 +0 -0
  87. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/0.0.0 +0 -0
  88. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_east/0.0.0 +0 -0
  89. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_north/0.0.0 +0 -0
  90. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_south/0.0.0 +0 -0
  91. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/0.0.0 +0 -0
  92. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_east/0.0.0 +0 -0
  93. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_north/0.0.0 +0 -0
  94. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_south/0.0.0 +0 -0
  95. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/0.0.0 +0 -0
  96. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_east/0.0.0 +0 -0
  97. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_north/0.0.0 +0 -0
  98. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_south/0.0.0 +0 -0
  99. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/0.0.0 +0 -0
  100. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_east/0.0.0 +0 -0
  101. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_north/0.0.0 +0 -0
  102. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_south/0.0.0 +0 -0
  103. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/0.0.0 +0 -0
  104. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_east/0.0.0 +0 -0
  105. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_north/0.0.0 +0 -0
  106. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_south/0.0.0 +0 -0
  107. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/0.0.0 +0 -0
  108. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_east/0.0.0 +0 -0
  109. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_north/0.0.0 +0 -0
  110. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_south/0.0.0 +0 -0
  111. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/0.0.0 +0 -0
  112. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_east/0.0.0 +0 -0
  113. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_north/0.0.0 +0 -0
  114. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_south/0.0.0 +0 -0
  115. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/0.0.0 +0 -0
  116. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_east/0.0.0 +0 -0
  117. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_north/0.0.0 +0 -0
  118. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_south/0.0.0 +0 -0
  119. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/0.0.0 +0 -0
  120. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_east/0.0.0 +0 -0
  121. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_north/0.0.0 +0 -0
  122. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_south/0.0.0 +0 -0
  123. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/0.0.0 +0 -0
  124. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +0 -7
  125. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zattrs +0 -3
  126. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/0.0.0 +0 -0
  127. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/0.0.0 +0 -0
  128. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/0.0.0 +0 -0
  129. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/0.0.0 +0 -0
  130. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/0.0.0 +0 -0
  131. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/0.0.0 +0 -0
  132. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/0.0.0 +0 -0
  133. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/0.0 +0 -0
  134. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/0.0 +0 -0
  135. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/0.0 +0 -0
  136. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/0.0.0 +0 -0
  137. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/0.0.0 +0 -0
  138. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/0.0.0 +0 -0
  139. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/0.0.0 +0 -0
  140. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/0.0 +0 -0
  141. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/0.0 +0 -0
  142. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/0.0 +0 -0
  143. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/0.0 +0 -0
  144. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/.zattrs +0 -1
  145. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/0.0 +0 -0
  146. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/.zattrs +0 -1
  147. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zattrs +0 -1
  148. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
  149. roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/.zattrs +0 -1
  150. roms_tools/tests/test_setup/test_datasets.py +8 -3
  151. roms_tools/tests/test_setup/test_grid.py +6 -5
  152. roms_tools/tests/test_setup/test_initial_conditions.py +8 -4
  153. roms_tools/tests/test_setup/test_surface_forcing.py +47 -27
  154. roms_tools/tests/test_setup/test_tides.py +6 -4
  155. {roms_tools-1.6.0.dist-info → roms_tools-1.6.2.dist-info}/METADATA +2 -1
  156. {roms_tools-1.6.0.dist-info → roms_tools-1.6.2.dist-info}/RECORD +159 -159
  157. {roms_tools-1.6.0.dist-info → roms_tools-1.6.2.dist-info}/LICENSE +0 -0
  158. {roms_tools-1.6.0.dist-info → roms_tools-1.6.2.dist-info}/WHEEL +0 -0
  159. {roms_tools-1.6.0.dist-info → roms_tools-1.6.2.dist-info}/top_level.txt +0 -0
roms_tools/setup/tides.py CHANGED
@@ -129,7 +129,7 @@ class TidalForcing:
129
129
 
130
130
  ds = self._add_global_metadata(ds)
131
131
 
132
- self._validate(ds)
132
+ self._validate(ds, variable_info)
133
133
 
134
134
  # substitute NaNs over land by a fill value to avoid blow-up of ROMS
135
135
  for var_name in ds.data_vars:
@@ -176,33 +176,37 @@ class TidalForcing:
176
176
 
177
177
  # Define a dictionary for variable names and their associated information
178
178
  variable_info = {
179
- "ssh_Re": default_info,
180
- "ssh_Im": default_info,
181
- "pot_Re": default_info,
182
- "pot_Im": default_info,
179
+ "ssh_Re": {**default_info, "validate": True},
180
+ "ssh_Im": {**default_info, "validate": False},
181
+ "pot_Re": {**default_info, "validate": False},
182
+ "pot_Im": {**default_info, "validate": False},
183
183
  "u_Re": {
184
184
  "location": "u",
185
185
  "is_vector": True,
186
186
  "vector_pair": "v_Re",
187
187
  "is_3d": False,
188
+ "validate": True,
188
189
  },
189
190
  "v_Re": {
190
191
  "location": "v",
191
192
  "is_vector": True,
192
193
  "vector_pair": "u_Re",
193
194
  "is_3d": False,
195
+ "validate": True,
194
196
  },
195
197
  "u_Im": {
196
198
  "location": "u",
197
199
  "is_vector": True,
198
200
  "vector_pair": "v_Im",
199
201
  "is_3d": False,
202
+ "validate": False,
200
203
  },
201
204
  "v_Im": {
202
205
  "location": "v",
203
206
  "is_vector": True,
204
207
  "vector_pair": "u_Im",
205
208
  "is_3d": False,
209
+ "validate": False,
206
210
  },
207
211
  }
208
212
 
@@ -239,14 +243,17 @@ class TidalForcing:
239
243
 
240
244
  return ds
241
245
 
242
- def _validate(self, ds):
243
- """Validates the dataset by checking for NaN values at wet points, which would
244
- indicate missing raw data coverage over the target domain.
246
+ def _validate(self, ds, variable_info):
247
+ """Validates the dataset by checking for NaN values at wet points for specified
248
+ variables, which would indicate missing raw data coverage over the target
249
+ domain.
245
250
 
246
251
  Parameters
247
252
  ----------
248
253
  ds : xarray.Dataset
249
254
  The dataset to validate, containing tidal variables and a mask for wet points.
255
+ variable_info : dict
256
+ A dictionary containing metadata about the variables, including whether to validate them.
250
257
 
251
258
  Raises
252
259
  ------
@@ -260,7 +267,9 @@ class TidalForcing:
260
267
  The method utilizes `self.grid.ds.mask_rho` to determine the wet points in the domain.
261
268
  """
262
269
  for var_name in ds.data_vars:
263
- nan_check(ds[var_name].isel(ntides=0), self.grid.ds.mask_rho)
270
+ # only validate variables based on "validate" flag if use_dask is false
271
+ if not self.use_dask or variable_info[var_name]["validate"]:
272
+ nan_check(ds[var_name].isel(ntides=0), self.grid.ds.mask_rho)
264
273
 
265
274
  def plot(self, var_name, ntides=0) -> None:
266
275
  """Plot the specified tidal forcing variable for a given tidal constituent.
@@ -300,7 +309,14 @@ class TidalForcing:
300
309
  >>> tidal_forcing.plot("ssh_Re", nc=0)
301
310
  """
302
311
 
303
- field = self.ds[var_name].isel(ntides=ntides).compute()
312
+ field = self.ds[var_name].isel(ntides=ntides)
313
+
314
+ if self.use_dask:
315
+ from dask.diagnostics import ProgressBar
316
+
317
+ with ProgressBar():
318
+ field = field.load()
319
+
304
320
  if all(dim in field.dims for dim in ["eta_rho", "xi_rho"]):
305
321
  field = field.where(self.grid.ds.mask_rho)
306
322
  field = field.assign_coords(
@@ -378,7 +394,13 @@ class TidalForcing:
378
394
  if filepath.suffix == ".nc":
379
395
  filepath = filepath.with_suffix("")
380
396
 
381
- dataset_list = [self.ds.load()]
397
+ if self.use_dask:
398
+ from dask.diagnostics import ProgressBar
399
+
400
+ with ProgressBar():
401
+ self.ds.load()
402
+
403
+ dataset_list = [self.ds]
382
404
  output_filenames = [str(filepath)]
383
405
 
384
406
  saved_filenames = save_datasets(
@@ -419,8 +441,8 @@ class TidalForcing:
419
441
  "TidalForcing": {
420
442
  "source": self.source,
421
443
  "ntides": self.ntides,
422
- "model_reference_date": self.model_reference_date.isoformat(),
423
444
  "allan_factor": self.allan_factor,
445
+ "model_reference_date": self.model_reference_date.isoformat(),
424
446
  }
425
447
  }
426
448
 
@@ -431,7 +453,7 @@ class TidalForcing:
431
453
  # Write header
432
454
  file.write(header)
433
455
  # Write YAML data
434
- yaml.dump(yaml_data, file, default_flow_style=False)
456
+ yaml.dump(yaml_data, file, default_flow_style=False, sort_keys=False)
435
457
 
436
458
  @classmethod
437
459
  def from_yaml(
roms_tools/setup/utils.py CHANGED
@@ -724,23 +724,31 @@ def get_target_coords(grid, use_coarse_grid=False):
724
724
  Returns
725
725
  -------
726
726
  dict
727
- Dictionary containing the longitude, latitude, and angle arrays, along with a boolean indicating
727
+ Dictionary containing the longitude, latitude, angle and mask arrays, along with a boolean indicating
728
728
  if the grid straddles the meridian.
729
729
  """
730
730
  # Select grid variables based on whether the coarse grid is used
731
731
  if use_coarse_grid:
732
- lat, lon, angle = (
733
- grid.ds.lat_coarse,
734
- grid.ds.lon_coarse,
735
- grid.ds.angle_coarse,
732
+ lat, lon, angle, mask = (
733
+ grid.ds.lat_coarse.rename({"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}),
734
+ grid.ds.lon_coarse.rename({"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}),
735
+ grid.ds.angle_coarse.rename(
736
+ {"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}
737
+ ),
738
+ grid.ds.mask_coarse.rename(
739
+ {"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}
740
+ ),
736
741
  )
742
+
737
743
  lat_psi = grid.ds.get("lat_psi_coarse")
738
744
  lon_psi = grid.ds.get("lon_psi_coarse")
745
+
739
746
  else:
740
- lat, lon, angle = (
747
+ lat, lon, angle, mask = (
741
748
  grid.ds.lat_rho,
742
749
  grid.ds.lon_rho,
743
750
  grid.ds.angle,
751
+ grid.ds.mask_rho,
744
752
  )
745
753
  lat_psi = grid.ds.get("lat_psi")
746
754
  lon_psi = grid.ds.get("lon_psi")
@@ -763,6 +771,7 @@ def get_target_coords(grid, use_coarse_grid=False):
763
771
  "lat_psi": lat_psi,
764
772
  "lon_psi": lon_psi,
765
773
  "angle": angle,
774
+ "mask": mask,
766
775
  "straddle": straddle,
767
776
  }
768
777
 
@@ -1,17 +1,19 @@
1
1
  import pytest
2
2
  from datetime import datetime
3
- from roms_tools import BoundaryForcing
3
+ import xarray as xr
4
+ from roms_tools import Grid, BoundaryForcing
4
5
  import textwrap
5
6
  from roms_tools.setup.download import download_test_data
6
7
  from conftest import calculate_file_hash
7
8
  from pathlib import Path
9
+ import logging
8
10
 
9
11
 
10
12
  @pytest.mark.parametrize(
11
13
  "boundary_forcing_fixture",
12
14
  [
13
15
  "boundary_forcing",
14
- "boundary_forcing_with_2d_fill",
16
+ # "boundary_forcing_with_2d_fill",
15
17
  ],
16
18
  )
17
19
  def test_boundary_forcing_creation(boundary_forcing_fixture, request):
@@ -51,7 +53,7 @@ def test_boundary_forcing_creation(boundary_forcing_fixture, request):
51
53
  "boundary_forcing_fixture",
52
54
  [
53
55
  "bgc_boundary_forcing_from_climatology",
54
- "bgc_boundary_forcing_from_climatology_with_2d_fill",
56
+ # "bgc_boundary_forcing_from_climatology_with_2d_fill",
55
57
  ],
56
58
  )
57
59
  def test_boundary_forcing_creation_with_bgc(boundary_forcing_fixture, request):
@@ -85,8 +87,101 @@ def test_boundary_forcing_creation_with_bgc(boundary_forcing_fixture, request):
85
87
  assert hasattr(boundary_forcing.ds, "climatology")
86
88
 
87
89
 
88
- def test_boundary_forcing_plot_save(boundary_forcing, tmp_path):
89
- """Test plot and save methods."""
90
+ def test_unsuccessful_boundary_forcing_creation_with_1d_fill(use_dask):
91
+
92
+ grid = Grid(
93
+ nx=2,
94
+ ny=2,
95
+ size_x=500,
96
+ size_y=1000,
97
+ center_lon=0,
98
+ center_lat=55,
99
+ rot=10,
100
+ N=3, # number of vertical levels
101
+ theta_s=5.0, # surface control parameter
102
+ theta_b=2.0, # bottom control parameter
103
+ hc=250.0, # critical depth
104
+ )
105
+
106
+ fname = download_test_data("GLORYS_coarse_test_data.nc")
107
+
108
+ with pytest.raises(ValueError, match="consists entirely of NaNs"):
109
+
110
+ BoundaryForcing(
111
+ grid=grid,
112
+ start_time=datetime(2021, 6, 29),
113
+ end_time=datetime(2021, 6, 30),
114
+ source={"name": "GLORYS", "path": fname},
115
+ apply_2d_horizontal_fill=False,
116
+ use_dask=use_dask,
117
+ )
118
+
119
+ fname_bgc = download_test_data("CESM_regional_coarse_test_data_climatology.nc")
120
+
121
+ with pytest.raises(ValueError, match="consists entirely of NaNs"):
122
+
123
+ BoundaryForcing(
124
+ grid=grid,
125
+ start_time=datetime(2021, 6, 29),
126
+ end_time=datetime(2021, 6, 30),
127
+ source={"path": fname_bgc, "name": "CESM_REGRIDDED", "climatology": True},
128
+ type="bgc",
129
+ apply_2d_horizontal_fill=False,
130
+ use_dask=use_dask,
131
+ )
132
+
133
+
134
+ def test_boundary_divided_by_land_warning(caplog, use_dask):
135
+
136
+ # Iceland intersects the western boundary of the following grid
137
+ grid = Grid(
138
+ nx=5, ny=5, size_x=500, size_y=500, center_lon=-10, center_lat=65, rot=0
139
+ )
140
+
141
+ fname = download_test_data("GLORYS_coarse_test_data.nc")
142
+
143
+ with caplog.at_level(logging.WARNING):
144
+ BoundaryForcing(
145
+ grid=grid,
146
+ start_time=datetime(2021, 6, 29),
147
+ end_time=datetime(2021, 6, 30),
148
+ source={"path": fname, "name": "GLORYS", "climatology": False},
149
+ apply_2d_horizontal_fill=False,
150
+ use_dask=use_dask,
151
+ )
152
+ # Verify the warning message in the log
153
+ assert "the western boundary is divided by land" in caplog.text
154
+
155
+
156
+ def test_1d_and_2d_fill_coincide_if_no_land(use_dask):
157
+
158
+ # this grid lies entirely over open ocean
159
+ grid = Grid(nx=5, ny=5, size_x=300, size_y=300, center_lon=-5, center_lat=65, rot=0)
160
+
161
+ fname = download_test_data("GLORYS_coarse_test_data.nc")
162
+
163
+ kwargs = {
164
+ "grid": grid,
165
+ "start_time": datetime(2021, 6, 29),
166
+ "end_time": datetime(2021, 6, 29),
167
+ "source": {"path": fname, "name": "GLORYS", "climatology": False},
168
+ "use_dask": use_dask,
169
+ }
170
+
171
+ bf_1d_fill = BoundaryForcing(
172
+ **kwargs,
173
+ apply_2d_horizontal_fill=False,
174
+ )
175
+ bf_2d_fill = BoundaryForcing(
176
+ **kwargs,
177
+ apply_2d_horizontal_fill=True,
178
+ )
179
+
180
+ xr.testing.assert_allclose(bf_1d_fill.ds, bf_2d_fill.ds, rtol=1.0e-4)
181
+
182
+
183
+ def test_boundary_forcing_plot(boundary_forcing):
184
+ """Test plot."""
90
185
 
91
186
  boundary_forcing.plot(var_name="temp_south", layer_contours=True)
92
187
  boundary_forcing.plot(var_name="temp_east", layer_contours=True)
@@ -99,6 +194,10 @@ def test_boundary_forcing_plot_save(boundary_forcing, tmp_path):
99
194
  boundary_forcing.plot(var_name="vbar_north")
100
195
  boundary_forcing.plot(var_name="ubar_west")
101
196
 
197
+
198
+ def test_boundary_forcing_save(boundary_forcing, tmp_path):
199
+ """Test save method."""
200
+
102
201
  for file_str in ["test_bf", "test_bf.nc"]:
103
202
  # Create a temporary filepath using the tmp_path fixture
104
203
  for filepath in [
@@ -106,9 +205,19 @@ def test_boundary_forcing_plot_save(boundary_forcing, tmp_path):
106
205
  str(tmp_path / file_str),
107
206
  ]: # test for Path object and str
108
207
 
109
- # Test saving without partitioning
208
+ # Test saving without partitioning and grouping
110
209
  saved_filenames = boundary_forcing.save(filepath)
111
210
 
211
+ filepath_str = str(Path(filepath).with_suffix(""))
212
+ expected_filepath = Path(f"{filepath_str}.nc")
213
+
214
+ assert saved_filenames == [expected_filepath]
215
+ assert expected_filepath.exists()
216
+ expected_filepath.unlink()
217
+
218
+ # Test saving without partitioning but with grouping
219
+ saved_filenames = boundary_forcing.save(filepath, group=True)
220
+
112
221
  filepath_str = str(Path(filepath).with_suffix(""))
113
222
  expected_filepath = Path(f"{filepath_str}_202106.nc")
114
223
 
@@ -116,8 +225,8 @@ def test_boundary_forcing_plot_save(boundary_forcing, tmp_path):
116
225
  assert expected_filepath.exists()
117
226
  expected_filepath.unlink()
118
227
 
119
- # Test saving with partitioning
120
- saved_filenames = boundary_forcing.save(filepath, np_eta=2)
228
+ # Test saving with partitioning and grouping
229
+ saved_filenames = boundary_forcing.save(filepath, np_eta=2, group=True)
121
230
  expected_filepath_list = [
122
231
  Path(filepath_str + f"_202106.{index}.nc") for index in range(2)
123
232
  ]
@@ -129,16 +238,18 @@ def test_boundary_forcing_plot_save(boundary_forcing, tmp_path):
129
238
  expected_filepath.unlink()
130
239
 
131
240
 
132
- def test_bgc_boundary_forcing_plot_save(
133
- bgc_boundary_forcing_from_climatology, tmp_path
134
- ):
135
- """Test plot and save methods."""
241
+ def test_bgc_boundary_forcing_plot(bgc_boundary_forcing_from_climatology):
242
+ """Test plot method."""
136
243
 
137
244
  bgc_boundary_forcing_from_climatology.plot(var_name="ALK_south")
138
245
  bgc_boundary_forcing_from_climatology.plot(var_name="ALK_east")
139
246
  bgc_boundary_forcing_from_climatology.plot(var_name="ALK_north")
140
247
  bgc_boundary_forcing_from_climatology.plot(var_name="ALK_west")
141
248
 
249
+
250
+ def test_bgc_boundary_forcing_save(bgc_boundary_forcing_from_climatology, tmp_path):
251
+ """Test save method."""
252
+
142
253
  for file_str in ["test_bf", "test_bf.nc"]:
143
254
  # Create a temporary filepath using the tmp_path fixture
144
255
  for filepath in [
@@ -146,9 +257,20 @@ def test_bgc_boundary_forcing_plot_save(
146
257
  str(tmp_path / file_str),
147
258
  ]: # test for Path object and str
148
259
 
149
- # Test saving without partitioning
260
+ # Test saving without partitioning and grouping
150
261
  saved_filenames = bgc_boundary_forcing_from_climatology.save(filepath)
151
262
 
263
+ filepath_str = str(Path(filepath).with_suffix(""))
264
+ expected_filepath = Path(f"{filepath_str}.nc")
265
+ assert saved_filenames == [expected_filepath]
266
+ assert expected_filepath.exists()
267
+ expected_filepath.unlink()
268
+
269
+ # Test saving without partitioning but with grouping
270
+ saved_filenames = bgc_boundary_forcing_from_climatology.save(
271
+ filepath, group=True
272
+ )
273
+
152
274
  filepath_str = str(Path(filepath).with_suffix(""))
153
275
  expected_filepath = Path(f"{filepath_str}_clim.nc")
154
276
  assert saved_filenames == [expected_filepath]
@@ -157,7 +279,7 @@ def test_bgc_boundary_forcing_plot_save(
157
279
 
158
280
  # Test saving with partitioning
159
281
  saved_filenames = bgc_boundary_forcing_from_climatology.save(
160
- filepath, np_xi=2
282
+ filepath, np_xi=2, group=True
161
283
  )
162
284
 
163
285
  expected_filepath_list = [
@@ -207,9 +329,9 @@ def test_files_have_same_hash(boundary_forcing, tmp_path, use_dask):
207
329
  filepath2 = tmp_path / "test2.nc"
208
330
 
209
331
  boundary_forcing.to_yaml(yaml_filepath)
210
- boundary_forcing.save(filepath1)
332
+ boundary_forcing.save(filepath1, group=True)
211
333
  bdry_forcing_from_file = BoundaryForcing.from_yaml(yaml_filepath, use_dask=use_dask)
212
- bdry_forcing_from_file.save(filepath2)
334
+ bdry_forcing_from_file.save(filepath2, group=True)
213
335
 
214
336
  filepath_str1 = str(Path(filepath1).with_suffix(""))
215
337
  filepath_str2 = str(Path(filepath2).with_suffix(""))
@@ -235,9 +357,9 @@ def test_files_have_same_hash_clim(
235
357
  filepath2 = tmp_path / "test2.nc"
236
358
 
237
359
  bgc_boundary_forcing_from_climatology.to_yaml(yaml_filepath)
238
- bgc_boundary_forcing_from_climatology.save(filepath1)
360
+ bgc_boundary_forcing_from_climatology.save(filepath1, group=True)
239
361
  bdry_forcing_from_file = BoundaryForcing.from_yaml(yaml_filepath, use_dask=use_dask)
240
- bdry_forcing_from_file.save(filepath2)
362
+ bdry_forcing_from_file.save(filepath2, group=True)
241
363
 
242
364
  filepath_str1 = str(Path(filepath1).with_suffix(""))
243
365
  filepath_str2 = str(Path(filepath2).with_suffix(""))