diff --git a/components/lfric-xios/build/testframework/xiostest.py b/components/lfric-xios/build/testframework/xiostest.py index b24dec612..76adcbe0c 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,9 +17,7 @@ import shutil from typing import List, Optional -from testframework import MpiTest -import xarray as xr -import matplotlib.pyplot as plt +from testframework import MpiTest # pylint: disable=no-name-in-module ############################################################################## @@ -22,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) @@ -60,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): """ @@ -71,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. """ @@ -94,69 +100,45 @@ 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', '--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, ) - return proc.returncode, proc.stderr - - 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))] + kgo_check_okay = (proc.returncode == 0) + if not kgo_check_okay: + print(f"{proc.stderr}\n") - 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 kgo_check_okay 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 # pylint: disable=import-outside-toplevel, import-error - 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): + def post_execution(self, return_code: int): # pylint: disable=unused-argument """ Cache XIOS logging output for analysis. """ @@ -169,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 """ @@ -177,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/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 a7424d577..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. ############################################################################## @@ -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 c952520d6..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 @@ -22,6 +23,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): @@ -32,16 +34,14 @@ 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'), '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..." @@ -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,11 +96,10 @@ 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}") - 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'): + 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')): raise TestFailed("Output data does not match expected values") return "Reading full set of cyclic data from the past okay..." @@ -128,16 +127,14 @@ 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'), '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, '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..." @@ -145,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): @@ -165,16 +163,14 @@ 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'), '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, '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..." @@ -187,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.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 2b6eaa737..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. ############################################################################## @@ -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_data_match(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - 'temporal_field'): - 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_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_data_match(Path(self.test_working_dir, 'lfric_xios_temporal_input.nc'), - Path(self.test_working_dir, 'lfric_xios_temporal_output.nc'), - 'temporal_field'): - 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.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 e8b12b0e4..ed345d076 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. ############################################################################## @@ -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 @@ -25,6 +26,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): @@ -35,16 +37,14 @@ 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') - 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): @@ -69,11 +70,9 @@ 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}") - 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'): + 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-cyclic data at higher model frequency okay..." @@ -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,15 +101,13 @@ 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') - 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, '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..." @@ -125,21 +122,21 @@ 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_config( "non_cyclic_base.nml", "non_cyclic_mid.nml", {'calendar_start':'2024-01-01 15:01:00'} ) + 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): + 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_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..." @@ -153,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] @@ -182,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] @@ -210,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.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 a20a90b73..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. ############################################################################## @@ -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/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/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. !----------------------------------------------------------------------------- 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..4d705880b --- /dev/null +++ b/components/lfric-xios/integration-test/tools/plot_output.py @@ -0,0 +1,50 @@ +#!/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 # pylint: disable=wrong-import-position, ungrouped-imports + +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() diff --git a/rose-stem/site/meto/common/suite_config_azspice.cylc b/rose-stem/site/meto/common/suite_config_azspice.cylc index 6af6a464e..cfcfab386 100644 --- a/rose-stem/site/meto/common/suite_config_azspice.cylc +++ b/rose-stem/site/meto/common/suite_config_azspice.cylc @@ -92,7 +92,7 @@ [[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 diff --git a/rose-stem/site/meto/common/suite_config_ex1a.cylc b/rose-stem/site/meto/common/suite_config_ex1a.cylc index 2a7a108c4..8950e23e4 100644 --- a/rose-stem/site/meto/common/suite_config_ex1a.cylc +++ b/rose-stem/site/meto/common/suite_config_ex1a.cylc @@ -127,11 +127,11 @@ [[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