From ca1f07aa9624b3b81810ef09c39e71dc216ef5ab Mon Sep 17 00:00:00 2001 From: EdHone Date: Tue, 28 Apr 2026 14:47:09 +0100 Subject: [PATCH 1/7] Some progress made towards dependency removal --- .../build/testframework/xiostest.py | 49 ++++--------------- .../lfric_xios_cyclic_temporal_test.py | 16 +++--- .../lfric_xios_temporal_test.py | 5 +- .../integration-test/tools/plot_output.py | 40 +++++++++++++++ 4 files changed, 59 insertions(+), 51 deletions(-) create mode 100644 components/lfric-xios/integration-test/tools/plot_output.py diff --git a/components/lfric-xios/build/testframework/xiostest.py b/components/lfric-xios/build/testframework/xiostest.py index b24dec612..d9d822094 100644 --- a/components/lfric-xios/build/testframework/xiostest.py +++ b/components/lfric-xios/build/testframework/xiostest.py @@ -12,8 +12,6 @@ from typing import List, Optional from testframework import MpiTest -import xarray as xr -import matplotlib.pyplot as plt ############################################################################## @@ -111,50 +109,23 @@ def nc_data_match(self, in_file: Path, out_file: Path, varname: str): """ Contextually compare output data. """ - ds_in = xr.open_dataset(in_file, engine='netcdf4', decode_timedelta=False) - ds_out = xr.open_dataset(out_file, engine='netcdf4', decode_timedelta=False) - comparison_window = [max(min(ds_out['time'].values), min(ds_in['time'].values)), - min(max(ds_out['time'].values), max(ds_in['time'].values))] - - ds_in_comp = ds_in.sel(time=slice(comparison_window[0], comparison_window[1])) - ds_out_comp = ds_out.sel(time=slice(comparison_window[0], comparison_window[1])) - - if ds_in_comp['time'].size == 0: - return False - else: - result = [(ds_in_comp['time'] == ds_out_comp['time']).values.all(), - (ds_in_comp[varname] == ds_out_comp[varname]).values.all()] - return all(result) + return True def plot_output(self, in_file: Path, out_file: Path, varname: str): """ - Visually compare input and output data. + Visually compare input and output data. If the environment variable + PLOT_TEST_OUTPUT is not set as True, No plot will be generated. This + routine depends on the matplotlib package. """ - def get_ts_data(file_path, field_id): - - ds = xr.open_dataset(file_path, engine='netcdf4', decode_timedelta=False) - ts = ds[field_id].mean(ds[field_id].dims[1::]) - time = ds[field_id].coords['time'] - - return ts, time - - input_ts, input_time = get_ts_data(in_file, varname) - output_ts, output_time = get_ts_data(out_file, varname) - - plt.rcParams["font.family"] = "serif" - _, ax = plt.subplots(figsize=([10.8, 4.8])) - ax.scatter(output_time, output_ts, c='C0', s=50) - ax.plot(output_time, output_ts, linestyle='--', lw=2, label="Model output data") - ax.scatter(input_time, input_ts, c='C3', marker='s', s=100, label="Input data") - - ax.set_xlabel("Date/Time") - ax.set_ylabel("Mean model data") + if os.environ.get('PLOT_TEST_OUTPUT', False): + sys.path.append(str((Path(__file__).parent.parent.parent / + "integration-test" / "tools"))) + from plot_output import plot_test_output # noqa: E402 - plt.legend(frameon=False) - plt.savefig(f"{self.test_working_dir}/{type(self).__name__}.png", bbox_inches="tight") - plt.close() + plot_path = self.test_working_dir / f"{type(self).__name__}.png" + plot_test_output(in_file, out_file, varname, plot_path) def post_execution(self, return_code): """ diff --git a/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py b/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py index c952520d6..205a6548c 100755 --- a/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py @@ -98,9 +98,9 @@ def test(self, returncode: int, out: str, err: str): raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + f"stderr:\n" + f"{err}") - if not self.nc_data_match(Path(self.test_working_dir, 'cyclic_past_kgo.nc'), - Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check( + Path(self.test_working_dir, 'cyclic_past_kgo.nc'), + Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc')): raise TestFailed("Output data does not match expected values") return "Reading full set of cyclic data from the past okay..." @@ -135,9 +135,8 @@ def test(self, returncode: int, out: str, err: str): Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), 'temporal_field') - if not self.nc_data_match(Path(self.test_working_dir, 'cyclic_high_freq_kgo.nc'), - Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'cyclic_high_freq_kgo.nc'), + Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc')): raise TestFailed("Output data does not match expected values") return "Reading full set of cyclic data from the past okay..." @@ -172,9 +171,8 @@ def test(self, returncode: int, out: str, err: str): Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), 'temporal_field') - if not self.nc_data_match(Path(self.test_working_dir, 'non_sync_kgo.nc'), - Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'non_sync_kgo.nc'), + Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc')): raise TestFailed("Output data does not match expected values") return "Reading non-synchronised cyclic data okay..." diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py index e8b12b0e4..a01404210 100755 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py @@ -108,9 +108,8 @@ def test(self, returncode: int, out: str, err: str): Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), 'temporal_field') - if not self.nc_data_match(Path(self.test_working_dir, 'non_sync_kgo.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'non_sync_kgo.nc'), + Path(self.test_working_dir, 'lfric_xios_temporal_output.nc')): raise TestFailed("Output data does not match input data for same time values") return "Reading non-synchronised non-cyclic data at higher model frequency okay..." diff --git a/components/lfric-xios/integration-test/tools/plot_output.py b/components/lfric-xios/integration-test/tools/plot_output.py new file mode 100644 index 000000000..3ffbd580c --- /dev/null +++ b/components/lfric-xios/integration-test/tools/plot_output.py @@ -0,0 +1,40 @@ +from pathlib import Path +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt # noqa: E402 + +# REMOVE XARRAY +import xarray as xr # noqa: E402 + +def _get_ts_data(file_path, field_id): + """ + Get time series data for a given field from a netCDF file. + """ + + ds = xr.open_dataset(file_path, engine='netcdf4', decode_timedelta=False) + ts = ds[field_id].mean(ds[field_id].dims[1::]) + time = ds[field_id].coords['time'] + + return ts, time + + +def plot_test_output(in_file: Path, out_file: Path, varname: str, plot_file_path: Path): + """ + Visually compare input and output data. + """ + + input_ts, input_time = _get_ts_data(in_file, varname) + output_ts, output_time = _get_ts_data(out_file, varname) + + plt.rcParams["font.family"] = "serif" + _, ax = plt.subplots(figsize=([10.8, 4.8])) + ax.scatter(output_time, output_ts, c='C0', s=50) + ax.plot(output_time, output_ts, linestyle='--', lw=2, label="Model output data") + ax.scatter(input_time, input_ts, c='C3', marker='s', s=100, label="Input data") + + ax.set_xlabel("Date/Time") + ax.set_ylabel("Mean model data") + + plt.legend(frameon=False) + plt.savefig(f"{plot_file_path}", bbox_inches="tight") + plt.close() \ No newline at end of file From 8c9bf960ff8aaf414d7badb1ca8b4251e9b845ad Mon Sep 17 00:00:00 2001 From: EdHone Date: Wed, 29 Apr 2026 15:22:25 +0100 Subject: [PATCH 2/7] Make plotting and dependencies and optional extra --- .../build/testframework/xiostest.py | 15 +- .../lfric_xios_cyclic_temporal_test.py | 18 +- .../lfric_xios_temporal_iodef_test.py | 12 +- .../lfric_xios_temporal_test.py | 22 +- .../resources/data/cyclic_full_kgo.cdl | 526 +++++++++ .../resources/data/non_cyclic_full_kgo.cdl | 324 ++++++ .../data/non_cyclic_high_freq_iodef_kgo.cdl | 1027 +++++++++++++++++ .../data/non_cyclic_high_freq_kgo.cdl | 286 +++++ .../resources/data/non_cyclic_partial_kgo.cdl | 324 ++++++ .../integration-test/tools/plot_output.py | 5 +- 10 files changed, 2521 insertions(+), 38 deletions(-) create mode 100644 components/lfric-xios/integration-test/resources/data/cyclic_full_kgo.cdl create mode 100644 components/lfric-xios/integration-test/resources/data/non_cyclic_full_kgo.cdl create mode 100644 components/lfric-xios/integration-test/resources/data/non_cyclic_high_freq_iodef_kgo.cdl create mode 100644 components/lfric-xios/integration-test/resources/data/non_cyclic_high_freq_kgo.cdl create mode 100644 components/lfric-xios/integration-test/resources/data/non_cyclic_partial_kgo.cdl diff --git a/components/lfric-xios/build/testframework/xiostest.py b/components/lfric-xios/build/testframework/xiostest.py index d9d822094..3c5fa225e 100644 --- a/components/lfric-xios/build/testframework/xiostest.py +++ b/components/lfric-xios/build/testframework/xiostest.py @@ -98,20 +98,17 @@ def nc_kgo_check(self, output: Path, kgo: Path): Compare output files with nccmp. """ proc = subprocess.run( - ['nccmp', '-Fdm', '--exclude=Mesh2d', '--tolerance=0.000001', f'{output}', f'{kgo}'], + ['nccmp', '-Fdm', '--exclude=Mesh2d,Mesh2d_face_edges,Mesh2d_face_links', '--tolerance=0.000001', f'{output}', f'{kgo}'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) - return proc.returncode, proc.stderr - - def nc_data_match(self, in_file: Path, out_file: Path, varname: str): - """ - Contextually compare output data. - """ - - return True + kgo_check_okay = (proc.returncode == 0) + if not kgo_check_okay: + print(f"{proc.stderr}\n") + return kgo_check_okay + def plot_output(self, in_file: Path, out_file: Path, varname: str): """ Visually compare input and output data. If the environment variable diff --git a/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py b/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py index 205a6548c..bcdcd67ed 100755 --- a/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py @@ -22,6 +22,7 @@ class LfricXiosFullCyclicTest(LFRicXiosTest): # pylint: disable=too-few-public- def __init__(self): super().__init__(command=[sys.argv[1], "cyclic_full.nml"], processes=1) self.gen_data('temporal_data.cdl', 'lfric_xios_cyclic_input.nc') + self.gen_data('cyclic_full_kgo.cdl', 'cyclic_full_kgo.nc') self.gen_config( 'cyclic_base.nml', 'cyclic_full.nml', {} ) def test(self, returncode: int, out: str, err: str): @@ -39,9 +40,8 @@ def test(self, returncode: int, out: str, err: str): Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), 'temporal_field') - if not self.nc_data_match(Path(self.test_working_dir, 'lfric_xios_cyclic_input.nc'), - Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), + Path(self.test_working_dir, 'cyclic_full_kgo.nc')): raise TestFailed("Output data does not match input data for same time values") return "Reading full set of cyclic data okay..." @@ -99,8 +99,8 @@ def test(self, returncode: int, out: str, err: str): f"stderr:\n" + f"{err}") if not self.nc_kgo_check( - Path(self.test_working_dir, 'cyclic_past_kgo.nc'), - Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc')): + Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), + Path(self.test_working_dir, 'cyclic_past_kgo.nc')): raise TestFailed("Output data does not match expected values") return "Reading full set of cyclic data from the past okay..." @@ -135,8 +135,8 @@ def test(self, returncode: int, out: str, err: str): Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), 'temporal_field') - if not self.nc_kgo_check(Path(self.test_working_dir, 'cyclic_high_freq_kgo.nc'), - Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc')): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), + Path(self.test_working_dir, 'cyclic_high_freq_kgo.nc')): raise TestFailed("Output data does not match expected values") return "Reading full set of cyclic data from the past okay..." @@ -171,8 +171,8 @@ def test(self, returncode: int, out: str, err: str): Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), 'temporal_field') - if not self.nc_kgo_check(Path(self.test_working_dir, 'non_sync_kgo.nc'), - Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc')): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), + Path(self.test_working_dir, 'non_sync_kgo.nc')): raise TestFailed("Output data does not match expected values") return "Reading non-synchronised cyclic data okay..." diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py b/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py index 2b6eaa737..ca4143b03 100755 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py @@ -26,6 +26,7 @@ class LfricXiosFullNonCyclicIodefTest(LFRicXiosTest): # pylint: disable=too-few def __init__(self): super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], processes=1, iodef_file="iodef_temporal.xml") self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') + self.gen_data('non_cyclic_full_kgo.cdl', 'non_cyclic_full_kgo.nc') self.gen_config( "non_cyclic_base.nml", "non_cyclic_full.nml", {} ) def test(self, returncode: int, out: str, err: str): @@ -38,9 +39,8 @@ def test(self, returncode: int, out: str, err: str): raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + f"stderr:\n" + f"{err}") - if not self.nc_data_match(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), + Path(self.test_working_dir, 'non_cyclic_full_kgo.nc')): raise TestFailed("Output data does not match input data for same time values") return "Reading full set of non-cylic data okay..." @@ -55,6 +55,7 @@ class LfricXiosFullNonCyclicIodefHighFreqTest(LFRicXiosTest): # pylint: disable def __init__(self): super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], processes=1, iodef_file="iodef_temporal.xml") self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') + self.gen_data('non_cyclic_high_freq_iodef_kgo.cdl', 'non_cyclic_high_freq_kgo.nc') self.gen_config( "non_cyclic_base.nml", "non_cyclic_full.nml", {"dt": 10.0, "timestep_end": '60'} ) @@ -68,9 +69,8 @@ def test(self, returncode: int, out: str, err: str): raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + f"stderr:\n" + f"{err}") - if not self.nc_data_match(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), + Path(self.test_working_dir, 'non_cyclic_high_freq_kgo.nc')): raise TestFailed("Output data does not match input data for same time values") return "Reading full set of non-cylic data okay..." diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py index a01404210..dd1945bd7 100755 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py @@ -25,6 +25,7 @@ class LfricXiosFullNonCyclicTest(LFRicXiosTest): # pylint: disable=too-few-publ def __init__(self): super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], processes=1) self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') + self.gen_data('non_cyclic_full_kgo.cdl', 'non_cyclic_full_kgo.nc') self.gen_config( "non_cyclic_base.nml", "non_cyclic_full.nml", {} ) def test(self, returncode: int, out: str, err: str): @@ -42,9 +43,8 @@ def test(self, returncode: int, out: str, err: str): Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), 'temporal_field') - if not self.nc_data_match(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), + Path(self.test_working_dir, 'non_cyclic_full_kgo.nc')): raise TestFailed("Output data does not match input data for same time values") return "Reading full set of non-cyclic data okay..." @@ -59,6 +59,7 @@ class LfricXiosNonCyclicHighFreqTest(LFRicXiosTest): # pylint: disable=too-few- def __init__(self): super().__init__(command=[sys.argv[1], "non_cyclic_high_freq.nml"], processes=1) self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') + self.gen_data('non_cyclic_high_freq_kgo.cdl', 'non_cyclic_high_freq_kgo.nc') self.gen_config( "non_cyclic_base.nml", "non_cyclic_high_freq.nml", {"dt":10.0} ) def test(self, returncode: int, out: str, err: str): @@ -71,9 +72,8 @@ def test(self, returncode: int, out: str, err: str): raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + f"stderr:\n" + f"{err}") - if not self.nc_data_match(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), + Path(self.test_working_dir, 'non_cyclic_high_freq_kgo.nc')): raise TestFailed("Output data does not match input data for same time values") return "Reading full set of non-cyclic data at higher model frequency okay..." @@ -108,8 +108,8 @@ def test(self, returncode: int, out: str, err: str): Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), 'temporal_field') - if not self.nc_kgo_check(Path(self.test_working_dir, 'non_sync_kgo.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc')): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), + Path(self.test_working_dir, 'non_sync_kgo.nc')): raise TestFailed("Output data does not match input data for same time values") return "Reading non-synchronised non-cyclic data at higher model frequency okay..." @@ -124,6 +124,7 @@ class LfricXiosPartialNonCyclicTest(LFRicXiosTest): # pylint: disable=too-few-p def __init__(self): super().__init__(command=[sys.argv[1], "non_cyclic_mid.nml"], processes=1) self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') + self.gen_data('non_cyclic_partial_kgo.cdl', 'non_cyclic_partial_kgo.nc') self.gen_config( "non_cyclic_base.nml", "non_cyclic_mid.nml", {'calendar_start':'2024-01-01 15:01:00'} ) def test(self, returncode: int, out: str, err: str): @@ -136,9 +137,8 @@ def test(self, returncode: int, out: str, err: str): f"stderr:\n" + f"{err}") - if not self.nc_data_match(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - 'temporal_field'): + if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), + Path(self.test_working_dir, 'non_cyclic_partial_kgo.nc')): raise TestFailed("Output data does not match input data for same time values") return "Reading partial set of non-cyclic data okay..." diff --git a/components/lfric-xios/integration-test/resources/data/cyclic_full_kgo.cdl b/components/lfric-xios/integration-test/resources/data/cyclic_full_kgo.cdl new file mode 100644 index 000000000..bfd3a4240 --- /dev/null +++ b/components/lfric-xios/integration-test/resources/data/cyclic_full_kgo.cdl @@ -0,0 +1,526 @@ +netcdf lfric_xios_cyclic_output { +dimensions: + axis_nbounds = 2 ; + Two = 2 ; + nMesh2d_node = 1 ; + nMesh2d_edge = UNLIMITED ; // (0 currently) + nMesh2d_face = 9 ; + nMesh2d_vertex = 4 ; + vert_axis_half_levels = 5 ; + time = UNLIMITED ; // (25 currently) +variables: + int Mesh2d ; + Mesh2d:cf_role = "mesh_topology" ; + Mesh2d:long_name = "Topology data of 2D unstructured mesh" ; + Mesh2d:topology_dimension = 2 ; + Mesh2d:node_coordinates = "Mesh2d_node_x Mesh2d_node_y" ; + Mesh2d:edge_coordinates = "Mesh2d_edge_x Mesh2d_edge_y" ; + Mesh2d:edge_node_connectivity = "Mesh2d_edge_nodes" ; + Mesh2d:face_edge_connectivity = "Mesh2d_face_edges" ; + Mesh2d:edge_face_connectivity = "Mesh2d_edge_face_links" ; + Mesh2d:face_face_connectivity = "Mesh2d_face_links" ; + Mesh2d:face_coordinates = "Mesh2d_face_x Mesh2d_face_y" ; + Mesh2d:face_node_connectivity = "Mesh2d_face_nodes" ; + Mesh2d:geometry = "planar" ; + float Mesh2d_node_x(nMesh2d_node) ; + Mesh2d_node_x:standard_name = "projection_x_coordinate" ; + Mesh2d_node_x:long_name = "x coordinate of projection" ; + Mesh2d_node_x:units = "m" ; + Mesh2d_node_x:scale_factor = 10000. ; + float Mesh2d_node_y(nMesh2d_node) ; + Mesh2d_node_y:standard_name = "projection_y_coordinate" ; + Mesh2d_node_y:long_name = "y coordinate of projection" ; + Mesh2d_node_y:units = "m" ; + Mesh2d_node_y:scale_factor = 10000. ; + float Mesh2d_edge_x(nMesh2d_edge) ; + Mesh2d_edge_x:standard_name = "projection_x_coordinate" ; + Mesh2d_edge_x:long_name = "x coordinate of projection" ; + Mesh2d_edge_x:units = "m" ; + Mesh2d_edge_x:scale_factor = 10000. ; + float Mesh2d_edge_y(nMesh2d_edge) ; + Mesh2d_edge_y:standard_name = "projection_y_coordinate" ; + Mesh2d_edge_y:long_name = "y coordinate of projection" ; + Mesh2d_edge_y:units = "m" ; + Mesh2d_edge_y:scale_factor = 10000. ; + int Mesh2d_edge_nodes(nMesh2d_edge, Two) ; + Mesh2d_edge_nodes:cf_role = "edge_node_connectivity" ; + Mesh2d_edge_nodes:long_name = "Maps every edge/link to two nodes that it connects." ; + Mesh2d_edge_nodes:start_index = 0 ; + float Mesh2d_face_x(nMesh2d_face) ; + Mesh2d_face_x:standard_name = "projection_x_coordinate" ; + Mesh2d_face_x:long_name = "x coordinate of projection" ; + Mesh2d_face_x:units = "m" ; + Mesh2d_face_x:scale_factor = 10000. ; + float Mesh2d_face_y(nMesh2d_face) ; + Mesh2d_face_y:standard_name = "projection_y_coordinate" ; + Mesh2d_face_y:long_name = "y coordinate of projection" ; + Mesh2d_face_y:units = "m" ; + Mesh2d_face_y:scale_factor = 10000. ; + int Mesh2d_face_nodes(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_nodes:cf_role = "face_node_connectivity" ; + Mesh2d_face_nodes:long_name = "Maps every face to its corner nodes." ; + Mesh2d_face_nodes:start_index = 0 ; + int Mesh2d_face_edges(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_edges:cf_role = "face_edge_connectivity" ; + Mesh2d_face_edges:long_name = "Maps every face to its edges." ; + Mesh2d_face_edges:start_index = 0 ; + Mesh2d_face_edges:_FillValue = -999 ; + int Mesh2d_edge_face_links(nMesh2d_edge, Two) ; + Mesh2d_edge_face_links:cf_role = "edge_face_connectivity" ; + Mesh2d_edge_face_links:long_name = "neighbor faces for edges" ; + Mesh2d_edge_face_links:start_index = 0 ; + Mesh2d_edge_face_links:_FillValue = -999 ; + Mesh2d_edge_face_links:comment = "missing neighbor faces are indicated using _FillValue" ; + int Mesh2d_face_links(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_links:cf_role = "face_face_connectivity" ; + Mesh2d_face_links:long_name = "Indicates which other faces neighbor each face" ; + Mesh2d_face_links:start_index = 0 ; + Mesh2d_face_links:_FillValue = -999 ; + Mesh2d_face_links:flag_values = -1 ; + Mesh2d_face_links:flag_meanings = "out_of_mesh" ; + float vert_axis_half_levels(vert_axis_half_levels) ; + vert_axis_half_levels:name = "vert_axis_half_levels" ; + double time(time) ; + time:axis = "T" ; + time:standard_name = "time" ; + time:long_name = "Time axis" ; + time:calendar = "gregorian" ; + time:units = "seconds since 2024-01-01 15:01:00" ; + time:time_origin = "2024-01-01 15:01:00" ; + time:bounds = "time_bounds" ; + time:coordinates = " forecast_reference_time forecast_period" ; + double time_bounds(time, axis_nbounds) ; + time_bounds:coordinates = " forecast_reference_time forecast_period" ; + double temporal_field(time, vert_axis_half_levels, nMesh2d_face) ; + temporal_field:mesh = "Mesh2d" ; + temporal_field:location = "face" ; + temporal_field:online_operation = "instant" ; + temporal_field:interval_operation = "60 s" ; + temporal_field:interval_write = "60 s" ; + temporal_field:cell_methods = "time: point" ; + temporal_field:coordinates = "Mesh2d_face_y Mesh2d_face_x forecast_reference_time forecast_period" ; + double forecast_reference_time ; + forecast_reference_time:units = "seconds since 2024-01-01 15:01:00" ; + forecast_reference_time:calendar = "gregorian" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + double forecast_period(time) ; + forecast_period:units = "seconds" ; + forecast_period:standard_name = "forecast_period" ; + forecast_period:coordinates = " forecast_reference_time forecast_period" ; + +// global attributes: + :name = "lfric_xios_cyclic_output" ; + :title = "Created by xios" ; + :timeStamp = "2026-Apr-29 11:52:53 GMT" ; + :uuid = "0b903b5b-8d6f-49f3-9d91-abb96385007c" ; + :description = "LFRic file format v0.2.0" ; + :Conventions = "UGRID-1.0" ; +data: + + Mesh2d = 1437303793 ; + + Mesh2d_node_x = 0 ; + + Mesh2d_node_y = 0 ; + + Mesh2d_face_x = 0.0001, 0.0002, 0.0001, 0.0003, 0.0001, 0.0003, 0.0002, + 0.0003, 0.0002 ; + + Mesh2d_face_y = 0.0001, 0.0001, 0.0001, 0.0002, 0.0002, 0.0002, 0.0003, + 0.0003, 0.0003 ; + + Mesh2d_face_nodes = + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 ; + + Mesh2d_face_edges = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + Mesh2d_face_links = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + vert_axis_half_levels = 0.5, 1.5, 2.5, 3.5, 4.5 ; + + time = 60, 120, 180, 240, 300, 360, 420, 480, 540, 600, 660, 720, 780, 840, + 900, 960, 1020, 1080, 1140, 1200, 1260, 1320, 1380, 1440, 1500 ; + + time_bounds = + 60, 60, + 120, 120, + 180, 180, + 240, 240, + 300, 300, + 360, 360, + 420, 420, + 480, 480, + 540, 540, + 600, 600, + 660, 660, + 720, 720, + 780, 780, + 840, 840, + 900, 900, + 960, 960, + 1020, 1020, + 1080, 1080, + 1140, 1140, + 1200, 1200, + 1260, 1260, + 1320, 1320, + 1380, 1380, + 1440, 1440, + 1500, 1500 ; + + temporal_field = + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857 ; + + forecast_reference_time = 0 ; + + forecast_period = 60, 120, 180, 240, 300, 360, 420, 480, 540, 600, 660, 720, + 780, 840, 900, 960, 1020, 1080, 1140, 1200, 1260, 1320, 1380, 1440, 1500 ; +} diff --git a/components/lfric-xios/integration-test/resources/data/non_cyclic_full_kgo.cdl b/components/lfric-xios/integration-test/resources/data/non_cyclic_full_kgo.cdl new file mode 100644 index 000000000..089478794 --- /dev/null +++ b/components/lfric-xios/integration-test/resources/data/non_cyclic_full_kgo.cdl @@ -0,0 +1,324 @@ +netcdf lfric_xios_temporal_output { +dimensions: + axis_nbounds = 2 ; + Two = 2 ; + nMesh2d_node = 1 ; + nMesh2d_edge = UNLIMITED ; // (0 currently) + nMesh2d_face = 9 ; + nMesh2d_vertex = 4 ; + vert_axis_half_levels = 5 ; + time = UNLIMITED ; // (10 currently) +variables: + int Mesh2d ; + Mesh2d:cf_role = "mesh_topology" ; + Mesh2d:long_name = "Topology data of 2D unstructured mesh" ; + Mesh2d:topology_dimension = 2 ; + Mesh2d:node_coordinates = "Mesh2d_node_x Mesh2d_node_y" ; + Mesh2d:edge_coordinates = "Mesh2d_edge_x Mesh2d_edge_y" ; + Mesh2d:edge_node_connectivity = "Mesh2d_edge_nodes" ; + Mesh2d:face_edge_connectivity = "Mesh2d_face_edges" ; + Mesh2d:edge_face_connectivity = "Mesh2d_edge_face_links" ; + Mesh2d:face_face_connectivity = "Mesh2d_face_links" ; + Mesh2d:face_coordinates = "Mesh2d_face_x Mesh2d_face_y" ; + Mesh2d:face_node_connectivity = "Mesh2d_face_nodes" ; + Mesh2d:geometry = "planar" ; + float Mesh2d_node_x(nMesh2d_node) ; + Mesh2d_node_x:standard_name = "projection_x_coordinate" ; + Mesh2d_node_x:long_name = "x coordinate of projection" ; + Mesh2d_node_x:units = "m" ; + Mesh2d_node_x:scale_factor = 10000. ; + float Mesh2d_node_y(nMesh2d_node) ; + Mesh2d_node_y:standard_name = "projection_y_coordinate" ; + Mesh2d_node_y:long_name = "y coordinate of projection" ; + Mesh2d_node_y:units = "m" ; + Mesh2d_node_y:scale_factor = 10000. ; + float Mesh2d_edge_x(nMesh2d_edge) ; + Mesh2d_edge_x:standard_name = "projection_x_coordinate" ; + Mesh2d_edge_x:long_name = "x coordinate of projection" ; + Mesh2d_edge_x:units = "m" ; + Mesh2d_edge_x:scale_factor = 10000. ; + float Mesh2d_edge_y(nMesh2d_edge) ; + Mesh2d_edge_y:standard_name = "projection_y_coordinate" ; + Mesh2d_edge_y:long_name = "y coordinate of projection" ; + Mesh2d_edge_y:units = "m" ; + Mesh2d_edge_y:scale_factor = 10000. ; + int Mesh2d_edge_nodes(nMesh2d_edge, Two) ; + Mesh2d_edge_nodes:cf_role = "edge_node_connectivity" ; + Mesh2d_edge_nodes:long_name = "Maps every edge/link to two nodes that it connects." ; + Mesh2d_edge_nodes:start_index = 0 ; + float Mesh2d_face_x(nMesh2d_face) ; + Mesh2d_face_x:standard_name = "projection_x_coordinate" ; + Mesh2d_face_x:long_name = "x coordinate of projection" ; + Mesh2d_face_x:units = "m" ; + Mesh2d_face_x:scale_factor = 10000. ; + float Mesh2d_face_y(nMesh2d_face) ; + Mesh2d_face_y:standard_name = "projection_y_coordinate" ; + Mesh2d_face_y:long_name = "y coordinate of projection" ; + Mesh2d_face_y:units = "m" ; + Mesh2d_face_y:scale_factor = 10000. ; + int Mesh2d_face_nodes(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_nodes:cf_role = "face_node_connectivity" ; + Mesh2d_face_nodes:long_name = "Maps every face to its corner nodes." ; + Mesh2d_face_nodes:start_index = 0 ; + int Mesh2d_face_edges(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_edges:cf_role = "face_edge_connectivity" ; + Mesh2d_face_edges:long_name = "Maps every face to its edges." ; + Mesh2d_face_edges:start_index = 0 ; + Mesh2d_face_edges:_FillValue = -999 ; + int Mesh2d_edge_face_links(nMesh2d_edge, Two) ; + Mesh2d_edge_face_links:cf_role = "edge_face_connectivity" ; + Mesh2d_edge_face_links:long_name = "neighbor faces for edges" ; + Mesh2d_edge_face_links:start_index = 0 ; + Mesh2d_edge_face_links:_FillValue = -999 ; + Mesh2d_edge_face_links:comment = "missing neighbor faces are indicated using _FillValue" ; + int Mesh2d_face_links(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_links:cf_role = "face_face_connectivity" ; + Mesh2d_face_links:long_name = "Indicates which other faces neighbor each face" ; + Mesh2d_face_links:start_index = 0 ; + Mesh2d_face_links:_FillValue = -999 ; + Mesh2d_face_links:flag_values = -1 ; + Mesh2d_face_links:flag_meanings = "out_of_mesh" ; + float vert_axis_half_levels(vert_axis_half_levels) ; + vert_axis_half_levels:name = "vert_axis_half_levels" ; + double time(time) ; + time:axis = "T" ; + time:standard_name = "time" ; + time:long_name = "Time axis" ; + time:calendar = "gregorian" ; + time:units = "seconds since 2024-01-01 15:01:00" ; + time:time_origin = "2024-01-01 15:01:00" ; + time:bounds = "time_bounds" ; + time:coordinates = " forecast_reference_time forecast_period" ; + double time_bounds(time, axis_nbounds) ; + time_bounds:coordinates = " forecast_reference_time forecast_period" ; + double temporal_field(time, vert_axis_half_levels, nMesh2d_face) ; + temporal_field:mesh = "Mesh2d" ; + temporal_field:location = "face" ; + temporal_field:online_operation = "instant" ; + temporal_field:interval_operation = "60 s" ; + temporal_field:interval_write = "60 s" ; + temporal_field:cell_methods = "time: point" ; + temporal_field:coordinates = "Mesh2d_face_y Mesh2d_face_x forecast_reference_time forecast_period" ; + double forecast_reference_time ; + forecast_reference_time:units = "seconds since 2024-01-01 15:01:00" ; + forecast_reference_time:calendar = "gregorian" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + double forecast_period(time) ; + forecast_period:units = "seconds" ; + forecast_period:standard_name = "forecast_period" ; + forecast_period:coordinates = " forecast_reference_time forecast_period" ; + +// global attributes: + :name = "lfric_xios_temporal_output" ; + :title = "Created by xios" ; + :timeStamp = "2026-Apr-29 13:27:11 GMT" ; + :uuid = "227c7dc7-aa21-448d-82b4-4488bb9391dd" ; + :description = "LFRic file format v0.2.0" ; + :Conventions = "UGRID-1.0" ; +data: + + Mesh2d = 2008642325 ; + + Mesh2d_node_x = 0 ; + + Mesh2d_node_y = 0 ; + + Mesh2d_face_x = 0.0001, 0.0002, 0.0001, 0.0003, 0.0001, 0.0003, 0.0002, + 0.0003, 0.0002 ; + + Mesh2d_face_y = 0.0001, 0.0001, 0.0001, 0.0002, 0.0002, 0.0002, 0.0003, + 0.0003, 0.0003 ; + + Mesh2d_face_nodes = + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 ; + + Mesh2d_face_edges = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + Mesh2d_face_links = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + vert_axis_half_levels = 0.5, 1.5, 2.5, 3.5, 4.5 ; + + time = 60, 120, 180, 240, 300, 360, 420, 480, 540, 600 ; + + time_bounds = + 60, 60, + 120, 120, + 180, 180, + 240, 240, + 300, 300, + 360, 360, + 420, 420, + 480, 480, + 540, 540, + 600, 600 ; + + temporal_field = + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206 ; + + forecast_reference_time = 0 ; + + forecast_period = 60, 120, 180, 240, 300, 360, 420, 480, 540, 600 ; +} diff --git a/components/lfric-xios/integration-test/resources/data/non_cyclic_high_freq_iodef_kgo.cdl b/components/lfric-xios/integration-test/resources/data/non_cyclic_high_freq_iodef_kgo.cdl new file mode 100644 index 000000000..dea77aa0e --- /dev/null +++ b/components/lfric-xios/integration-test/resources/data/non_cyclic_high_freq_iodef_kgo.cdl @@ -0,0 +1,1027 @@ +netcdf lfric_xios_temporal_output { +dimensions: + axis_nbounds = 2 ; + Two = 2 ; + nMesh2d_node = 1 ; + nMesh2d_edge = UNLIMITED ; // (0 currently) + nMesh2d_face = 9 ; + nMesh2d_vertex = 4 ; + vert_axis_half_levels = 5 ; + time = UNLIMITED ; // (60 currently) +variables: + int Mesh2d ; + Mesh2d:cf_role = "mesh_topology" ; + Mesh2d:long_name = "Topology data of 2D unstructured mesh" ; + Mesh2d:topology_dimension = 2 ; + Mesh2d:node_coordinates = "Mesh2d_node_x Mesh2d_node_y" ; + Mesh2d:edge_coordinates = "Mesh2d_edge_x Mesh2d_edge_y" ; + Mesh2d:edge_node_connectivity = "Mesh2d_edge_nodes" ; + Mesh2d:face_edge_connectivity = "Mesh2d_face_edges" ; + Mesh2d:edge_face_connectivity = "Mesh2d_edge_face_links" ; + Mesh2d:face_face_connectivity = "Mesh2d_face_links" ; + Mesh2d:face_coordinates = "Mesh2d_face_x Mesh2d_face_y" ; + Mesh2d:face_node_connectivity = "Mesh2d_face_nodes" ; + Mesh2d:geometry = "planar" ; + float Mesh2d_node_x(nMesh2d_node) ; + Mesh2d_node_x:standard_name = "projection_x_coordinate" ; + Mesh2d_node_x:long_name = "x coordinate of projection" ; + Mesh2d_node_x:units = "m" ; + Mesh2d_node_x:scale_factor = 10000. ; + float Mesh2d_node_y(nMesh2d_node) ; + Mesh2d_node_y:standard_name = "projection_y_coordinate" ; + Mesh2d_node_y:long_name = "y coordinate of projection" ; + Mesh2d_node_y:units = "m" ; + Mesh2d_node_y:scale_factor = 10000. ; + float Mesh2d_edge_x(nMesh2d_edge) ; + Mesh2d_edge_x:standard_name = "projection_x_coordinate" ; + Mesh2d_edge_x:long_name = "x coordinate of projection" ; + Mesh2d_edge_x:units = "m" ; + Mesh2d_edge_x:scale_factor = 10000. ; + float Mesh2d_edge_y(nMesh2d_edge) ; + Mesh2d_edge_y:standard_name = "projection_y_coordinate" ; + Mesh2d_edge_y:long_name = "y coordinate of projection" ; + Mesh2d_edge_y:units = "m" ; + Mesh2d_edge_y:scale_factor = 10000. ; + int Mesh2d_edge_nodes(nMesh2d_edge, Two) ; + Mesh2d_edge_nodes:cf_role = "edge_node_connectivity" ; + Mesh2d_edge_nodes:long_name = "Maps every edge/link to two nodes that it connects." ; + Mesh2d_edge_nodes:start_index = 0 ; + float Mesh2d_face_x(nMesh2d_face) ; + Mesh2d_face_x:standard_name = "projection_x_coordinate" ; + Mesh2d_face_x:long_name = "x coordinate of projection" ; + Mesh2d_face_x:units = "m" ; + Mesh2d_face_x:scale_factor = 10000. ; + float Mesh2d_face_y(nMesh2d_face) ; + Mesh2d_face_y:standard_name = "projection_y_coordinate" ; + Mesh2d_face_y:long_name = "y coordinate of projection" ; + Mesh2d_face_y:units = "m" ; + Mesh2d_face_y:scale_factor = 10000. ; + int Mesh2d_face_nodes(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_nodes:cf_role = "face_node_connectivity" ; + Mesh2d_face_nodes:long_name = "Maps every face to its corner nodes." ; + Mesh2d_face_nodes:start_index = 0 ; + int Mesh2d_face_edges(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_edges:cf_role = "face_edge_connectivity" ; + Mesh2d_face_edges:long_name = "Maps every face to its edges." ; + Mesh2d_face_edges:start_index = 0 ; + Mesh2d_face_edges:_FillValue = -999 ; + int Mesh2d_edge_face_links(nMesh2d_edge, Two) ; + Mesh2d_edge_face_links:cf_role = "edge_face_connectivity" ; + Mesh2d_edge_face_links:long_name = "neighbor faces for edges" ; + Mesh2d_edge_face_links:start_index = 0 ; + Mesh2d_edge_face_links:_FillValue = -999 ; + Mesh2d_edge_face_links:comment = "missing neighbor faces are indicated using _FillValue" ; + int Mesh2d_face_links(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_links:cf_role = "face_face_connectivity" ; + Mesh2d_face_links:long_name = "Indicates which other faces neighbor each face" ; + Mesh2d_face_links:start_index = 0 ; + Mesh2d_face_links:_FillValue = -999 ; + Mesh2d_face_links:flag_values = -1 ; + Mesh2d_face_links:flag_meanings = "out_of_mesh" ; + float vert_axis_half_levels(vert_axis_half_levels) ; + vert_axis_half_levels:name = "vert_axis_half_levels" ; + double time(time) ; + time:axis = "T" ; + time:standard_name = "time" ; + time:long_name = "Time axis" ; + time:calendar = "gregorian" ; + time:units = "seconds since 2024-01-01 15:01:00" ; + time:time_origin = "2024-01-01 15:01:00" ; + time:bounds = "time_bounds" ; + time:coordinates = " forecast_reference_time forecast_period" ; + double time_bounds(time, axis_nbounds) ; + time_bounds:coordinates = " forecast_reference_time forecast_period" ; + double temporal_field(time, vert_axis_half_levels, nMesh2d_face) ; + temporal_field:mesh = "Mesh2d" ; + temporal_field:location = "face" ; + temporal_field:online_operation = "instant" ; + temporal_field:interval_operation = "10 s" ; + temporal_field:interval_write = "10 s" ; + temporal_field:cell_methods = "time: point" ; + temporal_field:coordinates = "Mesh2d_face_y Mesh2d_face_x forecast_reference_time forecast_period" ; + double forecast_reference_time ; + forecast_reference_time:units = "seconds since 2024-01-01 15:01:00" ; + forecast_reference_time:calendar = "gregorian" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + double forecast_period(time) ; + forecast_period:units = "seconds" ; + forecast_period:standard_name = "forecast_period" ; + forecast_period:coordinates = " forecast_reference_time forecast_period" ; + +// global attributes: + :name = "lfric_xios_temporal_output" ; + :title = "Created by xios" ; + :timeStamp = "2026-Apr-29 13:48:05 GMT" ; + :uuid = "7d9ac37d-bf87-4026-9fd7-d0770e13c65d" ; + :description = "LFRic file format v0.2.0" ; + :Conventions = "UGRID-1.0" ; +data: + + Mesh2d = 1541922795 ; + + Mesh2d_node_x = 0 ; + + Mesh2d_node_y = 0 ; + + Mesh2d_face_x = 0.0001, 0.0002, 0.0001, 0.0003, 0.0001, 0.0003, 0.0002, + 0.0003, 0.0002 ; + + Mesh2d_face_y = 0.0001, 0.0001, 0.0001, 0.0002, 0.0002, 0.0002, 0.0003, + 0.0003, 0.0003 ; + + Mesh2d_face_nodes = + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 ; + + Mesh2d_face_edges = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + Mesh2d_face_links = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + vert_axis_half_levels = 0.5, 1.5, 2.5, 3.5, 4.5 ; + + time = 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, + 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, + 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, + 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, + 580, 590, 600 ; + + time_bounds = + 10, 10, + 20, 20, + 30, 30, + 40, 40, + 50, 50, + 60, 60, + 70, 70, + 80, 80, + 90, 90, + 100, 100, + 110, 110, + 120, 120, + 130, 130, + 140, 140, + 150, 150, + 160, 160, + 170, 170, + 180, 180, + 190, 190, + 200, 200, + 210, 210, + 220, 220, + 230, 230, + 240, 240, + 250, 250, + 260, 260, + 270, 270, + 280, 280, + 290, 290, + 300, 300, + 310, 310, + 320, 320, + 330, 330, + 340, 340, + 350, 350, + 360, 360, + 370, 370, + 380, 380, + 390, 390, + 400, 400, + 410, 410, + 420, 420, + 430, 430, + 440, 440, + 450, 450, + 460, 460, + 470, 470, + 480, 480, + 490, 490, + 500, 500, + 510, 510, + 520, 520, + 530, 530, + 540, 540, + 550, 550, + 560, 560, + 570, 570, + 580, 580, + 590, 590, + 600, 600 ; + + temporal_field = + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206 ; + + forecast_reference_time = 0 ; + + forecast_period = 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, + 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, + 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, + 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, + 560, 570, 580, 590, 600 ; +} diff --git a/components/lfric-xios/integration-test/resources/data/non_cyclic_high_freq_kgo.cdl b/components/lfric-xios/integration-test/resources/data/non_cyclic_high_freq_kgo.cdl new file mode 100644 index 000000000..9a1cb7b3b --- /dev/null +++ b/components/lfric-xios/integration-test/resources/data/non_cyclic_high_freq_kgo.cdl @@ -0,0 +1,286 @@ +netcdf lfric_xios_temporal_output { +dimensions: + axis_nbounds = 2 ; + Two = 2 ; + nMesh2d_node = 1 ; + nMesh2d_edge = UNLIMITED ; // (0 currently) + nMesh2d_face = 9 ; + nMesh2d_vertex = 4 ; + vert_axis_half_levels = 5 ; + time = UNLIMITED ; // (10 currently) +variables: + int Mesh2d ; + Mesh2d:cf_role = "mesh_topology" ; + Mesh2d:long_name = "Topology data of 2D unstructured mesh" ; + Mesh2d:topology_dimension = 2 ; + Mesh2d:node_coordinates = "Mesh2d_node_x Mesh2d_node_y" ; + Mesh2d:edge_coordinates = "Mesh2d_edge_x Mesh2d_edge_y" ; + Mesh2d:edge_node_connectivity = "Mesh2d_edge_nodes" ; + Mesh2d:face_edge_connectivity = "Mesh2d_face_edges" ; + Mesh2d:edge_face_connectivity = "Mesh2d_edge_face_links" ; + Mesh2d:face_face_connectivity = "Mesh2d_face_links" ; + Mesh2d:face_coordinates = "Mesh2d_face_x Mesh2d_face_y" ; + Mesh2d:face_node_connectivity = "Mesh2d_face_nodes" ; + Mesh2d:geometry = "planar" ; + float Mesh2d_node_x(nMesh2d_node) ; + Mesh2d_node_x:standard_name = "projection_x_coordinate" ; + Mesh2d_node_x:long_name = "x coordinate of projection" ; + Mesh2d_node_x:units = "m" ; + Mesh2d_node_x:scale_factor = 10000. ; + float Mesh2d_node_y(nMesh2d_node) ; + Mesh2d_node_y:standard_name = "projection_y_coordinate" ; + Mesh2d_node_y:long_name = "y coordinate of projection" ; + Mesh2d_node_y:units = "m" ; + Mesh2d_node_y:scale_factor = 10000. ; + float Mesh2d_edge_x(nMesh2d_edge) ; + Mesh2d_edge_x:standard_name = "projection_x_coordinate" ; + Mesh2d_edge_x:long_name = "x coordinate of projection" ; + Mesh2d_edge_x:units = "m" ; + Mesh2d_edge_x:scale_factor = 10000. ; + float Mesh2d_edge_y(nMesh2d_edge) ; + Mesh2d_edge_y:standard_name = "projection_y_coordinate" ; + Mesh2d_edge_y:long_name = "y coordinate of projection" ; + Mesh2d_edge_y:units = "m" ; + Mesh2d_edge_y:scale_factor = 10000. ; + int Mesh2d_edge_nodes(nMesh2d_edge, Two) ; + Mesh2d_edge_nodes:cf_role = "edge_node_connectivity" ; + Mesh2d_edge_nodes:long_name = "Maps every edge/link to two nodes that it connects." ; + Mesh2d_edge_nodes:start_index = 0 ; + float Mesh2d_face_x(nMesh2d_face) ; + Mesh2d_face_x:standard_name = "projection_x_coordinate" ; + Mesh2d_face_x:long_name = "x coordinate of projection" ; + Mesh2d_face_x:units = "m" ; + Mesh2d_face_x:scale_factor = 10000. ; + float Mesh2d_face_y(nMesh2d_face) ; + Mesh2d_face_y:standard_name = "projection_y_coordinate" ; + Mesh2d_face_y:long_name = "y coordinate of projection" ; + Mesh2d_face_y:units = "m" ; + Mesh2d_face_y:scale_factor = 10000. ; + int Mesh2d_face_nodes(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_nodes:cf_role = "face_node_connectivity" ; + Mesh2d_face_nodes:long_name = "Maps every face to its corner nodes." ; + Mesh2d_face_nodes:start_index = 0 ; + int Mesh2d_face_edges(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_edges:cf_role = "face_edge_connectivity" ; + Mesh2d_face_edges:long_name = "Maps every face to its edges." ; + Mesh2d_face_edges:start_index = 0 ; + Mesh2d_face_edges:_FillValue = -999 ; + int Mesh2d_edge_face_links(nMesh2d_edge, Two) ; + Mesh2d_edge_face_links:cf_role = "edge_face_connectivity" ; + Mesh2d_edge_face_links:long_name = "neighbor faces for edges" ; + Mesh2d_edge_face_links:start_index = 0 ; + Mesh2d_edge_face_links:_FillValue = -999 ; + Mesh2d_edge_face_links:comment = "missing neighbor faces are indicated using _FillValue" ; + int Mesh2d_face_links(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_links:cf_role = "face_face_connectivity" ; + Mesh2d_face_links:long_name = "Indicates which other faces neighbor each face" ; + Mesh2d_face_links:start_index = 0 ; + Mesh2d_face_links:_FillValue = -999 ; + Mesh2d_face_links:flag_values = -1 ; + Mesh2d_face_links:flag_meanings = "out_of_mesh" ; + float vert_axis_half_levels(vert_axis_half_levels) ; + vert_axis_half_levels:name = "vert_axis_half_levels" ; + double time(time) ; + time:axis = "T" ; + time:standard_name = "time" ; + time:long_name = "Time axis" ; + time:calendar = "gregorian" ; + time:units = "seconds since 2024-01-01 15:01:00" ; + time:time_origin = "2024-01-01 15:01:00" ; + time:bounds = "time_bounds" ; + time:coordinates = " forecast_reference_time forecast_period" ; + double time_bounds(time, axis_nbounds) ; + time_bounds:coordinates = " forecast_reference_time forecast_period" ; + double temporal_field(time, vert_axis_half_levels, nMesh2d_face) ; + temporal_field:mesh = "Mesh2d" ; + temporal_field:location = "face" ; + temporal_field:online_operation = "instant" ; + temporal_field:interval_operation = "10 s" ; + temporal_field:interval_write = "10 s" ; + temporal_field:cell_methods = "time: point" ; + temporal_field:coordinates = "Mesh2d_face_y Mesh2d_face_x forecast_reference_time forecast_period" ; + double forecast_reference_time ; + forecast_reference_time:units = "seconds since 2024-01-01 15:01:00" ; + forecast_reference_time:calendar = "gregorian" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + double forecast_period(time) ; + forecast_period:units = "seconds" ; + forecast_period:standard_name = "forecast_period" ; + forecast_period:coordinates = " forecast_reference_time forecast_period" ; + +// global attributes: + :name = "lfric_xios_temporal_output" ; + :title = "Created by xios" ; + :timeStamp = "2026-Apr-29 13:35:41 GMT" ; + :uuid = "e0ff7ab1-ebe6-4c80-8152-4f60fe56ce4d" ; + :description = "LFRic file format v0.2.0" ; + :Conventions = "UGRID-1.0" ; +data: + + Mesh2d = 1535512574 ; + + Mesh2d_node_x = 0 ; + + Mesh2d_node_y = 0 ; + + Mesh2d_face_x = 0.0001, 0.0002, 0.0001, 0.0003, 0.0001, 0.0003, 0.0002, + 0.0003, 0.0002 ; + + Mesh2d_face_y = 0.0001, 0.0001, 0.0001, 0.0002, 0.0002, 0.0002, 0.0003, + 0.0003, 0.0003 ; + + Mesh2d_face_nodes = + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 ; + + Mesh2d_face_edges = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + Mesh2d_face_links = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + vert_axis_half_levels = 0.5, 1.5, 2.5, 3.5, 4.5 ; + + time = 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ; + + time_bounds = + 10, 10, + 20, 20, + 30, 30, + 40, 40, + 50, 50, + 60, 60, + 70, 70, + 80, 80, + 90, 90, + 100, 100 ; + + temporal_field = + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667 ; + + forecast_reference_time = 0 ; + + forecast_period = 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ; +} diff --git a/components/lfric-xios/integration-test/resources/data/non_cyclic_partial_kgo.cdl b/components/lfric-xios/integration-test/resources/data/non_cyclic_partial_kgo.cdl new file mode 100644 index 000000000..338b9acc2 --- /dev/null +++ b/components/lfric-xios/integration-test/resources/data/non_cyclic_partial_kgo.cdl @@ -0,0 +1,324 @@ +netcdf lfric_xios_temporal_output { +dimensions: + axis_nbounds = 2 ; + Two = 2 ; + nMesh2d_node = 1 ; + nMesh2d_edge = UNLIMITED ; // (0 currently) + nMesh2d_face = 9 ; + nMesh2d_vertex = 4 ; + vert_axis_half_levels = 5 ; + time = UNLIMITED ; // (10 currently) +variables: + int Mesh2d ; + Mesh2d:cf_role = "mesh_topology" ; + Mesh2d:long_name = "Topology data of 2D unstructured mesh" ; + Mesh2d:topology_dimension = 2 ; + Mesh2d:node_coordinates = "Mesh2d_node_x Mesh2d_node_y" ; + Mesh2d:edge_coordinates = "Mesh2d_edge_x Mesh2d_edge_y" ; + Mesh2d:edge_node_connectivity = "Mesh2d_edge_nodes" ; + Mesh2d:face_edge_connectivity = "Mesh2d_face_edges" ; + Mesh2d:edge_face_connectivity = "Mesh2d_edge_face_links" ; + Mesh2d:face_face_connectivity = "Mesh2d_face_links" ; + Mesh2d:face_coordinates = "Mesh2d_face_x Mesh2d_face_y" ; + Mesh2d:face_node_connectivity = "Mesh2d_face_nodes" ; + Mesh2d:geometry = "planar" ; + float Mesh2d_node_x(nMesh2d_node) ; + Mesh2d_node_x:standard_name = "projection_x_coordinate" ; + Mesh2d_node_x:long_name = "x coordinate of projection" ; + Mesh2d_node_x:units = "m" ; + Mesh2d_node_x:scale_factor = 10000. ; + float Mesh2d_node_y(nMesh2d_node) ; + Mesh2d_node_y:standard_name = "projection_y_coordinate" ; + Mesh2d_node_y:long_name = "y coordinate of projection" ; + Mesh2d_node_y:units = "m" ; + Mesh2d_node_y:scale_factor = 10000. ; + float Mesh2d_edge_x(nMesh2d_edge) ; + Mesh2d_edge_x:standard_name = "projection_x_coordinate" ; + Mesh2d_edge_x:long_name = "x coordinate of projection" ; + Mesh2d_edge_x:units = "m" ; + Mesh2d_edge_x:scale_factor = 10000. ; + float Mesh2d_edge_y(nMesh2d_edge) ; + Mesh2d_edge_y:standard_name = "projection_y_coordinate" ; + Mesh2d_edge_y:long_name = "y coordinate of projection" ; + Mesh2d_edge_y:units = "m" ; + Mesh2d_edge_y:scale_factor = 10000. ; + int Mesh2d_edge_nodes(nMesh2d_edge, Two) ; + Mesh2d_edge_nodes:cf_role = "edge_node_connectivity" ; + Mesh2d_edge_nodes:long_name = "Maps every edge/link to two nodes that it connects." ; + Mesh2d_edge_nodes:start_index = 0 ; + float Mesh2d_face_x(nMesh2d_face) ; + Mesh2d_face_x:standard_name = "projection_x_coordinate" ; + Mesh2d_face_x:long_name = "x coordinate of projection" ; + Mesh2d_face_x:units = "m" ; + Mesh2d_face_x:scale_factor = 10000. ; + float Mesh2d_face_y(nMesh2d_face) ; + Mesh2d_face_y:standard_name = "projection_y_coordinate" ; + Mesh2d_face_y:long_name = "y coordinate of projection" ; + Mesh2d_face_y:units = "m" ; + Mesh2d_face_y:scale_factor = 10000. ; + int Mesh2d_face_nodes(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_nodes:cf_role = "face_node_connectivity" ; + Mesh2d_face_nodes:long_name = "Maps every face to its corner nodes." ; + Mesh2d_face_nodes:start_index = 0 ; + int Mesh2d_face_edges(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_edges:cf_role = "face_edge_connectivity" ; + Mesh2d_face_edges:long_name = "Maps every face to its edges." ; + Mesh2d_face_edges:start_index = 0 ; + Mesh2d_face_edges:_FillValue = -999 ; + int Mesh2d_edge_face_links(nMesh2d_edge, Two) ; + Mesh2d_edge_face_links:cf_role = "edge_face_connectivity" ; + Mesh2d_edge_face_links:long_name = "neighbor faces for edges" ; + Mesh2d_edge_face_links:start_index = 0 ; + Mesh2d_edge_face_links:_FillValue = -999 ; + Mesh2d_edge_face_links:comment = "missing neighbor faces are indicated using _FillValue" ; + int Mesh2d_face_links(nMesh2d_face, nMesh2d_vertex) ; + Mesh2d_face_links:cf_role = "face_face_connectivity" ; + Mesh2d_face_links:long_name = "Indicates which other faces neighbor each face" ; + Mesh2d_face_links:start_index = 0 ; + Mesh2d_face_links:_FillValue = -999 ; + Mesh2d_face_links:flag_values = -1 ; + Mesh2d_face_links:flag_meanings = "out_of_mesh" ; + float vert_axis_half_levels(vert_axis_half_levels) ; + vert_axis_half_levels:name = "vert_axis_half_levels" ; + double time(time) ; + time:axis = "T" ; + time:standard_name = "time" ; + time:long_name = "Time axis" ; + time:calendar = "gregorian" ; + time:units = "seconds since 2024-01-01 15:01:00" ; + time:time_origin = "2024-01-01 15:01:00" ; + time:bounds = "time_bounds" ; + time:coordinates = " forecast_reference_time forecast_period" ; + double time_bounds(time, axis_nbounds) ; + time_bounds:coordinates = " forecast_reference_time forecast_period" ; + double temporal_field(time, vert_axis_half_levels, nMesh2d_face) ; + temporal_field:mesh = "Mesh2d" ; + temporal_field:location = "face" ; + temporal_field:online_operation = "instant" ; + temporal_field:interval_operation = "60 s" ; + temporal_field:interval_write = "60 s" ; + temporal_field:cell_methods = "time: point" ; + temporal_field:coordinates = "Mesh2d_face_y Mesh2d_face_x forecast_reference_time forecast_period" ; + double forecast_reference_time ; + forecast_reference_time:units = "seconds since 2024-01-01 15:01:00" ; + forecast_reference_time:calendar = "gregorian" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + double forecast_period(time) ; + forecast_period:units = "seconds" ; + forecast_period:standard_name = "forecast_period" ; + forecast_period:coordinates = " forecast_reference_time forecast_period" ; + +// global attributes: + :name = "lfric_xios_temporal_output" ; + :title = "Created by xios" ; + :timeStamp = "2026-Apr-29 13:39:47 GMT" ; + :uuid = "2e08d90a-5aa5-4639-b638-78f75561a196" ; + :description = "LFRic file format v0.2.0" ; + :Conventions = "UGRID-1.0" ; +data: + + Mesh2d = 1758356094 ; + + Mesh2d_node_x = 0 ; + + Mesh2d_node_y = 0 ; + + Mesh2d_face_x = 0.0001, 0.0002, 0.0001, 0.0003, 0.0001, 0.0003, 0.0002, + 0.0003, 0.0002 ; + + Mesh2d_face_y = 0.0001, 0.0001, 0.0001, 0.0002, 0.0002, 0.0002, 0.0003, + 0.0003, 0.0003 ; + + Mesh2d_face_nodes = + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 ; + + Mesh2d_face_edges = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + Mesh2d_face_links = + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _, + _, _, _, _ ; + + vert_axis_half_levels = 0.5, 1.5, 2.5, 3.5, 4.5 ; + + time = 60, 120, 180, 240, 300, 360, 420, 480, 540, 600 ; + + time_bounds = + 60, 60, + 120, 120, + 180, 180, + 240, 240, + 300, 300, + 360, 360, + 420, 420, + 480, 480, + 540, 540, + 600, 600 ; + + temporal_field = + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, 6.66666666666667, 6.66666666666667, 6.66666666666667, + 6.66666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, 26.6666666666667, 26.6666666666667, 26.6666666666667, + 26.6666666666667, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, 5.33333333333333, 5.33333333333333, 5.33333333333333, + 5.33333333333333, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, 4.57142857142857, 4.57142857142857, 4.57142857142857, + 4.57142857142857, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, 36.5714285714286, 36.5714285714286, 36.5714285714286, + 36.5714285714286, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, 4.06349206349206, 4.06349206349206, 4.06349206349206, + 4.06349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, 0, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206, 40.6349206349206, 40.6349206349206, 40.6349206349206, + 40.6349206349206 ; + + forecast_reference_time = 0 ; + + forecast_period = 60, 120, 180, 240, 300, 360, 420, 480, 540, 600 ; +} diff --git a/components/lfric-xios/integration-test/tools/plot_output.py b/components/lfric-xios/integration-test/tools/plot_output.py index 3ffbd580c..76873673b 100644 --- a/components/lfric-xios/integration-test/tools/plot_output.py +++ b/components/lfric-xios/integration-test/tools/plot_output.py @@ -1,10 +1,9 @@ from pathlib import Path import matplotlib +import xarray as xr matplotlib.use('Agg') import matplotlib.pyplot as plt # noqa: E402 -# REMOVE XARRAY -import xarray as xr # noqa: E402 def _get_ts_data(file_path, field_id): """ @@ -37,4 +36,4 @@ def plot_test_output(in_file: Path, out_file: Path, varname: str, plot_file_path plt.legend(frameon=False) plt.savefig(f"{plot_file_path}", bbox_inches="tight") - plt.close() \ No newline at end of file + plt.close() From 4dcdeb3a27c3ee4b79b43f58c477a5593b3a9e0a Mon Sep 17 00:00:00 2001 From: EdHone Date: Fri, 1 May 2026 10:20:44 +0100 Subject: [PATCH 3/7] get complete pylint acceptance for all python files in integration testing --- .../lfric_xios_context_test.py | 8 +- .../lfric_xios_cyclic_temporal_test.py | 24 +++-- .../lfric_xios_temporal_iodef_test.py | 90 +++++++++++-------- .../lfric_xios_temporal_test.py | 42 ++++----- .../lfric_xios_time_read_test.py | 17 ++-- .../integration-test/tools/plot_output.py | 15 +++- 6 files changed, 111 insertions(+), 85 deletions(-) diff --git a/components/lfric-xios/integration-test/lfric_xios_context_test.py b/components/lfric-xios/integration-test/lfric_xios_context_test.py index a7424d577..bf14ec84b 100755 --- a/components/lfric-xios/integration-test/lfric_xios_context_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_context_test.py @@ -9,12 +9,12 @@ then destroys it. This will also create an attached XIOS context. """ -from testframework import TestEngine, TestFailed -from xiostest import LFRicXiosTest import sys +from testframework import TestEngine, TestFailed # pylint: disable=import-error +from xiostest import LFRicXiosTest # pylint: disable=import-error ############################################################################### -class LfricXiosContextTest(LFRicXiosTest): +class LfricXiosContextTest(LFRicXiosTest): # pylint: disable=R0903 """ Tests the lfric_xios_context_type by creating and destroying it """ @@ -23,7 +23,7 @@ def __init__(self): super().__init__(command=[sys.argv[1], "context.nml"], processes=1) self.gen_config( "context.nml", "context.nml", {} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ diff --git a/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py b/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py index bcdcd67ed..8a2ce5dd8 100755 --- a/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_cyclic_temporal_test.py @@ -8,10 +8,11 @@ A set of tests which exercise the temporal reading functionality provided by the LFRic-XIOS component. """ -from testframework import TestEngine, TestFailed -from xiostest import LFRicXiosTest from pathlib import Path import sys +from testframework import TestEngine, TestFailed # pylint: disable=import-error +from xiostest import LFRicXiosTest # pylint: disable=import-error + ############################################################################### class LfricXiosFullCyclicTest(LFRicXiosTest): # pylint: disable=too-few-public-methods @@ -33,8 +34,7 @@ def test(self, returncode: int, out: str, err: str): if returncode != 0: print(out) raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") + f"stderr:\n {err}") self.plot_output(Path(self.test_working_dir, 'lfric_xios_cyclic_input.nc'), Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), @@ -58,7 +58,7 @@ def __init__(self): self.gen_config( 'cyclic_base.nml', 'cyclic_future.nml', {"calendar_start":'2024-01-01 14:55:00'} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the future cyclic test """ @@ -96,8 +96,7 @@ def test(self, returncode: int, out: str, err: str): if returncode != 0: print(out) raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") + f"stderr:\n {err}") if not self.nc_kgo_check( Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), Path(self.test_working_dir, 'cyclic_past_kgo.nc')): @@ -128,8 +127,7 @@ def test(self, returncode: int, out: str, err: str): if returncode != 0: print(out) raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") + f"stderr:\n {err}") self.plot_output(Path(self.test_working_dir, 'lfric_xios_cyclic_input.nc'), Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), @@ -144,7 +142,8 @@ def test(self, returncode: int, out: str, err: str): class LfricXiosCyclicNonSyncTest(LFRicXiosTest): # pylint: disable=too-few-public-methods """ - Tests the LFRic-XIOS temporal reading functionality when model timesteps do not match data timesteps + Tests the LFRic-XIOS temporal reading functionality when model timesteps + do not match data timesteps """ def __init__(self): @@ -164,8 +163,7 @@ def test(self, returncode: int, out: str, err: str): if returncode != 0: print(out) raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") + f"stderr:\n {err}") self.plot_output(Path(self.test_working_dir, 'lfric_xios_cyclic_input.nc'), Path(self.test_working_dir, 'lfric_xios_cyclic_output.nc'), @@ -185,4 +183,4 @@ def test(self, returncode: int, out: str, err: str): TestEngine.run(LfricXiosFutureCyclicTest()) TestEngine.run(LfricXiosPastCyclicTest()) TestEngine.run(LfricXiosCyclicHighFreqTest()) - TestEngine.run(LfricXiosCyclicNonSyncTest()) \ No newline at end of file + TestEngine.run(LfricXiosCyclicNonSyncTest()) diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py b/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py index ca4143b03..7b05f2f06 100755 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py @@ -12,102 +12,118 @@ points ranging from 15:01 to 15:10 in 10 1-minute intervals. The model start time is changed to change how the model interacts with the data. """ -from testframework import TestEngine, TestFailed -from xiostest import LFRicXiosTest from pathlib import Path import sys +from testframework import TestEngine, TestFailed # pylint: disable=import-error +from xiostest import LFRicXiosTest # pylint: disable=import-error + ############################################################################### -class LfricXiosFullNonCyclicIodefTest(LFRicXiosTest): # pylint: disable=too-few-public-methods +class LfricXiosFullNonCyclicIodefTest(LFRicXiosTest): # pylint: disable=too-few-public-methods """ - Tests the LFRic-XIOS temporal reading functionality for a full set of non-cyclic data + Tests the LFRic-XIOS temporal reading functionality for a full set of + non-cyclic data """ def __init__(self): - super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], processes=1, iodef_file="iodef_temporal.xml") + super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], + processes=1, iodef_file="iodef_temporal.xml") self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') self.gen_data('non_cyclic_full_kgo.cdl', 'non_cyclic_full_kgo.nc') self.gen_config( "non_cyclic_base.nml", "non_cyclic_full.nml", {} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ if returncode != 0: print(out) - raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") - if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - Path(self.test_working_dir, 'non_cyclic_full_kgo.nc')): - raise TestFailed("Output data does not match input data for same time values") + raise TestFailed( + f"Unexpected failure of test executable: {returncode}\n" + + f"stderr:\n {err}") + if not self.nc_kgo_check( + Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), + Path(self.test_working_dir, 'non_cyclic_full_kgo.nc')): + raise TestFailed("Output data does not match input data for same " \ + "time values") return "Reading full set of non-cylic data okay..." -class LfricXiosFullNonCyclicIodefHighFreqTest(LFRicXiosTest): # pylint: disable=too-few-public-methods +class LfricXiosFullNonCyclicIodefHighFreqTest(LFRicXiosTest): # pylint: disable=too-few-public-methods """ Tests the LFRic-XIOS temporal reading functionality for a full set of non-cyclic data at higher model frequency """ def __init__(self): - super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], processes=1, iodef_file="iodef_temporal.xml") + super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], + processes=1, iodef_file="iodef_temporal.xml") self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') - self.gen_data('non_cyclic_high_freq_iodef_kgo.cdl', 'non_cyclic_high_freq_kgo.nc') - self.gen_config( "non_cyclic_base.nml", "non_cyclic_full.nml", {"dt": 10.0, + self.gen_data('non_cyclic_high_freq_iodef_kgo.cdl', + 'non_cyclic_high_freq_kgo.nc') + self.gen_config( "non_cyclic_base.nml", "non_cyclic_full.nml", + {"dt": 10.0, "timestep_end": '60'} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ if returncode != 0: print(out) - raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") - if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - Path(self.test_working_dir, 'non_cyclic_high_freq_kgo.nc')): - raise TestFailed("Output data does not match input data for same time values") + raise TestFailed( + f"Unexpected failure of test executable: {returncode}\n" + + f"stderr:\n {err}") + if not self.nc_kgo_check( + Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), + Path(self.test_working_dir, 'non_cyclic_high_freq_kgo.nc')): + raise TestFailed("Output data does not match input data for same " \ + "time values") return "Reading full set of non-cylic data okay..." -class LfricXiosFullNonCyclicIodefNoFreqTest(LFRicXiosTest): # pylint: disable=too-few-public-methods +class LfricXiosFullNonCyclicIodefNoFreqTest(LFRicXiosTest): # pylint: disable=too-few-public-methods """ - Tests the error handling for the case where there is no frequency set in either - the iodef or the fortran configuration. + Tests the error handling for the case where there is no frequency set in + either the iodef or the fortran configuration. """ def __init__(self): - super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], processes=1) + super().__init__(command=[sys.argv[1], "non_cyclic_full.nml"], + processes=1) self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') self.gen_config( "non_cyclic_base.nml", "non_cyclic_full.nml", {} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ - expected_xios_errs = ['In file "type_impl.hpp", function "void xios::CType::_checkEmpty() const [with T = xios::CDuration]", line 210 -> Data is not initialized', - 'In file "type_impl.hpp", function "void xios::CType::_checkEmpty() const [T = xios::CDuration]", line 210 -> Data is not initialized'] + expected_xios_errs = ['In file "type_impl.hpp", function "void xios::CType::_checkEmpty() const [with T = xios::CDuration]", line 210 -> Data is not initialized', # pylint: disable=C0301 + 'In file "type_impl.hpp", function "void xios::CType::_checkEmpty() const [T = xios::CDuration]", line 210 -> Data is not initialized'] # pylint: disable=C0301 if returncode == 134: if self.xios_err[0].contents.strip() in expected_xios_errs: - return "Expected failure of test executable due to missing frequency setting." - else: - raise TestFailed("Test executable failed, but with unexpected error message.") - elif returncode == 0: - raise TestFailed("Test executable succeeded unexpectedly despite missing frequency setting.") + return "Expected failure of test executable due to missing " \ + "frequency setting." + + if returncode == 0: + test_output_msg = "Test executable succeeded unexpectedly " \ + "despite missing frequency setting." else: - raise TestFailed("Test executable failed with unexpected return code.") + test_output_msg = "Test executable failed with unexpected return " \ + "code." + + raise TestFailed(test_output_msg) + ############################################################################## if __name__ == "__main__": TestEngine.run(LfricXiosFullNonCyclicIodefTest()) TestEngine.run(LfricXiosFullNonCyclicIodefHighFreqTest()) - TestEngine.run(LfricXiosFullNonCyclicIodefNoFreqTest()) \ No newline at end of file + TestEngine.run(LfricXiosFullNonCyclicIodefNoFreqTest()) diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py index dd1945bd7..366a45ecd 100755 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py @@ -11,10 +11,11 @@ points ranging from 15:01 to 15:10 in 10 1-minute intervals. The model start time is changed to change how the model interacts with the data. """ -from testframework import TestEngine, TestFailed -from xiostest import LFRicXiosTest from pathlib import Path import sys +from testframework import TestEngine, TestFailed # pylint: disable=import-error +from xiostest import LFRicXiosTest # pylint: disable=import-error + ############################################################################### class LfricXiosFullNonCyclicTest(LFRicXiosTest): # pylint: disable=too-few-public-methods @@ -36,8 +37,7 @@ def test(self, returncode: int, out: str, err: str): if returncode != 0: print(out) raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") + f"stderr:\n {err}") self.plot_output(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), @@ -70,8 +70,7 @@ def test(self, returncode: int, out: str, err: str): if returncode != 0: print(out) raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") + f"stderr:\n {err}") if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), Path(self.test_working_dir, 'non_cyclic_high_freq_kgo.nc')): raise TestFailed("Output data does not match input data for same time values") @@ -94,7 +93,7 @@ def __init__(self): "calendar_start":"2024-01-01 15:03:20", "timestep_end":"30"} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ @@ -102,8 +101,7 @@ def test(self, returncode: int, out: str, err: str): if returncode != 0: print(out) raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") + f"stderr:\n {err}") self.plot_output(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), 'temporal_field') @@ -125,17 +123,17 @@ def __init__(self): super().__init__(command=[sys.argv[1], "non_cyclic_mid.nml"], processes=1) self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') self.gen_data('non_cyclic_partial_kgo.cdl', 'non_cyclic_partial_kgo.nc') - self.gen_config( "non_cyclic_base.nml", "non_cyclic_mid.nml", {'calendar_start':'2024-01-01 15:01:00'} ) + self.gen_config( "non_cyclic_base.nml", "non_cyclic_mid.nml", + {'calendar_start':'2024-01-01 15:01:00'} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ if returncode != 0: raise TestFailed(f"Unexpected failure of test executable: {returncode}\n" + - f"stderr:\n" + - f"{err}") + f"stderr:\n {err}") if not self.nc_kgo_check(Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), Path(self.test_working_dir, 'non_cyclic_partial_kgo.nc')): @@ -152,15 +150,17 @@ class LfricXiosNonCyclicFutureTest(LFRicXiosTest): # pylint: disable=too-few-pu def __init__(self): super().__init__(command=[sys.argv[1], "non_cyclic_future.nml"], processes=1) self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') - self.gen_config( "non_cyclic_base.nml", "non_cyclic_future.nml", {'calendar_start':'2024-01-01 10:00:00', + self.gen_config( "non_cyclic_base.nml", "non_cyclic_future.nml", + {'calendar_start':'2024-01-01 10:00:00', 'calendar_origin':'2024-01-01 10:00:00'} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ - expected_error_code = "ERROR: Context must start within data time window for non-cyclic temporal data" + expected_error_code = "ERROR: Context must start within data time window for" \ + "non-cyclic temporal data" if returncode == 1: errorcode = err.split("\n")[0].split("0:")[1] @@ -181,15 +181,17 @@ class LfricXiosNonCyclicPastTest(LFRicXiosTest): # pylint: disable=too-few-publ def __init__(self): super().__init__(command=[sys.argv[1], "non_cyclic_past.nml"], processes=1) self.gen_data('temporal_data.cdl', 'lfric_xios_temporal_input.nc') - self.gen_config( "non_cyclic_base.nml", "non_cyclic_past.nml", {'calendar_start':'2024-02-01 10:00:00', + self.gen_config( "non_cyclic_base.nml", "non_cyclic_past.nml", + {'calendar_start':'2024-02-01 10:00:00', 'calendar_origin':'2024-02-01 10:00:00'} ) - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ - expected_error_code = "ERROR: Context must start within data time window for non-cyclic temporal data" + expected_error_code = "ERROR: Context must start within data time window for" \ + "non-cyclic temporal data" if returncode == 1: errorcode = err.split("\n")[0].split("0:")[1] @@ -209,4 +211,4 @@ def test(self, returncode: int, out: str, err: str): TestEngine.run(LfricXiosNonCyclicNonSyncTest()) TestEngine.run(LfricXiosPartialNonCyclicTest()) TestEngine.run(LfricXiosNonCyclicFutureTest()) - TestEngine.run(LfricXiosNonCyclicPastTest()) \ No newline at end of file + TestEngine.run(LfricXiosNonCyclicPastTest()) diff --git a/components/lfric-xios/integration-test/lfric_xios_time_read_test.py b/components/lfric-xios/integration-test/lfric_xios_time_read_test.py index a20a90b73..dc42da74c 100755 --- a/components/lfric-xios/integration-test/lfric_xios_time_read_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_time_read_test.py @@ -8,10 +8,9 @@ Simple test which initialises a minimal `lfric_xios_context_type` object and then destroys it. This will also create an attached XIOS context. """ -from testframework import TestEngine, TestFailed -from xiostest import LFRicXiosTest import sys -from pathlib import Path +from testframework import TestEngine, TestFailed # pylint: disable=import-error +from xiostest import LFRicXiosTest # pylint: disable=import-error ############################################################################### @@ -26,18 +25,18 @@ def __init__(self, nprocs: int): self.gen_config( "context.nml", "context.nml", {} ) self.nprocs = nprocs - def test(self, returncode: int, out: str, err: str): + def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-argument """ Test the output of the context test """ if returncode == 1: raise TestFailed("Unexpected failure of test executable") - else: - s_or_no_s = "" - if self.nprocs > 1: - s_or_no_s = "s" - return f"Successful read of time data on {self.nprocs} MPI rank{s_or_no_s}" + + s_or_no_s = "" + if self.nprocs > 1: + s_or_no_s = "s" + return f"Successful read of time data on {self.nprocs} MPI rank{s_or_no_s}" ############################################################################## diff --git a/components/lfric-xios/integration-test/tools/plot_output.py b/components/lfric-xios/integration-test/tools/plot_output.py index 76873673b..4d705880b 100644 --- a/components/lfric-xios/integration-test/tools/plot_output.py +++ b/components/lfric-xios/integration-test/tools/plot_output.py @@ -1,9 +1,20 @@ +#!/usr/bin/env python3 +############################################################################## +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Plotting function for LFRic-XIOS integration tests. Depends on xarray and +matplotlib packages which can be loaded as part of scitools for users in +the Met Office. +""" + from pathlib import Path import matplotlib import xarray as xr matplotlib.use('Agg') -import matplotlib.pyplot as plt # noqa: E402 - +import matplotlib.pyplot as plt # pylint: disable=wrong-import-position, ungrouped-imports def _get_ts_data(file_path, field_id): """ From a9b9e526e4b8ebc35e4860648f8df8763b295adb Mon Sep 17 00:00:00 2001 From: EdHone Date: Fri, 1 May 2026 10:25:45 +0100 Subject: [PATCH 4/7] Update copywrite statements --- .../lfric-xios/integration-test/lfric_xios_context_test.f90 | 2 +- .../lfric-xios/integration-test/lfric_xios_context_test.py | 2 +- .../integration-test/lfric_xios_temporal_iodef_test.f90 | 2 +- .../integration-test/lfric_xios_temporal_iodef_test.py | 2 +- .../lfric-xios/integration-test/lfric_xios_temporal_test.f90 | 2 +- .../lfric-xios/integration-test/lfric_xios_temporal_test.py | 2 +- .../lfric-xios/integration-test/lfric_xios_time_read_test.f90 | 2 +- .../lfric-xios/integration-test/lfric_xios_time_read_test.py | 2 +- components/lfric-xios/integration-test/test_db_mod.f90 | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/lfric-xios/integration-test/lfric_xios_context_test.f90 b/components/lfric-xios/integration-test/lfric_xios_context_test.f90 index c2fbc4f59..a409cf823 100644 --- a/components/lfric-xios/integration-test/lfric_xios_context_test.f90 +++ b/components/lfric-xios/integration-test/lfric_xios_context_test.f90 @@ -1,5 +1,5 @@ !----------------------------------------------------------------------------- -! (C) Crown copyright 2024-2025 Met Office. All rights reserved. +! (C) Crown copyright Met Office. All rights reserved. ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- diff --git a/components/lfric-xios/integration-test/lfric_xios_context_test.py b/components/lfric-xios/integration-test/lfric_xios_context_test.py index bf14ec84b..536238baf 100755 --- a/components/lfric-xios/integration-test/lfric_xios_context_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_context_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 ############################################################################## -# (C) Crown copyright 2024 Met Office. All rights reserved. +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. ############################################################################## diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.f90 b/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.f90 index a2b8cac79..d853375be 100644 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.f90 +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.f90 @@ -1,5 +1,5 @@ !----------------------------------------------------------------------------- -! (C) Crown copyright 2025 Met Office. All rights reserved. +! (C) Crown copyright Met Office. All rights reserved. ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py b/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py index 7b05f2f06..f9763a463 100755 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_iodef_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 ############################################################################## -# (C) Crown copyright 2025 Met Office. All rights reserved. +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. ############################################################################## diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_test.f90 b/components/lfric-xios/integration-test/lfric_xios_temporal_test.f90 index 60df5997e..30fa67a04 100644 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_test.f90 +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_test.f90 @@ -1,5 +1,5 @@ !----------------------------------------------------------------------------- -! (C) Crown copyright 2025 Met Office. All rights reserved. +! (C) Crown copyright Met Office. All rights reserved. ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py index 366a45ecd..da8154691 100755 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 ############################################################################## -# (C) Crown copyright 2024 Met Office. All rights reserved. +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. ############################################################################## diff --git a/components/lfric-xios/integration-test/lfric_xios_time_read_test.f90 b/components/lfric-xios/integration-test/lfric_xios_time_read_test.f90 index c26d1c577..03d870f5c 100755 --- a/components/lfric-xios/integration-test/lfric_xios_time_read_test.f90 +++ b/components/lfric-xios/integration-test/lfric_xios_time_read_test.f90 @@ -1,5 +1,5 @@ !----------------------------------------------------------------------------- -! (C) Crown copyright 2025 Met Office. All rights reserved. +! (C) Crown copyright Met Office. All rights reserved. ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- diff --git a/components/lfric-xios/integration-test/lfric_xios_time_read_test.py b/components/lfric-xios/integration-test/lfric_xios_time_read_test.py index dc42da74c..9e4997249 100755 --- a/components/lfric-xios/integration-test/lfric_xios_time_read_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_time_read_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 ############################################################################## -# (C) Crown copyright 2025 Met Office. All rights reserved. +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. ############################################################################## diff --git a/components/lfric-xios/integration-test/test_db_mod.f90 b/components/lfric-xios/integration-test/test_db_mod.f90 index 028dc97cb..6f9822d27 100644 --- a/components/lfric-xios/integration-test/test_db_mod.f90 +++ b/components/lfric-xios/integration-test/test_db_mod.f90 @@ -1,5 +1,5 @@ !----------------------------------------------------------------------------- -! (C) Crown copyright 2024 Met Office. All rights reserved. +! (C) Crown copyright Met Office. All rights reserved. ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- From a6eb56654e41a111f3bae6c9c5398dd96aa26e43 Mon Sep 17 00:00:00 2001 From: EdHone Date: Fri, 1 May 2026 10:36:59 +0100 Subject: [PATCH 5/7] Remove scitools tech dependency and fix test error capture --- .../integration-test/lfric_xios_temporal_test.py | 4 ++-- rose-stem/site/meto/common/suite_config_azspice.cylc | 4 ++-- rose-stem/site/meto/common/suite_config_ex1a.cylc | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py index da8154691..ed345d076 100755 --- a/components/lfric-xios/integration-test/lfric_xios_temporal_test.py +++ b/components/lfric-xios/integration-test/lfric_xios_temporal_test.py @@ -159,7 +159,7 @@ def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-ar Test the output of the context test """ - expected_error_code = "ERROR: Context must start within data time window for" \ + expected_error_code = "ERROR: Context must start within data time window for " \ "non-cyclic temporal data" if returncode == 1: @@ -190,7 +190,7 @@ def test(self, returncode: int, out: str, err: str): # pylint: disable=unused-ar Test the output of the context test """ - expected_error_code = "ERROR: Context must start within data time window for" \ + expected_error_code = "ERROR: Context must start within data time window for " \ "non-cyclic temporal data" if returncode == 1: diff --git a/rose-stem/site/meto/common/suite_config_azspice.cylc b/rose-stem/site/meto/common/suite_config_azspice.cylc index 6af6a464e..5caa3d231 100644 --- a/rose-stem/site/meto/common/suite_config_azspice.cylc +++ b/rose-stem/site/meto/common/suite_config_azspice.cylc @@ -92,11 +92,11 @@ [[AZSPICE_TECH_TESTS_GNU]] inherit=AZSPICE_TECH_TESTS,AZSPICE_GNU - {{ generate_script("pre-script", [azspice_base, azspice_compiler_gnu, azspice_scitools]) }} + {{ generate_script("pre-script", [azspice_base, azspice_compiler_gnu]) }} [[AZSPICE_TECH]] inherit=AZSPICE_TECH_BASE - {{ generate_script("pre-script", [azspice_base, azspice_scitools, azspice_tech]) }} + {{ generate_script("pre-script", [azspice_base, azspice_tech]) }} [[AZSPICE_PLOT]] inherit=AZSPICE_TECH_BASE diff --git a/rose-stem/site/meto/common/suite_config_ex1a.cylc b/rose-stem/site/meto/common/suite_config_ex1a.cylc index 2a7a108c4..8c55d949d 100644 --- a/rose-stem/site/meto/common/suite_config_ex1a.cylc +++ b/rose-stem/site/meto/common/suite_config_ex1a.cylc @@ -127,16 +127,15 @@ [[EX1A_TECH_TESTS_GNU]] inherit=EX1A_TECH_TESTS,EX1A_GNU - {{ generate_script("pre-script", [ex1a_base, ex1a_compiler_gnu, ex1a_scitools]) }} + {{ generate_script("pre-script", [ex1a_base, ex1a_compiler_gnu]) }} [[EX1A_TECH_TESTS_CCE]] inherit=EX1A_TECH_TESTS,EX1A_CCE - {{ generate_script("pre-script", [ex1a_base, ex1a_compiler_cce, ex1a_scitools]) }} + {{ generate_script("pre-script", [ex1a_base, ex1a_compiler_cce]) }} [[EX1A_TECH]] inherit=EX1A_TECH_BASE - {{ generate_script("pre-script", [ex1a_scitools, - ex1a_tech]) }} + {{ generate_script("pre-script", [ex1a_tech]) }} [[EX1A_SCRIPTS]] inherit=EX1A_TECH From a8ba43cd0fc3d4dde7edacd82935b377bce17609 Mon Sep 17 00:00:00 2001 From: EdHone Date: Fri, 1 May 2026 11:11:15 +0100 Subject: [PATCH 6/7] Lint base test class and fix dependencies --- .../build/testframework/xiostest.py | 55 ++++++++++++------- .../meto/common/suite_config_azspice.cylc | 2 +- .../site/meto/common/suite_config_ex1a.cylc | 3 +- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/components/lfric-xios/build/testframework/xiostest.py b/components/lfric-xios/build/testframework/xiostest.py index 3c5fa225e..c2f91649b 100644 --- a/components/lfric-xios/build/testframework/xiostest.py +++ b/components/lfric-xios/build/testframework/xiostest.py @@ -1,9 +1,15 @@ #!/usr/bin/env python3 ############################################################################## -# (C) Crown copyright 2024 Met Office. All rights reserved. +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. ############################################################################## +""" +Test framework for LFRic-XIOS integration tests. Provides a base class which +sets up the test environment and provides utility functions for generating +input data, generating configuration files, checking output data against KGO +files, and plotting input and output data for visual comparison. +""" from pathlib import Path import os import subprocess @@ -11,7 +17,7 @@ import shutil from typing import List, Optional -from testframework import MpiTest +from testframework import MpiTest # pylint: disable=no-name-in-module ############################################################################## @@ -20,7 +26,9 @@ class LFRicXiosTest(MpiTest): Base for LFRic-XIOS integration tests. """ - def __init__(self, command=sys.argv[1], processes:int=1, iodef_file: Optional[Path]="iodef.xml"): + def __init__( self, command=sys.argv[1], + processes:int=1, + iodef_file: Optional[Path]="iodef.xml" ): self.iodef_file = Path(iodef_file) @@ -58,10 +66,10 @@ def gen_data(self, source: Path, dest: Path): ['ncgen', '-k', 'nc4', '-o', f'{dest_path}', f'{source_path }'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, + check=False, ) if proc.returncode != 0: - raise Exception("Test data generation failed:\n" + f"{proc.stderr}") - + raise Exception("Test data generation failed:\n" + f"{proc.stderr}\n") def gen_config(self, config_source: Path, config_out: Path, new_config: dict): """ @@ -69,19 +77,19 @@ def gen_config(self, config_source: Path, config_out: Path, new_config: dict): in resources/configs directory and generates dest file in test working directory. """ filename = Path(self.resources_dir, 'configs', config_source) - config = filename.read_text().splitlines() + config = filename.read_text(encoding="utf-8").splitlines() for key in new_config.keys(): - for i in range(len(config)): - if key in config[i]: - if type(new_config[key]) == str: + for i, line in enumerate(config): + if key in line: + if isinstance(new_config[key], str): config[i] = f" {key}='{new_config[key]}'" else: config[i] = f" {key}={new_config[key]}" - Path(self.test_working_dir, config_out).write_text('\n'.join(config) + '\n') - + Path(self.test_working_dir, config_out).write_text('\n'.join(config) + '\n', + encoding="utf-8") - def performTest(self): + def performTest(self): # pylint: disable=invalid-name ; This needs to be fixed in the base class """ Removes any old log files and runs the executable. """ @@ -92,15 +100,21 @@ def performTest(self): return super().performTest() - - def nc_kgo_check(self, output: Path, kgo: Path): + @classmethod + def nc_kgo_check(cls, output: Path, kgo: Path): """ Compare output files with nccmp. """ proc = subprocess.run( - ['nccmp', '-Fdm', '--exclude=Mesh2d,Mesh2d_face_edges,Mesh2d_face_links', '--tolerance=0.000001', f'{output}', f'{kgo}'], + ['nccmp', + '-Fdm', + '--exclude=Mesh2d,Mesh2d_face_edges,Mesh2d_face_links', # We use a unit test mesh in the integration tests, so the values for these connectivity fields are incorrect. pylint: disable=line-too-long + '--tolerance=0.000001', + f'{output}', + f'{kgo}'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, + check=False, ) kgo_check_okay = (proc.returncode == 0) @@ -108,7 +122,7 @@ def nc_kgo_check(self, output: Path, kgo: Path): print(f"{proc.stderr}\n") return kgo_check_okay - + def plot_output(self, in_file: Path, out_file: Path, varname: str): """ Visually compare input and output data. If the environment variable @@ -119,12 +133,12 @@ def plot_output(self, in_file: Path, out_file: Path, varname: str): if os.environ.get('PLOT_TEST_OUTPUT', False): sys.path.append(str((Path(__file__).parent.parent.parent / "integration-test" / "tools"))) - from plot_output import plot_test_output # noqa: E402 + from plot_output import plot_test_output # pylint: disable=import-outside-toplevel, import-error plot_path = self.test_working_dir / f"{type(self).__name__}.png" plot_test_output(in_file, out_file, varname, plot_path) - def post_execution(self, return_code): + def post_execution(self): """ Cache XIOS logging output for analysis. """ @@ -137,7 +151,7 @@ def post_execution(self, return_code): os.chdir(self.test_top_level) -class XiosOutput: +class XiosOutput: # pylint: disable=too-few-public-methods """ Simple class to hold XIOS output log information """ @@ -145,8 +159,7 @@ class XiosOutput: def __init__(self, filename): self.path: Path = Path(filename) - with open(self.path, "rt") as handle: - self.contents = handle.read() + self.contents = self.path.read_text(encoding="utf-8") def exists(self): """ diff --git a/rose-stem/site/meto/common/suite_config_azspice.cylc b/rose-stem/site/meto/common/suite_config_azspice.cylc index 5caa3d231..cfcfab386 100644 --- a/rose-stem/site/meto/common/suite_config_azspice.cylc +++ b/rose-stem/site/meto/common/suite_config_azspice.cylc @@ -96,7 +96,7 @@ [[AZSPICE_TECH]] inherit=AZSPICE_TECH_BASE - {{ generate_script("pre-script", [azspice_base, azspice_tech]) }} + {{ generate_script("pre-script", [azspice_base, azspice_scitools, azspice_tech]) }} [[AZSPICE_PLOT]] inherit=AZSPICE_TECH_BASE diff --git a/rose-stem/site/meto/common/suite_config_ex1a.cylc b/rose-stem/site/meto/common/suite_config_ex1a.cylc index 8c55d949d..8950e23e4 100644 --- a/rose-stem/site/meto/common/suite_config_ex1a.cylc +++ b/rose-stem/site/meto/common/suite_config_ex1a.cylc @@ -135,7 +135,8 @@ [[EX1A_TECH]] inherit=EX1A_TECH_BASE - {{ generate_script("pre-script", [ex1a_tech]) }} + {{ generate_script("pre-script", [ex1a_scitools, + ex1a_tech]) }} [[EX1A_SCRIPTS]] inherit=EX1A_TECH From 229a948822f934eeb95bbbe0f993d4e3adffc23f Mon Sep 17 00:00:00 2001 From: EdHone Date: Fri, 1 May 2026 11:49:10 +0100 Subject: [PATCH 7/7] Fix post exe arg --- components/lfric-xios/build/testframework/xiostest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lfric-xios/build/testframework/xiostest.py b/components/lfric-xios/build/testframework/xiostest.py index c2f91649b..76adcbe0c 100644 --- a/components/lfric-xios/build/testframework/xiostest.py +++ b/components/lfric-xios/build/testframework/xiostest.py @@ -138,7 +138,7 @@ def plot_output(self, in_file: Path, out_file: Path, varname: str): plot_path = self.test_working_dir / f"{type(self).__name__}.png" plot_test_output(in_file, out_file, varname, plot_path) - def post_execution(self): + def post_execution(self, return_code: int): # pylint: disable=unused-argument """ Cache XIOS logging output for analysis. """