roms-tools 2.7.0__py3-none-any.whl → 3.0.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 (1066) hide show
  1. ci/environment-with-xesmf.yml +2 -1
  2. ci/environment.yml +2 -1
  3. roms_tools/__init__.py +10 -9
  4. roms_tools/analysis/roms_output.py +23 -66
  5. roms_tools/constants.py +3 -0
  6. roms_tools/download.py +1 -1
  7. roms_tools/plot.py +14 -10
  8. roms_tools/regrid.py +3 -2
  9. roms_tools/setup/boundary_forcing.py +30 -27
  10. roms_tools/setup/cdr_forcing.py +997 -836
  11. roms_tools/setup/cdr_release.py +537 -0
  12. roms_tools/setup/datasets.py +51 -16
  13. roms_tools/setup/fill.py +1 -1
  14. roms_tools/setup/grid.py +202 -76
  15. roms_tools/setup/initial_conditions.py +28 -24
  16. roms_tools/setup/mask.py +5 -3
  17. roms_tools/setup/nesting.py +14 -11
  18. roms_tools/setup/river_forcing.py +55 -45
  19. roms_tools/setup/surface_forcing.py +154 -41
  20. roms_tools/setup/tides.py +19 -15
  21. roms_tools/setup/topography.py +10 -6
  22. roms_tools/setup/utils.py +371 -101
  23. roms_tools/tests/test_analysis/test_roms_output.py +119 -36
  24. roms_tools/tests/test_regrid.py +3 -1
  25. roms_tools/tests/test_setup/test_boundary_forcing.py +57 -7
  26. roms_tools/tests/test_setup/test_cdr_forcing.py +900 -714
  27. roms_tools/tests/test_setup/test_cdr_release.py +388 -0
  28. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_east/c/0/0/0 +0 -0
  29. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_east/zarr.json +54 -0
  30. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_north/c/0/0/0 +0 -0
  31. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_north/zarr.json +54 -0
  32. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_south/c/0/0/0 +0 -0
  33. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_south/zarr.json +54 -0
  34. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/c/0/0/0 +0 -0
  35. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/zarr.json +54 -0
  36. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_east/c/0/0/0 +0 -0
  37. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_east/zarr.json +54 -0
  38. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_north/c/0/0/0 +0 -0
  39. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_north/zarr.json +54 -0
  40. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_south/c/0/0/0 +0 -0
  41. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_south/zarr.json +54 -0
  42. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/c/0/0/0 +0 -0
  43. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/zarr.json +54 -0
  44. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_east/c/0/0/0 +0 -0
  45. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_east/zarr.json +54 -0
  46. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_north/c/0/0/0 +0 -0
  47. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_north/zarr.json +54 -0
  48. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_south/c/0/0/0 +0 -0
  49. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_south/zarr.json +54 -0
  50. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/c/0/0/0 +0 -0
  51. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/zarr.json +54 -0
  52. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_east/c/0/0/0 +0 -0
  53. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_east/zarr.json +54 -0
  54. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_north/c/0/0/0 +0 -0
  55. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_north/zarr.json +54 -0
  56. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_south/c/0/0/0 +0 -0
  57. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_south/zarr.json +54 -0
  58. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/c/0/0/0 +0 -0
  59. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/zarr.json +54 -0
  60. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_east/c/0/0/0 +0 -0
  61. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_east/zarr.json +54 -0
  62. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_north/c/0/0/0 +0 -0
  63. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_north/zarr.json +54 -0
  64. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_south/c/0/0/0 +0 -0
  65. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_south/zarr.json +54 -0
  66. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/c/0/0/0 +0 -0
  67. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/zarr.json +54 -0
  68. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_east/c/0/0/0 +0 -0
  69. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_east/zarr.json +54 -0
  70. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_north/c/0/0/0 +0 -0
  71. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_north/zarr.json +54 -0
  72. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_south/c/0/0/0 +0 -0
  73. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_south/zarr.json +54 -0
  74. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/c/0/0/0 +0 -0
  75. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/zarr.json +54 -0
  76. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_east/c/0/0/0 +0 -0
  77. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_east/zarr.json +54 -0
  78. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_north/c/0/0/0 +0 -0
  79. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_north/zarr.json +54 -0
  80. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_south/c/0/0/0 +0 -0
  81. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_south/zarr.json +54 -0
  82. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/c/0/0/0 +0 -0
  83. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/zarr.json +54 -0
  84. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_east/c/0/0/0 +0 -0
  85. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_east/zarr.json +54 -0
  86. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_north/c/0/0/0 +0 -0
  87. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_north/zarr.json +54 -0
  88. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_south/c/0/0/0 +0 -0
  89. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_south/zarr.json +54 -0
  90. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/c/0/0/0 +0 -0
  91. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/zarr.json +54 -0
  92. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_east/c/0/0/0 +0 -0
  93. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_east/zarr.json +54 -0
  94. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_north/c/0/0/0 +0 -0
  95. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_north/zarr.json +54 -0
  96. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_south/c/0/0/0 +0 -0
  97. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_south/zarr.json +54 -0
  98. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/c/0/0/0 +0 -0
  99. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/zarr.json +54 -0
  100. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_east/c/0/0/0 +0 -0
  101. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_east/zarr.json +54 -0
  102. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_north/c/0/0/0 +0 -0
  103. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_north/zarr.json +54 -0
  104. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_south/c/0/0/0 +0 -0
  105. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_south/zarr.json +54 -0
  106. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/c/0/0/0 +0 -0
  107. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/zarr.json +54 -0
  108. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_east/c/0/0/0 +0 -0
  109. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_east/zarr.json +54 -0
  110. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_north/c/0/0/0 +0 -0
  111. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_north/zarr.json +54 -0
  112. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_south/c/0/0/0 +0 -0
  113. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_south/zarr.json +54 -0
  114. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/c/0/0/0 +0 -0
  115. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/zarr.json +54 -0
  116. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_east/c/0/0/0 +0 -0
  117. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_east/zarr.json +54 -0
  118. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_north/c/0/0/0 +0 -0
  119. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_north/zarr.json +54 -0
  120. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_south/c/0/0/0 +0 -0
  121. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_south/zarr.json +54 -0
  122. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/c/0/0/0 +0 -0
  123. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/zarr.json +54 -0
  124. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_east/c/0/0/0 +0 -0
  125. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_east/zarr.json +54 -0
  126. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_north/c/0/0/0 +0 -0
  127. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_north/zarr.json +54 -0
  128. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_south/c/0/0/0 +0 -0
  129. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_south/zarr.json +54 -0
  130. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/c/0/0/0 +0 -0
  131. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/zarr.json +54 -0
  132. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_east/c/0/0/0 +0 -0
  133. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_east/zarr.json +54 -0
  134. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_north/c/0/0/0 +0 -0
  135. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_north/zarr.json +54 -0
  136. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_south/c/0/0/0 +0 -0
  137. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_south/zarr.json +54 -0
  138. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/c/0/0/0 +0 -0
  139. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/zarr.json +54 -0
  140. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_east/c/0/0/0 +0 -0
  141. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_east/zarr.json +54 -0
  142. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_north/c/0/0/0 +0 -0
  143. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_north/zarr.json +54 -0
  144. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_south/c/0/0/0 +0 -0
  145. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_south/zarr.json +54 -0
  146. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/c/0/0/0 +0 -0
  147. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/zarr.json +54 -0
  148. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_east/c/0/0/0 +0 -0
  149. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_east/zarr.json +54 -0
  150. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_north/c/0/0/0 +0 -0
  151. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_north/zarr.json +54 -0
  152. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_south/c/0/0/0 +0 -0
  153. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_south/zarr.json +54 -0
  154. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/c/0/0/0 +0 -0
  155. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/zarr.json +54 -0
  156. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_east/c/0/0/0 +0 -0
  157. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_east/zarr.json +54 -0
  158. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_north/c/0/0/0 +0 -0
  159. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_north/zarr.json +54 -0
  160. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_south/c/0/0/0 +0 -0
  161. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_south/zarr.json +54 -0
  162. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/c/0/0/0 +0 -0
  163. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/zarr.json +54 -0
  164. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/abs_time/c/0 +0 -0
  165. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/abs_time/zarr.json +47 -0
  166. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/bry_time/c/0 +0 -0
  167. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/bry_time/zarr.json +48 -0
  168. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_east/c/0/0/0 +0 -0
  169. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_east/zarr.json +54 -0
  170. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_north/c/0/0/0 +0 -0
  171. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_north/zarr.json +54 -0
  172. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_south/c/0/0/0 +0 -0
  173. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_south/zarr.json +54 -0
  174. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/c/0/0/0 +0 -0
  175. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/zarr.json +54 -0
  176. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_east/c/0/0/0 +0 -0
  177. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_east/zarr.json +54 -0
  178. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_north/c/0/0/0 +0 -0
  179. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_north/zarr.json +54 -0
  180. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_south/c/0/0/0 +0 -0
  181. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_south/zarr.json +54 -0
  182. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/c/0/0/0 +0 -0
  183. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/zarr.json +54 -0
  184. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_east/c/0/0/0 +0 -0
  185. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_east/zarr.json +54 -0
  186. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_north/c/0/0/0 +0 -0
  187. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_north/zarr.json +54 -0
  188. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_south/c/0/0/0 +0 -0
  189. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_south/zarr.json +54 -0
  190. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/c/0/0/0 +0 -0
  191. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/zarr.json +54 -0
  192. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_east/c/0/0/0 +0 -0
  193. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_east/zarr.json +54 -0
  194. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_north/c/0/0/0 +0 -0
  195. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_north/zarr.json +54 -0
  196. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_south/c/0/0/0 +0 -0
  197. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_south/zarr.json +54 -0
  198. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/c/0/0/0 +0 -0
  199. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/zarr.json +54 -0
  200. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_east/c/0/0/0 +0 -0
  201. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_east/zarr.json +54 -0
  202. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_north/c/0/0/0 +0 -0
  203. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_north/zarr.json +54 -0
  204. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_south/c/0/0/0 +0 -0
  205. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_south/zarr.json +54 -0
  206. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/c/0/0/0 +0 -0
  207. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/zarr.json +54 -0
  208. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_east/c/0/0/0 +0 -0
  209. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_east/zarr.json +54 -0
  210. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_north/c/0/0/0 +0 -0
  211. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_north/zarr.json +54 -0
  212. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_south/c/0/0/0 +0 -0
  213. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_south/zarr.json +54 -0
  214. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/c/0/0/0 +0 -0
  215. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/zarr.json +54 -0
  216. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_east/c/0/0/0 +0 -0
  217. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_east/zarr.json +54 -0
  218. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_north/c/0/0/0 +0 -0
  219. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_north/zarr.json +54 -0
  220. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_south/c/0/0/0 +0 -0
  221. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_south/zarr.json +54 -0
  222. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/c/0/0/0 +0 -0
  223. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/zarr.json +54 -0
  224. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_east/c/0/0/0 +0 -0
  225. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_east/zarr.json +54 -0
  226. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_north/c/0/0/0 +0 -0
  227. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_north/zarr.json +54 -0
  228. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_south/c/0/0/0 +0 -0
  229. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_south/zarr.json +54 -0
  230. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/c/0/0/0 +0 -0
  231. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/zarr.json +54 -0
  232. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_east/c/0/0/0 +0 -0
  233. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_east/zarr.json +54 -0
  234. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_north/c/0/0/0 +0 -0
  235. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_north/zarr.json +54 -0
  236. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_south/c/0/0/0 +0 -0
  237. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_south/zarr.json +54 -0
  238. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/c/0/0/0 +0 -0
  239. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/zarr.json +54 -0
  240. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/month/c/0 +0 -0
  241. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/month/zarr.json +45 -0
  242. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_east/c/0/0/0 +0 -0
  243. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_east/zarr.json +54 -0
  244. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_north/c/0/0/0 +0 -0
  245. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_north/zarr.json +54 -0
  246. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_south/c/0/0/0 +0 -0
  247. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_south/zarr.json +54 -0
  248. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/c/0/0/0 +0 -0
  249. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/zarr.json +54 -0
  250. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_east/c/0/0/0 +0 -0
  251. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_east/zarr.json +54 -0
  252. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_north/c/0/0/0 +0 -0
  253. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_north/zarr.json +54 -0
  254. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_south/c/0/0/0 +0 -0
  255. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_south/zarr.json +54 -0
  256. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/c/0/0/0 +0 -0
  257. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/zarr.json +54 -0
  258. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_east/c/0/0/0 +0 -0
  259. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_east/zarr.json +54 -0
  260. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_north/c/0/0/0 +0 -0
  261. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_north/zarr.json +54 -0
  262. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_south/c/0/0/0 +0 -0
  263. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_south/zarr.json +54 -0
  264. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/c/0/0/0 +0 -0
  265. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/zarr.json +54 -0
  266. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_east/c/0/0/0 +0 -0
  267. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_east/zarr.json +54 -0
  268. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_north/c/0/0/0 +0 -0
  269. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_north/zarr.json +54 -0
  270. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_south/c/0/0/0 +0 -0
  271. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_south/zarr.json +54 -0
  272. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/c/0/0/0 +0 -0
  273. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/zarr.json +54 -0
  274. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_east/c/0/0/0 +0 -0
  275. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_east/zarr.json +54 -0
  276. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_north/c/0/0/0 +0 -0
  277. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_north/zarr.json +54 -0
  278. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_south/c/0/0/0 +0 -0
  279. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_south/zarr.json +54 -0
  280. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/c/0/0/0 +0 -0
  281. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/zarr.json +54 -0
  282. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zarr.json +7076 -0
  283. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_east/c/0/0/0 +0 -0
  284. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_east/zarr.json +54 -0
  285. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_north/c/0/0/0 +0 -0
  286. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_north/zarr.json +54 -0
  287. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_south/c/0/0/0 +0 -0
  288. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_south/zarr.json +54 -0
  289. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/c/0/0/0 +0 -0
  290. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/zarr.json +54 -0
  291. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/abs_time/c/0 +0 -0
  292. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/abs_time/zarr.json +47 -0
  293. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust/c/0/0/0 +0 -0
  294. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust/zarr.json +56 -0
  295. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust_time/c/0 +0 -0
  296. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust_time/zarr.json +48 -0
  297. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron/c/0/0/0 +0 -0
  298. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron/zarr.json +56 -0
  299. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron_time/c/0 +0 -0
  300. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron_time/zarr.json +48 -0
  301. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/month/c/0 +0 -0
  302. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/month/zarr.json +45 -0
  303. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy/c/0/0/0 +0 -0
  304. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy/zarr.json +54 -0
  305. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy_time/c/0 +0 -0
  306. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy_time/zarr.json +48 -0
  307. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox/c/0/0/0 +0 -0
  308. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox/zarr.json +56 -0
  309. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox_time/c/0 +0 -0
  310. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox_time/zarr.json +48 -0
  311. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air/c/0/0/0 +0 -0
  312. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air/zarr.json +56 -0
  313. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air_alt/c/0/0/0 +0 -0
  314. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air_alt/zarr.json +54 -0
  315. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_time/c/0 +0 -0
  316. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_time/zarr.json +48 -0
  317. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/zarr.json +686 -0
  318. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK/c/0/0/0/0 +0 -0
  319. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK/zarr.json +57 -0
  320. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK_ALT_CO2/c/0/0/0/0 +0 -0
  321. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK_ALT_CO2/zarr.json +57 -0
  322. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_r/c/0 +0 -0
  323. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_r/zarr.json +47 -0
  324. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_w/c/0 +0 -0
  325. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_w/zarr.json +47 -0
  326. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC/c/0/0/0/0 +0 -0
  327. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC/zarr.json +57 -0
  328. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC_ALT_CO2/c/0/0/0/0 +0 -0
  329. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC_ALT_CO2/zarr.json +57 -0
  330. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOC/c/0/0/0/0 +0 -0
  331. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOC/zarr.json +57 -0
  332. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOCr/c/0/0/0/0 +0 -0
  333. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOCr/zarr.json +57 -0
  334. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DON/c/0/0/0/0 +0 -0
  335. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DON/zarr.json +57 -0
  336. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DONr/c/0/0/0/0 +0 -0
  337. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DONr/zarr.json +57 -0
  338. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOP/c/0/0/0/0 +0 -0
  339. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOP/zarr.json +57 -0
  340. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOPr/c/0/0/0/0 +0 -0
  341. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOPr/zarr.json +57 -0
  342. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Fe/c/0/0/0/0 +0 -0
  343. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Fe/zarr.json +57 -0
  344. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Lig/c/0/0/0/0 +0 -0
  345. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Lig/zarr.json +57 -0
  346. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NH4/c/0/0/0/0 +0 -0
  347. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NH4/zarr.json +57 -0
  348. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NO3/c/0/0/0/0 +0 -0
  349. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NO3/zarr.json +57 -0
  350. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/O2/c/0/0/0/0 +0 -0
  351. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/O2/zarr.json +57 -0
  352. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/PO4/c/0/0/0/0 +0 -0
  353. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/PO4/zarr.json +57 -0
  354. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/SiO3/c/0/0/0/0 +0 -0
  355. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/SiO3/zarr.json +57 -0
  356. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/abs_time/zarr.json +47 -0
  357. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatC/c/0/0/0/0 +0 -0
  358. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatC/zarr.json +57 -0
  359. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatChl/c/0/0/0/0 +0 -0
  360. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatChl/zarr.json +57 -0
  361. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatFe/c/0/0/0/0 +0 -0
  362. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatFe/zarr.json +57 -0
  363. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatP/c/0/0/0/0 +0 -0
  364. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatP/zarr.json +57 -0
  365. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatSi/c/0/0/0/0 +0 -0
  366. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatSi/zarr.json +57 -0
  367. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazC/c/0/0/0/0 +0 -0
  368. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazC/zarr.json +57 -0
  369. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazChl/c/0/0/0/0 +0 -0
  370. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazChl/zarr.json +57 -0
  371. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazFe/c/0/0/0/0 +0 -0
  372. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazFe/zarr.json +57 -0
  373. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazP/c/0/0/0/0 +0 -0
  374. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazP/zarr.json +57 -0
  375. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ocean_time/c/0 +0 -0
  376. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ocean_time/zarr.json +47 -0
  377. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/salt/c/0/0/0/0 +0 -0
  378. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/salt/zarr.json +57 -0
  379. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spC/c/0/0/0/0 +0 -0
  380. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spC/zarr.json +57 -0
  381. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spCaCO3/c/0/0/0/0 +0 -0
  382. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spCaCO3/zarr.json +57 -0
  383. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spChl/c/0/0/0/0 +0 -0
  384. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spChl/zarr.json +57 -0
  385. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spFe/c/0/0/0/0 +0 -0
  386. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spFe/zarr.json +57 -0
  387. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spP/c/0/0/0/0 +0 -0
  388. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spP/zarr.json +57 -0
  389. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/temp/c/0/0/0/0 +0 -0
  390. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/temp/zarr.json +57 -0
  391. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/u/c/0/0/0/0 +0 -0
  392. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/u/zarr.json +57 -0
  393. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ubar/c/0/0/0 +0 -0
  394. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ubar/zarr.json +54 -0
  395. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/v/c/0/0/0/0 +0 -0
  396. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/v/zarr.json +57 -0
  397. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/vbar/c/0/0/0 +0 -0
  398. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/vbar/zarr.json +54 -0
  399. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/w/zarr.json +57 -0
  400. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zarr.json +2481 -0
  401. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zeta/c/0/0/0 +0 -0
  402. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zeta/zarr.json +54 -0
  403. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zooC/c/0/0/0/0 +0 -0
  404. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zooC/zarr.json +57 -0
  405. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/abs_time/c/0 +0 -0
  406. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/abs_time/zarr.json +47 -0
  407. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/month/c/0 +0 -0
  408. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/month/zarr.json +45 -0
  409. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/c/0 +0 -0
  410. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/zarr.json +45 -0
  411. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_fraction/c/0/0 +0 -0
  412. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_fraction/zarr.json +50 -0
  413. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_index/c/0/0 +0 -0
  414. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_index/zarr.json +50 -0
  415. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_name/c/0 +0 -0
  416. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_name/zarr.json +43 -0
  417. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_time/c/0 +0 -0
  418. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_time/zarr.json +48 -0
  419. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_tracer/c/0/0/0 +0 -0
  420. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_tracer/zarr.json +53 -0
  421. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_volume/c/0/0 +0 -0
  422. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_volume/zarr.json +51 -0
  423. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_long_name/c/0 +0 -0
  424. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_long_name/zarr.json +43 -0
  425. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_name/c/0 +0 -0
  426. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_name/zarr.json +43 -0
  427. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_unit/c/0 +0 -0
  428. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_unit/zarr.json +43 -0
  429. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/zarr.json +574 -0
  430. roms_tools/tests/test_setup/test_datasets.py +8 -6
  431. roms_tools/tests/test_setup/test_fill.py +3 -2
  432. roms_tools/tests/test_setup/test_grid.py +419 -101
  433. roms_tools/tests/test_setup/test_initial_conditions.py +69 -7
  434. roms_tools/tests/test_setup/test_nesting.py +8 -6
  435. roms_tools/tests/test_setup/test_river_forcing.py +15 -15
  436. roms_tools/tests/test_setup/test_surface_forcing.py +210 -116
  437. roms_tools/tests/test_setup/test_tides.py +6 -4
  438. roms_tools/tests/test_setup/test_utils.py +10 -6
  439. roms_tools/tests/test_setup/test_validation.py +6 -2
  440. roms_tools/tests/test_tiling/test_partition.py +18 -4
  441. roms_tools/tests/test_utils.py +21 -0
  442. roms_tools/tests/test_vertical_coordinate.py +11 -6
  443. roms_tools/tiling/partition.py +30 -11
  444. roms_tools/utils.py +228 -44
  445. roms_tools/vertical_coordinate.py +7 -5
  446. roms_tools-3.0.0.dist-info/METADATA +143 -0
  447. roms_tools-3.0.0.dist-info/RECORD +1462 -0
  448. roms_tools-3.0.0.dist-info/WHEEL +5 -0
  449. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/.zattrs +0 -14
  450. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/.zgroup +0 -3
  451. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/.zmetadata +0 -4456
  452. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_east/.zarray +0 -24
  453. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_east/.zattrs +0 -10
  454. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_east/0.0.0 +0 -0
  455. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_north/.zarray +0 -24
  456. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_north/.zattrs +0 -10
  457. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_north/0.0.0 +0 -0
  458. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_south/.zarray +0 -24
  459. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_south/.zattrs +0 -10
  460. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_south/0.0.0 +0 -0
  461. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/.zarray +0 -24
  462. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/.zattrs +0 -10
  463. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/0.0.0 +0 -0
  464. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_east/.zarray +0 -24
  465. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_east/.zattrs +0 -10
  466. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_east/0.0.0 +0 -0
  467. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_north/.zarray +0 -24
  468. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_north/.zattrs +0 -10
  469. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_north/0.0.0 +0 -0
  470. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_south/.zarray +0 -24
  471. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_south/.zattrs +0 -10
  472. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_south/0.0.0 +0 -0
  473. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/.zarray +0 -24
  474. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/.zattrs +0 -10
  475. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/0.0.0 +0 -0
  476. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_east/.zarray +0 -24
  477. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_east/.zattrs +0 -10
  478. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_east/0.0.0 +0 -0
  479. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_north/.zarray +0 -24
  480. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_north/.zattrs +0 -10
  481. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_north/0.0.0 +0 -0
  482. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_south/.zarray +0 -24
  483. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_south/.zattrs +0 -10
  484. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_south/0.0.0 +0 -0
  485. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/.zarray +0 -24
  486. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/.zattrs +0 -10
  487. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/0.0.0 +0 -0
  488. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_east/.zarray +0 -24
  489. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_east/.zattrs +0 -10
  490. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_east/0.0.0 +0 -0
  491. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_north/.zarray +0 -24
  492. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_north/.zattrs +0 -10
  493. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_north/0.0.0 +0 -0
  494. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_south/.zarray +0 -24
  495. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_south/.zattrs +0 -10
  496. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_south/0.0.0 +0 -0
  497. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/.zarray +0 -24
  498. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/.zattrs +0 -10
  499. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/0.0.0 +0 -0
  500. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_east/.zarray +0 -24
  501. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_east/.zattrs +0 -10
  502. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_east/0.0.0 +0 -0
  503. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_north/.zarray +0 -24
  504. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_north/.zattrs +0 -10
  505. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_north/0.0.0 +0 -0
  506. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_south/.zarray +0 -24
  507. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_south/.zattrs +0 -10
  508. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_south/0.0.0 +0 -0
  509. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/.zarray +0 -24
  510. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/.zattrs +0 -10
  511. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/0.0.0 +0 -0
  512. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_east/.zarray +0 -24
  513. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_east/.zattrs +0 -10
  514. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_east/0.0.0 +0 -0
  515. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_north/.zarray +0 -24
  516. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_north/.zattrs +0 -10
  517. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_north/0.0.0 +0 -0
  518. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_south/.zarray +0 -24
  519. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_south/.zattrs +0 -10
  520. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_south/0.0.0 +0 -0
  521. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/.zarray +0 -24
  522. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/.zattrs +0 -10
  523. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/0.0.0 +0 -0
  524. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_east/.zarray +0 -24
  525. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_east/.zattrs +0 -10
  526. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_east/0.0.0 +0 -0
  527. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_north/.zarray +0 -24
  528. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_north/.zattrs +0 -10
  529. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_north/0.0.0 +0 -0
  530. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_south/.zarray +0 -24
  531. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_south/.zattrs +0 -10
  532. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_south/0.0.0 +0 -0
  533. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/.zarray +0 -24
  534. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/.zattrs +0 -10
  535. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/0.0.0 +0 -0
  536. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_east/.zarray +0 -24
  537. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_east/.zattrs +0 -10
  538. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_east/0.0.0 +0 -0
  539. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_north/.zarray +0 -24
  540. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_north/.zattrs +0 -10
  541. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_north/0.0.0 +0 -0
  542. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_south/.zarray +0 -24
  543. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_south/.zattrs +0 -10
  544. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_south/0.0.0 +0 -0
  545. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/.zarray +0 -24
  546. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/.zattrs +0 -10
  547. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/0.0.0 +0 -0
  548. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_east/.zarray +0 -24
  549. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_east/.zattrs +0 -10
  550. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_east/0.0.0 +0 -0
  551. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_north/.zarray +0 -24
  552. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_north/.zattrs +0 -10
  553. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_north/0.0.0 +0 -0
  554. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_south/.zarray +0 -24
  555. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_south/.zattrs +0 -10
  556. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_south/0.0.0 +0 -0
  557. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/.zarray +0 -24
  558. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/.zattrs +0 -10
  559. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/0.0.0 +0 -0
  560. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_east/.zarray +0 -24
  561. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_east/.zattrs +0 -10
  562. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_east/0.0.0 +0 -0
  563. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_north/.zarray +0 -24
  564. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_north/.zattrs +0 -10
  565. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_north/0.0.0 +0 -0
  566. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_south/.zarray +0 -24
  567. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_south/.zattrs +0 -10
  568. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_south/0.0.0 +0 -0
  569. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/.zarray +0 -24
  570. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/.zattrs +0 -10
  571. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/0.0.0 +0 -0
  572. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_east/.zarray +0 -24
  573. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_east/.zattrs +0 -10
  574. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_east/0.0.0 +0 -0
  575. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_north/.zarray +0 -24
  576. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_north/.zattrs +0 -10
  577. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_north/0.0.0 +0 -0
  578. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_south/.zarray +0 -24
  579. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_south/.zattrs +0 -10
  580. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_south/0.0.0 +0 -0
  581. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/.zarray +0 -24
  582. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/.zattrs +0 -10
  583. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/0.0.0 +0 -0
  584. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_east/.zarray +0 -24
  585. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_east/.zattrs +0 -10
  586. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_east/0.0.0 +0 -0
  587. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_north/.zarray +0 -24
  588. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_north/.zattrs +0 -10
  589. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_north/0.0.0 +0 -0
  590. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_south/.zarray +0 -24
  591. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_south/.zattrs +0 -10
  592. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_south/0.0.0 +0 -0
  593. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/.zarray +0 -24
  594. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/.zattrs +0 -10
  595. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/0.0.0 +0 -0
  596. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_east/.zarray +0 -24
  597. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_east/.zattrs +0 -10
  598. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_east/0.0.0 +0 -0
  599. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_north/.zarray +0 -24
  600. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_north/.zattrs +0 -10
  601. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_north/0.0.0 +0 -0
  602. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_south/.zarray +0 -24
  603. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_south/.zattrs +0 -10
  604. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_south/0.0.0 +0 -0
  605. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/.zarray +0 -24
  606. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/.zattrs +0 -10
  607. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/0.0.0 +0 -0
  608. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_east/.zarray +0 -24
  609. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_east/.zattrs +0 -10
  610. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_east/0.0.0 +0 -0
  611. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_north/.zarray +0 -24
  612. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_north/.zattrs +0 -10
  613. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_north/0.0.0 +0 -0
  614. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_south/.zarray +0 -24
  615. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_south/.zattrs +0 -10
  616. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_south/0.0.0 +0 -0
  617. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/.zarray +0 -24
  618. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/.zattrs +0 -10
  619. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/0.0.0 +0 -0
  620. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_east/.zarray +0 -24
  621. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_east/.zattrs +0 -10
  622. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_east/0.0.0 +0 -0
  623. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_north/.zarray +0 -24
  624. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_north/.zattrs +0 -10
  625. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_north/0.0.0 +0 -0
  626. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_south/.zarray +0 -24
  627. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_south/.zattrs +0 -10
  628. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_south/0.0.0 +0 -0
  629. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/.zarray +0 -24
  630. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/.zattrs +0 -10
  631. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/0.0.0 +0 -0
  632. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_east/.zarray +0 -24
  633. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_east/.zattrs +0 -10
  634. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_east/0.0.0 +0 -0
  635. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_north/.zarray +0 -24
  636. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_north/.zattrs +0 -10
  637. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_north/0.0.0 +0 -0
  638. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_south/.zarray +0 -24
  639. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_south/.zattrs +0 -10
  640. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_south/0.0.0 +0 -0
  641. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/.zarray +0 -24
  642. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/.zattrs +0 -10
  643. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/0.0.0 +0 -0
  644. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_east/.zarray +0 -24
  645. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_east/.zattrs +0 -10
  646. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_east/0.0.0 +0 -0
  647. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_north/.zarray +0 -24
  648. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_north/.zattrs +0 -10
  649. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_north/0.0.0 +0 -0
  650. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_south/.zarray +0 -24
  651. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_south/.zattrs +0 -10
  652. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_south/0.0.0 +0 -0
  653. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/.zarray +0 -24
  654. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/.zattrs +0 -10
  655. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/0.0.0 +0 -0
  656. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/abs_time/.zarray +0 -20
  657. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/abs_time/.zattrs +0 -8
  658. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/abs_time/0 +0 -0
  659. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/bry_time/.zarray +0 -20
  660. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/bry_time/.zattrs +0 -8
  661. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/bry_time/0 +0 -0
  662. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_east/.zarray +0 -24
  663. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_east/.zattrs +0 -10
  664. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_east/0.0.0 +0 -0
  665. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_north/.zarray +0 -24
  666. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_north/.zattrs +0 -10
  667. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_north/0.0.0 +0 -0
  668. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_south/.zarray +0 -24
  669. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_south/.zattrs +0 -10
  670. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_south/0.0.0 +0 -0
  671. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/.zarray +0 -24
  672. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/.zattrs +0 -10
  673. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/0.0.0 +0 -0
  674. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_east/.zarray +0 -24
  675. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_east/.zattrs +0 -10
  676. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_east/0.0.0 +0 -0
  677. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_north/.zarray +0 -24
  678. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_north/.zattrs +0 -10
  679. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_north/0.0.0 +0 -0
  680. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_south/.zarray +0 -24
  681. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_south/.zattrs +0 -10
  682. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_south/0.0.0 +0 -0
  683. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/.zarray +0 -24
  684. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/.zattrs +0 -10
  685. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/0.0.0 +0 -0
  686. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_east/.zarray +0 -24
  687. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_east/.zattrs +0 -10
  688. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_east/0.0.0 +0 -0
  689. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_north/.zarray +0 -24
  690. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_north/.zattrs +0 -10
  691. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_north/0.0.0 +0 -0
  692. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_south/.zarray +0 -24
  693. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_south/.zattrs +0 -10
  694. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_south/0.0.0 +0 -0
  695. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/.zarray +0 -24
  696. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/.zattrs +0 -10
  697. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/0.0.0 +0 -0
  698. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_east/.zarray +0 -24
  699. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_east/.zattrs +0 -10
  700. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_east/0.0.0 +0 -0
  701. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_north/.zarray +0 -24
  702. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_north/.zattrs +0 -10
  703. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_north/0.0.0 +0 -0
  704. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_south/.zarray +0 -24
  705. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_south/.zattrs +0 -10
  706. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_south/0.0.0 +0 -0
  707. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/.zarray +0 -24
  708. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/.zattrs +0 -10
  709. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/0.0.0 +0 -0
  710. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_east/.zarray +0 -24
  711. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_east/.zattrs +0 -10
  712. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_east/0.0.0 +0 -0
  713. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_north/.zarray +0 -24
  714. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_north/.zattrs +0 -10
  715. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_north/0.0.0 +0 -0
  716. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_south/.zarray +0 -24
  717. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_south/.zattrs +0 -10
  718. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_south/0.0.0 +0 -0
  719. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/.zarray +0 -24
  720. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/.zattrs +0 -10
  721. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/0.0.0 +0 -0
  722. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_east/.zarray +0 -24
  723. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_east/.zattrs +0 -10
  724. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_east/0.0.0 +0 -0
  725. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_north/.zarray +0 -24
  726. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_north/.zattrs +0 -10
  727. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_north/0.0.0 +0 -0
  728. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_south/.zarray +0 -24
  729. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_south/.zattrs +0 -10
  730. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_south/0.0.0 +0 -0
  731. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/.zarray +0 -24
  732. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/.zattrs +0 -10
  733. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/0.0.0 +0 -0
  734. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_east/.zarray +0 -24
  735. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_east/.zattrs +0 -10
  736. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_east/0.0.0 +0 -0
  737. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_north/.zarray +0 -24
  738. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_north/.zattrs +0 -10
  739. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_north/0.0.0 +0 -0
  740. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_south/.zarray +0 -24
  741. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_south/.zattrs +0 -10
  742. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_south/0.0.0 +0 -0
  743. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/.zarray +0 -24
  744. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/.zattrs +0 -10
  745. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/0.0.0 +0 -0
  746. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_east/.zarray +0 -24
  747. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_east/.zattrs +0 -10
  748. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_east/0.0.0 +0 -0
  749. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_north/.zarray +0 -24
  750. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_north/.zattrs +0 -10
  751. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_north/0.0.0 +0 -0
  752. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_south/.zarray +0 -24
  753. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_south/.zattrs +0 -10
  754. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_south/0.0.0 +0 -0
  755. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/.zarray +0 -24
  756. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/.zattrs +0 -10
  757. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/0.0.0 +0 -0
  758. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_east/.zarray +0 -24
  759. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_east/.zattrs +0 -10
  760. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_east/0.0.0 +0 -0
  761. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_north/.zarray +0 -24
  762. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_north/.zattrs +0 -10
  763. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_north/0.0.0 +0 -0
  764. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_south/.zarray +0 -24
  765. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_south/.zattrs +0 -10
  766. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_south/0.0.0 +0 -0
  767. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/.zarray +0 -24
  768. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/.zattrs +0 -10
  769. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/0.0.0 +0 -0
  770. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/month/.zarray +0 -20
  771. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/month/.zattrs +0 -6
  772. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/month/0 +0 -0
  773. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_east/.zarray +0 -24
  774. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_east/.zattrs +0 -10
  775. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_east/0.0.0 +0 -0
  776. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_north/.zarray +0 -24
  777. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_north/.zattrs +0 -10
  778. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_north/0.0.0 +0 -0
  779. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_south/.zarray +0 -24
  780. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_south/.zattrs +0 -10
  781. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_south/0.0.0 +0 -0
  782. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/.zarray +0 -24
  783. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/.zattrs +0 -10
  784. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/0.0.0 +0 -0
  785. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_east/.zarray +0 -24
  786. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_east/.zattrs +0 -10
  787. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_east/0.0.0 +0 -0
  788. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_north/.zarray +0 -24
  789. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_north/.zattrs +0 -10
  790. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_north/0.0.0 +0 -0
  791. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_south/.zarray +0 -24
  792. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_south/.zattrs +0 -10
  793. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_south/0.0.0 +0 -0
  794. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/.zarray +0 -24
  795. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/.zattrs +0 -10
  796. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/0.0.0 +0 -0
  797. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_east/.zarray +0 -24
  798. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_east/.zattrs +0 -10
  799. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_east/0.0.0 +0 -0
  800. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_north/.zarray +0 -24
  801. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_north/.zattrs +0 -10
  802. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_north/0.0.0 +0 -0
  803. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_south/.zarray +0 -24
  804. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_south/.zattrs +0 -10
  805. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_south/0.0.0 +0 -0
  806. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/.zarray +0 -24
  807. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/.zattrs +0 -10
  808. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/0.0.0 +0 -0
  809. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_east/.zarray +0 -24
  810. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_east/.zattrs +0 -10
  811. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_east/0.0.0 +0 -0
  812. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_north/.zarray +0 -24
  813. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_north/.zattrs +0 -10
  814. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_north/0.0.0 +0 -0
  815. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_south/.zarray +0 -24
  816. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_south/.zattrs +0 -10
  817. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_south/0.0.0 +0 -0
  818. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/.zarray +0 -24
  819. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/.zattrs +0 -10
  820. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/0.0.0 +0 -0
  821. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_east/.zarray +0 -24
  822. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_east/.zattrs +0 -10
  823. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_east/0.0.0 +0 -0
  824. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_north/.zarray +0 -24
  825. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_north/.zattrs +0 -10
  826. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_north/0.0.0 +0 -0
  827. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_south/.zarray +0 -24
  828. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_south/.zattrs +0 -10
  829. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_south/0.0.0 +0 -0
  830. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/.zarray +0 -24
  831. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/.zattrs +0 -10
  832. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/0.0.0 +0 -0
  833. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_east/.zarray +0 -24
  834. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_east/.zattrs +0 -10
  835. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_east/0.0.0 +0 -0
  836. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_north/.zarray +0 -24
  837. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_north/.zattrs +0 -10
  838. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_north/0.0.0 +0 -0
  839. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_south/.zarray +0 -24
  840. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_south/.zattrs +0 -10
  841. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_south/0.0.0 +0 -0
  842. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/.zarray +0 -24
  843. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/.zattrs +0 -10
  844. roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/0.0.0 +0 -0
  845. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/.zattrs +0 -12
  846. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/.zgroup +0 -3
  847. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/.zmetadata +0 -424
  848. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/abs_time/.zarray +0 -20
  849. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/abs_time/.zattrs +0 -8
  850. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/abs_time/0 +0 -0
  851. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust/.zarray +0 -24
  852. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust/.zattrs +0 -12
  853. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust/0.0.0 +0 -0
  854. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust_time/.zarray +0 -20
  855. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust_time/.zattrs +0 -8
  856. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/dust_time/0 +0 -0
  857. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron/.zarray +0 -24
  858. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron/.zattrs +0 -12
  859. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron/0.0.0 +0 -0
  860. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron_time/.zarray +0 -20
  861. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron_time/.zattrs +0 -8
  862. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/iron_time/0 +0 -0
  863. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/month/.zarray +0 -20
  864. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/month/.zattrs +0 -6
  865. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/month/0 +0 -0
  866. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy/.zarray +0 -24
  867. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy/.zattrs +0 -10
  868. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy/0.0.0 +0 -0
  869. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy_time/.zarray +0 -20
  870. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy_time/.zattrs +0 -8
  871. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nhy_time/0 +0 -0
  872. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox/.zarray +0 -24
  873. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox/.zattrs +0 -10
  874. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox/0.0.0 +0 -0
  875. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox_time/.zarray +0 -20
  876. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox_time/.zattrs +0 -8
  877. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/nox_time/0 +0 -0
  878. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air/.zarray +0 -24
  879. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air/.zattrs +0 -12
  880. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air/0.0.0 +0 -0
  881. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air_alt/.zarray +0 -24
  882. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air_alt/.zattrs +0 -10
  883. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_air_alt/0.0.0 +0 -0
  884. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_time/.zarray +0 -20
  885. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_time/.zattrs +0 -8
  886. roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_unified_climatology.zarr/pco2_time/0 +0 -0
  887. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/.zattrs +0 -12
  888. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/.zgroup +0 -3
  889. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/.zmetadata +0 -1600
  890. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK/.zarray +0 -26
  891. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK/.zattrs +0 -11
  892. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK/0.0.0.0 +0 -0
  893. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK_ALT_CO2/.zarray +0 -26
  894. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK_ALT_CO2/.zattrs +0 -11
  895. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ALK_ALT_CO2/0.0.0.0 +0 -0
  896. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_r/.zarray +0 -20
  897. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_r/.zattrs +0 -7
  898. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_r/0 +0 -0
  899. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_w/.zarray +0 -20
  900. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_w/.zattrs +0 -7
  901. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Cs_w/0 +0 -0
  902. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC/.zarray +0 -26
  903. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC/.zattrs +0 -11
  904. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC/0.0.0.0 +0 -0
  905. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC_ALT_CO2/.zarray +0 -26
  906. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC_ALT_CO2/.zattrs +0 -11
  907. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DIC_ALT_CO2/0.0.0.0 +0 -0
  908. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOC/.zarray +0 -26
  909. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOC/.zattrs +0 -11
  910. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOC/0.0.0.0 +0 -0
  911. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOCr/.zarray +0 -26
  912. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOCr/.zattrs +0 -11
  913. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOCr/0.0.0.0 +0 -0
  914. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DON/.zarray +0 -26
  915. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DON/.zattrs +0 -11
  916. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DON/0.0.0.0 +0 -0
  917. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DONr/.zarray +0 -26
  918. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DONr/.zattrs +0 -11
  919. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DONr/0.0.0.0 +0 -0
  920. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOP/.zarray +0 -26
  921. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOP/.zattrs +0 -11
  922. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOP/0.0.0.0 +0 -0
  923. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOPr/.zarray +0 -26
  924. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOPr/.zattrs +0 -11
  925. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/DOPr/0.0.0.0 +0 -0
  926. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Fe/.zarray +0 -26
  927. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Fe/.zattrs +0 -11
  928. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Fe/0.0.0.0 +0 -0
  929. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Lig/.zarray +0 -26
  930. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Lig/.zattrs +0 -11
  931. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/Lig/0.0.0.0 +0 -0
  932. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NH4/.zarray +0 -26
  933. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NH4/.zattrs +0 -11
  934. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NH4/0.0.0.0 +0 -0
  935. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NO3/.zarray +0 -26
  936. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NO3/.zattrs +0 -11
  937. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/NO3/0.0.0.0 +0 -0
  938. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/O2/.zarray +0 -26
  939. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/O2/.zattrs +0 -11
  940. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/O2/0.0.0.0 +0 -0
  941. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/PO4/.zarray +0 -26
  942. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/PO4/.zattrs +0 -11
  943. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/PO4/0.0.0.0 +0 -0
  944. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/SiO3/.zarray +0 -26
  945. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/SiO3/.zattrs +0 -11
  946. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/SiO3/0.0.0.0 +0 -0
  947. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/abs_time/.zarray +0 -20
  948. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/abs_time/.zattrs +0 -8
  949. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/abs_time/0 +0 -0
  950. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatC/.zarray +0 -26
  951. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatC/.zattrs +0 -11
  952. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatC/0.0.0.0 +0 -0
  953. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatChl/.zarray +0 -26
  954. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatChl/.zattrs +0 -11
  955. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatChl/0.0.0.0 +0 -0
  956. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatFe/.zarray +0 -26
  957. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatFe/.zattrs +0 -11
  958. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatFe/0.0.0.0 +0 -0
  959. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatP/.zarray +0 -26
  960. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatP/.zattrs +0 -11
  961. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatP/0.0.0.0 +0 -0
  962. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatSi/.zarray +0 -26
  963. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatSi/.zattrs +0 -11
  964. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diatSi/0.0.0.0 +0 -0
  965. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazC/.zarray +0 -26
  966. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazC/.zattrs +0 -11
  967. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazC/0.0.0.0 +0 -0
  968. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazChl/.zarray +0 -26
  969. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazChl/.zattrs +0 -11
  970. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazChl/0.0.0.0 +0 -0
  971. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazFe/.zarray +0 -26
  972. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazFe/.zattrs +0 -11
  973. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazFe/0.0.0.0 +0 -0
  974. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazP/.zarray +0 -26
  975. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazP/.zattrs +0 -11
  976. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/diazP/0.0.0.0 +0 -0
  977. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ocean_time/.zarray +0 -20
  978. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ocean_time/.zattrs +0 -7
  979. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ocean_time/0 +0 -0
  980. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/salt/.zarray +0 -26
  981. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/salt/.zattrs +0 -11
  982. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/salt/0.0.0.0 +0 -0
  983. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spC/.zarray +0 -26
  984. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spC/.zattrs +0 -11
  985. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spC/0.0.0.0 +0 -0
  986. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spCaCO3/.zarray +0 -26
  987. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spCaCO3/.zattrs +0 -11
  988. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spCaCO3/0.0.0.0 +0 -0
  989. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spChl/.zarray +0 -26
  990. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spChl/.zattrs +0 -11
  991. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spChl/0.0.0.0 +0 -0
  992. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spFe/.zarray +0 -26
  993. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spFe/.zattrs +0 -11
  994. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spFe/0.0.0.0 +0 -0
  995. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spP/.zarray +0 -26
  996. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spP/.zattrs +0 -11
  997. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/spP/0.0.0.0 +0 -0
  998. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/temp/.zarray +0 -26
  999. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/temp/.zattrs +0 -11
  1000. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/temp/0.0.0.0 +0 -0
  1001. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/u/.zarray +0 -26
  1002. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/u/.zattrs +0 -11
  1003. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/u/0.0.0.0 +0 -0
  1004. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ubar/.zarray +0 -24
  1005. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ubar/.zattrs +0 -10
  1006. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/ubar/0.0.0 +0 -0
  1007. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/v/.zarray +0 -26
  1008. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/v/.zattrs +0 -11
  1009. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/v/0.0.0.0 +0 -0
  1010. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/vbar/.zarray +0 -24
  1011. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/vbar/.zattrs +0 -10
  1012. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/vbar/0.0.0 +0 -0
  1013. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/w/.zarray +0 -26
  1014. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/w/.zattrs +0 -11
  1015. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/w/0.0.0.0 +0 -0
  1016. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zeta/.zarray +0 -24
  1017. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zeta/.zattrs +0 -10
  1018. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zeta/0.0.0 +0 -0
  1019. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zooC/.zarray +0 -26
  1020. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zooC/.zattrs +0 -11
  1021. roms_tools/tests/test_setup/test_data/initial_conditions_with_unified_bgc_from_climatology.zarr/zooC/0.0.0.0 +0 -0
  1022. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/.zattrs +0 -3
  1023. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/.zgroup +0 -3
  1024. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/.zmetadata +0 -351
  1025. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/abs_time/.zarray +0 -20
  1026. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/abs_time/.zattrs +0 -8
  1027. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/abs_time/0 +0 -0
  1028. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/month/.zarray +0 -20
  1029. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/month/.zattrs +0 -6
  1030. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/month/0 +0 -0
  1031. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/.zarray +0 -20
  1032. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/.zattrs +0 -6
  1033. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/0 +0 -0
  1034. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_fraction/.zarray +0 -22
  1035. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_fraction/.zattrs +0 -8
  1036. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_fraction/0.0 +0 -0
  1037. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_index/.zarray +0 -22
  1038. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_index/.zattrs +0 -8
  1039. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_index/0.0 +0 -0
  1040. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_name/.zarray +0 -24
  1041. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_name/.zattrs +0 -6
  1042. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_name/0 +0 -0
  1043. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_time/.zarray +0 -20
  1044. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_time/.zattrs +0 -8
  1045. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_time/0 +0 -0
  1046. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_tracer/.zarray +0 -24
  1047. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_tracer/.zattrs +0 -9
  1048. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_tracer/0.0.0 +0 -0
  1049. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_volume/.zarray +0 -22
  1050. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_volume/.zattrs +0 -9
  1051. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_volume/0.0 +0 -0
  1052. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_long_name/.zarray +0 -20
  1053. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_long_name/.zattrs +0 -6
  1054. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_long_name/0 +0 -0
  1055. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_name/.zarray +0 -20
  1056. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_name/.zattrs +0 -6
  1057. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_name/0 +0 -0
  1058. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_unit/.zarray +0 -20
  1059. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_unit/.zattrs +0 -6
  1060. roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_unit/0 +0 -0
  1061. roms_tools/tests/test_setup/test_topography.py +0 -201
  1062. roms_tools-2.7.0.dist-info/METADATA +0 -147
  1063. roms_tools-2.7.0.dist-info/RECORD +0 -1670
  1064. roms_tools-2.7.0.dist-info/WHEEL +0 -5
  1065. {roms_tools-2.7.0.dist-info → roms_tools-3.0.0.dist-info}/licenses/LICENSE +0 -0
  1066. {roms_tools-2.7.0.dist-info → roms_tools-3.0.0.dist-info}/top_level.txt +0 -0
@@ -1,389 +1,379 @@
1
- from dataclasses import dataclass, field
1
+ import itertools
2
+ import logging
3
+ from collections import Counter
2
4
  from datetime import datetime
3
5
  from pathlib import Path
4
- from typing import Optional, List, Dict, Union
5
- import numpy as np
6
- import xarray as xr
6
+ from typing import Annotated, Iterator
7
+
7
8
  import cartopy.crs as ccrs
8
- import logging
9
+ import gcm_filters
10
+ import matplotlib.gridspec as gridspec
9
11
  import matplotlib.pyplot as plt
10
- import matplotlib.cm as cm
12
+ import numpy as np
13
+ import xarray as xr
14
+ from matplotlib.axes import Axes
15
+ from pydantic import (
16
+ BaseModel,
17
+ Field,
18
+ RootModel,
19
+ conlist,
20
+ model_serializer,
21
+ model_validator,
22
+ )
23
+
11
24
  from roms_tools import Grid
12
- from roms_tools.constants import NUM_TRACERS
13
- from roms_tools.plot import _plot, _get_projection
25
+ from roms_tools.constants import R_EARTH
26
+ from roms_tools.plot import _get_projection, _plot
14
27
  from roms_tools.regrid import LateralRegridFromROMS
15
- from roms_tools.utils import (
16
- _generate_coordinate_range,
17
- _remove_edge_nans,
18
- save_datasets,
28
+ from roms_tools.setup.cdr_release import (
29
+ Release,
30
+ ReleaseType,
31
+ TracerPerturbation,
32
+ VolumeRelease,
19
33
  )
20
34
  from roms_tools.setup.utils import (
21
- gc_dist,
22
- get_tracer_defaults,
23
- get_tracer_metadata_dict,
24
- add_tracer_metadata_to_ds,
25
- to_float,
26
- _to_yaml,
27
35
  _from_yaml,
36
+ _to_dict,
37
+ _write_to_yaml,
38
+ add_tracer_metadata_to_ds,
39
+ convert_to_relative_days,
40
+ gc_dist,
41
+ get_target_coords,
42
+ )
43
+ from roms_tools.utils import (
44
+ _generate_focused_coordinate_range,
45
+ _remove_edge_nans,
46
+ normalize_longitude,
47
+ save_datasets,
28
48
  )
29
49
 
50
+ INCLUDE_ALL_RELEASE_NAMES = "all"
30
51
 
31
- @dataclass(kw_only=True)
32
- class CDRVolumePointSource:
33
- """Represents one or several volume sources of water with tracers at specific
34
- location(s). This class is particularly useful for modeling point sources of Carbon
35
- Dioxide Removal (CDR) forcing data, such as the injection of water and
36
- biogeochemical tracers, e.g., alkalinity (ALK) or dissolved inorganic carbon (DIC),
37
- through a pipe.
38
52
 
39
- Parameters
40
- ----------
41
- grid : Grid, optional
42
- Object representing the grid for spatial context.
43
- start_time : datetime
44
- Start time of the ROMS model simulation.
45
- end_time : datetime
46
- End time of the ROMS model simulation.
47
- model_reference_date : datetime, optional
48
- Reference date for converting absolute times to model-relative time. Defaults to Jan 1, 2000.
49
- releases : dict, optional
50
- A dictionary of existing releases. Defaults to empty dictionary.
51
-
52
- Attributes
53
- ----------
54
- ds : xr.Dataset
55
- The xarray dataset containing release metadata and forcing variables.
56
- """
53
+ class ReleaseSimulationManager(BaseModel):
54
+ """Validates and adjusts a single release against a ROMS simulation time window and
55
+ grid."""
57
56
 
58
- grid: Optional["Grid"] = None
57
+ release: Release
58
+ grid: Grid | None = None
59
59
  start_time: datetime
60
60
  end_time: datetime
61
- model_reference_date: datetime = datetime(2000, 1, 1)
62
- releases: Optional[dict] = field(default_factory=dict)
63
-
64
- ds: xr.Dataset = field(init=False, repr=False)
65
61
 
66
- def __post_init__(self):
67
- if self.start_time >= self.end_time:
68
- raise ValueError("`start_time` must be earlier than `end_time`.")
69
-
70
- # Start with an empty dataset representing zero releases
71
- ds = xr.Dataset(
72
- {
73
- "cdr_time": (["time"], np.empty(0)),
74
- "cdr_lon": (["ncdr"], np.empty(0)),
75
- "cdr_lat": (["ncdr"], np.empty(0)),
76
- "cdr_dep": (["ncdr"], np.empty(0)),
77
- "cdr_hsc": (["ncdr"], np.empty(0)),
78
- "cdr_vsc": (["ncdr"], np.empty(0)),
79
- "cdr_volume": (["time", "ncdr"], np.empty((0, 0))),
80
- "cdr_tracer": (
81
- ["time", "ntracers", "ncdr"],
82
- np.empty((0, NUM_TRACERS, 0)),
83
- ),
84
- },
85
- coords={
86
- "time": (["time"], np.empty(0)),
87
- "release_name": (["ncdr"], np.empty(0, dtype=str)),
88
- },
89
- )
90
- ds = add_tracer_metadata_to_ds(ds)
91
- self.ds = ds
92
-
93
- tracer_metadata = get_tracer_metadata_dict()
94
- self.releases["_tracer_metadata"] = tracer_metadata
95
-
96
- if self.releases:
97
- if "_metadata" not in self.releases:
98
- tracer_metadata = get_tracer_metadata_dict()
99
- self.releases["_tracer_metadata"] = tracer_metadata
100
-
101
- for name, params in self.releases.items():
102
- if name == "_tracer_metadata":
103
- continue # skip metadata entry
104
- self._validate_release_location(
105
- name=name,
106
- lat=params["lat"],
107
- lon=params["lon"],
108
- depth=params["depth"],
109
- )
110
- self._add_release_to_ds(name=name, **params)
111
-
112
- def add_release(
62
+ @model_validator(mode="after")
63
+ def check_release_times_within_simulation_window(
113
64
  self,
114
- *,
115
- name: str,
116
- lat: float,
117
- lon: float,
118
- depth: float,
119
- times: Optional[List[datetime]] = None,
120
- volume_fluxes: Union[float, List[float]] = 0.0,
121
- tracer_concentrations: Optional[Dict[str, Union[float, List[float]]]] = None,
122
- fill_values: str = "auto",
123
- ):
124
- """Adds a release (point source) of water with tracers to the forcing dataset
125
- and dictionary.
65
+ ) -> "ReleaseSimulationManager":
66
+ """Ensure the release times are within the [start_time, end_time] simulation
67
+ window."""
126
68
 
127
- This method registers a point source at a specific location (latitude, longitude, and depth).
128
- The release includes both a volume flux of water and tracer
129
- concentrations, which can be constant or time-varying.
69
+ times = self.release.times
70
+ if len(times) == 0:
71
+ return self
130
72
 
131
- Parameters
132
- ----------
133
- name : str
134
- Unique identifier for the release.
135
- lat : float or int
136
- Latitude of the release location in degrees North. Must be between -90 and 90.
137
- lon : float or int
138
- Longitude of the release location in degrees East. No restrictions on bounds.
139
- depth : float or int
140
- Depth of the release in meters. Must be non-negative.
141
- times : list of datetime.datetime, optional
142
- Explicit time points for volume fluxes and tracer concentrations. Defaults to [self.start_time, self.end_time] if None.
73
+ if times[0] < self.start_time:
74
+ raise ValueError(
75
+ f"First time in release '{self.release.name}' is before start_time ({self.start_time})."
76
+ )
143
77
 
144
- Example: `times=[datetime(2022, 1, 1), datetime(2022, 1, 2), datetime(2022, 1, 3)]`
78
+ if times[-1] > self.end_time:
79
+ raise ValueError(
80
+ f"Last time in release '{self.release.name}' is after end_time ({self.end_time})."
81
+ )
145
82
 
146
- volume_fluxes : float, int, or list of float/int, optional
83
+ return self
147
84
 
148
- Volume flux(es) of the release in m³/s over time.
85
+ @model_validator(mode="after")
86
+ def validate_release_location(self) -> "ReleaseSimulationManager":
87
+ """Ensure the release is consistent with the simulation grid."""
88
+ _validate_release_location(self.grid, self.release)
89
+ return self
149
90
 
150
- - Constant: applies uniformly across the entire simulation period.
151
- - Time-varying: must match the length of `times`.
91
+ @model_validator(mode="after")
92
+ def extend_to_endpoints(self) -> "ReleaseSimulationManager":
93
+ """Extend the release time series to include the simulation time endpoints."""
94
+ self.release._extend_to_endpoints(self.start_time, self.end_time)
95
+ return self
152
96
 
153
- Example:
154
97
 
155
- - Constant: `volume_fluxes=1000.0` (uniform across the entire simulation period).
156
- - Time-varying: `volume_fluxes=[1000.0, 1500.0, 2000.0]` (corresponds to each `times` entry).
98
+ class ReleaseCollector(RootModel):
99
+ """Collects and validates multiple releases against each other."""
157
100
 
158
- tracer_concentrations : dict, optional
101
+ root: conlist(
102
+ Annotated[
103
+ VolumeRelease | TracerPerturbation, Field(discriminator="release_type")
104
+ ],
105
+ min_length=1,
106
+ ) = Field(alias="releases")
159
107
 
160
- Dictionary of tracer names and their concentration values. The concentration values can be either
161
- a float/int (constant in time) or a list of float/int (time-varying).
108
+ _release_type: ReleaseType = None
162
109
 
163
- - Constant: applies uniformly across the entire simulation period.
164
- - Time-varying: must match the length of `times`.
110
+ def __iter__(self) -> Iterator[Release]:
111
+ return iter(self.root)
165
112
 
166
- Default is an empty dictionary (`{}`) if not provided.
167
- Example:
113
+ def __getitem__(self, item: int | str) -> Release:
114
+ if isinstance(item, int):
115
+ return self.root[item]
116
+ elif isinstance(item, str):
117
+ for release in self.root:
118
+ if release.name == item:
119
+ return release
120
+ raise KeyError(f"Release named '{item}' not found.")
121
+ else:
122
+ raise TypeError(f"Invalid key type: {type(item)}. Must be int or str.")
168
123
 
169
- - Constant: `{"ALK": 2000.0, "DIC": 1900.0}`
170
- - Time-varying: `{"ALK": [2000.0, 2050.0, 2013.3], "DIC": [1900.0, 1920.0, 1910.2]}`
171
- - Mixed: `{"ALK": 2000.0, "DIC": [1900.0, 1920.0, 1910.2]}`
124
+ @model_validator(mode="before")
125
+ @classmethod
126
+ def unpack_dict(cls, data):
127
+ """This helps directly translate a dict of {"releases": [...]} into just the
128
+ list of releases."""
129
+ if isinstance(data, dict):
130
+ try:
131
+ return data["releases"]
132
+ except KeyError:
133
+ raise ValueError(
134
+ "Expected a dictionary with a 'releases' key, or else a list of releases"
135
+ )
136
+ return data
172
137
 
173
- fill_values : str, optional
138
+ @model_validator(mode="after")
139
+ def check_unique_name(self) -> "ReleaseCollector":
140
+ """Check that all releases have unique names."""
141
+ names = [release.name for release in self.root]
142
+ duplicates = [name for name, count in Counter(names).items() if count > 1]
174
143
 
175
- Strategy for filling missing tracer concentration values. Options:
144
+ if duplicates:
145
+ raise ValueError(
146
+ f"Multiple releases share the following name(s): {', '.join(repr(d) for d in duplicates)}. "
147
+ "Each release must have a unique name."
148
+ )
176
149
 
177
- - "auto" (default): automatically set values to non-zero defaults
178
- - "zero": fill missing values with 0.0
179
- """
180
- # Check that the name is unique
181
- if name in self.releases:
182
- raise ValueError(f"A release with the name '{name}' already exists.")
150
+ return self
183
151
 
184
- # Check that fill_values has proper string
185
- if fill_values not in ("auto", "zero"):
152
+ @model_validator(mode="after")
153
+ def check_all_releases_same_type(self):
154
+ """Ensure all releases are of the same type, and set the release_type."""
155
+ release_types = set(r.release_type for r in self.root)
156
+ if len(release_types) > 1:
157
+ type_list = ", ".join(map(str, release_types))
186
158
  raise ValueError(
187
- f"Invalid fill_values option: '{fill_values}'. "
188
- "Must be 'auto' or 'zero'."
159
+ f"Not all releases have the same type. Received: {type_list}"
189
160
  )
161
+ return self
190
162
 
191
- # Set default for times if None
192
- if times is None:
193
- times = []
194
-
195
- # Set default for tracer_concentrations if None
196
- if tracer_concentrations is None:
197
- tracer_concentrations = {}
198
-
199
- # Fill in missing tracer concentrations
200
- defaults = get_tracer_defaults()
201
- for tracer_name in self.ds.tracer_name.values:
202
- if tracer_name not in tracer_concentrations:
203
- tracer_name = str(tracer_name)
204
- if tracer_name in ["temp", "salt"]:
205
- tracer_concentrations[tracer_name] = defaults[tracer_name]
206
- else:
207
- if fill_values == "auto":
208
- tracer_concentrations[tracer_name] = defaults[tracer_name]
209
- elif fill_values == "zero":
210
- tracer_concentrations[tracer_name] = 0.0
211
-
212
- # Check input parameters
213
- self._input_checks(
214
- name=name,
215
- lat=lat,
216
- lon=lon,
217
- depth=depth,
218
- times=times,
219
- volume_fluxes=volume_fluxes,
220
- tracer_concentrations=tracer_concentrations,
221
- )
163
+ @property
164
+ def release_type(self):
165
+ release_types = set(r.release_type for r in self.root)
166
+ return release_types.pop()
222
167
 
223
- # Convert integers to floats
224
- lat = float(lat)
225
- lon = float(lon)
226
- depth = float(depth)
227
- volume_fluxes = to_float(volume_fluxes)
228
- tracer_concentrations = {
229
- tracer: to_float(vals) for tracer, vals in tracer_concentrations.items()
230
- }
231
168
 
232
- # Extend volume fluxes and tracer_concentrations across simulation period if necessary
233
- times, volume_fluxes, tracer_concentrations = self._handle_simulation_endpoints(
234
- times, volume_fluxes, tracer_concentrations
235
- )
169
+ class CDRForcingDatasetBuilder:
170
+ """Constructs the xarray `Dataset` to be saved as NetCDF."""
236
171
 
237
- # Validate release location
238
- self._validate_release_location(name=name, lat=lat, lon=lon, depth=depth)
239
-
240
- self._add_release_to_dict(
241
- name=name,
242
- lat=lat,
243
- lon=lon,
244
- depth=depth,
245
- times=times,
246
- volume_fluxes=volume_fluxes,
247
- tracer_concentrations=tracer_concentrations,
248
- )
172
+ def __init__(self, releases, model_reference_date, release_type: ReleaseType):
173
+ self.releases = releases
174
+ self.model_reference_date = model_reference_date
175
+ self.release_type = release_type
249
176
 
250
- self._add_release_to_ds(
251
- name=name,
252
- lat=lat,
253
- lon=lon,
254
- depth=depth,
255
- times=times,
256
- volume_fluxes=volume_fluxes,
257
- tracer_concentrations=tracer_concentrations,
177
+ def build(self) -> xr.Dataset:
178
+ """Build the CDR forcing dataset."""
179
+
180
+ all_times = itertools.chain.from_iterable(r.times for r in self.releases)
181
+ unique_times = np.unique(np.array(list(all_times), dtype="datetime64[ns]"))
182
+ unique_rel_times = convert_to_relative_days(
183
+ unique_times, self.model_reference_date
258
184
  )
259
185
 
260
- def _add_release_to_ds(
261
- self,
262
- *,
263
- name: str,
264
- lat: float,
265
- lon: float,
266
- depth: float,
267
- times: Optional[List[datetime]] = None,
268
- tracer_concentrations: Optional[Dict[str, Union[float, List[float]]]] = None,
269
- volume_fluxes: Union[float, List[float]] = 0.0,
270
- ):
271
- """Add the release data for a specific release to the forcing dataset."""
186
+ ds = self._initialize_dataset(unique_times, unique_rel_times)
272
187
 
273
- # Convert times to datetime64[ns]
274
- times = np.array(times, dtype="datetime64[ns]")
188
+ for ncdr, release in enumerate(self.releases):
189
+ times = np.array(release.times, dtype="datetime64[ns]")
190
+ rel_times = convert_to_relative_days(times, self.model_reference_date)
275
191
 
276
- # Ensure reference date is also datetime64[ns]
277
- ref = np.datetime64(self.model_reference_date, "ns")
192
+ if self.release_type == ReleaseType.volume:
193
+ ds["cdr_volume"].loc[{"ncdr": ncdr}] = np.interp(
194
+ unique_rel_times, rel_times, release.volume_fluxes.values
195
+ )
196
+ tracer_key = "cdr_tracer"
197
+ tracer_data = release.tracer_concentrations
198
+ elif self.release_type == ReleaseType.tracer_perturbation:
199
+ tracer_key = "cdr_trcflx"
200
+ tracer_data = release.tracer_fluxes
201
+
202
+ for ntracer in range(ds.ntracers.size):
203
+ tracer_name = ds.tracer_name[ntracer].item()
204
+ ds[tracer_key].loc[{"ntracers": ntracer, "ncdr": ncdr}] = np.interp(
205
+ unique_rel_times,
206
+ rel_times,
207
+ tracer_data[tracer_name].values,
208
+ )
278
209
 
279
- # Compute model-relative times in days
280
- rel_times = (times - ref) / np.timedelta64(1, "D")
210
+ return ds
281
211
 
282
- # Merge with existing time dimension
283
- existing_times = (
284
- self.ds["time"].values
285
- if len(self.ds["time"]) > 0
286
- else np.array([], dtype="datetime64[ns]")
287
- )
288
- existing_rel_times = (
289
- self.ds["cdr_time"].values if len(self.ds["cdr_time"]) > 0 else []
290
- )
291
- union_times = np.union1d(existing_times, times)
292
- union_rel_times = np.union1d(existing_rel_times, rel_times)
212
+ def _initialize_dataset(self, unique_times, unique_rel_times) -> xr.Dataset:
213
+ """Create and initialize a CDR xarray.Dataset with metadata and empty variables.
214
+
215
+ Parameters
216
+ ----------
217
+ unique_times : array-like
218
+ Array of unique absolute times for the release.
219
+ unique_rel_times : array-like
220
+ Array of unique relative times (days since model reference date).
221
+
222
+ Returns
223
+ -------
224
+ xr.Dataset
225
+ Initialized dataset with time, location, and release-type-dependent variables.
226
+ """
293
227
 
294
- # Initialize a fresh dataset to accommodate the new release.
295
- # xarray does not handle dynamic resizing of dimensions well (e.g., increasing 'ncdr' by 1),
296
- # so we recreate the dataset with the updated size.
297
228
  ds = xr.Dataset()
298
- ds["time"] = ("time", union_times)
299
- ds["cdr_time"] = ("time", union_rel_times)
300
- ds = add_tracer_metadata_to_ds(ds)
301
-
302
- release_names = np.concatenate([self.ds.release_name.values, [name]])
303
- ds = ds.assign_coords({"release_name": (["ncdr"], release_names)})
304
- ds["cdr_lon"] = xr.zeros_like(ds.ncdr, dtype=np.float64)
305
- ds["cdr_lat"] = xr.zeros_like(ds.ncdr, dtype=np.float64)
306
- ds["cdr_dep"] = xr.zeros_like(ds.ncdr, dtype=np.float64)
307
- ds["cdr_hsc"] = xr.zeros_like(ds.ncdr, dtype=np.float64)
308
- ds["cdr_vsc"] = xr.zeros_like(ds.ncdr, dtype=np.float64)
309
-
310
- ds["cdr_volume"] = xr.zeros_like(ds.cdr_time * ds.ncdr, dtype=np.float64)
311
- ds["cdr_tracer"] = xr.zeros_like(
312
- ds.cdr_time * ds.ntracers * ds.ncdr, dtype=np.float64
229
+ ds["time"] = ("time", unique_times)
230
+ ds["cdr_time"] = ("time", unique_rel_times)
231
+ ds["cdr_lon"] = ("ncdr", [r.lon for r in self.releases])
232
+ ds["cdr_lat"] = ("ncdr", [r.lat for r in self.releases])
233
+ ds["cdr_dep"] = ("ncdr", [r.depth for r in self.releases])
234
+ ds["cdr_hsc"] = ("ncdr", [r.hsc for r in self.releases])
235
+ ds["cdr_vsc"] = ("ncdr", [r.vsc for r in self.releases])
236
+ ds = ds.assign_coords(
237
+ {"release_name": (["ncdr"], [r.name for r in self.releases])}
313
238
  )
314
239
 
315
- # Retain previous experiment locations
316
- if len(self.ds["ncdr"]) > 0:
317
- for i in range(len(self.ds.ncdr)):
318
- for var_name in ["cdr_lon", "cdr_lat", "cdr_dep", "cdr_hsc", "cdr_vsc"]:
319
- ds[var_name].loc[{"ncdr": i}] = self.ds[var_name].isel(ncdr=i)
320
-
321
- # Add the new experiment location
322
- for var_name, value in zip(
323
- ["cdr_lon", "cdr_lat", "cdr_dep", "cdr_hsc", "cdr_vsc"],
324
- [lon, lat, depth, 0.0, 0.0],
325
- ):
326
- ds[var_name].loc[{"ncdr": ds.sizes["ncdr"] - 1}] = np.float64(value)
327
-
328
- # Interpolate and retain previous experiment volume fluxes and tracer concentrations
329
- if len(self.ds["ncdr"]) > 0:
330
- for i in range(len(self.ds.ncdr)):
331
- interpolated = np.interp(
332
- union_rel_times,
333
- self.ds["cdr_time"].values,
334
- self.ds["cdr_volume"].isel(ncdr=i).values,
335
- )
336
- ds["cdr_volume"].loc[{"ncdr": i}] = interpolated
337
-
338
- for n in range(len(self.ds.ntracers)):
339
- interpolated = np.interp(
340
- union_rel_times,
341
- self.ds["cdr_time"].values,
342
- self.ds["cdr_tracer"].isel(ntracers=n, ncdr=i).values,
343
- )
344
- ds["cdr_tracer"].loc[{"ntracers": n, "ncdr": i}] = interpolated
345
-
346
- # Handle new experiment volume fluxes and tracer concentrations
347
- if isinstance(volume_fluxes, list):
348
- interpolated = np.interp(union_rel_times, rel_times, volume_fluxes)
349
- else:
350
- interpolated = np.full(len(union_rel_times), volume_fluxes)
351
-
352
- ds["cdr_volume"].loc[{"ncdr": ds.sizes["ncdr"] - 1}] = interpolated
240
+ if self.release_type == ReleaseType.volume:
241
+ ds = add_tracer_metadata_to_ds(
242
+ ds, with_flux_units=False
243
+ ) # adds the coordinate "tracer_name"
244
+ ds["cdr_volume"] = xr.zeros_like(ds.cdr_time * ds.ncdr, dtype=np.float64)
245
+ ds["cdr_tracer"] = xr.zeros_like(
246
+ ds.cdr_time * ds.ntracers * ds.ncdr, dtype=np.float64
247
+ )
353
248
 
354
- for n in range(len(self.ds.ntracers)):
355
- tracer_name = ds.tracer_name[n].item()
356
- if isinstance(tracer_concentrations[tracer_name], list):
357
- interpolated = np.interp(
358
- union_rel_times, rel_times, tracer_concentrations[tracer_name]
359
- )
360
- else:
361
- interpolated = np.full(
362
- len(union_rel_times), tracer_concentrations[tracer_name]
363
- )
249
+ elif self.release_type == ReleaseType.tracer_perturbation:
250
+ ds = add_tracer_metadata_to_ds(
251
+ ds, with_flux_units=True
252
+ ) # adds the coordinate "tracer_name"
253
+ ds["cdr_trcflx"] = xr.zeros_like(
254
+ ds.cdr_time * ds.ntracers * ds.ncdr, dtype=np.float64
255
+ )
364
256
 
365
- ds["cdr_tracer"].loc[
366
- {"ntracers": n, "ncdr": ds.sizes["ncdr"] - 1}
367
- ] = interpolated
257
+ # Assign attributes
258
+ attr_map = self._get_attr_map()
259
+ for var, attrs in attr_map.items():
260
+ if var in ds.data_vars or var in ds.coords:
261
+ ds[var].attrs.update(attrs)
368
262
 
369
- self.ds = ds
263
+ return ds
370
264
 
371
- def _add_release_to_dict(self, name: str, **params):
372
- """Add the release data for a specific 'name' to the releases dictionary.
265
+ def _get_attr_map(self) -> dict[str, dict[str, str]]:
266
+ """Returns metadata (long name and units) for variables in the CDRForcing xarray
267
+ dataset.
373
268
 
374
- Parameters
375
- ----------
376
- name : str
377
- The unique name for the release to be added to the dictionary.
378
- **params : keyword arguments
379
- Parameters to be added for the specific release (e.g., location, volume fluxes, etc.).
269
+ Returns
270
+ -------
271
+ dict
272
+ Keys are variable names, values are dicts with 'long_name' and 'units'.
380
273
  """
381
- # Add the parameters to the dictionary under the given name
382
- if name not in self.releases:
383
- self.releases[name] = {}
384
- self.releases[name].update(params)
274
+ return {
275
+ "time": {"long_name": "absolute time"},
276
+ "cdr_time": {
277
+ "long_name": f"relative time: days since {self.model_reference_date}",
278
+ "units": "days",
279
+ },
280
+ "release_name": {"long_name": "Name of release"},
281
+ "cdr_lon": {
282
+ "long_name": "Longitude of CDR release",
283
+ "units": "degrees east",
284
+ },
285
+ "cdr_lat": {
286
+ "long_name": "Latitude of CDR release",
287
+ "units": "degrees north",
288
+ },
289
+ "cdr_dep": {"long_name": "Depth of CDR release", "units": "meters"},
290
+ "cdr_hsc": {
291
+ "long_name": "Horizontal scale of CDR release",
292
+ "units": "meters",
293
+ },
294
+ "cdr_vsc": {
295
+ "long_name": "Vertical scale of CDR release",
296
+ "units": "meters",
297
+ },
298
+ "cdr_trcflx": {
299
+ "long_name": "CDR tracer flux",
300
+ "description": "Tracer fluxes for CDR releases",
301
+ },
302
+ "cdr_volume": {
303
+ "long_name": "CDR volume flux",
304
+ "units": "m3/s",
305
+ "description": "Volume flux associated with CDR releases",
306
+ },
307
+ "cdr_tracer": {
308
+ "long_name": "CDR tracer concentration",
309
+ "description": "Tracer concentrations for CDR releases",
310
+ },
311
+ }
312
+
313
+
314
+ class CDRForcing(BaseModel):
315
+ """Represents Carbon Dioxide Removal (CDR) forcing.
316
+
317
+ Parameters
318
+ ----------
319
+ grid : Grid, optional
320
+ Object representing the grid for spatial context.
321
+ start_time : datetime
322
+ Start time of the ROMS model simulation.
323
+ end_time : datetime
324
+ End time of the ROMS model simulation.
325
+ model_reference_date : datetime, optional
326
+ Reference date for converting absolute times to model-relative time. Defaults to Jan 1, 2000.
327
+ releases : list of Release
328
+ A list of one or more CDR release objects.
329
+
330
+ Attributes
331
+ ----------
332
+ ds : xr.Dataset
333
+ The xarray dataset containing release metadata and forcing variables.
334
+ """
385
335
 
386
- def plot_volume_flux(self, start=None, end=None, releases="all"):
336
+ grid: Grid | None = None
337
+ start_time: datetime
338
+ end_time: datetime
339
+ model_reference_date: datetime = datetime(2000, 1, 1)
340
+ releases: ReleaseCollector
341
+
342
+ # this is defined during init and shouldn't be serialized
343
+ _ds: xr.Dataset = None
344
+
345
+ @model_validator(mode="after")
346
+ def _validate(self):
347
+ if self.start_time >= self.end_time:
348
+ raise ValueError(
349
+ f"`start_time` ({self.start_time}) must be earlier than `end_time` ({self.end_time})."
350
+ )
351
+
352
+ for release in self.releases:
353
+ ReleaseSimulationManager(
354
+ release=release,
355
+ grid=self.grid,
356
+ start_time=self.start_time,
357
+ end_time=self.end_time,
358
+ )
359
+
360
+ builder = CDRForcingDatasetBuilder(
361
+ self.releases, self.model_reference_date, self.release_type
362
+ )
363
+ self._ds = builder.build()
364
+ return self
365
+
366
+ @property
367
+ def release_type(self) -> ReleaseType:
368
+ return self.releases.release_type
369
+
370
+ @property
371
+ def ds(self) -> xr.Dataset:
372
+ return self._ds
373
+
374
+ def plot_volume_flux(
375
+ self, start=None, end=None, release_names=INCLUDE_ALL_RELEASE_NAMES
376
+ ):
387
377
  """Plot the volume flux for each specified release within the given time range.
388
378
 
389
379
  Parameters
@@ -392,26 +382,39 @@ class CDRVolumePointSource:
392
382
  Start datetime for the plot. If None, defaults to `self.start_time`.
393
383
  end : datetime or None
394
384
  End datetime for the plot. If None, defaults to `self.end_time`.
395
- releases : str, list of str, or "all", optional
396
- A string or list of release names to plot.
397
- If "all", the method will plot all releases.
398
- The default is "all".
385
+ release_names : list[str], or str, optional
386
+ A list of release names to plot.
387
+ If a string equal to "all", all releases will be plotted.
388
+ Defaults to "all".
389
+
390
+ Raises
391
+ ------
392
+ ValueError
393
+ If self.releases are not of type VolumeRelease.
394
+ If `release_names` is not a list of strings or "all".
395
+ If any of the specified release names do not exist in `self.releases`.
399
396
  """
400
397
 
398
+ if self.release_type != ReleaseType.volume:
399
+ raise ValueError(
400
+ "plot_volume_flux is only supported when all releases are of type VolumeRelease."
401
+ )
402
+
401
403
  start = start or self.start_time
402
404
  end = end or self.end_time
403
405
 
404
- # Handle "all" releases case
405
- if releases == "all":
406
- releases = [k for k in self.releases if k != "_tracer_metadata"]
407
- # Validate input for release names
408
- self._validate_release_input(releases)
406
+ valid_release_names = [r.name for r in self.releases]
407
+
408
+ if release_names == INCLUDE_ALL_RELEASE_NAMES:
409
+ release_names = valid_release_names
410
+
411
+ _validate_release_input(release_names, valid_release_names)
409
412
 
410
413
  data = self.ds["cdr_volume"]
411
414
 
412
415
  self._plot_line(
413
416
  data,
414
- releases,
417
+ release_names,
415
418
  start,
416
419
  end,
417
420
  title="Volume flux of release(s)",
@@ -419,250 +422,250 @@ class CDRVolumePointSource:
419
422
  )
420
423
 
421
424
  def plot_tracer_concentration(
422
- self, name: str, start=None, end=None, releases="all"
425
+ self,
426
+ tracer_name: str,
427
+ start=None,
428
+ end=None,
429
+ release_names=INCLUDE_ALL_RELEASE_NAMES,
423
430
  ):
424
431
  """Plot the concentration of a given tracer for each specified release within
425
432
  the given time range.
426
433
 
427
434
  Parameters
428
435
  ----------
429
- name : str
436
+ tracer_name : str
430
437
  Name of the tracer to plot, e.g., "ALK", "DIC", etc.
431
438
  start : datetime or None
432
439
  Start datetime for the plot. If None, defaults to `self.start_time`.
433
440
  end : datetime or None
434
441
  End datetime for the plot. If None, defaults to `self.end_time`.
435
- releases : str, list of str, or "all", optional
436
- A string or list of release names to plot.
437
- If "all", the method will plot all releases.
438
- The default is "all".
442
+ release_names : list[str], or str, optional
443
+ A list of release names to plot.
444
+ If a string equal to "all", all releases will be plotted.
445
+ Defaults to "all".
446
+
447
+ Raises
448
+ ------
449
+ ValueError
450
+ If self.releases are not of type VolumeRelease.
451
+ If `release_names` is not a list of strings or "all".
452
+ If any of the specified release names do not exist in `self.releases`.
453
+ If `tracer_name` does not exist in self.ds["tracer_name"])
439
454
  """
455
+ if self.release_type != ReleaseType.volume:
456
+ raise ValueError(
457
+ "plot_tracer_concentration is only supported when all releases are of type VolumeRelease."
458
+ )
459
+
440
460
  start = start or self.start_time
441
461
  end = end or self.end_time
442
462
 
443
- # Handle "all" releases case
444
- if releases == "all":
445
- releases = [k for k in self.releases if k != "_tracer_metadata"]
446
- # Validate input for release names
447
- self._validate_release_input(releases)
463
+ valid_release_names = [r.name for r in self.releases]
464
+
465
+ if release_names == INCLUDE_ALL_RELEASE_NAMES:
466
+ release_names = valid_release_names
467
+
468
+ _validate_release_input(release_names, valid_release_names)
448
469
 
449
470
  tracer_names = list(self.ds["tracer_name"].values)
450
- if name not in tracer_names:
471
+ if tracer_name not in tracer_names:
451
472
  raise ValueError(
452
- f"Tracer '{name}' not found. Available: {', '.join(tracer_names)}"
473
+ f"Tracer '{tracer_name}' not found. Available: {', '.join(tracer_names)}"
453
474
  )
454
475
 
455
- tracer_index = tracer_names.index(name)
476
+ tracer_index = tracer_names.index(tracer_name)
456
477
  data = self.ds["cdr_tracer"].isel(ntracers=tracer_index)
457
478
 
458
- if name == "temp":
479
+ if tracer_name == "temp":
459
480
  title = "Temperature of release water"
460
- elif name == "salt":
481
+ elif tracer_name == "salt":
461
482
  title = "Salinity of release water"
462
483
  else:
463
- title = f"{name} concentration of release(s)"
484
+ title = f"{tracer_name} concentration of release(s)"
485
+
486
+ self._plot_line(
487
+ data,
488
+ release_names,
489
+ start,
490
+ end,
491
+ title=title,
492
+ ylabel=f"{self.ds['tracer_unit'].isel(ntracers=tracer_index).values.item()}",
493
+ )
494
+
495
+ def plot_tracer_flux(
496
+ self,
497
+ tracer_name: str,
498
+ start=None,
499
+ end=None,
500
+ release_names=INCLUDE_ALL_RELEASE_NAMES,
501
+ ):
502
+ """Plot the flux of a given tracer for each specified release within the given
503
+ time range.
504
+
505
+ Parameters
506
+ ----------
507
+ tracer_name : str
508
+ Name of the tracer to plot, e.g., "ALK", "DIC", etc.
509
+ start : datetime or None
510
+ Start datetime for the plot. If None, defaults to `self.start_time`.
511
+ end : datetime or None
512
+ End datetime for the plot. If None, defaults to `self.end_time`.
513
+ release_names : list[str], or str, optional
514
+ A list of release names to plot.
515
+ If a string equal to "all", all releases will be plotted.
516
+ Defaults to "all".
517
+
518
+ Raises
519
+ ------
520
+ ValueError
521
+ If self.releases are not of type TracerPerturbation.
522
+ If `release_names` is not a list of strings or "all".
523
+ If any of the specified release names do not exist in `self.releases`.
524
+ If `tracer_name` does not exist in self.ds["tracer_name"])
525
+ """
526
+ if self.release_type != ReleaseType.tracer_perturbation:
527
+ raise ValueError(
528
+ "plot_tracer_flux is only supported when all releases are of type TracerPerturbation."
529
+ )
530
+
531
+ start = start or self.start_time
532
+ end = end or self.end_time
533
+
534
+ valid_release_names = [r.name for r in self.releases]
535
+
536
+ if release_names == INCLUDE_ALL_RELEASE_NAMES:
537
+ release_names = valid_release_names
538
+
539
+ _validate_release_input(release_names, valid_release_names)
540
+
541
+ tracer_names = list(self.ds["tracer_name"].values)
542
+ if tracer_name not in tracer_names:
543
+ raise ValueError(
544
+ f"Tracer '{tracer_name}' not found. Available: {', '.join(tracer_names)}"
545
+ )
546
+
547
+ tracer_index = tracer_names.index(tracer_name)
548
+ data = self.ds["cdr_trcflx"].isel(ntracers=tracer_index)
549
+
550
+ title = f"{tracer_name} flux of release(s)"
464
551
 
465
552
  self._plot_line(
466
553
  data,
467
- releases,
554
+ release_names,
468
555
  start,
469
556
  end,
470
557
  title=title,
471
558
  ylabel=f"{self.ds['tracer_unit'].isel(ntracers=tracer_index).values.item()}",
472
559
  )
473
560
 
474
- def _plot_line(self, data, releases, start, end, title="", ylabel=""):
561
+ def _plot_line(self, data, release_names, start, end, title="", ylabel=""):
475
562
  """Plots a line graph for the specified releases and time range."""
476
- colors = self._get_release_colors()
563
+ valid_release_names = [r.name for r in self.releases]
564
+ colors = _get_release_colors(valid_release_names)
477
565
 
478
566
  fig, ax = plt.subplots(1, 1, figsize=(7, 4))
479
- for release in releases:
480
- ncdr = np.where(self.ds["release_name"].values == release)[0][0]
567
+ for name in release_names:
568
+ ncdr = np.where(self.ds["release_name"].values == name)[0].item()
481
569
  data.isel(ncdr=ncdr).plot(
482
570
  ax=ax,
483
571
  linewidth=2,
484
- label=release,
485
- color=colors[release],
572
+ label=name,
573
+ color=colors[name],
486
574
  marker="x",
487
575
  )
488
576
 
489
- if len(releases) > 0:
577
+ if len(release_names) > 0:
490
578
  ax.legend()
491
579
 
492
- ax.set(title=title, ylabel=ylabel)
580
+ ax.set(title=title, ylabel=ylabel, xlabel="time")
493
581
  ax.set_xlim([start, end])
494
582
 
495
- def plot_location_top_view(self, releases="all"):
496
- """Plot the top-down view of release locations.
583
+ def plot_locations(self, release_names="all"):
584
+ """Plot centers of release locations in top-down view.
497
585
 
498
586
  Parameters
499
587
  ----------
500
- releases : list of str or str, optional
501
- A single release name (string) or a list of release names (strings) to plot.
502
- Default is 'all', which will plot all releases.
588
+ release_names : list of str or "all", optional
589
+ A list of release names to plot.
590
+ If "all", the method will plot all releases.
591
+ The default is "all".
503
592
 
504
593
  Raises
505
594
  ------
506
595
  ValueError
596
+ If `release_names` is not a list of strings or "all".
597
+ If any of the specified release names do not exist in `self.releases`.
507
598
  If `self.grid` is not set.
508
- If `releases` is not a string or list of strings.
509
- If any of the specified releases do not exist in `self.releases`.
510
599
  """
600
+
511
601
  # Ensure that the grid is provided
512
602
  if self.grid is None:
513
603
  raise ValueError(
514
604
  "A grid must be provided for plotting. Please pass a valid `Grid` object."
515
605
  )
516
606
 
517
- # Handle "all" releases case
518
- if releases == "all":
519
- releases = [k for k in self.releases if k != "_tracer_metadata"]
607
+ valid_release_names = [r.name for r in self.releases]
520
608
 
521
- # Validate input for release names
522
- self._validate_release_input(releases)
609
+ if release_names == "all":
610
+ release_names = valid_release_names
611
+
612
+ _validate_release_input(release_names, valid_release_names)
523
613
 
524
- # Proceed with plotting
525
- field = self.grid.ds.mask_rho
526
614
  lon_deg = self.grid.ds.lon_rho
527
615
  lat_deg = self.grid.ds.lat_rho
528
616
  if self.grid.straddle:
529
617
  lon_deg = xr.where(lon_deg > 180, lon_deg - 360, lon_deg)
530
- field = field.assign_coords({"lon": lon_deg, "lat": lat_deg})
618
+ trans = _get_projection(lon_deg, lat_deg)
619
+ fig, ax = plt.subplots(1, 1, figsize=(13, 7), subplot_kw={"projection": trans})
531
620
 
621
+ # Plot blue background on map
622
+ field = self.grid.ds.mask_rho
623
+ field = field.assign_coords({"lon": lon_deg, "lat": lat_deg})
532
624
  vmax = 6
533
625
  vmin = 0
534
626
  cmap = plt.colormaps.get_cmap("Blues")
535
627
  kwargs = {"vmax": vmax, "vmin": vmin, "cmap": cmap}
536
-
537
- trans = _get_projection(lon_deg, lat_deg)
538
-
539
- fig, ax = plt.subplots(1, 1, figsize=(13, 7), subplot_kw={"projection": trans})
540
-
541
628
  _plot(field, kwargs=kwargs, ax=ax, c=None, add_colorbar=False)
542
629
 
543
- proj = ccrs.PlateCarree()
544
-
545
- colors = self._get_release_colors()
546
-
547
- for name in releases:
548
- # transform coordinates to projected space
549
- transformed_lon, transformed_lat = trans.transform_point(
550
- self.releases[name]["lon"],
551
- self.releases[name]["lat"],
552
- proj,
553
- )
554
-
555
- ax.plot(
556
- transformed_lon,
557
- transformed_lat,
558
- marker="x",
559
- markersize=8,
560
- markeredgewidth=2,
561
- label=name,
562
- color=colors[name],
563
- )
564
-
565
- ax.set_title("Release locations")
566
- ax.legend(loc="center left", bbox_to_anchor=(1.1, 0.5))
630
+ # Plot release locations
631
+ colors = _get_release_colors(valid_release_names)
632
+ _plot_location(
633
+ grid=self.grid,
634
+ releases=[self.releases[name] for name in release_names],
635
+ ax=ax,
636
+ colors=colors,
637
+ )
567
638
 
568
- def plot_location_side_view(self, release: str = None):
569
- """Plot the release location from a side view, showing bathymetry sections along
570
- both fixed longitude and latitude.
639
+ def plot_distribution(self, release_name: str, mark_release_center: bool = True):
640
+ """Plot the release location from a top and side view.
571
641
 
572
- This method creates two plots:
642
+ This method creates three plots:
573
643
 
574
- - A bathymetry section along a fixed longitude (latitudinal view),
575
- with the release location marked by an "x".
576
- - A bathymetry section along a fixed latitude (longitudinal view),
577
- with the release location also marked by an "x".
644
+ - A top view of the release distribution.
645
+ - A side view of the release distribution along a fixed longitude.
646
+ - A side view of the release distribution along a fixed latitude.
578
647
 
579
648
  Parameters
580
649
  ----------
581
- release : str, optional
582
- Name of the release to plot. If only one release is available,
583
- it is used by default. If multiple releases are available, this must be specified.
650
+ release_name : str
651
+ Name of the release to plot.
652
+ mark_release_center : bool, default True
653
+ Whether to mark the center of the release distribution with an "x".
584
654
 
585
655
  Raises
586
656
  ------
587
657
  ValueError
588
-
589
658
  If `self.grid` is not set.
590
- If the specified `release` does not exist in `self.releases`.
591
- If no `release` is provided when multiple releases are available.
659
+ If the specified `release_name` does not exist in `self.releases`.
592
660
  """
593
661
  if self.grid is None:
594
662
  raise ValueError(
595
663
  "A grid must be provided for plotting. Please pass a valid `Grid` object."
596
664
  )
597
665
 
598
- valid_releases = [r for r in self.releases if r != "_tracer_metadata"]
599
- if release is None:
600
- if len(valid_releases) == 1:
601
- release = valid_releases[0]
602
- else:
603
- raise ValueError(
604
- f"Multiple releases found: {valid_releases}. Please specify a single release to plot."
605
- )
606
-
607
- self._validate_release_input(release, list_allowed=False)
608
-
609
- def _plot_bathymetry_section(
610
- ax, h, dim, fixed_val, coord_deg, resolution, title
611
- ):
612
- """Plots a bathymetry section along a fixed latitude or longitude.
613
-
614
- Parameters
615
- ----------
616
- ax : matplotlib.axes.Axes
617
- The axis on which the plot will be drawn.
618
-
619
- h : xarray.DataArray
620
- The bathymetry data to plot.
621
-
622
- dim : str
623
- The dimension along which to plot the section, either "lat" or "lon".
624
-
625
- fixed_val : float
626
- The fixed value of latitude or longitude for the section.
627
-
628
- coord_deg : xarray.DataArray
629
- The array of latitude or longitude coordinates.
630
-
631
- resolution : float
632
- The resolution at which to generate the coordinate range.
633
-
634
- title : str
635
- The title for the plot.
636
-
637
- Returns
638
- -------
639
- None
640
- The function does not return anything. It directly plots the bathymetry section on the provided axis.
641
- """
642
- # Determine coordinate names and build target range
643
- var_range = _generate_coordinate_range(
644
- coord_deg.min().values, coord_deg.max().values, resolution
645
- )
646
- var_name = "lat" if dim == "lon" else "lon"
647
- range_da = xr.DataArray(
648
- var_range,
649
- dims=[var_name],
650
- attrs={"units": "°N" if var_name == "lat" else "°E"},
651
- )
652
-
653
- # Construct target coordinates for regridding
654
- target_coords = {dim: [fixed_val], var_name: range_da}
655
- regridder = LateralRegridFromROMS(h, target_coords)
656
- section = regridder.apply(h)
657
- section, _ = _remove_edge_nans(section, var_name)
658
-
659
- # Plot the bathymetry section
660
- section.plot(ax=ax, color="k")
661
- ax.fill_between(section[var_name], section.squeeze(), y2=0, color="#deebf7")
662
- ax.invert_yaxis()
663
- ax.set_xlabel("Latitude [°N]" if var_name == "lat" else "Longitude [°E]")
664
- ax.set_ylabel("Depth [m]")
665
- ax.set_title(title)
666
+ valid_release_names = [r.name for r in self.releases]
667
+ _validate_release_input(release_name, valid_release_names, list_allowed=False)
668
+ release = self.releases[release_name]
666
669
 
667
670
  # Prepare grid coordinates
668
671
  lon_deg = self.grid.ds.lon_rho
@@ -670,71 +673,94 @@ class CDRVolumePointSource:
670
673
  if self.grid.straddle:
671
674
  lon_deg = xr.where(lon_deg > 180, lon_deg - 360, lon_deg)
672
675
 
673
- resolution = self.grid._infer_nominal_horizontal_resolution()
674
- h = self.grid.ds.h.assign_coords({"lon": lon_deg, "lat": lat_deg})
675
-
676
- # Set up plot
677
- fig, axs = plt.subplots(2, 1, figsize=(7, 8))
678
-
679
- # Plot along fixed longitude
680
- _plot_bathymetry_section(
681
- ax=axs[0],
682
- h=h,
683
- dim="lon",
684
- fixed_val=self.releases[release]["lon"],
685
- coord_deg=lat_deg,
686
- resolution=resolution,
687
- title=f"Longitude: {self.releases[release]['lon']}°E",
676
+ # Setup figure
677
+ fig = plt.figure(figsize=(12, 5.5))
678
+ gs = gridspec.GridSpec(nrows=2, ncols=2, figure=fig)
679
+ trans = _get_projection(lon_deg, lat_deg)
680
+ ax0 = fig.add_subplot(gs[:, 0], projection=trans)
681
+ ax1 = fig.add_subplot(gs[0, 1])
682
+ ax2 = fig.add_subplot(gs[1, 1])
683
+ cmap = plt.colormaps.get_cmap("RdPu")
684
+ cmap.set_bad(color="gray")
685
+ kwargs = {"cmap": cmap}
686
+
687
+ # Top down view plot
688
+ horizontal_field = _map_horizontal_gaussian(self.grid, release)
689
+ horizontal_field = horizontal_field.assign_coords(
690
+ {"lon": lon_deg, "lat": lat_deg}
688
691
  )
689
-
690
- colors = self._get_release_colors()
691
-
692
- axs[0].plot(
693
- self.releases[release]["lat"],
694
- self.releases[release]["depth"],
695
- color=colors[release],
696
- marker="x",
697
- markersize=8,
698
- markeredgewidth=2,
692
+ _plot(
693
+ horizontal_field.where(self.grid.ds.mask_rho),
694
+ kwargs=kwargs,
695
+ ax=ax0,
696
+ c=None,
697
+ add_colorbar=False,
699
698
  )
699
+ if mark_release_center:
700
+ _plot_location(
701
+ grid=self.grid, releases=[release], ax=ax0, include_legend=False
702
+ )
700
703
 
701
- # Plot along fixed latitude
702
- _plot_bathymetry_section(
703
- ax=axs[1],
704
- h=h,
705
- dim="lat",
706
- fixed_val=self.releases[release]["lat"],
707
- coord_deg=lon_deg,
708
- resolution=resolution,
709
- title=f"Latitude: {self.releases[release]['lat']}°N",
704
+ # Side view plots
705
+ kwargs = {
706
+ "cmap": cmap,
707
+ "y": "depth",
708
+ "yincrease": False,
709
+ "add_colorbar": False,
710
+ }
711
+ # Plot along latitude
712
+ vertical_field = _map_vertical_gaussian(
713
+ self.grid, release, horizontal_field, orientation="latitude"
710
714
  )
711
- axs[1].plot(
712
- self.releases[release]["lon"],
713
- self.releases[release]["depth"],
714
- color=colors[release],
715
- marker="x",
716
- markersize=8,
717
- markeredgewidth=2,
715
+ more_kwargs = {"x": "lat"}
716
+ vertical_field.plot(**kwargs, **more_kwargs, ax=ax1)
717
+ if mark_release_center:
718
+ ax1.plot(
719
+ release.lat,
720
+ release.depth,
721
+ color="k",
722
+ marker="x",
723
+ markersize=8,
724
+ markeredgewidth=2,
725
+ )
726
+
727
+ ax1.set(title=f"Longitude: {release.lon}°E", xlabel="Latitude [°N]")
728
+ # Plot along longitude
729
+ vertical_field = _map_vertical_gaussian(
730
+ self.grid, release, horizontal_field, orientation="longitude"
718
731
  )
732
+ more_kwargs = {"x": "lon"}
733
+ vertical_field.plot(**kwargs, **more_kwargs, ax=ax2)
734
+ if mark_release_center:
735
+ release_lon = normalize_longitude(release.lon, self.grid.straddle)
736
+ ax2.plot(
737
+ release_lon,
738
+ release.depth,
739
+ color="k",
740
+ marker="x",
741
+ markersize=8,
742
+ markeredgewidth=2,
743
+ )
744
+ ax2.set(title=f"Latitude: {release.lat}°N", xlabel="Longitude [°E]")
719
745
 
720
746
  # Adjust layout and title
721
- fig.subplots_adjust(hspace=0.4)
722
- fig.suptitle(f"Release location for: {release}")
747
+ fig.subplots_adjust(hspace=0.45)
748
+ fig.suptitle(f"Release distribution for: {release_name}")
723
749
 
724
750
  def save(
725
751
  self,
726
- filepath: Union[str, Path],
727
- ) -> None:
752
+ filepath: str | Path,
753
+ ) -> list[Path]:
728
754
  """Save the volume source with tracers to netCDF4 file.
729
755
 
730
756
  Parameters
731
757
  ----------
732
- filepath : Union[str, Path]
758
+ filepath : str | Path
733
759
  The base path and filename for the output files.
734
760
 
735
761
  Returns
736
762
  -------
737
- List[Path]
763
+ list[Path]
738
764
  A list of `Path` objects for the saved files. Each element in the list corresponds to a file that was saved.
739
765
  """
740
766
 
@@ -752,375 +778,510 @@ class CDRVolumePointSource:
752
778
 
753
779
  return saved_filenames
754
780
 
755
- def to_yaml(self, filepath: Union[str, Path]) -> None:
781
+ @model_serializer
782
+ def _serialize(self) -> dict:
783
+ return _to_dict(self)
784
+
785
+ def to_yaml(self, filepath: str | Path) -> None:
756
786
  """Export the parameters of the class to a YAML file, including the version of
757
787
  roms-tools.
758
788
 
759
789
  Parameters
760
790
  ----------
761
- filepath : Union[str, Path]
791
+ filepath : str | Path
762
792
  The path to the YAML file where the parameters will be saved.
763
793
  """
764
794
 
765
- _to_yaml(self, filepath)
795
+ forcing_dict = self.model_dump()
796
+ metadata = self.releases[0].get_tracer_metadata()
797
+ forcing_dict["CDRForcing"]["_tracer_metadata"] = metadata
798
+
799
+ _write_to_yaml(forcing_dict, filepath)
766
800
 
767
801
  @classmethod
768
- def from_yaml(cls, filepath: Union[str, Path]) -> "CDRVolumePointSource":
769
- """Create an instance of the CDRVolumePointSource class from a YAML file.
802
+ def from_yaml(cls, filepath: str | Path) -> "CDRForcing":
803
+ """Create an instance of the CDRForcing class from a YAML file.
770
804
 
771
805
  Parameters
772
806
  ----------
773
- filepath : Union[str, Path]
807
+ filepath : str | Path
774
808
  The path to the YAML file from which the parameters will be read.
775
809
 
776
810
  Returns
777
811
  -------
778
- CDRVolumePointSource
779
- An instance of the CDRVolumePointSource class.
812
+ CDRForcing
813
+ An instance of the CDRForcing class.
780
814
  """
781
815
  filepath = Path(filepath)
782
816
 
783
817
  grid = Grid.from_yaml(filepath)
784
818
  params = _from_yaml(cls, filepath)
819
+ params.pop("_tracer_metadata", None)
785
820
 
786
821
  return cls(grid=grid, **params)
787
822
 
788
- def _input_checks(
789
- self,
790
- name,
791
- lat,
792
- lon,
793
- depth,
794
- times,
795
- volume_fluxes,
796
- tracer_concentrations,
797
- ):
798
- """Perform various input checks on release parameters.
799
-
800
- - Checks that latitude is between -90 and 90.
801
- - Checks that depth is non-negative.
802
- - Ensures 'times' is a list of datetime objects and is monotonically increasing.
803
- - Verifies that times are within the defined start and end time.
804
- - Ensures volume fluxes is either a list of floats/ints or a single float/int.
805
- - Ensures each tracer concentration is either a float/int or a list of floats/ints.
806
- - Ensures the lengths of 'volume_fluxes' and 'tracer_concentrations' match the length of 'times' if they are lists.
807
- - Ensures all entries in 'volume_fluxes' and 'tracer_concentrations' are non-negative.
808
- """
809
823
 
810
- # Check that lat is valid
811
- if not (-90 <= lat <= 90):
812
- raise ValueError(
813
- f"Invalid latitude {lat}. Latitude must be between -90 and 90."
814
- )
824
+ def _validate_release_input(releases, valid_releases, list_allowed=True):
825
+ """Validates the input for release names in plotting methods to ensure they are in
826
+ an acceptable format and exist within the set of valid releases.
815
827
 
816
- # Check that depth is non-negative
817
- if depth < 0:
818
- raise ValueError(
819
- f"Invalid depth {depth}. Depth must be a non-negative number."
820
- )
821
-
822
- # Ensure that times is a list of datetimes
823
- if not all(isinstance(t, datetime) for t in times):
824
- raise ValueError(
825
- f"If 'times' is provided, all entries must be datetime objects. Got: {[type(t) for t in times]}"
826
- )
827
-
828
- if len(times) > 0:
829
- if len(times) > 1:
830
- # Check that times is strictly monotonically increasing sequence
831
- if not all(t1 < t2 for t1, t2 in zip(times, times[1:])):
832
- raise ValueError(
833
- f"The 'times' list must be strictly monotonically increasing. Got: {[t for t in times]}"
834
- )
828
+ This method ensures that the `releases` parameter is either a single release name (string) or a list
829
+ of release names (strings), and checks that each release exists in the set of valid releases.
835
830
 
836
- # Check that first time is not before start_time
837
- if times[0] < self.start_time:
838
- raise ValueError(
839
- f"First entry in `times` ({times[0]}) cannot be before `self.start_time` ({self.start_time})."
840
- )
841
-
842
- # Check that last time is not after end_time
843
- if times[-1] > self.end_time:
844
- raise ValueError(
845
- f"Last entry in `times` ({times[-1]}) cannot be after `self.end_time` ({self.end_time})."
846
- )
831
+ Parameters
832
+ ----------
833
+ releases : str or list of str
834
+ A single release name as a string, or a list of release names (strings) to validate.
835
+
836
+ list_allowed : bool, optional
837
+ If `True`, a list of release names is allowed. If `False`, only a single release name (string)
838
+ is allowed. Default is `True`.
839
+
840
+ Raises
841
+ ------
842
+ ValueError
843
+ If `releases` is not a string or list of strings, or if any release name is invalid (not in `self.releases`).
844
+
845
+ Notes
846
+ -----
847
+ This method checks that the `releases` input is in a valid format (either a string or a list of strings),
848
+ and ensures each release is present in the set of valid releases defined in `self.releases`. Invalid releases
849
+ are reported in the error message.
850
+
851
+ If `list_allowed` is set to `False`, only a single release name (string) will be accepted. Otherwise, a
852
+ list of release names is also acceptable.
853
+ """
847
854
 
848
- # Ensure volume fluxes is either a list of floats/ints or a single float/int
849
- if not isinstance(volume_fluxes, (float, int)) and not (
850
- isinstance(volume_fluxes, list)
851
- and all(isinstance(v, (float, int)) for v in volume_fluxes)
852
- ):
853
- raise ValueError(
854
- "Invalid 'volume_fluxes' input: must be a float/int or a list of floats/ints."
855
- )
855
+ # Ensure that a list of releases is only allowed if `list_allowed` is True
856
+ if not list_allowed and not isinstance(releases, str):
857
+ raise ValueError(
858
+ f"Only a single release name (string) is allowed. Got: {releases}"
859
+ )
856
860
 
857
- # Ensure each tracer concentration is either a float/int or a list of floats/ints
858
- for key, val in tracer_concentrations.items():
859
- if not isinstance(val, (float, int)) and not (
860
- isinstance(val, list) and all(isinstance(v, (float, int)) for v in val)
861
- ):
862
- raise ValueError(
863
- f"Invalid tracer concentration for '{key}': must be a float/int or a list of floats/ints."
864
- )
861
+ if isinstance(releases, str):
862
+ releases = [releases] # Convert to list if a single string is provided
863
+ elif isinstance(releases, list):
864
+ if not all(isinstance(r, str) for r in releases):
865
+ raise ValueError("All elements in `releases` list must be strings.")
866
+ else:
867
+ raise ValueError(
868
+ "`releases` should be a string (single release name) or a list of strings (release names)."
869
+ )
865
870
 
866
- # Ensure that time series for 'times', 'volume_fluxes', and 'tracer_concentrations' are all the same length
867
- num_times = len(times)
871
+ # Validate that the specified releases exist in self.releases
872
+ invalid_releases = [
873
+ release for release in releases if release not in valid_releases
874
+ ]
875
+ if invalid_releases:
876
+ raise ValueError(f"Invalid releases: {', '.join(invalid_releases)}")
868
877
 
869
- # Check that volume fluxes is either a constant or has the same length as 'times'
870
- if isinstance(volume_fluxes, list) and len(volume_fluxes) != num_times:
871
- raise ValueError(
872
- f"The length of `volume_fluxes` ({len(volume_fluxes)}) does not match the length of `times` ({num_times})."
873
- )
874
878
 
875
- # Check that tracer_concentrations are either constants or have the same length as 'times'
876
- for key, tracer_values in tracer_concentrations.items():
877
- if isinstance(tracer_values, list) and len(tracer_values) != num_times:
878
- raise ValueError(
879
- f"The length of tracer '{key}' ({len(tracer_values)}) does not match the length of `times` ({num_times})."
880
- )
879
+ def _get_release_colors(valid_releases: list[str]) -> dict[str, tuple]:
880
+ """Returns a dictionary of colors for the valid releases, based on a consistent
881
+ colormap.
881
882
 
882
- # Check that volume fluxes and tracer concentrations are valid
883
- if isinstance(volume_fluxes, (float, int)) and volume_fluxes < 0:
884
- raise ValueError(f"Volume flux must be non-negative. Got: {volume_fluxes}")
885
- elif isinstance(volume_fluxes, list) and not all(v >= 0 for v in volume_fluxes):
886
- raise ValueError(
887
- f"All entries in `volume_fluxes` must be non-negative. Got: {volume_fluxes}"
888
- )
889
- for key, tracer_values in tracer_concentrations.items():
890
- if key != "temp":
891
- if isinstance(tracer_values, (float, int)) and tracer_values < 0:
892
- raise ValueError(
893
- f"The concentration of tracer '{key}' must be non-negative. Got: {tracer_values}"
894
- )
895
- elif isinstance(tracer_values, list) and not all(
896
- c >= 0 for c in tracer_values
897
- ):
898
- raise ValueError(
899
- f"All entries in `tracer_concentrations['{key}']` must be non-negative. Got: {tracer_values}"
900
- )
901
-
902
- def _handle_simulation_endpoints(self, times, volume_fluxes, tracer_concentrations):
903
- """Ensure that the release time series starts at self.start_time and ends at
904
- self.end_time.
905
-
906
- If `volume_fluxes` is a list and does not cover the endpoints, zero volume fluxes are added.
907
- Tracer concentrations are extended accordingly by duplicating endpoint values.
908
- """
883
+ Parameters
884
+ ----------
885
+ valid_releases : List[str]
886
+ List of release names to assign colors to.
887
+
888
+ Returns
889
+ -------
890
+ Dict[str, tuple]
891
+ A dictionary where the keys are release names and the values are their corresponding colors,
892
+ assigned based on the order of releases in the valid releases list.
893
+
894
+ Raises
895
+ ------
896
+ ValueError
897
+ If the number of valid releases exceeds the available colormap capacity.
898
+
899
+ Notes
900
+ -----
901
+ The colormap is chosen dynamically based on the number of valid releases:
902
+
903
+ - If there are 10 or fewer releases, the "tab10" colormap is used.
904
+ - If there are more than 10 but fewer than or equal to 20 releases, the "tab20" colormap is used.
905
+ - For more than 20 releases, the "tab20b" colormap is used.
906
+ """
909
907
 
910
- if len(times) > 0:
911
- # Handle start_time
912
- if times[0] != self.start_time:
913
- if isinstance(volume_fluxes, list):
914
- volume_fluxes.insert(0, 0.0)
908
+ # Determine the colormap based on the number of releases
909
+ if len(valid_releases) <= 10:
910
+ color_map = plt.get_cmap("tab10")
911
+ elif len(valid_releases) <= 20:
912
+ color_map = plt.get_cmap("tab20")
913
+ else:
914
+ color_map = plt.get_cmap("tab20b")
915
+
916
+ # Ensure the number of releases doesn't exceed the available colormap capacity
917
+ if len(valid_releases) > color_map.N:
918
+ raise ValueError(
919
+ f"Too many releases. The selected colormap supports up to {color_map.N} releases."
920
+ )
915
921
 
916
- for key, vals in tracer_concentrations.items():
917
- if isinstance(vals, list):
918
- vals.insert(0, vals[0])
922
+ # Create a dictionary of colors based on the release indices
923
+ colors = {name: color_map(i) for i, name in enumerate(valid_releases)}
919
924
 
920
- times.insert(0, self.start_time)
925
+ return colors
921
926
 
922
- # Handle end_time
923
- if times[-1] != self.end_time:
924
- if isinstance(volume_fluxes, list):
925
- volume_fluxes.append(0.0)
926
927
 
927
- for key, vals in tracer_concentrations.items():
928
- if isinstance(vals, list):
929
- vals.append(vals[-1])
928
+ def _validate_release_location(grid, release: Release):
929
+ """Validates the closest grid location for a release site.
930
930
 
931
- times.append(self.end_time)
931
+ This function ensures that the given release site (lat, lon, depth) lies
932
+ within the ocean portion of the model grid domain. It:
932
933
 
934
+ - Checks if the point is within the grid domain (with buffer for boundary artifacts).
935
+ - Verifies that the location is not on land.
936
+ - Verifies that the location is not below the seafloor.
937
+ """
938
+ if grid:
939
+ # Adjust longitude based on whether it crosses the International Date Line (straddle case)
940
+ if grid.straddle:
941
+ lon = xr.where(release.lon > 180, release.lon - 360, release.lon)
933
942
  else:
934
- times = [self.start_time, self.end_time]
935
-
936
- return times, volume_fluxes, tracer_concentrations
937
-
938
- def _validate_release_location(self, name, lat, lon, depth):
939
- """Validates the closest grid location for a release site.
943
+ lon = xr.where(release.lon < 0, release.lon + 360, release.lon)
940
944
 
941
- This function ensures that the given release site (lat, lon, depth) lies
942
- within the ocean portion of the model grid domain. It:
945
+ dx = 1 / grid.ds.pm
946
+ dy = 1 / grid.ds.pn
947
+ max_grid_spacing = np.sqrt(dx**2 + dy**2) / 2
943
948
 
944
- - Checks if the point is within the grid domain (with buffer for boundary artifacts).
945
- - Verifies that the location is not on land.
946
- - Verifies that the location is not below the seafloor.
949
+ # Compute great-circle distance to all grid points
950
+ dist = gc_dist(grid.ds.lon_rho, grid.ds.lat_rho, lon, release.lat)
951
+ dist_min = dist.min(dim=["eta_rho", "xi_rho"])
947
952
 
948
- Parameters
949
- ----------
950
- name : str
951
- A unique identifier for the release location.
952
- lat : float
953
- Latitude of the release location.
954
- lon : float
955
- Longitude of the release location.
956
- depth : float
957
- Depth (positive, in meters) of the release location.
958
-
959
- Raises
960
- ------
961
- ValueError
962
- If the location is:
963
- - Outside the model grid.
964
- - On the boundary of the grid domain (eta_rho, xi_rho = 0 or max).
965
- - On land (based on `mask_rho`).
966
- - Below the ocean bottom (`h < depth`).
967
- Warning
968
- If no grid is available to validate the location.
969
- """
970
- if self.grid:
971
- # Adjust longitude based on whether it crosses the International Date Line (straddle case)
972
- if self.grid.straddle:
973
- lon = xr.where(lon > 180, lon - 360, lon)
974
- else:
975
- lon = xr.where(lon < 0, lon + 360, lon)
976
-
977
- dx = 1 / self.grid.ds.pm
978
- dy = 1 / self.grid.ds.pn
979
- max_grid_spacing = np.sqrt(dx**2 + dy**2) / 2
980
-
981
- # Compute great-circle distance to all grid points
982
- dist = gc_dist(self.grid.ds.lon_rho, self.grid.ds.lat_rho, lon, lat)
983
- dist_min = dist.min(dim=["eta_rho", "xi_rho"])
984
-
985
- if (dist_min > max_grid_spacing).all():
986
- raise ValueError(
987
- f"Release site '{name}' is outside of the grid domain. "
988
- "Ensure the provided (lat, lon) falls within the model grid extent."
989
- )
953
+ if (dist_min > max_grid_spacing).all():
954
+ raise ValueError(
955
+ f"Release site '{release.name}' is outside of the grid domain. "
956
+ "Ensure the provided (lat, lon) falls within the model grid extent."
957
+ )
990
958
 
991
- # Find the indices of the closest grid cell
992
- indices = np.where(dist == dist_min)
993
- eta_rho = indices[0][0]
994
- xi_rho = indices[1][0]
959
+ # Find the indices of the closest grid cell
960
+ indices = np.where(dist == dist_min)
961
+ eta_rho = indices[0][0]
962
+ xi_rho = indices[1][0]
995
963
 
996
- eta_max = self.grid.ds.sizes["eta_rho"] - 1
997
- xi_max = self.grid.ds.sizes["xi_rho"] - 1
964
+ eta_max = grid.ds.sizes["eta_rho"] - 1
965
+ xi_max = grid.ds.sizes["xi_rho"] - 1
998
966
 
999
- if eta_rho in [0, eta_max] or xi_rho in [0, xi_max]:
1000
- raise ValueError(
1001
- f"Release site '{name}' is located too close to the grid boundary. "
1002
- "Place release location (lat, lon) away from grid boundaries."
1003
- )
1004
-
1005
- if self.grid.ds.mask_rho[eta_rho, xi_rho].values == 0:
1006
- raise ValueError(
1007
- f"Release site '{name}' is on land. "
1008
- "Please provide coordinates (lat, lon) over ocean."
1009
- )
967
+ if eta_rho in [0, eta_max] or xi_rho in [0, xi_max]:
968
+ raise ValueError(
969
+ f"Release site '{release.name}' is located too close to the grid boundary. "
970
+ "Place release location (lat, lon) away from grid boundaries."
971
+ )
1010
972
 
1011
- if self.grid.ds.h[eta_rho, xi_rho].values < depth:
1012
- raise ValueError(
1013
- f"Release site '{name}' lies below the seafloor. "
1014
- f"Seafloor depth is {self.grid.ds.h[eta_rho, xi_rho].values:.2f} m, "
1015
- f"but requested depth is {depth:.2f} m. Adjust depth or location (lat, lon)."
1016
- )
973
+ if grid.ds.mask_rho[eta_rho, xi_rho].values == 0:
974
+ raise ValueError(
975
+ f"Release site '{release.name}' is on land. "
976
+ "Please provide coordinates (lat, lon) over ocean."
977
+ )
1017
978
 
1018
- else:
1019
- logging.warning(
1020
- "Grid not provided: cannot verify whether the specified lat/lon/depth location is within the domain or on land. "
1021
- "Please check manually or provide a grid when instantiating the class."
979
+ if grid.ds.h[eta_rho, xi_rho].values < release.depth:
980
+ raise ValueError(
981
+ f"Release site '{release.name}' lies below the seafloor. "
982
+ f"Seafloor depth is {grid.ds.h[eta_rho, xi_rho].values:.2f} m, "
983
+ f"but requested depth is {release.depth:.2f} m. Adjust depth or location (lat, lon)."
1022
984
  )
1023
985
 
1024
- def _validate_release_input(self, releases, list_allowed=True):
1025
- """Validates the input for release names in plotting methods to ensure they are
1026
- in an acceptable format and exist within the set of valid releases.
986
+ else:
987
+ logging.warning(
988
+ "Grid not provided: cannot verify whether the specified lat/lon/depth location is within the domain or on land. "
989
+ "Please check manually or provide a grid when instantiating the class."
990
+ )
1027
991
 
1028
- This method ensures that the `releases` parameter is either a single release name (string) or a list
1029
- of release names (strings), and checks that each release exists in the set of valid releases.
1030
992
 
1031
- Parameters
1032
- ----------
1033
- releases : str or list of str
1034
- A single release name as a string, or a list of release names (strings) to validate.
993
+ def _map_horizontal_gaussian(grid: Grid, release: Release):
994
+ """Map a tracer release to the ROMS grid as a normalized 2D Gaussian distribution.
1035
995
 
1036
- list_allowed : bool, optional
1037
- If `True`, a list of release names is allowed. If `False`, only a single release name (string)
1038
- is allowed. Default is `True`.
996
+ The tracer is centered at the nearest grid cell to the release location, then smoothed
997
+ using a Gaussian filter (via GCM-Filters) with horizontal scale `release.hsc`. Land points
998
+ are masked out, and the distribution is renormalized to integrate to 1 over the ocean.
1039
999
 
1040
- Raises
1041
- ------
1042
- ValueError
1043
- If `releases` is not a string or list of strings, or if any release name is invalid (not in `self.releases`).
1000
+ Parameters
1001
+ ----------
1002
+ grid : Grid
1003
+ ROMS grid object with grid metrics and land mask.
1004
+ release : Release
1005
+ Release location and horizontal scale (hsc) in meters.
1006
+
1007
+ Returns
1008
+ -------
1009
+ delta_smooth : xarray.DataArray
1010
+ Normalized 2D tracer distribution on the ROMS grid (zero over land).
1011
+ """
1012
+ # Find closest grid cell center
1013
+ target_coords = get_target_coords(grid)
1014
+ lon = release.lon
1015
+ if target_coords["straddle"]:
1016
+ lon = xr.where(lon > 180, lon - 360, lon)
1017
+ else:
1018
+ lon = xr.where(lon < 0, lon + 360, lon)
1019
+ dist = gc_dist(target_coords["lon"], target_coords["lat"], lon, release.lat)
1020
+ dist_min = dist.min(dim=["eta_rho", "xi_rho"])
1021
+
1022
+ # Find the indices of the closest grid cell
1023
+ indices = np.where(dist == dist_min)
1024
+ eta_rho = indices[0][0]
1025
+ xi_rho = indices[1][0]
1026
+
1027
+ # Create a delta function at the center of the Gaussian release
1028
+ delta = xr.zeros_like(grid.ds.mask_rho)
1029
+ delta[eta_rho, xi_rho] = 1
1030
+
1031
+ # Calculate the grid cell area from the inverse grid metrics (pm, pn)
1032
+ area = 1 / (grid.ds.pm * grid.ds.pn)
1033
+
1034
+ # Compute the mean grid spacing (dx) as the average of mean dx and dy
1035
+ dx = (((1 / grid.ds.pm).mean() + (1 / grid.ds.pn).mean()) / 2).item()
1036
+
1037
+ # Extend the domain in both dimensions to mitigate boundary effects during filtering
1038
+ # - Create a mask of ones ignoring land (will be renormalized later)
1039
+ mask = xr.ones_like(grid.ds.mask_rho)
1040
+
1041
+ # Extend the mask along eta_rho by concatenating three copies plus a zeroed edge cell
1042
+ margin_mask = xr.concat(
1043
+ [mask, mask, mask, 0 * mask.isel(eta_rho=-1)], dim="eta_rho"
1044
+ )
1045
+ # Similarly extend along xi_rho
1046
+ margin_mask = xr.concat(
1047
+ [margin_mask, margin_mask, margin_mask, 0 * margin_mask.isel(xi_rho=-1)],
1048
+ dim="xi_rho",
1049
+ )
1050
+
1051
+ # Extend the delta function in the same manner to match the enlarged domain
1052
+ delta_extended = xr.concat(
1053
+ [0 * delta, delta, 0 * delta, 0 * delta.isel(eta_rho=-1)], dim="eta_rho"
1054
+ )
1055
+ delta_extended = xr.concat(
1056
+ [
1057
+ 0 * delta_extended,
1058
+ delta_extended,
1059
+ 0 * delta_extended,
1060
+ 0 * delta_extended.isel(xi_rho=-1),
1061
+ ],
1062
+ dim="xi_rho",
1063
+ )
1064
+
1065
+ # Extend the cell area array to match the enlarged domain
1066
+ area_extended = xr.concat([area, area, area, area.isel(eta_rho=-1)], dim="eta_rho")
1067
+ area_extended = xr.concat(
1068
+ [area_extended, area_extended, area_extended, area_extended.isel(xi_rho=-1)],
1069
+ dim="xi_rho",
1070
+ )
1071
+
1072
+ # Define Gaussian filter parameters:
1073
+ # - filter_scale is computed so that the Gaussian's std dev matches
1074
+ # the equivalent boxcar filter of width equal to release.hsc / dx
1075
+ # multiplied by sqrt(12) to convert from boxcar to Gaussian std dev.
1076
+ filter_scale = release.hsc / dx * np.sqrt(12)
1077
+
1078
+ filter = gcm_filters.Filter(
1079
+ filter_scale=filter_scale,
1080
+ dx_min=1,
1081
+ filter_shape=gcm_filters.FilterShape.GAUSSIAN,
1082
+ grid_type=gcm_filters.GridType.REGULAR_WITH_LAND_AREA_WEIGHTED,
1083
+ grid_vars={"wet_mask": margin_mask, "area": area_extended},
1084
+ )
1085
+
1086
+ # Apply the Gaussian filter to the extended delta function over spatial dimensions
1087
+ delta_smooth = filter.apply(delta_extended, dims=["eta_rho", "xi_rho"])
1088
+
1089
+ # Remove the extended margins to return to the original domain size
1090
+ delta_smooth = delta_smooth.isel(
1091
+ eta_rho=slice(grid.ds.sizes["eta_rho"], -grid.ds.sizes["eta_rho"] - 1),
1092
+ xi_rho=slice(grid.ds.sizes["xi_rho"], -grid.ds.sizes["eta_rho"] - 1),
1093
+ )
1094
+
1095
+ # Mask out land cells and set values to zero there
1096
+ delta_smooth = delta_smooth.where(grid.ds.mask_rho, 0.0)
1097
+
1098
+ # Renormalize so the integral over ocean points sums to 1
1099
+ integral = delta_smooth.sum(dim=["eta_rho", "xi_rho"])
1100
+ delta_smooth = delta_smooth / integral
1101
+
1102
+ return delta_smooth
1103
+
1104
+
1105
+ def _map_vertical_gaussian(grid, release, field, orientation="latitude"):
1106
+ """Extract a vertical section from a ROMS grid and apply a Gaussian distribution in
1107
+ depth.
1108
+
1109
+ This function interpolates a horizontally Gaussian field (e.g., from a tracer release)
1110
+ along either a constant latitude or longitude section and distributes it vertically using
1111
+ a Gaussian profile centered around the release depth.
1044
1112
 
1045
- Notes
1046
- -----
1047
- This method checks that the `releases` input is in a valid format (either a string or a list of strings),
1048
- and ensures each release is present in the set of valid releases defined in `self.releases`. Invalid releases
1049
- are reported in the error message.
1113
+ Parameters
1114
+ ----------
1115
+ grid : Grid
1116
+ ROMS grid object with methods and attributes used for horizontal resolution,
1117
+ depth computation, and straddling logic.
1118
+ release : Release
1119
+ Release object containing coordinates (`lat`, `lon`, `depth`) and vertical
1120
+ spread (`vsc`) for the Gaussian distribution.
1121
+ field : xr.DataArray
1122
+ 2D horizontal tracer field defined on the ROMS grid.
1123
+ orientation : {"latitude", "longitude"}, default "latitude"
1124
+ Orientation of the extracted vertical section. If "latitude", extracts
1125
+ a section along constant longitude. If "longitude", extracts a section
1126
+ along constant latitude.
1127
+
1128
+ Returns
1129
+ -------
1130
+ vertical_field : xr.DataArray
1131
+ 2D field (depth vs. latitude or longitude) with the vertically-distributed
1132
+ Gaussian mapped along the specified section.
1133
+ """
1134
+ meters_per_degree = 2 * np.pi * R_EARTH / 360
1135
+ release_lon = normalize_longitude(release.lon, grid.straddle)
1050
1136
 
1051
- If `list_allowed` is set to `False`, only a single release name (string) will be accepted. Otherwise, a
1052
- list of release names is also acceptable.
1053
- """
1137
+ if orientation == "longitude":
1138
+ lon_deg = grid.ds.lon_rho
1139
+ if grid.straddle:
1140
+ lon_deg = xr.where(lon_deg > 180, lon_deg - 360, lon_deg)
1141
+ hsc_in_degrees = release.hsc / (meters_per_degree * np.cos(release.lat))
1142
+ lons, _ = _generate_focused_coordinate_range(
1143
+ center=release_lon,
1144
+ sc=hsc_in_degrees,
1145
+ min_val=lon_deg.min().values,
1146
+ max_val=lon_deg.max().values,
1147
+ N=2000,
1148
+ )
1149
+ lons = xr.DataArray(lons, dims=["lon"], attrs={"units": "°E"})
1150
+ lats = [release.lat]
1054
1151
 
1055
- # Ensure that a list of releases is only allowed if `list_allowed` is True
1056
- if not list_allowed and not isinstance(releases, str):
1057
- raise ValueError(
1058
- f"Only a single release name (string) is allowed. Got: {releases}"
1059
- )
1152
+ elif orientation == "latitude":
1153
+ lons = [release_lon]
1154
+ hsc_in_degrees = release.hsc / (
1155
+ meters_per_degree * np.cos(grid.ds.lat_rho.mean().values)
1156
+ )
1157
+ lats, _ = _generate_focused_coordinate_range(
1158
+ center=release.lat,
1159
+ sc=hsc_in_degrees,
1160
+ min_val=grid.ds.lat_rho.min().values,
1161
+ max_val=grid.ds.lat_rho.max().values,
1162
+ N=2000,
1163
+ )
1164
+ lats = xr.DataArray(lats, dims=["lat"], attrs={"units": "°N"})
1165
+ else:
1166
+ raise ValueError(
1167
+ "`section_orientation` must be either 'latitude' or 'longitude'."
1168
+ )
1060
1169
 
1061
- if isinstance(releases, str):
1062
- releases = [releases] # Convert to list if a single string is provided
1063
- elif isinstance(releases, list):
1064
- if not all(isinstance(r, str) for r in releases):
1065
- raise ValueError("All elements in `releases` list must be strings.")
1066
- else:
1067
- raise ValueError(
1068
- "`releases` should be a string (single release name) or a list of strings (release names)."
1069
- )
1170
+ # Regrid 2D horizontal Gaussian onto desired 1D horizontal section
1171
+ target_coords = {"lat": lats, "lon": lons}
1172
+ lateral_regrid = LateralRegridFromROMS(field, target_coords)
1173
+ field = lateral_regrid.apply(field).squeeze()
1174
+ h = lateral_regrid.apply(grid.ds.h).squeeze()
1175
+
1176
+ # Define depth levels
1177
+ depth_levels, _ = _generate_focused_coordinate_range(
1178
+ center=release.depth,
1179
+ sc=release.vsc,
1180
+ min_val=0.0,
1181
+ max_val=h.max().values,
1182
+ N=2000,
1183
+ )
1184
+ depth_levels = xr.DataArray(
1185
+ np.asarray(depth_levels),
1186
+ dims=["depth"],
1187
+ attrs={"long_name": "Depth", "units": "m"},
1188
+ )
1189
+ depth_levels = depth_levels.astype(np.float32)
1190
+
1191
+ if release.vsc == 0:
1192
+ # Find index of depth_level closest to release.depth
1193
+ closest_idx = np.abs(depth_levels - release.depth).argmin()
1194
+ weights = xr.zeros_like(depth_levels)
1195
+ weights[closest_idx] = 1.0
1196
+ else:
1197
+ # Compute Gaussian weights at each layer center
1198
+ weights = np.exp(-0.5 * ((depth_levels - release.depth) / release.vsc) ** 2)
1199
+ weights /= weights.sum()
1200
+
1201
+ # Redistribute Gaussian mass from under topography to open ocean
1202
+ weights = weights.where(depth_levels < h)
1203
+ weights = weights / weights.sum()
1204
+
1205
+ # Map 1D to 2D Gaussian
1206
+ vertical_field = field * weights
1207
+
1208
+ # Remove NaNs at the edges
1209
+ if orientation == "longitude":
1210
+ vertical_field, _ = _remove_edge_nans(vertical_field, "lon", layer_depth=h)
1211
+ if orientation == "latitude":
1212
+ vertical_field, _ = _remove_edge_nans(vertical_field, "lat", layer_depth=h)
1213
+
1214
+ vertical_field = vertical_field.assign_coords({"depth": depth_levels})
1215
+
1216
+ return vertical_field
1217
+
1218
+
1219
+ def _plot_location(
1220
+ grid: Grid,
1221
+ releases: ReleaseCollector,
1222
+ ax: Axes,
1223
+ colors: dict[str, tuple] | None = None,
1224
+ include_legend: bool = True,
1225
+ ) -> None:
1226
+ """Plot the center location of each release on a top-down map view.
1227
+
1228
+ Each release is represented as a point on the map, with its color
1229
+ determined by the `colors` dictionary.
1070
1230
 
1071
- # Validate that the specified releases exist in self.releases
1072
- valid_releases = [k for k in self.releases if k != "_tracer_metadata"]
1073
- invalid_releases = [
1074
- release for release in releases if release not in valid_releases
1075
- ]
1076
- if invalid_releases:
1077
- raise ValueError(f"Invalid releases: {', '.join(invalid_releases)}")
1231
+ Parameters
1232
+ ----------
1233
+ grid : Grid
1234
+ The grid object defining the spatial extent and coordinate system for the plot.
1078
1235
 
1079
- def _get_release_colors(self):
1080
- """Returns a dictionary of colors for the valid releases, based on a consistent
1081
- colormap.
1236
+ releases : ReleaseCollector
1237
+ Collection of `Release` objects to plot. Each `Release` must have `.lat`, `.lon`,
1238
+ and `.name` attributes.
1082
1239
 
1083
- Parameters
1084
- ----------
1085
- None
1240
+ ax : matplotlib.axes.Axes
1241
+ The Matplotlib axis object to plot on.
1086
1242
 
1087
- Returns
1088
- -------
1089
- dict
1090
- A dictionary where the keys are release names and the values are their corresponding colors,
1091
- assigned based on the order of releases in the valid releases list.
1243
+ colors : dict of str to tuple, optional
1244
+ Optional dictionary mapping release names to RGBA color tuples. If not provided,
1245
+ all releases are plotted in a default color (`"#dd1c77"`).
1092
1246
 
1093
- Raises
1094
- ------
1095
- ValueError
1096
- If the number of valid releases exceeds the available colormap capacity.
1247
+ include_legend : bool, default True
1248
+ Whether to include a legend showing release names.
1097
1249
 
1098
- Notes
1099
- -----
1100
- The colormap is chosen dynamically based on the number of valid releases:
1250
+ Returns
1251
+ -------
1252
+ None
1253
+ """
1101
1254
 
1102
- - If there are 10 or fewer releases, the "tab10" colormap is used.
1103
- - If there are more than 10 but fewer than or equal to 20 releases, the "tab20" colormap is used.
1104
- - For more than 20 releases, the "tab20b" colormap is used.
1105
- """
1255
+ lon_deg = grid.ds.lon_rho
1256
+ lat_deg = grid.ds.lat_rho
1257
+ if grid.straddle:
1258
+ lon_deg = xr.where(lon_deg > 180, lon_deg - 360, lon_deg)
1259
+ trans = _get_projection(lon_deg, lat_deg)
1106
1260
 
1107
- valid_releases = [k for k in self.releases if k != "_tracer_metadata"]
1261
+ proj = ccrs.PlateCarree()
1108
1262
 
1109
- # Determine the colormap based on the number of releases
1110
- if len(valid_releases) <= 10:
1111
- color_map = cm.get_cmap("tab10")
1112
- elif len(valid_releases) <= 20:
1113
- color_map = cm.get_cmap("tab20")
1114
- else:
1115
- color_map = cm.get_cmap("tab20b")
1263
+ for release in releases:
1264
+ # transform coordinates to projected space
1265
+ transformed_lon, transformed_lat = trans.transform_point(
1266
+ release.lon,
1267
+ release.lat,
1268
+ proj,
1269
+ )
1116
1270
 
1117
- # Ensure the number of releases doesn't exceed the available colormap capacity
1118
- if len(valid_releases) > color_map.N:
1119
- raise ValueError(
1120
- f"Too many releases. The selected colormap supports up to {color_map.N} releases."
1121
- )
1271
+ if colors is not None:
1272
+ color = colors[release.name]
1273
+ else:
1274
+ color = "k"
1122
1275
 
1123
- # Create a dictionary of colors based on the release indices
1124
- colors = {name: color_map(i) for i, name in enumerate(valid_releases)}
1276
+ ax.plot(
1277
+ transformed_lon,
1278
+ transformed_lat,
1279
+ marker="x",
1280
+ markersize=8,
1281
+ markeredgewidth=2,
1282
+ label=release.name,
1283
+ color=color,
1284
+ )
1125
1285
 
1126
- return colors
1286
+ if include_legend:
1287
+ ax.legend(loc="center left", bbox_to_anchor=(1.1, 0.5))