roms-tools 0.1.0__py3-none-any.whl → 1.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.
@@ -0,0 +1,2622 @@
1
+ import pytest
2
+ from datetime import datetime
3
+ from roms_tools import Grid, SurfaceForcing
4
+ from roms_tools.setup.download import download_test_data
5
+ import tempfile
6
+ import os
7
+ import numpy as np
8
+ import textwrap
9
+
10
+
11
+ @pytest.fixture
12
+ def grid_that_straddles_dateline():
13
+ """
14
+ Fixture for creating a domain that straddles the dateline and lies within the bounds of the regional ERA5 data.
15
+ """
16
+ grid = Grid(
17
+ nx=5,
18
+ ny=5,
19
+ size_x=1800,
20
+ size_y=2400,
21
+ center_lon=-10,
22
+ center_lat=61,
23
+ rot=20,
24
+ )
25
+
26
+ return grid
27
+
28
+
29
+ @pytest.fixture
30
+ def grid_that_straddles_dateline_but_is_too_big_for_regional_test_data():
31
+ """
32
+ Fixture for creating a domain that straddles the dateline but exceeds the bounds of the regional ERA5 data.
33
+ Centered east of dateline.
34
+ """
35
+ grid = Grid(
36
+ nx=5,
37
+ ny=5,
38
+ size_x=2000,
39
+ size_y=2400,
40
+ center_lon=10,
41
+ center_lat=61,
42
+ rot=20,
43
+ )
44
+
45
+ return grid
46
+
47
+
48
+ @pytest.fixture
49
+ def another_grid_that_straddles_dateline_but_is_too_big_for_regional_test_data():
50
+ """
51
+ Fixture for creating a domain that straddles the dateline but exceeds the bounds of the regional ERA5 data.
52
+ Centered west of dateline. This one was hard to catch for the nan_check for a long time, but should work now.
53
+ """
54
+ grid = Grid(
55
+ nx=5,
56
+ ny=5,
57
+ size_x=1950,
58
+ size_y=2400,
59
+ center_lon=-30,
60
+ center_lat=61,
61
+ rot=25,
62
+ )
63
+
64
+ return grid
65
+
66
+
67
+ @pytest.fixture
68
+ def grid_that_lies_east_of_dateline_less_than_five_degrees_away():
69
+ """
70
+ Fixture for creating a domain that lies east of Greenwich meridian, but less than 5 degrees away.
71
+ We care about the 5 degree mark because it decides whether the code handles the longitudes as straddling the dateline or not.
72
+ """
73
+
74
+ grid = Grid(
75
+ nx=5,
76
+ ny=5,
77
+ size_x=500,
78
+ size_y=2000,
79
+ center_lon=10,
80
+ center_lat=61,
81
+ rot=0,
82
+ )
83
+
84
+ return grid
85
+
86
+
87
+ @pytest.fixture
88
+ def grid_that_lies_east_of_dateline_more_than_five_degrees_away():
89
+ """
90
+ Fixture for creating a domain that lies east of Greenwich meridian, more than 5 degrees away.
91
+ We care about the 5 degree mark because it decides whether the code handles the longitudes as straddling the dateline or not.
92
+ """
93
+ grid = Grid(
94
+ nx=5,
95
+ ny=5,
96
+ size_x=500,
97
+ size_y=2400,
98
+ center_lon=15,
99
+ center_lat=61,
100
+ rot=0,
101
+ )
102
+
103
+ return grid
104
+
105
+
106
+ @pytest.fixture
107
+ def grid_that_lies_west_of_dateline_less_than_five_degrees_away():
108
+ """
109
+ Fixture for creating a domain that lies west of Greenwich meridian, less than 5 degrees away.
110
+ We care about the 5 degree mark because it decides whether the code handles the longitudes as straddling the dateline or not.
111
+ """
112
+
113
+ grid = Grid(
114
+ nx=5,
115
+ ny=5,
116
+ size_x=700,
117
+ size_y=2400,
118
+ center_lon=-15,
119
+ center_lat=61,
120
+ rot=0,
121
+ )
122
+
123
+ return grid
124
+
125
+
126
+ @pytest.fixture
127
+ def grid_that_lies_west_of_dateline_more_than_five_degrees_away():
128
+ """
129
+ Fixture for creating a domain that lies west of Greenwich meridian, more than 5 degrees away.
130
+ We care about the 5 degree mark because it decides whether the code handles the longitudes as straddling the dateline or not.
131
+ """
132
+
133
+ grid = Grid(
134
+ nx=5,
135
+ ny=5,
136
+ size_x=1000,
137
+ size_y=2400,
138
+ center_lon=-25,
139
+ center_lat=61,
140
+ rot=0,
141
+ )
142
+
143
+ return grid
144
+
145
+
146
+ @pytest.fixture
147
+ def grid_that_straddles_180_degree_meridian():
148
+ """
149
+ Fixture for creating a domain that straddles 180 degree meridian. This is a good test grid for the global ERA5 data, which comes on an [-180, 180] longitude grid.
150
+ """
151
+
152
+ grid = Grid(
153
+ nx=5,
154
+ ny=5,
155
+ size_x=1800,
156
+ size_y=2400,
157
+ center_lon=180,
158
+ center_lat=61,
159
+ rot=20,
160
+ )
161
+
162
+ return grid
163
+
164
+
165
+ @pytest.mark.parametrize(
166
+ "grid_fixture",
167
+ [
168
+ "grid_that_straddles_dateline",
169
+ "grid_that_lies_east_of_dateline_less_than_five_degrees_away",
170
+ "grid_that_lies_east_of_dateline_more_than_five_degrees_away",
171
+ "grid_that_lies_west_of_dateline_less_than_five_degrees_away",
172
+ "grid_that_lies_west_of_dateline_more_than_five_degrees_away",
173
+ ],
174
+ )
175
+ def test_successful_initialization_with_regional_data(grid_fixture, request):
176
+ """
177
+ Test successful initialization of SurfaceForcing with regional data.
178
+
179
+ Verifies that attributes are correctly set and data contains expected variables.
180
+ """
181
+ start_time = datetime(2020, 1, 31)
182
+ end_time = datetime(2020, 2, 2)
183
+
184
+ fname = download_test_data("ERA5_regional_test_data.nc")
185
+
186
+ grid = request.getfixturevalue(grid_fixture)
187
+
188
+ sfc_forcing = SurfaceForcing(
189
+ grid=grid,
190
+ start_time=start_time,
191
+ end_time=end_time,
192
+ physics_source={"name": "ERA5", "path": fname},
193
+ )
194
+
195
+ assert sfc_forcing.ds is not None
196
+
197
+ grid.coarsen()
198
+
199
+ sfc_forcing = SurfaceForcing(
200
+ grid=grid,
201
+ use_coarse_grid=True,
202
+ start_time=start_time,
203
+ end_time=end_time,
204
+ physics_source={"name": "ERA5", "path": fname},
205
+ )
206
+
207
+ assert "uwnd" in sfc_forcing.ds["physics"]
208
+ assert "vwnd" in sfc_forcing.ds["physics"]
209
+ assert "swrad" in sfc_forcing.ds["physics"]
210
+ assert "lwrad" in sfc_forcing.ds["physics"]
211
+ assert "Tair" in sfc_forcing.ds["physics"]
212
+ assert "qair" in sfc_forcing.ds["physics"]
213
+ assert "rain" in sfc_forcing.ds["physics"]
214
+
215
+ assert sfc_forcing.start_time == start_time
216
+ assert sfc_forcing.end_time == end_time
217
+ assert sfc_forcing.physics_source == {
218
+ "name": "ERA5",
219
+ "path": fname,
220
+ "climatology": False,
221
+ }
222
+
223
+
224
+ @pytest.mark.parametrize(
225
+ "grid_fixture",
226
+ [
227
+ "grid_that_straddles_dateline_but_is_too_big_for_regional_test_data",
228
+ "another_grid_that_straddles_dateline_but_is_too_big_for_regional_test_data",
229
+ ],
230
+ )
231
+ def test_nan_detection_initialization_with_regional_data(grid_fixture, request):
232
+ """
233
+ Test handling of NaN values during initialization with regional data.
234
+
235
+ Ensures ValueError is raised if NaN values are detected in the dataset.
236
+ """
237
+ start_time = datetime(2020, 1, 31)
238
+ end_time = datetime(2020, 2, 2)
239
+
240
+ fname = download_test_data("ERA5_regional_test_data.nc")
241
+
242
+ grid = request.getfixturevalue(grid_fixture)
243
+
244
+ with pytest.raises(ValueError, match="NaN values found"):
245
+
246
+ SurfaceForcing(
247
+ grid=grid,
248
+ start_time=start_time,
249
+ end_time=end_time,
250
+ physics_source={"name": "ERA5", "path": fname},
251
+ )
252
+
253
+ grid.coarsen()
254
+
255
+ with pytest.raises(ValueError, match="NaN values found"):
256
+ SurfaceForcing(
257
+ grid=grid,
258
+ use_coarse_grid=True,
259
+ start_time=start_time,
260
+ end_time=end_time,
261
+ physics_source={"name": "ERA5", "path": fname},
262
+ )
263
+
264
+
265
+ def test_no_longitude_intersection_initialization_with_regional_data(
266
+ grid_that_straddles_180_degree_meridian,
267
+ ):
268
+ """
269
+ Test initialization of SurfaceForcing with a grid that straddles the 180° meridian.
270
+
271
+ Ensures ValueError is raised when the longitude range does not intersect with the dataset.
272
+ """
273
+ start_time = datetime(2020, 1, 31)
274
+ end_time = datetime(2020, 2, 2)
275
+
276
+ fname = download_test_data("ERA5_regional_test_data.nc")
277
+
278
+ with pytest.raises(
279
+ ValueError, match="Selected longitude range does not intersect with dataset"
280
+ ):
281
+
282
+ SurfaceForcing(
283
+ grid=grid_that_straddles_180_degree_meridian,
284
+ start_time=start_time,
285
+ end_time=end_time,
286
+ physics_source={"name": "ERA5", "path": fname},
287
+ )
288
+
289
+ grid_that_straddles_180_degree_meridian.coarsen()
290
+
291
+ with pytest.raises(
292
+ ValueError, match="Selected longitude range does not intersect with dataset"
293
+ ):
294
+ SurfaceForcing(
295
+ grid=grid_that_straddles_180_degree_meridian,
296
+ use_coarse_grid=True,
297
+ start_time=start_time,
298
+ end_time=end_time,
299
+ physics_source={"name": "ERA5", "path": fname},
300
+ )
301
+
302
+
303
+ @pytest.mark.parametrize(
304
+ "grid_fixture",
305
+ [
306
+ "grid_that_straddles_dateline",
307
+ "grid_that_lies_east_of_dateline_less_than_five_degrees_away",
308
+ "grid_that_lies_east_of_dateline_more_than_five_degrees_away",
309
+ "grid_that_lies_west_of_dateline_less_than_five_degrees_away",
310
+ "grid_that_lies_west_of_dateline_more_than_five_degrees_away",
311
+ "grid_that_straddles_dateline_but_is_too_big_for_regional_test_data",
312
+ "another_grid_that_straddles_dateline_but_is_too_big_for_regional_test_data",
313
+ "grid_that_straddles_180_degree_meridian",
314
+ ],
315
+ )
316
+ def test_successful_initialization_with_global_data(grid_fixture, request):
317
+ """
318
+ Test initialization of SurfaceForcing with global data.
319
+
320
+ Verifies that the SurfaceForcing object is correctly initialized with global data,
321
+ including the correct handling of the grid and physics data. Checks both coarse and fine grid initialization.
322
+ """
323
+ start_time = datetime(2020, 1, 31)
324
+ end_time = datetime(2020, 2, 2)
325
+
326
+ fname = download_test_data("ERA5_global_test_data.nc")
327
+
328
+ grid = request.getfixturevalue(grid_fixture)
329
+
330
+ sfc_forcing = SurfaceForcing(
331
+ grid=grid,
332
+ start_time=start_time,
333
+ end_time=end_time,
334
+ physics_source={"name": "ERA5", "path": fname},
335
+ )
336
+ assert sfc_forcing.start_time == start_time
337
+ assert sfc_forcing.end_time == end_time
338
+ assert sfc_forcing.physics_source == {
339
+ "name": "ERA5",
340
+ "path": fname,
341
+ "climatology": False,
342
+ }
343
+
344
+ assert "uwnd" in sfc_forcing.ds["physics"]
345
+ assert "vwnd" in sfc_forcing.ds["physics"]
346
+ assert "swrad" in sfc_forcing.ds["physics"]
347
+ assert "lwrad" in sfc_forcing.ds["physics"]
348
+ assert "Tair" in sfc_forcing.ds["physics"]
349
+ assert "qair" in sfc_forcing.ds["physics"]
350
+ assert "rain" in sfc_forcing.ds["physics"]
351
+ assert sfc_forcing.ds["physics"].attrs["physics_source"] == "ERA5"
352
+
353
+ grid.coarsen()
354
+
355
+ sfc_forcing = SurfaceForcing(
356
+ grid=grid,
357
+ use_coarse_grid=True,
358
+ start_time=start_time,
359
+ end_time=end_time,
360
+ physics_source={"name": "ERA5", "path": fname},
361
+ )
362
+ assert sfc_forcing.start_time == start_time
363
+ assert sfc_forcing.end_time == end_time
364
+ assert sfc_forcing.physics_source == {
365
+ "name": "ERA5",
366
+ "path": fname,
367
+ "climatology": False,
368
+ }
369
+
370
+ assert "uwnd" in sfc_forcing.ds["physics"]
371
+ assert "vwnd" in sfc_forcing.ds["physics"]
372
+ assert "swrad" in sfc_forcing.ds["physics"]
373
+ assert "lwrad" in sfc_forcing.ds["physics"]
374
+ assert "Tair" in sfc_forcing.ds["physics"]
375
+ assert "qair" in sfc_forcing.ds["physics"]
376
+ assert "rain" in sfc_forcing.ds["physics"]
377
+ assert sfc_forcing.ds["physics"].attrs["physics_source"] == "ERA5"
378
+
379
+
380
+ @pytest.fixture
381
+ def surface_forcing(grid_that_straddles_180_degree_meridian):
382
+ """
383
+ Fixture for creating a SurfaceForcing object.
384
+ """
385
+
386
+ start_time = datetime(2020, 1, 31)
387
+ end_time = datetime(2020, 2, 2)
388
+
389
+ fname = download_test_data("ERA5_global_test_data.nc")
390
+
391
+ return SurfaceForcing(
392
+ grid=grid_that_straddles_180_degree_meridian,
393
+ start_time=start_time,
394
+ end_time=end_time,
395
+ physics_source={"name": "ERA5", "path": fname},
396
+ )
397
+
398
+
399
+ @pytest.fixture
400
+ def corrected_surface_forcing(grid_that_straddles_180_degree_meridian):
401
+ """
402
+ Fixture for creating a SurfaceForcing object with shortwave radiation correction.
403
+ """
404
+
405
+ start_time = datetime(2020, 1, 31)
406
+ end_time = datetime(2020, 2, 2)
407
+
408
+ fname = download_test_data("ERA5_global_test_data.nc")
409
+
410
+ return SurfaceForcing(
411
+ grid=grid_that_straddles_180_degree_meridian,
412
+ start_time=start_time,
413
+ end_time=end_time,
414
+ physics_source={"name": "ERA5", "path": fname},
415
+ correct_radiation=True,
416
+ )
417
+
418
+
419
+ @pytest.fixture
420
+ def corrected_surface_forcing_with_bgc(grid_that_straddles_180_degree_meridian):
421
+ """
422
+ Fixture for creating a SurfaceForcing object with shortwave radiation correction and BGC.
423
+ """
424
+
425
+ start_time = datetime(2020, 1, 31)
426
+ end_time = datetime(2020, 2, 2)
427
+
428
+ fname = download_test_data("ERA5_global_test_data.nc")
429
+ fname_bgc = download_test_data("CESM_surface_global_test_data.nc")
430
+
431
+ return SurfaceForcing(
432
+ grid=grid_that_straddles_180_degree_meridian,
433
+ start_time=start_time,
434
+ end_time=end_time,
435
+ physics_source={"name": "ERA5", "path": fname},
436
+ bgc_source={"name": "CESM_REGRIDDED", "path": fname_bgc},
437
+ correct_radiation=True,
438
+ )
439
+
440
+
441
+ @pytest.fixture
442
+ def corrected_surface_forcing_with_bgc_from_climatology(
443
+ grid_that_straddles_180_degree_meridian,
444
+ ):
445
+ """
446
+ Fixture for creating a SurfaceForcing object with shortwave radiation correction and BGC from climatology.
447
+ """
448
+
449
+ start_time = datetime(2020, 1, 31)
450
+ end_time = datetime(2020, 2, 2)
451
+
452
+ fname = download_test_data("ERA5_global_test_data.nc")
453
+ fname_bgc = download_test_data("CESM_surface_global_test_data_climatology.nc")
454
+
455
+ return SurfaceForcing(
456
+ grid=grid_that_straddles_180_degree_meridian,
457
+ start_time=start_time,
458
+ end_time=end_time,
459
+ physics_source={"name": "ERA5", "path": fname},
460
+ bgc_source={"name": "CESM_REGRIDDED", "path": fname_bgc, "climatology": True},
461
+ correct_radiation=True,
462
+ )
463
+
464
+
465
+ def test_time_attr_climatology(corrected_surface_forcing_with_bgc_from_climatology):
466
+ """
467
+ Test that the 'cycle_length' attribute is present in the time coordinate of the BGC dataset
468
+ when using climatology data.
469
+ """
470
+ assert hasattr(
471
+ corrected_surface_forcing_with_bgc_from_climatology.ds["bgc"].time,
472
+ "cycle_length",
473
+ )
474
+
475
+
476
+ def test_time_attr(corrected_surface_forcing_with_bgc):
477
+ """
478
+ Test that the 'cycle_length' attribute is not present in the time coordinate of the BGC dataset
479
+ when not using climatology data.
480
+ """
481
+ assert not hasattr(
482
+ corrected_surface_forcing_with_bgc.ds["bgc"].time, "cycle_length"
483
+ )
484
+
485
+
486
+ @pytest.mark.parametrize(
487
+ "sfc_forcing_fixture",
488
+ [
489
+ "corrected_surface_forcing_with_bgc",
490
+ "corrected_surface_forcing_with_bgc_from_climatology",
491
+ ],
492
+ )
493
+ def test_surface_forcing_creation(sfc_forcing_fixture, request):
494
+ """
495
+ Test the creation and initialization of the SurfaceForcing object.
496
+
497
+ Verifies that the SurfaceForcing object is properly created with correct attributes,
498
+ including physics and BGC sources. Ensures that expected variables are present in the dataset
499
+ and that attributes match the given configurations.
500
+ """
501
+
502
+ fname = download_test_data("ERA5_global_test_data.nc")
503
+
504
+ sfc_forcing = request.getfixturevalue(sfc_forcing_fixture)
505
+
506
+ assert sfc_forcing.start_time == datetime(2020, 1, 31)
507
+ assert sfc_forcing.end_time == datetime(2020, 2, 2)
508
+ assert sfc_forcing.physics_source == {
509
+ "name": "ERA5",
510
+ "path": fname,
511
+ "climatology": False,
512
+ }
513
+ assert sfc_forcing.bgc_source["name"] == "CESM_REGRIDDED"
514
+
515
+ assert "uwnd" in sfc_forcing.ds["physics"]
516
+ assert "vwnd" in sfc_forcing.ds["physics"]
517
+ assert "swrad" in sfc_forcing.ds["physics"]
518
+ assert "lwrad" in sfc_forcing.ds["physics"]
519
+ assert "Tair" in sfc_forcing.ds["physics"]
520
+ assert "qair" in sfc_forcing.ds["physics"]
521
+ assert "rain" in sfc_forcing.ds["physics"]
522
+ assert sfc_forcing.ds["physics"].attrs["physics_source"] == "ERA5"
523
+
524
+ assert "pco2_air" in sfc_forcing.ds["bgc"]
525
+ assert "pco2_air_alt" in sfc_forcing.ds["bgc"]
526
+ assert "iron" in sfc_forcing.ds["bgc"]
527
+ assert "dust" in sfc_forcing.ds["bgc"]
528
+ assert "nox" in sfc_forcing.ds["bgc"]
529
+ assert "nhy" in sfc_forcing.ds["bgc"]
530
+ assert sfc_forcing.ds["bgc"].attrs["bgc_source"] == "CESM_REGRIDDED"
531
+
532
+
533
+ @pytest.mark.parametrize(
534
+ "sfc_forcing_fixture, expected_swrad",
535
+ [
536
+ (
537
+ "surface_forcing",
538
+ [
539
+ np.array(
540
+ [
541
+ [
542
+ [
543
+ 2.5448965e01,
544
+ 8.8304184e01,
545
+ 1.5497435e02,
546
+ 2.1024680e02,
547
+ 2.8283499e02,
548
+ 2.6214133e02,
549
+ 2.4970605e02,
550
+ ],
551
+ [
552
+ 2.5577042e01,
553
+ 2.7288372e01,
554
+ 1.4094499e02,
555
+ 1.7884666e02,
556
+ 2.6748840e02,
557
+ 1.2747585e02,
558
+ 2.2650435e02,
559
+ ],
560
+ [
561
+ 1.3132906e02,
562
+ 1.3878809e02,
563
+ 1.5093468e02,
564
+ 2.1958447e02,
565
+ 1.0976684e02,
566
+ 8.2733292e01,
567
+ 1.0512259e02,
568
+ ],
569
+ [
570
+ 7.4981323e01,
571
+ 1.2092771e02,
572
+ 7.1995018e01,
573
+ 6.9545914e01,
574
+ 4.7777473e01,
575
+ 3.1707375e01,
576
+ 5.3525272e01,
577
+ ],
578
+ [
579
+ 3.9274761e01,
580
+ 3.0639046e01,
581
+ 4.3424637e01,
582
+ 2.4530054e01,
583
+ 1.6565577e01,
584
+ 1.3347603e01,
585
+ 2.5200823e01,
586
+ ],
587
+ [
588
+ 1.7271753e01,
589
+ 1.4315107e01,
590
+ 1.3658159e01,
591
+ 8.3364201e00,
592
+ 3.3492086e00,
593
+ 2.3186626e00,
594
+ 2.1239614e00,
595
+ ],
596
+ [
597
+ 1.0622320e01,
598
+ 6.2983389e00,
599
+ 1.1909541e00,
600
+ 0.0000000e00,
601
+ 0.0000000e00,
602
+ 0.0000000e00,
603
+ 0.0000000e00,
604
+ ],
605
+ ],
606
+ [
607
+ [
608
+ 4.1088528e01,
609
+ 9.1928207e01,
610
+ 2.3474031e02,
611
+ 2.4281172e02,
612
+ 2.6647174e02,
613
+ 2.4823715e02,
614
+ 2.1143315e02,
615
+ ],
616
+ [
617
+ 3.6657497e01,
618
+ 2.7476831e01,
619
+ 9.0126961e01,
620
+ 1.7404645e02,
621
+ 2.3448058e02,
622
+ 1.1212284e02,
623
+ 2.0697829e02,
624
+ ],
625
+ [
626
+ 1.4556892e02,
627
+ 1.6401329e02,
628
+ 1.5902567e02,
629
+ 2.2931277e02,
630
+ 8.7306885e01,
631
+ 7.2889664e01,
632
+ 8.1363327e01,
633
+ ],
634
+ [
635
+ 8.6130676e01,
636
+ 1.4423856e02,
637
+ 7.9196968e01,
638
+ 6.6386658e01,
639
+ 4.0398537e01,
640
+ 2.5448185e01,
641
+ 4.4373856e01,
642
+ ],
643
+ [
644
+ 6.2564697e01,
645
+ 4.2063602e01,
646
+ 5.5343834e01,
647
+ 2.2452137e01,
648
+ 1.8183729e01,
649
+ 1.0362802e01,
650
+ 1.8347992e01,
651
+ ],
652
+ [
653
+ 3.0191124e01,
654
+ 2.2519470e01,
655
+ 2.0529692e01,
656
+ 1.1819255e01,
657
+ 3.7765646e00,
658
+ 1.6394116e00,
659
+ 2.3138286e-01,
660
+ ],
661
+ [
662
+ 2.4330065e01,
663
+ 1.2172291e01,
664
+ 2.9702284e00,
665
+ 4.5030624e-02,
666
+ 0.0000000e00,
667
+ 0.0000000e00,
668
+ 0.0000000e00,
669
+ ],
670
+ ],
671
+ ],
672
+ dtype=np.float32,
673
+ )
674
+ ],
675
+ ),
676
+ (
677
+ "corrected_surface_forcing",
678
+ [
679
+ np.array(
680
+ [
681
+ [
682
+ [
683
+ 2.0345396e01,
684
+ 7.1687141e01,
685
+ 1.2855386e02,
686
+ 1.7835985e02,
687
+ 2.4759137e02,
688
+ 2.3055316e02,
689
+ 2.1866821e02,
690
+ ],
691
+ [
692
+ 1.8974031e01,
693
+ 2.0692104e01,
694
+ 1.1139817e02,
695
+ 1.4908310e02,
696
+ 2.3330269e02,
697
+ 1.1800186e02,
698
+ 2.1442001e02,
699
+ ],
700
+ [
701
+ 9.5367859e01,
702
+ 1.1730759e02,
703
+ 1.3710544e02,
704
+ 2.1596344e02,
705
+ 1.1043810e02,
706
+ 7.6220886e01,
707
+ 9.0121040e01,
708
+ ],
709
+ [
710
+ 7.7221687e01,
711
+ 1.2257743e02,
712
+ 7.8461441e01,
713
+ 7.3550613e01,
714
+ 4.7777473e01,
715
+ 3.1707375e01,
716
+ 5.4698215e01,
717
+ ],
718
+ [
719
+ 3.9274761e01,
720
+ 3.0638720e01,
721
+ 4.3393879e01,
722
+ 2.4530497e01,
723
+ 1.6565577e01,
724
+ 1.3347603e01,
725
+ 2.5458445e01,
726
+ ],
727
+ [
728
+ 1.7271362e01,
729
+ 1.4313513e01,
730
+ 1.3647677e01,
731
+ 8.3360624e00,
732
+ 3.3492086e00,
733
+ 2.3186626e00,
734
+ 2.1239614e00,
735
+ ],
736
+ [
737
+ 1.0622130e01,
738
+ 6.2982388e00,
739
+ 1.1909422e00,
740
+ 0.0000000e00,
741
+ 0.0000000e00,
742
+ 0.0000000e00,
743
+ 0.0000000e00,
744
+ ],
745
+ ],
746
+ [
747
+ [
748
+ 3.2848579e01,
749
+ 7.4629196e01,
750
+ 1.9472108e02,
751
+ 2.0598582e02,
752
+ 2.3326712e02,
753
+ 2.1832445e02,
754
+ 1.8515254e02,
755
+ ],
756
+ [
757
+ 2.7193939e01,
758
+ 2.0835009e01,
759
+ 7.1233307e01,
760
+ 1.4508174e02,
761
+ 2.0451334e02,
762
+ 1.0378988e02,
763
+ 1.9593568e02,
764
+ ],
765
+ [
766
+ 1.0570849e02,
767
+ 1.3862865e02,
768
+ 1.4445511e02,
769
+ 2.2553131e02,
770
+ 8.7840797e01,
771
+ 6.7152107e01,
772
+ 6.9752350e01,
773
+ ],
774
+ [
775
+ 8.8704170e01,
776
+ 1.4620630e02,
777
+ 8.6310257e01,
778
+ 7.0209435e01,
779
+ 4.0398537e01,
780
+ 2.5448185e01,
781
+ 4.5346252e01,
782
+ ],
783
+ [
784
+ 6.2564697e01,
785
+ 4.2063152e01,
786
+ 5.5304630e01,
787
+ 2.2452543e01,
788
+ 1.8183731e01,
789
+ 1.0362802e01,
790
+ 1.8535559e01,
791
+ ],
792
+ [
793
+ 3.0190443e01,
794
+ 2.2516962e01,
795
+ 2.0513937e01,
796
+ 1.1818749e01,
797
+ 3.7765646e00,
798
+ 1.6394116e00,
799
+ 2.3138286e-01,
800
+ ],
801
+ [
802
+ 2.4329630e01,
803
+ 1.2172097e01,
804
+ 2.9701986e00,
805
+ 4.5030624e-02,
806
+ 0.0000000e00,
807
+ 0.0000000e00,
808
+ 0.0000000e00,
809
+ ],
810
+ ],
811
+ ],
812
+ dtype=np.float32,
813
+ )
814
+ ],
815
+ ),
816
+ ],
817
+ )
818
+ def test_surface_forcing_data_consistency_plot_save(
819
+ sfc_forcing_fixture, expected_swrad, request, tmp_path
820
+ ):
821
+ """
822
+ Test that the data within the SurfaceForcing object remains consistent.
823
+ Also test plot and save methods in the same test since we dask arrays are already computed.
824
+ """
825
+ sfc_forcing = request.getfixturevalue(sfc_forcing_fixture)
826
+
827
+ sfc_forcing.ds.load()
828
+
829
+ expected_uwnd = np.array(
830
+ [
831
+ [
832
+ [
833
+ -6.007625,
834
+ -3.42977,
835
+ 0.21806262,
836
+ 5.360945,
837
+ 11.831764,
838
+ 12.798729,
839
+ 11.391347,
840
+ ],
841
+ [
842
+ -6.8175993,
843
+ -6.792098,
844
+ -0.18560751,
845
+ 3.0563045,
846
+ 8.710696,
847
+ -9.596989,
848
+ 8.090187,
849
+ ],
850
+ [
851
+ -13.518117,
852
+ -2.7482898,
853
+ 5.891369,
854
+ 5.1779666,
855
+ -7.379195,
856
+ -0.9924428,
857
+ 2.5351613,
858
+ ],
859
+ [
860
+ -4.3629227,
861
+ -6.437724,
862
+ -13.663748,
863
+ -12.0565195,
864
+ -1.2215672,
865
+ 1.772012,
866
+ 1.8781031,
867
+ ],
868
+ [
869
+ 0.47687545,
870
+ -1.5980082,
871
+ -1.5401305,
872
+ 0.6282165,
873
+ -3.6321266,
874
+ 1.5924206,
875
+ 1.7971114,
876
+ ],
877
+ [
878
+ 0.31979027,
879
+ 0.78913784,
880
+ 0.7617095,
881
+ 2.0062523,
882
+ 3.6265984,
883
+ 1.6264036,
884
+ 3.1069543,
885
+ ],
886
+ [
887
+ -0.7392475,
888
+ 0.82420295,
889
+ 2.6924515,
890
+ 4.395664,
891
+ 5.582694,
892
+ 5.9560614,
893
+ 5.92299,
894
+ ],
895
+ ],
896
+ [
897
+ [
898
+ -6.615435,
899
+ -4.2648177,
900
+ -0.41911495,
901
+ 4.795286,
902
+ 10.781866,
903
+ 13.12497,
904
+ 11.968585,
905
+ ],
906
+ [
907
+ -6.980567,
908
+ -6.5854936,
909
+ -1.6141279,
910
+ 3.2338471,
911
+ 8.506243,
912
+ -9.9049225,
913
+ 7.0150843,
914
+ ],
915
+ [
916
+ -13.734081,
917
+ -4.05169,
918
+ 5.714791,
919
+ 4.696765,
920
+ -7.2288737,
921
+ -2.1190686,
922
+ 2.7367542,
923
+ ],
924
+ [
925
+ -4.908295,
926
+ -6.761066,
927
+ -13.2362175,
928
+ -11.991249,
929
+ -0.5408727,
930
+ 2.354013,
931
+ 2.0929167,
932
+ ],
933
+ [
934
+ 0.41402856,
935
+ -1.3379232,
936
+ -1.4920205,
937
+ 0.5738855,
938
+ -3.6704328,
939
+ 1.5384829,
940
+ 2.1192918,
941
+ ],
942
+ [
943
+ 0.30093297,
944
+ 0.971923,
945
+ 0.93931144,
946
+ 2.0213463,
947
+ 3.6705747,
948
+ 1.5487708,
949
+ 2.9228706,
950
+ ],
951
+ [
952
+ -0.54992414,
953
+ 0.91518635,
954
+ 2.853546,
955
+ 4.5043445,
956
+ 5.6799273,
957
+ 6.0500693,
958
+ 6.0166245,
959
+ ],
960
+ ],
961
+ ],
962
+ dtype=np.float32,
963
+ )
964
+
965
+ expected_vwnd = np.array(
966
+ [
967
+ [
968
+ [
969
+ 15.366679,
970
+ 16.297422,
971
+ 11.619374,
972
+ 7.6118455,
973
+ -0.17023174,
974
+ -0.70611537,
975
+ 0.918054,
976
+ ],
977
+ [
978
+ 5.8549976,
979
+ 12.26627,
980
+ 8.788221,
981
+ 0.95048386,
982
+ -3.6778722,
983
+ 2.183071,
984
+ -8.522625,
985
+ ],
986
+ [
987
+ -4.818965,
988
+ -2.2781372,
989
+ 0.78555244,
990
+ -2.8322685,
991
+ 8.696728,
992
+ -1.6022366,
993
+ -6.2568765,
994
+ ],
995
+ [
996
+ -8.705794,
997
+ -6.312195,
998
+ -8.364019,
999
+ -8.063112,
1000
+ 11.151511,
1001
+ -0.7562826,
1002
+ -3.3305223,
1003
+ ],
1004
+ [
1005
+ 0.5503583,
1006
+ -0.5612107,
1007
+ -3.0128725,
1008
+ -3.231436,
1009
+ -4.0373354,
1010
+ -4.1747046,
1011
+ -1.7400578,
1012
+ ],
1013
+ [
1014
+ -2.0023136,
1015
+ -1.1348844,
1016
+ -1.0493268,
1017
+ -1.3957449,
1018
+ -5.500842,
1019
+ -2.139104,
1020
+ 0.51574695,
1021
+ ],
1022
+ [
1023
+ -3.2449172,
1024
+ -3.0666091,
1025
+ -2.4833071,
1026
+ -1.8068211,
1027
+ -0.78668225,
1028
+ 0.16977428,
1029
+ 0.3107974,
1030
+ ],
1031
+ ],
1032
+ [
1033
+ [
1034
+ 15.095973,
1035
+ 16.516485,
1036
+ 12.527047,
1037
+ 7.781989,
1038
+ 0.30071807,
1039
+ -1.2423985,
1040
+ 1.2902508,
1041
+ ],
1042
+ [
1043
+ 4.8637633,
1044
+ 12.339098,
1045
+ 9.587799,
1046
+ 2.498924,
1047
+ -3.3265023,
1048
+ 1.8309238,
1049
+ -8.718385,
1050
+ ],
1051
+ [
1052
+ -4.9639883,
1053
+ -2.5414722,
1054
+ 1.0753635,
1055
+ -1.1787742,
1056
+ 9.358983,
1057
+ -1.7478623,
1058
+ -5.962756,
1059
+ ],
1060
+ [
1061
+ -8.519542,
1062
+ -5.2647786,
1063
+ -8.270556,
1064
+ -8.179985,
1065
+ 11.100576,
1066
+ -0.04957591,
1067
+ -3.1815748,
1068
+ ],
1069
+ [
1070
+ 0.52395123,
1071
+ -0.5520083,
1072
+ -2.9008386,
1073
+ -3.410807,
1074
+ -4.2334967,
1075
+ -3.9974525,
1076
+ -1.6043161,
1077
+ ],
1078
+ [
1079
+ -2.1034713,
1080
+ -1.2443935,
1081
+ -1.030919,
1082
+ -1.4211166,
1083
+ -5.52376,
1084
+ -2.4278605,
1085
+ 0.50510705,
1086
+ ],
1087
+ [
1088
+ -3.3849669,
1089
+ -3.3259943,
1090
+ -2.9783287,
1091
+ -1.9397556,
1092
+ -1.0758145,
1093
+ -0.05373563,
1094
+ 0.31708276,
1095
+ ],
1096
+ ],
1097
+ ],
1098
+ dtype=np.float32,
1099
+ )
1100
+
1101
+ expected_lwrad = np.array(
1102
+ [
1103
+ [
1104
+ [
1105
+ 349.6652,
1106
+ 329.73444,
1107
+ 309.8111,
1108
+ 277.24893,
1109
+ 269.887,
1110
+ 259.9545,
1111
+ 252.45737,
1112
+ ],
1113
+ [
1114
+ 334.3932,
1115
+ 324.30423,
1116
+ 303.3417,
1117
+ 279.31738,
1118
+ 239.14821,
1119
+ 268.40637,
1120
+ 218.19089,
1121
+ ],
1122
+ [
1123
+ 272.54703,
1124
+ 261.52417,
1125
+ 250.08763,
1126
+ 211.38737,
1127
+ 274.8412,
1128
+ 180.4204,
1129
+ 157.67314,
1130
+ ],
1131
+ [
1132
+ 248.60202,
1133
+ 238.70256,
1134
+ 265.10126,
1135
+ 272.1406,
1136
+ 229.21912,
1137
+ 204.43091,
1138
+ 163.18147,
1139
+ ],
1140
+ [
1141
+ 182.60025,
1142
+ 159.89,
1143
+ 168.08347,
1144
+ 145.50589,
1145
+ 175.71254,
1146
+ 171.32625,
1147
+ 145.81366,
1148
+ ],
1149
+ [
1150
+ 167.89578,
1151
+ 161.10167,
1152
+ 144.19185,
1153
+ 147.91838,
1154
+ 174.96294,
1155
+ 173.1659,
1156
+ 133.38031,
1157
+ ],
1158
+ [
1159
+ 168.20734,
1160
+ 154.56114,
1161
+ 139.15524,
1162
+ 131.65768,
1163
+ 129.26778,
1164
+ 138.174,
1165
+ 167.19113,
1166
+ ],
1167
+ ],
1168
+ [
1169
+ [
1170
+ 349.78278,
1171
+ 328.78848,
1172
+ 276.55316,
1173
+ 273.44193,
1174
+ 266.28256,
1175
+ 254.63882,
1176
+ 252.37021,
1177
+ ],
1178
+ [
1179
+ 335.17593,
1180
+ 324.55026,
1181
+ 305.78543,
1182
+ 283.29886,
1183
+ 234.72049,
1184
+ 270.92914,
1185
+ 210.62497,
1186
+ ],
1187
+ [
1188
+ 276.69925,
1189
+ 260.20963,
1190
+ 248.46922,
1191
+ 209.37762,
1192
+ 281.7514,
1193
+ 173.16145,
1194
+ 161.8793,
1195
+ ],
1196
+ [
1197
+ 254.5296,
1198
+ 238.58257,
1199
+ 261.37173,
1200
+ 277.44806,
1201
+ 217.54973,
1202
+ 211.76616,
1203
+ 162.33136,
1204
+ ],
1205
+ [
1206
+ 176.24583,
1207
+ 155.69785,
1208
+ 164.8903,
1209
+ 158.71767,
1210
+ 170.58754,
1211
+ 174.22809,
1212
+ 148.65094,
1213
+ ],
1214
+ [
1215
+ 168.88553,
1216
+ 162.3888,
1217
+ 143.45665,
1218
+ 144.12737,
1219
+ 174.56282,
1220
+ 173.04388,
1221
+ 137.46349,
1222
+ ],
1223
+ [
1224
+ 167.90765,
1225
+ 154.07794,
1226
+ 145.49677,
1227
+ 132.35924,
1228
+ 131.83968,
1229
+ 147.98386,
1230
+ 153.403,
1231
+ ],
1232
+ ],
1233
+ ],
1234
+ dtype=np.float32,
1235
+ )
1236
+ expected_Tair = np.array(
1237
+ [
1238
+ [
1239
+ [
1240
+ 8.382342,
1241
+ 6.532331,
1242
+ 4.761866,
1243
+ 3.7316587,
1244
+ 3.4166677,
1245
+ 3.1780987,
1246
+ 2.1949596,
1247
+ ],
1248
+ [
1249
+ 4.619903,
1250
+ 3.0633764,
1251
+ 3.041514,
1252
+ 2.3080995,
1253
+ 1.5948807,
1254
+ -1.6109427,
1255
+ -4.4116983,
1256
+ ],
1257
+ [
1258
+ -1.5634246,
1259
+ -2.5504875,
1260
+ -1.4600551,
1261
+ -0.5690303,
1262
+ -2.3495994,
1263
+ -15.370553,
1264
+ -19.289997,
1265
+ ],
1266
+ [
1267
+ -9.177512,
1268
+ -3.4015727,
1269
+ -4.4484963,
1270
+ -3.7056556,
1271
+ -10.697647,
1272
+ -18.948631,
1273
+ -23.376123,
1274
+ ],
1275
+ [
1276
+ -15.661556,
1277
+ -23.100355,
1278
+ -21.994339,
1279
+ -29.661201,
1280
+ -26.471874,
1281
+ -26.348959,
1282
+ -28.97584,
1283
+ ],
1284
+ [
1285
+ -24.909988,
1286
+ -26.92668,
1287
+ -29.5114,
1288
+ -30.11024,
1289
+ -25.887157,
1290
+ -26.812098,
1291
+ -32.926876,
1292
+ ],
1293
+ [
1294
+ -26.899937,
1295
+ -29.645899,
1296
+ -30.121904,
1297
+ -29.684294,
1298
+ -30.642694,
1299
+ -29.153072,
1300
+ -27.390156,
1301
+ ],
1302
+ ],
1303
+ [
1304
+ [
1305
+ 8.394094,
1306
+ 6.5803084,
1307
+ 4.8808966,
1308
+ 3.784057,
1309
+ 3.468052,
1310
+ 3.2407324,
1311
+ 2.3333037,
1312
+ ],
1313
+ [
1314
+ 4.6263127,
1315
+ 3.4498365,
1316
+ 3.032674,
1317
+ 2.4419715,
1318
+ 1.5665886,
1319
+ -1.6296549,
1320
+ -4.232036,
1321
+ ],
1322
+ [
1323
+ -1.5784973,
1324
+ -2.401672,
1325
+ -1.3959641,
1326
+ -0.6793834,
1327
+ -1.9613675,
1328
+ -15.220611,
1329
+ -19.084148,
1330
+ ],
1331
+ [
1332
+ -8.883304,
1333
+ -3.3834128,
1334
+ -4.6765513,
1335
+ -3.9015381,
1336
+ -10.273033,
1337
+ -18.5212,
1338
+ -23.331766,
1339
+ ],
1340
+ [
1341
+ -14.871544,
1342
+ -22.748688,
1343
+ -21.973629,
1344
+ -29.777143,
1345
+ -26.546505,
1346
+ -26.173407,
1347
+ -29.139715,
1348
+ ],
1349
+ [
1350
+ -24.59206,
1351
+ -26.851955,
1352
+ -29.489199,
1353
+ -30.27334,
1354
+ -26.018312,
1355
+ -26.81835,
1356
+ -32.84492,
1357
+ ],
1358
+ [
1359
+ -26.451527,
1360
+ -29.415953,
1361
+ -30.07525,
1362
+ -29.673147,
1363
+ -30.659044,
1364
+ -29.123781,
1365
+ -27.695673,
1366
+ ],
1367
+ ],
1368
+ ],
1369
+ dtype=np.float32,
1370
+ )
1371
+
1372
+ expected_qair = np.array(
1373
+ [
1374
+ [
1375
+ [
1376
+ 0.0060822,
1377
+ 0.0048595,
1378
+ 0.00434452,
1379
+ 0.00392386,
1380
+ 0.00350679,
1381
+ 0.00393684,
1382
+ 0.00386832,
1383
+ ],
1384
+ [
1385
+ 0.00496396,
1386
+ 0.00444844,
1387
+ 0.00362669,
1388
+ 0.0027039,
1389
+ 0.00263158,
1390
+ 0.00268065,
1391
+ 0.00188471,
1392
+ ],
1393
+ [
1394
+ 0.00218931,
1395
+ 0.00164752,
1396
+ 0.00180771,
1397
+ 0.00201025,
1398
+ 0.00222373,
1399
+ 0.00087739,
1400
+ 0.0006346,
1401
+ ],
1402
+ [
1403
+ 0.0014008,
1404
+ 0.00205272,
1405
+ 0.00235442,
1406
+ 0.00265417,
1407
+ 0.00145444,
1408
+ 0.00066224,
1409
+ 0.00048542,
1410
+ ],
1411
+ [
1412
+ 0.00082356,
1413
+ 0.0004623,
1414
+ 0.00057463,
1415
+ 0.00025071,
1416
+ 0.00032594,
1417
+ 0.00033909,
1418
+ 0.00028633,
1419
+ ],
1420
+ [
1421
+ 0.00041308,
1422
+ 0.00034891,
1423
+ 0.00027696,
1424
+ 0.00024237,
1425
+ 0.00032729,
1426
+ 0.00030786,
1427
+ 0.00018568,
1428
+ ],
1429
+ [
1430
+ 0.00034559,
1431
+ 0.00027157,
1432
+ 0.00024169,
1433
+ 0.00026326,
1434
+ 0.00022696,
1435
+ 0.00025577,
1436
+ 0.00029947,
1437
+ ],
1438
+ ],
1439
+ [
1440
+ [
1441
+ 0.0061117,
1442
+ 0.00487523,
1443
+ 0.00432124,
1444
+ 0.00410334,
1445
+ 0.00363048,
1446
+ 0.00388888,
1447
+ 0.00398394,
1448
+ ],
1449
+ [
1450
+ 0.00499707,
1451
+ 0.0045597,
1452
+ 0.00391427,
1453
+ 0.00286811,
1454
+ 0.00263745,
1455
+ 0.00266608,
1456
+ 0.00188403,
1457
+ ],
1458
+ [
1459
+ 0.00221635,
1460
+ 0.00166319,
1461
+ 0.00184379,
1462
+ 0.00198759,
1463
+ 0.00228325,
1464
+ 0.00087703,
1465
+ 0.00064521,
1466
+ ],
1467
+ [
1468
+ 0.00143134,
1469
+ 0.00203374,
1470
+ 0.00229373,
1471
+ 0.00262552,
1472
+ 0.00149901,
1473
+ 0.00068139,
1474
+ 0.0004829,
1475
+ ],
1476
+ [
1477
+ 0.00085248,
1478
+ 0.00047552,
1479
+ 0.00056961,
1480
+ 0.00024881,
1481
+ 0.00032247,
1482
+ 0.00034516,
1483
+ 0.00028347,
1484
+ ],
1485
+ [
1486
+ 0.00042441,
1487
+ 0.00035251,
1488
+ 0.00027714,
1489
+ 0.00023793,
1490
+ 0.00031979,
1491
+ 0.00031098,
1492
+ 0.00018754,
1493
+ ],
1494
+ [
1495
+ 0.00035735,
1496
+ 0.00027766,
1497
+ 0.00024232,
1498
+ 0.00026297,
1499
+ 0.00022758,
1500
+ 0.00025663,
1501
+ 0.00029233,
1502
+ ],
1503
+ ],
1504
+ ],
1505
+ dtype=np.float32,
1506
+ )
1507
+
1508
+ expected_rain = np.array(
1509
+ [
1510
+ [
1511
+ [
1512
+ 3.61238503e00,
1513
+ 3.40189010e-01,
1514
+ 5.07690720e-02,
1515
+ 4.43821624e-02,
1516
+ 2.10043773e-01,
1517
+ 4.68921065e-01,
1518
+ 1.17921913e00,
1519
+ ],
1520
+ [
1521
+ 3.48412228e00,
1522
+ 3.86755776e00,
1523
+ 2.48581603e-01,
1524
+ 3.64060067e-02,
1525
+ 5.49296811e-02,
1526
+ 2.96591282e-01,
1527
+ 5.34151215e-03,
1528
+ ],
1529
+ [
1530
+ 9.73676443e-02,
1531
+ 1.11962268e-02,
1532
+ 9.25773978e-02,
1533
+ 1.36675648e-04,
1534
+ 1.21756345e-01,
1535
+ 0.00000000e00,
1536
+ 1.35925822e-02,
1537
+ ],
1538
+ [
1539
+ 7.06618875e-02,
1540
+ 3.13506752e-01,
1541
+ 4.56249267e-01,
1542
+ 1.30473804e00,
1543
+ 2.46778969e-02,
1544
+ 1.31649813e-02,
1545
+ 3.05349231e-02,
1546
+ ],
1547
+ [
1548
+ 0.00000000e00,
1549
+ 7.10712187e-03,
1550
+ 1.27204210e-02,
1551
+ 1.14610912e-02,
1552
+ 5.81587963e-02,
1553
+ 1.63536705e-02,
1554
+ 1.79725345e-02,
1555
+ ],
1556
+ [
1557
+ 2.68480852e-02,
1558
+ 2.18332373e-02,
1559
+ 1.34839285e-02,
1560
+ 8.68453179e-03,
1561
+ 2.92103793e-02,
1562
+ 2.44176220e-02,
1563
+ 4.91440296e-03,
1564
+ ],
1565
+ [
1566
+ 2.63865143e-02,
1567
+ 2.48033050e-02,
1568
+ 1.22478902e-02,
1569
+ 3.26886214e-03,
1570
+ 0.00000000e00,
1571
+ 7.88422953e-03,
1572
+ 3.26447487e-02,
1573
+ ],
1574
+ ],
1575
+ [
1576
+ [
1577
+ 5.15011311e00,
1578
+ 1.07888615e00,
1579
+ 4.82074311e-03,
1580
+ 6.01990409e-02,
1581
+ 1.50670428e-02,
1582
+ 4.35768366e-01,
1583
+ 1.39202833e00,
1584
+ ],
1585
+ [
1586
+ 3.28930092e00,
1587
+ 3.81418300e00,
1588
+ 7.94297993e-01,
1589
+ 1.15379691e-02,
1590
+ 7.38679767e-02,
1591
+ 3.54040235e-01,
1592
+ 2.69045797e-03,
1593
+ ],
1594
+ [
1595
+ 1.16046831e-01,
1596
+ 5.51193906e-03,
1597
+ 9.27464366e-02,
1598
+ 2.15600841e-02,
1599
+ 1.63438022e-01,
1600
+ 0.00000000e00,
1601
+ 1.25724524e-02,
1602
+ ],
1603
+ [
1604
+ 6.99779242e-02,
1605
+ 3.13537568e-01,
1606
+ 3.66352916e-01,
1607
+ 1.00021172e00,
1608
+ 2.27534100e-02,
1609
+ 2.78335381e-02,
1610
+ 3.07151340e-02,
1611
+ ],
1612
+ [
1613
+ 0.00000000e00,
1614
+ 6.13165740e-03,
1615
+ 1.10241473e-02,
1616
+ 1.25272367e-02,
1617
+ 4.68330160e-02,
1618
+ 2.40270998e-02,
1619
+ 1.89573225e-02,
1620
+ ],
1621
+ [
1622
+ 2.87261512e-02,
1623
+ 2.31106617e-02,
1624
+ 1.35146212e-02,
1625
+ 7.67777674e-03,
1626
+ 3.07483859e-02,
1627
+ 1.98638346e-02,
1628
+ 6.78182067e-03,
1629
+ ],
1630
+ [
1631
+ 2.84809899e-02,
1632
+ 2.73145214e-02,
1633
+ 1.30094122e-02,
1634
+ 3.26886214e-03,
1635
+ 0.00000000e00,
1636
+ 8.95222276e-03,
1637
+ 2.09490024e-02,
1638
+ ],
1639
+ ],
1640
+ ],
1641
+ dtype=np.float32,
1642
+ )
1643
+
1644
+ # Check the values in the dataset
1645
+ ds = sfc_forcing.ds["physics"]
1646
+
1647
+ assert np.allclose(ds["uwnd"].values, expected_uwnd)
1648
+ assert np.allclose(ds["vwnd"].values, expected_vwnd)
1649
+ assert np.allclose(ds["swrad"].values, expected_swrad)
1650
+ assert np.allclose(ds["lwrad"].values, expected_lwrad)
1651
+ assert np.allclose(ds["Tair"].values, expected_Tair)
1652
+ assert np.allclose(ds["qair"].values, expected_qair)
1653
+ assert np.allclose(ds["rain"].values, expected_rain)
1654
+
1655
+ sfc_forcing.plot(varname="uwnd", time=0)
1656
+
1657
+ # Create a temporary file
1658
+ with tempfile.NamedTemporaryFile(delete=True) as tmpfile:
1659
+ filepath = tmpfile.name
1660
+
1661
+ sfc_forcing.save(filepath)
1662
+ extended_filepath = filepath + "_physics_20200201-01.nc"
1663
+
1664
+ try:
1665
+ assert os.path.exists(extended_filepath)
1666
+ finally:
1667
+ os.remove(extended_filepath)
1668
+
1669
+
1670
+ def test_surface_forcing_bgc_data_consistency_plot_save(
1671
+ corrected_surface_forcing_with_bgc,
1672
+ ):
1673
+ """
1674
+ Test that the BGC data within the SurfaceForcing object remains consistent.
1675
+ Also test plot and save methods in the same test since we dask arrays are already computed.
1676
+ """
1677
+
1678
+ # Check the values in the dataset
1679
+ corrected_surface_forcing_with_bgc.plot(varname="pco2_air", time=0)
1680
+
1681
+ expected_pco2_air = np.array(
1682
+ [
1683
+ [
1684
+ [
1685
+ 404.22748,
1686
+ 413.57806,
1687
+ 415.53137,
1688
+ 412.00464,
1689
+ 408.90378,
1690
+ 403.009,
1691
+ 399.49335,
1692
+ ],
1693
+ [
1694
+ 418.73532,
1695
+ 426.9579,
1696
+ 437.74713,
1697
+ 441.56055,
1698
+ 442.04376,
1699
+ 388.9692,
1700
+ 388.6991,
1701
+ ],
1702
+ [
1703
+ 428.60126,
1704
+ 426.8612,
1705
+ 432.61078,
1706
+ 436.4323,
1707
+ 403.53485,
1708
+ 331.7332,
1709
+ 343.11868,
1710
+ ],
1711
+ [
1712
+ 401.68954,
1713
+ 425.14883,
1714
+ 436.7216,
1715
+ 455.18954,
1716
+ 357.83847,
1717
+ 316.44016,
1718
+ 354.0953,
1719
+ ],
1720
+ [
1721
+ 430.29868,
1722
+ 398.86063,
1723
+ 400.73868,
1724
+ 399.2477,
1725
+ 357.3982,
1726
+ 340.97977,
1727
+ 354.399,
1728
+ ],
1729
+ [
1730
+ 425.6459,
1731
+ 403.8653,
1732
+ 375.61847,
1733
+ 368.8612,
1734
+ 353.72507,
1735
+ 340.38684,
1736
+ 352.58127,
1737
+ ],
1738
+ [
1739
+ 417.63498,
1740
+ 414.74066,
1741
+ 393.7536,
1742
+ 361.35803,
1743
+ 357.5395,
1744
+ 353.18665,
1745
+ 361.26233,
1746
+ ],
1747
+ ]
1748
+ ],
1749
+ dtype=np.float32,
1750
+ )
1751
+
1752
+ assert np.allclose(
1753
+ corrected_surface_forcing_with_bgc.ds["bgc"]["pco2_air"].values,
1754
+ expected_pco2_air,
1755
+ )
1756
+
1757
+ # Create a temporary file
1758
+ with tempfile.NamedTemporaryFile(delete=True) as tmpfile:
1759
+ filepath = tmpfile.name
1760
+
1761
+ corrected_surface_forcing_with_bgc.save(filepath)
1762
+ physics_filepath = filepath + "_physics_20200201-01.nc"
1763
+ bgc_filepath = filepath + "_bgc_20200201-01.nc"
1764
+
1765
+ try:
1766
+ assert os.path.exists(physics_filepath)
1767
+ assert os.path.exists(bgc_filepath)
1768
+ finally:
1769
+ os.remove(physics_filepath)
1770
+ os.remove(bgc_filepath)
1771
+
1772
+
1773
+ def test_surface_forcing_bgc_data_from_clim_consistency_plot_save(
1774
+ corrected_surface_forcing_with_bgc_from_climatology,
1775
+ ):
1776
+ """
1777
+ Test that the BGC data within the SurfaceForcing object remains consistent.
1778
+ Also test plot and save methods in the same test since we dask arrays are already computed.
1779
+ """
1780
+
1781
+ # Check the values in the dataset
1782
+ corrected_surface_forcing_with_bgc_from_climatology.plot(varname="pco2_air", time=0)
1783
+
1784
+ expected_pco2_air = np.array(
1785
+ [
1786
+ [
1787
+ [
1788
+ 398.14603,
1789
+ 404.46167,
1790
+ 407.15097,
1791
+ 405.2776,
1792
+ 404.13507,
1793
+ 400.7547,
1794
+ 398.85083,
1795
+ ],
1796
+ [
1797
+ 409.1616,
1798
+ 415.79483,
1799
+ 425.67477,
1800
+ 427.0116,
1801
+ 430.06903,
1802
+ 395.88733,
1803
+ 390.09415,
1804
+ ],
1805
+ [
1806
+ 417.66122,
1807
+ 414.91043,
1808
+ 417.62463,
1809
+ 422.71118,
1810
+ 412.35883,
1811
+ 368.0207,
1812
+ 366.4949,
1813
+ ],
1814
+ [
1815
+ 387.8851,
1816
+ 412.7159,
1817
+ 418.03122,
1818
+ 449.04837,
1819
+ 382.74442,
1820
+ 324.06628,
1821
+ 360.40964,
1822
+ ],
1823
+ [
1824
+ 416.6366,
1825
+ 390.45486,
1826
+ 390.24994,
1827
+ 392.66037,
1828
+ 374.50775,
1829
+ 342.20087,
1830
+ 352.27393,
1831
+ ],
1832
+ [
1833
+ 411.73032,
1834
+ 394.3381,
1835
+ 370.42654,
1836
+ 366.05936,
1837
+ 353.22403,
1838
+ 343.92136,
1839
+ 341.2689,
1840
+ ],
1841
+ [
1842
+ 407.44583,
1843
+ 415.57016,
1844
+ 384.86288,
1845
+ 360.26337,
1846
+ 356.596,
1847
+ 352.26584,
1848
+ 357.4343,
1849
+ ],
1850
+ ],
1851
+ [
1852
+ [
1853
+ 404.22748,
1854
+ 413.57806,
1855
+ 415.53137,
1856
+ 412.00464,
1857
+ 408.90378,
1858
+ 403.009,
1859
+ 399.49335,
1860
+ ],
1861
+ [
1862
+ 418.73532,
1863
+ 426.9579,
1864
+ 437.74713,
1865
+ 441.56055,
1866
+ 442.04376,
1867
+ 388.9692,
1868
+ 388.6991,
1869
+ ],
1870
+ [
1871
+ 428.60126,
1872
+ 426.8612,
1873
+ 432.61078,
1874
+ 436.4323,
1875
+ 403.53485,
1876
+ 331.7332,
1877
+ 343.11868,
1878
+ ],
1879
+ [
1880
+ 401.68954,
1881
+ 425.14883,
1882
+ 436.7216,
1883
+ 455.18954,
1884
+ 357.83847,
1885
+ 316.44016,
1886
+ 354.0953,
1887
+ ],
1888
+ [
1889
+ 430.29868,
1890
+ 398.86063,
1891
+ 400.73868,
1892
+ 399.2477,
1893
+ 357.3982,
1894
+ 340.97977,
1895
+ 354.399,
1896
+ ],
1897
+ [
1898
+ 425.6459,
1899
+ 403.8653,
1900
+ 375.61847,
1901
+ 368.8612,
1902
+ 353.72507,
1903
+ 340.38684,
1904
+ 352.58127,
1905
+ ],
1906
+ [
1907
+ 417.63498,
1908
+ 414.74066,
1909
+ 393.7536,
1910
+ 361.35803,
1911
+ 357.5395,
1912
+ 353.18665,
1913
+ 361.26233,
1914
+ ],
1915
+ ],
1916
+ [
1917
+ [
1918
+ 410.8616,
1919
+ 423.02103,
1920
+ 423.09604,
1921
+ 419.10156,
1922
+ 414.9103,
1923
+ 407.07053,
1924
+ 401.62665,
1925
+ ],
1926
+ [
1927
+ 429.6854,
1928
+ 434.3063,
1929
+ 439.06766,
1930
+ 443.2926,
1931
+ 444.38937,
1932
+ 392.52994,
1933
+ 387.95245,
1934
+ ],
1935
+ [
1936
+ 438.13297,
1937
+ 440.14212,
1938
+ 446.70282,
1939
+ 445.9411,
1940
+ 395.38516,
1941
+ 326.51703,
1942
+ 338.68753,
1943
+ ],
1944
+ [
1945
+ 415.84042,
1946
+ 440.29053,
1947
+ 457.30914,
1948
+ 440.55865,
1949
+ 349.61758,
1950
+ 325.13593,
1951
+ 353.53876,
1952
+ ],
1953
+ [430.2406, 410.839, 411.3754, 402.27014, 358.84747, 346.353, 354.80054],
1954
+ [
1955
+ 435.1648,
1956
+ 413.51578,
1957
+ 385.1607,
1958
+ 372.467,
1959
+ 354.8004,
1960
+ 343.80344,
1961
+ 351.89355,
1962
+ ],
1963
+ [
1964
+ 429.8856,
1965
+ 423.3144,
1966
+ 405.6345,
1967
+ 363.35962,
1968
+ 357.49466,
1969
+ 354.8506,
1970
+ 361.87515,
1971
+ ],
1972
+ ],
1973
+ [
1974
+ [
1975
+ 404.8583,
1976
+ 415.5544,
1977
+ 416.2556,
1978
+ 410.7852,
1979
+ 405.22998,
1980
+ 398.49936,
1981
+ 395.41647,
1982
+ ],
1983
+ [
1984
+ 430.01413,
1985
+ 432.6222,
1986
+ 436.35675,
1987
+ 440.0094,
1988
+ 442.04233,
1989
+ 393.30008,
1990
+ 387.82687,
1991
+ ],
1992
+ [
1993
+ 439.19922,
1994
+ 439.70526,
1995
+ 444.8726,
1996
+ 444.12234,
1997
+ 384.99542,
1998
+ 326.7951,
1999
+ 337.15298,
2000
+ ],
2001
+ [
2002
+ 423.3211,
2003
+ 442.34293,
2004
+ 452.6943,
2005
+ 422.3202,
2006
+ 350.5441,
2007
+ 333.0299,
2008
+ 353.19067,
2009
+ ],
2010
+ [
2011
+ 435.60132,
2012
+ 416.37122,
2013
+ 412.31454,
2014
+ 396.5343,
2015
+ 360.8705,
2016
+ 351.0615,
2017
+ 354.82278,
2018
+ ],
2019
+ [
2020
+ 442.0921,
2021
+ 421.49625,
2022
+ 389.07895,
2023
+ 372.72894,
2024
+ 356.47137,
2025
+ 347.64758,
2026
+ 349.50967,
2027
+ ],
2028
+ [
2029
+ 423.49146,
2030
+ 437.96732,
2031
+ 416.40515,
2032
+ 364.74283,
2033
+ 357.54456,
2034
+ 357.6978,
2035
+ 363.92026,
2036
+ ],
2037
+ ],
2038
+ [
2039
+ [
2040
+ 364.66605,
2041
+ 348.29202,
2042
+ 327.21948,
2043
+ 312.5929,
2044
+ 310.1843,
2045
+ 311.27948,
2046
+ 319.08026,
2047
+ ],
2048
+ [
2049
+ 405.23355,
2050
+ 383.24057,
2051
+ 369.13156,
2052
+ 379.3948,
2053
+ 376.67355,
2054
+ 333.73822,
2055
+ 331.91266,
2056
+ ],
2057
+ [
2058
+ 405.19348,
2059
+ 396.86462,
2060
+ 388.22614,
2061
+ 390.81296,
2062
+ 335.50076,
2063
+ 305.39764,
2064
+ 324.62347,
2065
+ ],
2066
+ [
2067
+ 394.32132,
2068
+ 420.4284,
2069
+ 434.33023,
2070
+ 402.13177,
2071
+ 322.8607,
2072
+ 324.56433,
2073
+ 335.1503,
2074
+ ],
2075
+ [438.04025, 402.429, 398.4195, 385.3214, 360.3192, 352.68503, 345.7393],
2076
+ [
2077
+ 434.2024,
2078
+ 417.87787,
2079
+ 384.5583,
2080
+ 369.64655,
2081
+ 356.73856,
2082
+ 350.8263,
2083
+ 351.05643,
2084
+ ],
2085
+ [
2086
+ 400.25546,
2087
+ 432.73685,
2088
+ 409.8863,
2089
+ 364.9216,
2090
+ 359.2582,
2091
+ 361.94647,
2092
+ 366.58585,
2093
+ ],
2094
+ ],
2095
+ [
2096
+ [
2097
+ 320.0029,
2098
+ 330.2735,
2099
+ 303.61395,
2100
+ 307.58713,
2101
+ 320.75143,
2102
+ 331.16663,
2103
+ 335.8144,
2104
+ ],
2105
+ [353.0393, 332.46973, 303.4242, 296.3255, 298.1235, 326.996, 332.63177],
2106
+ [333.67642, 326.4859, 311.252, 282.5213, 294.0293, 341.41116, 356.1976],
2107
+ [
2108
+ 279.0954,
2109
+ 313.43964,
2110
+ 318.8591,
2111
+ 284.96204,
2112
+ 266.36942,
2113
+ 287.91168,
2114
+ 343.8091,
2115
+ ],
2116
+ [
2117
+ 336.50403,
2118
+ 312.51163,
2119
+ 317.2202,
2120
+ 300.65918,
2121
+ 293.41602,
2122
+ 290.27216,
2123
+ 345.08566,
2124
+ ],
2125
+ [
2126
+ 332.25598,
2127
+ 352.03445,
2128
+ 350.67816,
2129
+ 345.28265,
2130
+ 347.45816,
2131
+ 351.7342,
2132
+ 352.62457,
2133
+ ],
2134
+ [
2135
+ 337.58936,
2136
+ 362.37796,
2137
+ 386.74255,
2138
+ 366.58105,
2139
+ 361.49588,
2140
+ 365.00146,
2141
+ 368.1141,
2142
+ ],
2143
+ ],
2144
+ [
2145
+ [
2146
+ 305.92316,
2147
+ 306.93582,
2148
+ 320.42093,
2149
+ 334.3491,
2150
+ 350.7195,
2151
+ 373.15265,
2152
+ 368.141,
2153
+ ],
2154
+ [
2155
+ 293.1966,
2156
+ 303.76968,
2157
+ 312.18463,
2158
+ 316.862,
2159
+ 324.14975,
2160
+ 362.1812,
2161
+ 373.89975,
2162
+ ],
2163
+ [
2164
+ 287.50125,
2165
+ 288.732,
2166
+ 292.04642,
2167
+ 304.70465,
2168
+ 342.6752,
2169
+ 399.62433,
2170
+ 398.39957,
2171
+ ],
2172
+ [
2173
+ 285.4672,
2174
+ 281.2273,
2175
+ 281.9908,
2176
+ 287.84683,
2177
+ 327.07794,
2178
+ 345.76187,
2179
+ 364.13577,
2180
+ ],
2181
+ [
2182
+ 317.54077,
2183
+ 318.2395,
2184
+ 314.44913,
2185
+ 296.35068,
2186
+ 285.5732,
2187
+ 311.2991,
2188
+ 344.32465,
2189
+ ],
2190
+ [
2191
+ 340.03323,
2192
+ 356.31216,
2193
+ 360.23056,
2194
+ 346.04034,
2195
+ 301.41037,
2196
+ 286.5328,
2197
+ 332.2325,
2198
+ ],
2199
+ [
2200
+ 367.48395,
2201
+ 388.24136,
2202
+ 413.18228,
2203
+ 357.0047,
2204
+ 337.4069,
2205
+ 344.10382,
2206
+ 354.71527,
2207
+ ],
2208
+ ],
2209
+ [
2210
+ [
2211
+ 350.15866,
2212
+ 350.08246,
2213
+ 359.35062,
2214
+ 374.62405,
2215
+ 385.71454,
2216
+ 393.22922,
2217
+ 405.19373,
2218
+ ],
2219
+ [
2220
+ 346.96497,
2221
+ 341.0631,
2222
+ 348.13092,
2223
+ 356.104,
2224
+ 362.08224,
2225
+ 402.34842,
2226
+ 413.2263,
2227
+ ],
2228
+ [
2229
+ 335.66232,
2230
+ 335.02692,
2231
+ 333.9118,
2232
+ 345.72632,
2233
+ 377.76294,
2234
+ 438.64017,
2235
+ 440.5227,
2236
+ ],
2237
+ [
2238
+ 336.00873,
2239
+ 331.4235,
2240
+ 330.77084,
2241
+ 324.82394,
2242
+ 364.6463,
2243
+ 371.63107,
2244
+ 393.25018,
2245
+ ],
2246
+ [
2247
+ 376.79837,
2248
+ 364.86725,
2249
+ 352.64667,
2250
+ 332.04468,
2251
+ 330.4255,
2252
+ 342.30908,
2253
+ 369.07553,
2254
+ ],
2255
+ [
2256
+ 385.23654,
2257
+ 392.9487,
2258
+ 391.2472,
2259
+ 365.89276,
2260
+ 319.08,
2261
+ 340.74893,
2262
+ 358.08716,
2263
+ ],
2264
+ [
2265
+ 402.53976,
2266
+ 408.4651,
2267
+ 418.34943,
2268
+ 391.3722,
2269
+ 364.6873,
2270
+ 334.38284,
2271
+ 338.2357,
2272
+ ],
2273
+ ],
2274
+ [
2275
+ [
2276
+ 384.82806,
2277
+ 385.0281,
2278
+ 387.55463,
2279
+ 393.90097,
2280
+ 400.93903,
2281
+ 410.05496,
2282
+ 414.2652,
2283
+ ],
2284
+ [
2285
+ 373.90726,
2286
+ 375.20236,
2287
+ 376.56927,
2288
+ 380.03513,
2289
+ 377.76764,
2290
+ 408.7514,
2291
+ 421.60242,
2292
+ ],
2293
+ [
2294
+ 368.0287,
2295
+ 365.7465,
2296
+ 365.68936,
2297
+ 370.90225,
2298
+ 395.10336,
2299
+ 452.66885,
2300
+ 456.04254,
2301
+ ],
2302
+ [
2303
+ 359.98935,
2304
+ 355.42517,
2305
+ 356.04587,
2306
+ 353.28638,
2307
+ 387.7216,
2308
+ 389.9909,
2309
+ 412.54553,
2310
+ ],
2311
+ [
2312
+ 401.3988,
2313
+ 385.66016,
2314
+ 374.76376,
2315
+ 361.84274,
2316
+ 364.27496,
2317
+ 369.83444,
2318
+ 391.7403,
2319
+ ],
2320
+ [
2321
+ 406.04547,
2322
+ 410.4884,
2323
+ 404.08243,
2324
+ 390.9909,
2325
+ 364.52176,
2326
+ 372.848,
2327
+ 380.68518,
2328
+ ],
2329
+ [
2330
+ 421.35165,
2331
+ 423.7671,
2332
+ 430.52847,
2333
+ 414.28665,
2334
+ 377.83176,
2335
+ 361.36493,
2336
+ 363.71622,
2337
+ ],
2338
+ ],
2339
+ [
2340
+ [
2341
+ 384.3036,
2342
+ 386.03488,
2343
+ 390.42053,
2344
+ 393.7354,
2345
+ 398.90906,
2346
+ 407.59833,
2347
+ 414.67212,
2348
+ ],
2349
+ [
2350
+ 383.4824,
2351
+ 376.4454,
2352
+ 365.8679,
2353
+ 370.3737,
2354
+ 384.7454,
2355
+ 396.86765,
2356
+ 401.57266,
2357
+ ],
2358
+ [
2359
+ 384.68747,
2360
+ 384.93744,
2361
+ 376.9039,
2362
+ 374.37,
2363
+ 387.89017,
2364
+ 425.60678,
2365
+ 423.83215,
2366
+ ],
2367
+ [
2368
+ 349.58817,
2369
+ 353.14197,
2370
+ 354.39044,
2371
+ 362.20624,
2372
+ 376.7501,
2373
+ 388.17532,
2374
+ 397.94363,
2375
+ ],
2376
+ [
2377
+ 375.7726,
2378
+ 367.9115,
2379
+ 364.30243,
2380
+ 357.57803,
2381
+ 359.09372,
2382
+ 378.4864,
2383
+ 384.53183,
2384
+ ],
2385
+ [
2386
+ 392.0134,
2387
+ 393.79785,
2388
+ 389.5198,
2389
+ 381.37845,
2390
+ 367.65408,
2391
+ 371.40897,
2392
+ 376.8739,
2393
+ ],
2394
+ [
2395
+ 411.46152,
2396
+ 413.26355,
2397
+ 417.53354,
2398
+ 400.22797,
2399
+ 378.11246,
2400
+ 364.16946,
2401
+ 366.87015,
2402
+ ],
2403
+ ],
2404
+ [
2405
+ [
2406
+ 388.30124,
2407
+ 388.92444,
2408
+ 384.93433,
2409
+ 385.27805,
2410
+ 388.80548,
2411
+ 399.42645,
2412
+ 405.78516,
2413
+ ],
2414
+ [
2415
+ 379.37393,
2416
+ 383.77905,
2417
+ 381.04263,
2418
+ 387.48773,
2419
+ 383.45462,
2420
+ 388.63864,
2421
+ 392.0524,
2422
+ ],
2423
+ [
2424
+ 382.59354,
2425
+ 389.78592,
2426
+ 383.2384,
2427
+ 384.32312,
2428
+ 393.3613,
2429
+ 401.43216,
2430
+ 400.07477,
2431
+ ],
2432
+ [
2433
+ 347.17233,
2434
+ 368.4824,
2435
+ 367.16025,
2436
+ 390.05325,
2437
+ 381.87103,
2438
+ 375.94528,
2439
+ 384.04514,
2440
+ ],
2441
+ [
2442
+ 363.02823,
2443
+ 362.139,
2444
+ 365.81894,
2445
+ 370.0153,
2446
+ 376.21783,
2447
+ 376.71158,
2448
+ 375.15192,
2449
+ ],
2450
+ [
2451
+ 373.53513,
2452
+ 377.82776,
2453
+ 376.80414,
2454
+ 377.8196,
2455
+ 376.17963,
2456
+ 375.08887,
2457
+ 370.21902,
2458
+ ],
2459
+ [
2460
+ 384.6436,
2461
+ 392.61368,
2462
+ 397.12335,
2463
+ 392.19543,
2464
+ 374.7854,
2465
+ 366.11572,
2466
+ 364.30585,
2467
+ ],
2468
+ ],
2469
+ [
2470
+ [
2471
+ 397.632,
2472
+ 401.96716,
2473
+ 398.11554,
2474
+ 400.73257,
2475
+ 400.37378,
2476
+ 401.6573,
2477
+ 404.91113,
2478
+ ],
2479
+ [
2480
+ 406.49796,
2481
+ 414.25653,
2482
+ 415.96265,
2483
+ 422.45657,
2484
+ 425.28955,
2485
+ 399.92108,
2486
+ 391.84106,
2487
+ ],
2488
+ [
2489
+ 400.9218,
2490
+ 412.2611,
2491
+ 414.38895,
2492
+ 411.9613,
2493
+ 410.46597,
2494
+ 382.8714,
2495
+ 379.89563,
2496
+ ],
2497
+ [
2498
+ 367.06268,
2499
+ 389.9282,
2500
+ 390.5468,
2501
+ 416.58414,
2502
+ 404.75714,
2503
+ 356.0946,
2504
+ 370.88605,
2505
+ ],
2506
+ [
2507
+ 379.26697,
2508
+ 372.37427,
2509
+ 374.7852,
2510
+ 381.90277,
2511
+ 392.6096,
2512
+ 369.72604,
2513
+ 364.15964,
2514
+ ],
2515
+ [
2516
+ 385.33365,
2517
+ 380.70264,
2518
+ 369.23062,
2519
+ 368.49274,
2520
+ 371.57126,
2521
+ 372.64706,
2522
+ 358.38586,
2523
+ ],
2524
+ [
2525
+ 391.62207,
2526
+ 403.18228,
2527
+ 385.95084,
2528
+ 370.7342,
2529
+ 364.23724,
2530
+ 361.9076,
2531
+ 362.69427,
2532
+ ],
2533
+ ],
2534
+ ],
2535
+ dtype=np.float32,
2536
+ )
2537
+
2538
+ assert np.allclose(
2539
+ corrected_surface_forcing_with_bgc_from_climatology.ds["bgc"][
2540
+ "pco2_air"
2541
+ ].values,
2542
+ expected_pco2_air,
2543
+ )
2544
+
2545
+ # Create a temporary file
2546
+ with tempfile.NamedTemporaryFile(delete=True) as tmpfile:
2547
+ filepath = tmpfile.name
2548
+
2549
+ corrected_surface_forcing_with_bgc_from_climatology.save(filepath)
2550
+ physics_filepath = filepath + "_physics_20200201-01.nc"
2551
+ bgc_filepath = filepath + "_bgc_clim.nc"
2552
+
2553
+ try:
2554
+ assert os.path.exists(physics_filepath)
2555
+ assert os.path.exists(bgc_filepath)
2556
+ finally:
2557
+ os.remove(physics_filepath)
2558
+ os.remove(bgc_filepath)
2559
+
2560
+
2561
+ @pytest.mark.parametrize(
2562
+ "sfc_forcing_fixture",
2563
+ [
2564
+ "surface_forcing",
2565
+ "corrected_surface_forcing",
2566
+ "corrected_surface_forcing_with_bgc",
2567
+ "corrected_surface_forcing_with_bgc_from_climatology",
2568
+ ],
2569
+ )
2570
+ def test_roundtrip_yaml(sfc_forcing_fixture, request):
2571
+ """Test that creating an SurfaceForcing object, saving its parameters to yaml file, and re-opening yaml file creates the same object."""
2572
+
2573
+ sfc_forcing = request.getfixturevalue(sfc_forcing_fixture)
2574
+
2575
+ # Create a temporary file
2576
+ with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
2577
+ filepath = tmpfile.name
2578
+
2579
+ try:
2580
+ sfc_forcing.to_yaml(filepath)
2581
+
2582
+ sfc_forcing_from_file = SurfaceForcing.from_yaml(filepath)
2583
+
2584
+ assert sfc_forcing == sfc_forcing_from_file
2585
+
2586
+ finally:
2587
+ os.remove(filepath)
2588
+
2589
+
2590
+ def test_from_yaml_missing_surface_forcing():
2591
+ yaml_content = textwrap.dedent(
2592
+ """\
2593
+ ---
2594
+ roms_tools_version: 0.0.0
2595
+ ---
2596
+ Grid:
2597
+ nx: 100
2598
+ ny: 100
2599
+ size_x: 1800
2600
+ size_y: 2400
2601
+ center_lon: -10
2602
+ center_lat: 61
2603
+ rot: -20
2604
+ topography_source: ETOPO5
2605
+ smooth_factor: 8
2606
+ hmin: 5.0
2607
+ rmax: 0.2
2608
+ """
2609
+ )
2610
+
2611
+ with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
2612
+ yaml_filepath = tmp_file.name
2613
+ tmp_file.write(yaml_content.encode())
2614
+
2615
+ try:
2616
+ with pytest.raises(
2617
+ ValueError,
2618
+ match="No SurfaceForcing configuration found in the YAML file.",
2619
+ ):
2620
+ SurfaceForcing.from_yaml(yaml_filepath)
2621
+ finally:
2622
+ os.remove(yaml_filepath)