From 78aa249ac9112322bfdc5a616f72ffdea16d6d28 Mon Sep 17 00:00:00 2001 From: Chris Mauzey Date: Tue, 19 May 2026 15:02:12 -0700 Subject: [PATCH 1/3] Clean up temporary input and CV files when tests are done --- Test/test_cmor_nested_cv_attribute.py | 22 +++++++++++++++------- Test/test_cmor_path_and_file_templates.py | 19 +++++++++++++------ Test/test_python_branded_variable.py | 9 +++++++-- Test/test_python_forecast_coordinates.py | 17 +++++++++++++---- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/Test/test_cmor_nested_cv_attribute.py b/Test/test_cmor_nested_cv_attribute.py index d1c85d0b..3cc7652b 100644 --- a/Test/test_cmor_nested_cv_attribute.py +++ b/Test/test_cmor_nested_cv_attribute.py @@ -2,15 +2,14 @@ import cmor import unittest import os +from pathlib import Path from netCDF4 import Dataset -CV_PATH = "TestTables/CMIP6_CV_nested_attribute.json" - DATASET_INFO = { "_AXIS_ENTRY_FILE": "Tables/CMIP6_coordinate.json", "_FORMULA_VAR_FILE": "Tables/CMIP6_formula_terms.json", - "_controlled_vocabulary_file": CV_PATH, + "_controlled_vocabulary_file": "", "activity_id": "CMIP", "branch_method": "standard", "branch_time_in_child": 30.0, @@ -49,6 +48,9 @@ def setUp(self): """ Write out a simple file using CMOR """ + self.cv_file = Path("Test/CMIP6_CV_nested_attribute.json") + self.user_input_file = Path("Test/input_nested_attribute.json") + # Set up CMOR cmor.setup(inpath="Tables", netcdf_file_action=cmor.CMOR_REPLACE, logfile="cmor.log", create_subdirectories=0) @@ -67,18 +69,24 @@ def setUp(self): } } cv["CV"]["domain_id"] = domain_id - with open(CV_PATH, "w") as cv_outfile: + with open(self.cv_file, "w") as cv_outfile: json.dump(cv, cv_outfile, sort_keys=True, indent=4) # Define dataset using DATASET_INFO - with open("Test/input_nested_attribute.json", "w") as input_file: - json.dump(DATASET_INFO, input_file, sort_keys=True, indent=4) + with open(self.user_input_file, "w") as input_file: + user_input = DATASET_INFO.copy() + user_input["_controlled_vocabulary_file"] = str(self.cv_file) + json.dump(user_input, input_file, sort_keys=True, indent=4) # read dataset info - error_flag = cmor.dataset_json("Test/input_nested_attribute.json") + error_flag = cmor.dataset_json(str(self.user_input_file)) if error_flag: raise RuntimeError("CMOR dataset_json call failed") + def tearDown(self): + self.cv_file.unlink() + self.user_input_file.unlink() + def test_nested_cv_attribute(self): mip_table = "CMIP6_Omon.json" _ = cmor.load_table(mip_table) diff --git a/Test/test_cmor_path_and_file_templates.py b/Test/test_cmor_path_and_file_templates.py index 5c052782..5f99d65a 100644 --- a/Test/test_cmor_path_and_file_templates.py +++ b/Test/test_cmor_path_and_file_templates.py @@ -3,6 +3,7 @@ import unittest import os import numpy +from pathlib import Path CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" CV_PATH = "TestTables/CMIP7_CV.json" @@ -37,6 +38,12 @@ class TestPathAndFileTemplates(unittest.TestCase): + def setUp(self): + self.user_input_file = Path("Test/input_drs.json") + + def tearDown(self): + self.user_input_file.unlink() + def gen_cmor_file(self): tos = numpy.array([27, 27, 27, 27, 27, 27, 27, 27, @@ -106,13 +113,13 @@ def test_default_path_and_file_templates(self): json.dump(cv, cv_outfile, sort_keys=True, indent=4) # Define dataset using USER_INPUT - with open("Test/input_drs.json", "w") as input_file: + with open(self.user_input_file, "w") as input_file: user_input = USER_INPUT.copy() user_input["_controlled_vocabulary_file"] = test_cv_path json.dump(user_input, input_file, sort_keys=True, indent=4) # read dataset info - error_flag = cmor.dataset_json("Test/input_drs.json") + error_flag = cmor.dataset_json(str(self.user_input_file)) if error_flag: raise RuntimeError("CMOR dataset_json call failed") @@ -149,13 +156,13 @@ def test_cv_path_and_file_templates(self): json.dump(cv, cv_outfile, sort_keys=True, indent=4) # Define dataset using USER_INPUT - with open("Test/input_drs.json", "w") as input_file: + with open(self.user_input_file, "w") as input_file: user_input = USER_INPUT.copy() user_input["_controlled_vocabulary_file"] = test_cv_path json.dump(user_input, input_file, sort_keys=True, indent=4) # read dataset info - error_flag = cmor.dataset_json("Test/input_drs.json") + error_flag = cmor.dataset_json(str(self.user_input_file)) if error_flag: raise RuntimeError("CMOR dataset_json call failed") @@ -194,7 +201,7 @@ def test_user_input_path_and_file_templates(self): json.dump(cv, cv_outfile, sort_keys=True, indent=4) # Use directory path and file name templates from user input - with open("Test/input_drs.json", "w") as input_file: + with open(self.user_input_file, "w") as input_file: user_input = USER_INPUT.copy() user_input["_controlled_vocabulary_file"] = test_cv_path user_input["output_path_template"] = ( @@ -207,7 +214,7 @@ def test_user_input_path_and_file_templates(self): json.dump(user_input, input_file, sort_keys=True, indent=4) # read dataset info - error_flag = cmor.dataset_json("Test/input_drs.json") + error_flag = cmor.dataset_json(str(self.user_input_file)) if error_flag: raise RuntimeError("CMOR dataset_json call failed") diff --git a/Test/test_python_branded_variable.py b/Test/test_python_branded_variable.py index 482b5de1..da2f8edb 100644 --- a/Test/test_python_branded_variable.py +++ b/Test/test_python_branded_variable.py @@ -2,6 +2,7 @@ import cmor import unittest import os +from pathlib import Path from netCDF4 import Dataset @@ -46,19 +47,23 @@ def setUp(self): """ Write out a simple file using CMOR """ + self.user_input_file = Path("Test/input_branded_variable.json") + # Set up CMOR cmor.setup(inpath="TestTables", netcdf_file_action=cmor.CMOR_REPLACE, logfile="cmor.log", create_subdirectories=0) # Define dataset using DATASET_INFO - with open("Test/input_branded_variable.json", "w") as input_file_handle: + with open(self.user_input_file, "w") as input_file_handle: json.dump(DATASET_INFO, input_file_handle, sort_keys=True, indent=4) # read dataset info - error_flag = cmor.dataset_json("Test/input_branded_variable.json") + error_flag = cmor.dataset_json(str(self.user_input_file)) if error_flag: raise RuntimeError("CMOR dataset_json call failed") + def tearDown(self): + self.user_input_file.unlink() def test_variable_without_branding_suffix(self): mip_table = "CMIP6_Omon_branded_variable.json" diff --git a/Test/test_python_forecast_coordinates.py b/Test/test_python_forecast_coordinates.py index c27890fb..a5ebdc22 100644 --- a/Test/test_python_forecast_coordinates.py +++ b/Test/test_python_forecast_coordinates.py @@ -3,6 +3,7 @@ import cmor import unittest import os +from pathlib import Path from netCDF4 import Dataset @@ -47,19 +48,23 @@ def setUp(self): """ Write out a simple file using CMOR """ + self.user_input_file = Path("Test/input_forecast_coordinates.json") + # Set up CMOR cmor.setup(inpath="TestTables", netcdf_file_action=cmor.CMOR_REPLACE, logfile="cmor.log", create_subdirectories=0) # Define dataset using DATASET_INFO - with open("Test/input_leadtime.json", "w") as input_file_handle: + with open(self.user_input_file, "w") as input_file_handle: json.dump(DATASET_INFO, input_file_handle, sort_keys=True, indent=4) # read dataset info - error_flag = cmor.dataset_json("Test/input_leadtime.json") + error_flag = cmor.dataset_json(str(self.user_input_file)) if error_flag: raise RuntimeError("CMOR dataset_json call failed") + def tearDown(self): + self.user_input_file.unlink() def test_has_forcast_coordinates(self): # load MIP table @@ -100,19 +105,23 @@ def setUp(self): """ Write out a simple file using CMOR """ + self.user_input_file = Path("Test/input_leadtime.json") + # Set up CMOR cmor.setup(inpath="TestTables", netcdf_file_action=cmor.CMOR_REPLACE, logfile="cmor.log", create_subdirectories=0) # Define dataset using DATASET_INFO - with open("Test/input_leadtime.json", "w") as input_file_handle: + with open(self.user_input_file, "w") as input_file_handle: json.dump(DATASET_INFO, input_file_handle, sort_keys=True, indent=4) # read dataset info - error_flag = cmor.dataset_json("Test/input_leadtime.json") + error_flag = cmor.dataset_json(str(self.user_input_file)) if error_flag: raise RuntimeError("CMOR dataset_json call failed") + def tearDown(self): + self.user_input_file.unlink() def test_multiple_writes(self): # load MIP table From ae692644a48b939fa8f1db3de340b0bf4158bdf8 Mon Sep 17 00:00:00 2001 From: Chris Mauzey Date: Tue, 19 May 2026 16:44:33 -0700 Subject: [PATCH 2/3] Update CMIP7 unit tests to use latest CV from cmip7-cmor-tables --- Test/test_cmor_CMIP7.py | 33 ++++++++-------- Test/test_cmor_check_cv_structure.py | 38 +++++++------------ Test/test_cmor_chunking.py | 22 +++++------ Test/test_cmor_cv_root_string_attributes.py | 37 +++++++++--------- Test/test_cmor_frequency_required.py | 17 ++++++--- Test/test_cmor_license_attributes.py | 31 ++++++++------- Test/test_cmor_parent_attrs.py | 32 ++++++++-------- Test/test_cmor_path_and_file_templates.py | 29 ++++++++------ ...est_cmor_time_value_and_bounds_mismatch.py | 22 +++++------ cmip7-cmor-tables | 2 +- 10 files changed, 126 insertions(+), 137 deletions(-) diff --git a/Test/test_cmor_CMIP7.py b/Test/test_cmor_CMIP7.py index 4e9e686a..2b487395 100644 --- a/Test/test_cmor_CMIP7.py +++ b/Test/test_cmor_CMIP7.py @@ -7,7 +7,7 @@ from netCDF4 import Dataset CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = "TestTables/CMIP7_CV.json" +CV_PATH = "cmip7-cmor-tables/tables-cvs/cmor-cvs.json" USER_INPUT = { "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json", @@ -17,19 +17,17 @@ "activity_id": "CMIP", "calendar": "360_day", "cv_version": "6.2.19.0", - "drs_specs": "MIP-DRS7", - "experiment_id": "piControl", - "forcing_index": "f30", - "grid_label": "gn", - "initialization_index": "i000001d", - "institution_id": "PCMDI", - "license_id": "CC BY 4.0", - "nominal_resolution": "250 km", + "experiment_id": "amip", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", "outpath": ".", "physics_index": "p1", - "realization_index": "r009", - "source_id": "PCMDI-test-1-0", - "tracking_prefix": "hdl:21.14100", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", "host_collection": "CMIP7", "frequency": "mon", "region": "glb", @@ -122,7 +120,7 @@ def test_cmip7(self): 'frequency': 'mon', 'archive_id': 'WCRP', 'mip_era': 'CMIP7', - 'data_specs_version': 'CMIP-7.0.0.0', + 'data_specs_version': 'MIP-DS7.1.0.0', 'host_collection': 'CMIP7', } @@ -130,14 +128,15 @@ def test_cmip7(self): self.assertIn(attr, attrs) self.assertEqual(val, ds.getncattr(attr)) institution_id = USER_INPUT["institution_id"] - license_id = "CC BY 4.0" + license_id = "CC-BY-4.0" license_type = "Creative Commons Attribution 4.0 International" - license_url = "https://creativecommons.org/licenses/by/4.0/" + license_url = "https://creativecommons.org/licenses/by/4.0" license = \ (f"{license_id}; CMIP7 data produced by {institution_id} is " f"licensed under a {license_type} License ({license_url}). " "Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/" - "Guidance_for_users for terms of " + "Guidance_for_users/#2-terms-of-use-and-citations-requirements " + "for terms of " "use governing CMIP7 output, including citation requirements and " "proper acknowledgment. The data producers and data providers " "make no warranty, either express or implied, including, but not " @@ -204,7 +203,7 @@ def test_secondary_modeling_realm(self): 'frequency': 'mon', 'archive_id': 'WCRP', 'mip_era': 'CMIP7', - 'data_specs_version': 'CMIP-7.0.0.0', + 'data_specs_version': 'MIP-DS7.1.0.0', 'host_collection': 'CMIP7', 'realm': 'atmos land landIce', } diff --git a/Test/test_cmor_check_cv_structure.py b/Test/test_cmor_check_cv_structure.py index e6f4e389..02b0b941 100644 --- a/Test/test_cmor_check_cv_structure.py +++ b/Test/test_cmor_check_cv_structure.py @@ -5,7 +5,7 @@ from base_CMIP6_CV import BaseCVsTest CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = "TestTables/CMIP7_CV.json" +CV_PATH = "cmip7-cmor-tables/tables-cvs/cmor-cvs.json" USER_INPUT = { "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json", @@ -13,29 +13,19 @@ "_cmip7_option": 1, "_controlled_vocabulary_file": None, "activity_id": "CMIP", - "branch_time_in_child": 30.0, - "branch_time_in_parent": 10800.0, "calendar": "360_day", "cv_version": "6.2.19.0", - "drs_specs": "MIP-DRS7", - "experiment_id": "piControl", - "forcing_index": "f30", - "grid_label": "gn", - "initialization_index": "i000001d", - "institution_id": "PCMDI", - "license_id": "CC BY 4.0", - "nominal_resolution": "250 km", + "experiment_id": "amip", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", "outpath": ".", - "parent_mip_era": "CMIP7", - "parent_time_units": "days since 1850-01-01", - "parent_activity_id": "CMIP", - "parent_source_id": "PCMDI-test-1-0", - "parent_experiment_id": "piControl", - "parent_variant_label": "r1i1p1f3", "physics_index": "p1", - "realization_index": "r009", - "source_id": "PCMDI-test-1-0", - "tracking_prefix": "hdl:21.14100", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", "host_collection": "CMIP7", "frequency": "mon", "region": "glb", @@ -149,7 +139,7 @@ def test_check_cv_single_value_pairs(self): with open(CV_PATH, "r") as cv_infile: cv = json.load(cv_infile) - cv["CV"]["institution_id"]["PCMDI"] = {"LLNL": "Livermore, CA"} + cv["CV"]["institution_id"]["CCCma"] = {"Toronto": "Toronto, ON"} with open(cv_path, "w") as cv_outfile: json.dump(cv, cv_outfile, sort_keys=True, indent=4) @@ -166,7 +156,7 @@ def test_check_cv_single_value_pairs(self): self.assertCV( "in attribute \"institution_id\" cannot be an object", - "Value for \"PCMDI\"" + "Value for \"CCCma\"" ) os.remove(cv_path) @@ -182,7 +172,7 @@ def test_check_cv_array_values(self): netcdf_file_action=cmor.CMOR_REPLACE, logfile=self.tmpfile) - with open("TestTables/CMIP7_CV.json", "r") as cv_infile: + with open(CV_PATH, "r") as cv_infile: cv = json.load(cv_infile) cv["CV"]["source_type"] = [ "AER", @@ -221,7 +211,7 @@ def test_check_cv_nested_objects(self): netcdf_file_action=cmor.CMOR_REPLACE, logfile=self.tmpfile) - with open("TestTables/CMIP7_CV.json", "r") as cv_infile: + with open(CV_PATH, "r") as cv_infile: cv = json.load(cv_infile) cv["CV"]["nested_attr"] = {} cv["CV"]["nested_attr"]["nested_value"] = { diff --git a/Test/test_cmor_chunking.py b/Test/test_cmor_chunking.py index da967d11..cff259e1 100644 --- a/Test/test_cmor_chunking.py +++ b/Test/test_cmor_chunking.py @@ -9,7 +9,7 @@ import pyfive CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = "TestTables/CMIP7_CV.json" +CV_PATH = "cmip7-cmor-tables/tables-cvs/cmor-cvs.json" USER_INPUT = { "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json", @@ -19,19 +19,17 @@ "activity_id": "CMIP", "calendar": "360_day", "cv_version": "6.2.19.0", - "drs_specs": "MIP-DRS7", - "experiment_id": "piControl", - "forcing_index": "f30", - "grid_label": "gn", - "initialization_index": "i000001d", - "institution_id": "PCMDI", - "license_id": "CC BY 4.0", - "nominal_resolution": "250 km", + "experiment_id": "amip", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", "outpath": ".", "physics_index": "p1", - "realization_index": "r009", - "source_id": "PCMDI-test-1-0", - "tracking_prefix": "hdl:21.14100", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", "host_collection": "CMIP7", "frequency": "day", "region": "glb", diff --git a/Test/test_cmor_cv_root_string_attributes.py b/Test/test_cmor_cv_root_string_attributes.py index 496fa366..aed82ed6 100644 --- a/Test/test_cmor_cv_root_string_attributes.py +++ b/Test/test_cmor_cv_root_string_attributes.py @@ -9,7 +9,7 @@ from netCDF4 import Dataset CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = Path("TestTables/CMIP7_CV.json") +CV_PATH = Path("cmip7-cmor-tables/tables-cvs/cmor-cvs.json") USER_INPUT = { "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json", @@ -19,17 +19,17 @@ "activity_id": "CMIP", "calendar": "360_day", "cv_version": "6.2.19.0", - "experiment_id": "piControl", - "forcing_index": "f30", - "grid_label": "gn", - "initialization_index": "i000001d", - "institution_id": "PCMDI", - "license_id": "CC BY 4.0", - "nominal_resolution": "250 km", + "experiment_id": "amip", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", "outpath": ".", "physics_index": "p1", - "realization_index": "r009", - "source_id": "PCMDI-test-1-0", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", "host_collection": "CMIP7", "frequency": "mon", "region": "glb", @@ -40,11 +40,9 @@ class TestCVRootStringAttributes(unittest.TestCase): def setUp(self): self.tmpdir = Path(tempfile.mkdtemp(dir=str(Path("Test").resolve()))) - self.cv_path = self.tmpdir / "CMIP7_CV_root_strings.json" self.input_path = self.tmpdir / "input.json" self.output_dir = self.tmpdir / "output" self.output_dir.mkdir() - self.cv_relpath = self.cv_path.relative_to(Path.cwd()) self.input_relpath = self.input_path.relative_to(Path.cwd()) self.output_relpath = self.output_dir.relative_to(Path.cwd()) @@ -55,14 +53,11 @@ def test_sets_drs_specs_and_tracking_prefix_from_cv_root_strings(self): with CV_PATH.open() as cv_infile: cv = json.load(cv_infile) - cv["CV"]["drs_specs"] = "MIP-DRS7" - cv["CV"]["tracking_prefix"] = "hdl:21.14100" - - with self.cv_path.open("w") as cv_outfile: - json.dump(cv, cv_outfile, sort_keys=True, indent=4) + expected_drs_specs = cv["CV"]["drs_specs"] + expected_tracking_prefix = cv["CV"]["tracking_prefix"] user_input = USER_INPUT.copy() - user_input["_controlled_vocabulary_file"] = str(self.cv_relpath) + user_input["_controlled_vocabulary_file"] = str(CV_PATH) user_input["outpath"] = str(self.output_relpath) with self.input_path.open("w") as input_file: @@ -109,8 +104,10 @@ def test_sets_drs_specs_and_tracking_prefix_from_cv_root_strings(self): ds = Dataset(filename) self.assertNotIn("tracking_prefix", ds.ncattrs()) - self.assertEqual(ds.getncattr("drs_specs"), "MIP-DRS7") - self.assertTrue(ds.getncattr("tracking_id").startswith("hdl:21.14100/")) + self.assertEqual(ds.getncattr("drs_specs"), expected_drs_specs) + self.assertTrue( + ds.getncattr("tracking_id").startswith(f"{expected_tracking_prefix}/") + ) ds.close() filename.unlink(missing_ok=True) diff --git a/Test/test_cmor_frequency_required.py b/Test/test_cmor_frequency_required.py index bbf24b27..59ef69d8 100644 --- a/Test/test_cmor_frequency_required.py +++ b/Test/test_cmor_frequency_required.py @@ -5,7 +5,7 @@ from base_CMIP6_CV import BaseCVsTest CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = "TestTables/CMIP7_CV.json" +CV_PATH = "cmip7-cmor-tables/tables-cvs/cmor-cvs.json" def run(): @@ -21,13 +21,18 @@ def _create_cmip7_json(self, frequency=None, extra_fields=None): "_cmip7_option": 1, "_controlled_vocabulary_file": CV_PATH, "mip_era": "CMIP7", - "institution_id": "PCMDI", - "source_id": "PCMDI-test-1-0", - "experiment_id": "piControl", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", + "physics_index": "p1", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", + "experiment_id": "amip", "activity_id": "CMIP", "source_type": "AOGCM", - "grid_label": "gn", - "nominal_resolution": "250 km", "calendar": "360_day", "region": "glb", "outpath": ".", diff --git a/Test/test_cmor_license_attributes.py b/Test/test_cmor_license_attributes.py index d664e9e5..8acb4386 100644 --- a/Test/test_cmor_license_attributes.py +++ b/Test/test_cmor_license_attributes.py @@ -7,7 +7,7 @@ from netCDF4 import Dataset CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = "TestTables/CMIP7_CV.json" +CV_PATH = "cmip7-cmor-tables/tables-cvs/cmor-cvs.json" USER_INPUT = { "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json", @@ -17,19 +17,17 @@ "activity_id": "CMIP", "calendar": "360_day", "cv_version": "6.2.19.0", - "drs_specs": "MIP-DRS7", - "experiment_id": "piControl", - "forcing_index": "f30", - "grid_label": "gn", - "initialization_index": "i000001d", - "institution_id": "PCMDI", - "license_id": "CC BY 4.0", - "nominal_resolution": "250 km", + "experiment_id": "amip", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", "outpath": ".", "physics_index": "p1", - "realization_index": "r009", - "source_id": "PCMDI-test-1-0", - "tracking_prefix": "hdl:21.14100", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", "host_collection": "CMIP7", "frequency": "mon", "region": "glb", @@ -122,7 +120,7 @@ def test_cmip7_with_license_id_and_url(self): 'frequency': 'mon', 'archive_id': 'WCRP', 'mip_era': 'CMIP7', - 'data_specs_version': 'CMIP-7.0.0.0', + 'data_specs_version': 'MIP-DS7.1.0.0', 'host_collection': 'CMIP7', } @@ -130,14 +128,15 @@ def test_cmip7_with_license_id_and_url(self): self.assertTrue(attr in attrs) self.assertEqual(val, ds.getncattr(attr)) institution_id = USER_INPUT["institution_id"] - license_id = "CC BY 4.0" + license_id = "CC-BY-4.0" license_type = "Creative Commons Attribution 4.0 International" - license_url = "https://creativecommons.org/licenses/by/4.0/" + license_url = "https://creativecommons.org/licenses/by/4.0" license = \ (f"{license_id}; CMIP7 data produced by {institution_id} is " f"licensed under a {license_type} License ({license_url}). " "Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/" - "Guidance_for_users for terms of " + "Guidance_for_users/#2-terms-of-use-and-citations-requirements " + "for terms of " "use governing CMIP7 output, including citation requirements and " "proper acknowledgment. The data producers and data providers " "make no warranty, either express or implied, including, but not " diff --git a/Test/test_cmor_parent_attrs.py b/Test/test_cmor_parent_attrs.py index 9f38bb76..76cf3d51 100644 --- a/Test/test_cmor_parent_attrs.py +++ b/Test/test_cmor_parent_attrs.py @@ -8,7 +8,7 @@ from netCDF4 import Dataset CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = "TestTables/CMIP7_CV.json" +CV_PATH = "cmip7-cmor-tables/tables-cvs/cmor-cvs.json" USER_INPUT = { "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json", @@ -18,19 +18,17 @@ "activity_id": "CMIP", "calendar": "360_day", "cv_version": "6.2.19.0", - "drs_specs": "MIP-DRS7", - "experiment_id": "piControl", - "forcing_index": "f30", - "grid_label": "gn", - "initialization_index": "i000001d", - "institution_id": "PCMDI", - "license_id": "CC BY 4.0", - "nominal_resolution": "250 km", + "experiment_id": "amip", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", "outpath": ".", "physics_index": "p1", - "realization_index": "r009", - "source_id": "PCMDI-test-1-0", - "tracking_prefix": "hdl:21.14100", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", "host_collection": "CMIP7", "frequency": "mon", "region": "glb", @@ -140,7 +138,7 @@ def test_cmip7_with_parent_attributes(self): "experiment_id": "historical", "parent_mip_era": "CMIP7", "parent_time_units": "days since 1850-01-01", - "parent_source_id": "PCMDI-test-1-0", + "parent_source_id": "DUMMY-MODEL", "parent_experiment_id": "piControl", "parent_activity_id": "CMIP", "parent_variant_label": "r1i1p1f3", @@ -157,7 +155,7 @@ def test_cmip7_with_parent_attributes(self): "parent_mip_era": "CMIP7", "parent_time_units": "days since 1850-01-01", "parent_activity_id": "CMIP", - "parent_source_id": "PCMDI-test-1-0", + "parent_source_id": "DUMMY-MODEL", "parent_experiment_id": "piControl", "parent_variant_label": "r1i1p1f3" } @@ -217,7 +215,7 @@ def test_cmip7_errors_on_parent_experiment_without_cv_parent(self): pass self.assertCV( - 'Your experiment "piControl" does not have parent experiments.', + 'Your experiment "amip" does not have parent experiments.', 'Error:', number_of_lines_to_scan=6, ) @@ -261,7 +259,7 @@ def test_cmip7_errors_on_parent_experiment_not_in_cv(self): "experiment_id": "historical", "parent_mip_era": "CMIP7", "parent_time_units": "days since 1850-01-01", - "parent_source_id": "PCMDI-test-1-0", + "parent_source_id": "DUMMY-MODEL", "parent_experiment_id": "badParent", "parent_activity_id": "CMIP", "parent_variant_label": "r1i1p1f3", @@ -295,7 +293,7 @@ def test_cmip7_errors_on_incorrect_parent_activity_id(self): "experiment_id": "historical", "parent_mip_era": "CMIP7", "parent_time_units": "days since 1850-01-01", - "parent_source_id": "PCMDI-test-1-0", + "parent_source_id": "DUMMY-MODEL", "parent_experiment_id": "piControl", "parent_activity_id": "BadMIP", "parent_variant_label": "r1i1p1f3", diff --git a/Test/test_cmor_path_and_file_templates.py b/Test/test_cmor_path_and_file_templates.py index 5f99d65a..b6b01d2a 100644 --- a/Test/test_cmor_path_and_file_templates.py +++ b/Test/test_cmor_path_and_file_templates.py @@ -6,7 +6,7 @@ from pathlib import Path CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = "TestTables/CMIP7_CV.json" +CV_PATH = "cmip7-cmor-tables/tables-cvs/cmor-cvs.json" USER_INPUT = { "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json", @@ -16,19 +16,17 @@ "activity_id": "CMIP", "calendar": "360_day", "cv_version": "6.2.19.0", - "drs_specs": "MIP-DRS7", - "experiment_id": "piControl", - "forcing_index": "f30", - "grid_label": "gn", - "initialization_index": "i000001d", - "institution_id": "PCMDI", - "license_id": "CC BY 4.0", - "nominal_resolution": "250 km", + "experiment_id": "amip", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", "outpath": ".", "physics_index": "p1", - "realization_index": "r009", - "source_id": "PCMDI-test-1-0", - "tracking_prefix": "hdl:21.14100", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", "host_collection": "CMIP7", "frequency": "mon", "region": "glb", @@ -167,14 +165,21 @@ def test_cv_path_and_file_templates(self): raise RuntimeError("CMOR dataset_json call failed") filepath, attrs = self.gen_cmor_file() + attrs["drs_specs"] = cv["CV"]["drs_specs"] predicted_path_template = drs["directory_path_template"].replace("/","") predicted_path_template = predicted_path_template.replace("<","{").replace(">","}") predicted_path_template = predicted_path_template.replace("}{","}/{") + predicted_path_template = predicted_path_template.replace( + "{table}", "{table_id}" + ) predicted_file_template = drs["filename_template"] predicted_file_template = predicted_file_template.replace("<","{").replace(">","}") predicted_file_template = predicted_file_template.replace("}{","}_{") + predicted_file_template = predicted_file_template.replace( + "{table}", "{table_id}" + ) predicted_path = f'./{predicted_path_template.format(**attrs)}' predicted_file = f'{predicted_file_template.format(**attrs)}_201801-201802.nc' diff --git a/Test/test_cmor_time_value_and_bounds_mismatch.py b/Test/test_cmor_time_value_and_bounds_mismatch.py index 24279454..5951e995 100644 --- a/Test/test_cmor_time_value_and_bounds_mismatch.py +++ b/Test/test_cmor_time_value_and_bounds_mismatch.py @@ -6,7 +6,7 @@ import base_CMIP6_CV CMIP7_TABLES_PATH = "cmip7-cmor-tables/tables" -CV_PATH = "TestTables/CMIP7_CV.json" +CV_PATH = "cmip7-cmor-tables/tables-cvs/cmor-cvs.json" USER_INPUT = { "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json", @@ -16,19 +16,17 @@ "activity_id": "CMIP", "calendar": "360_day", "cv_version": "6.2.19.0", - "drs_specs": "MIP-DRS7", - "experiment_id": "piControl", - "forcing_index": "f30", - "grid_label": "gn", - "initialization_index": "i000001d", - "institution_id": "PCMDI", - "license_id": "CC BY 4.0", - "nominal_resolution": "250 km", + "experiment_id": "amip", + "forcing_index": "f3", + "grid_label": "g999", + "initialization_index": "i1", + "institution_id": "CCCma", + "license_id": "CC-BY-4.0", + "nominal_resolution": "100 km", "outpath": ".", "physics_index": "p1", - "realization_index": "r009", - "source_id": "PCMDI-test-1-0", - "tracking_prefix": "hdl:21.14100", + "realization_index": "r9", + "source_id": "DUMMY-MODEL", "host_collection": "CMIP7", "frequency": "mon", "region": "glb", diff --git a/cmip7-cmor-tables b/cmip7-cmor-tables index fb2b4324..37232b1b 160000 --- a/cmip7-cmor-tables +++ b/cmip7-cmor-tables @@ -1 +1 @@ -Subproject commit fb2b4324a4673ebb6aab52cc49cca79fe6a5b5e1 +Subproject commit 37232b1b2a53d6ccf5494bc6a2c4bfca8b6374f8 From 1f68836f8e76d97555f83874a6d16febf2e72049 Mon Sep 17 00:00:00 2001 From: Chris Mauzey Date: Tue, 19 May 2026 17:05:28 -0700 Subject: [PATCH 3/3] Remove old CMIP7 testing tables --- TestTables/CMIP7_CV.json | 364 --------------------------------- TestTables/CMIP7_atmos2d.json | 61 ------ TestTables/CMIP7_ocean2d.json | 41 ---- TestTables/CMIP7_oceanLev.json | 45 ---- 4 files changed, 511 deletions(-) delete mode 100644 TestTables/CMIP7_CV.json delete mode 100644 TestTables/CMIP7_atmos2d.json delete mode 100644 TestTables/CMIP7_ocean2d.json delete mode 100644 TestTables/CMIP7_oceanLev.json diff --git a/TestTables/CMIP7_CV.json b/TestTables/CMIP7_CV.json deleted file mode 100644 index 2b3f7c1e..00000000 --- a/TestTables/CMIP7_CV.json +++ /dev/null @@ -1,364 +0,0 @@ -{ - "CV":{ - "Conventions": [ - "CF-1.11", - "CF-1.12", - "CF-1.13" - ], - "DRS":{ - "directory_path_example":"CMIP7/CMIP/PCMDI-test-1-0/glb/mon/historical/r1i1p1f3/tas/tavg-h2m-hxy-u/gn/v20191207/", - "directory_path_template":"", - "filename_example":"tas_tavg-h2m-hxy-u_mon_glb_gn_PCMDI-test-1-0_historical_r1i1p1f3_185001-186912.nc", - "filename_template":"" - }, - "activity_id":{ - "AerChemMIP":"Aerosols and Chemistry Model Intercomparison Project", - "C4MIP":"Coupled Climate Carbon Cycle Model Intercomparison Project", - "CDRMIP":"Carbon Dioxide Removal Model Intercomparison Project", - "CFMIP":"Cloud Feedback Model Intercomparison Project", - "CMIP":"CMIP DECK: 1pctCO2, abrupt4xCO2, amip, esm-piControl, esm-historical, historical, and piControl experiments", - "CORDEX":"Coordinated Regional Climate Downscaling Experiment", - "DAMIP":"Detection and Attribution Model Intercomparison Project", - "DCPP":"Decadal Climate Prediction Project", - "DynVarMIP":"Dynamics and Variability Model Intercomparison Project", - "FAFMIP":"Flux-Anomaly-Forced Model Intercomparison Project", - "GMMIP":"Global Monsoons Model Intercomparison Project", - "GeoMIP":"Geoengineering Model Intercomparison Project", - "HighResMIP":"High-Resolution Model Intercomparison Project", - "ISMIP6":"Ice Sheet Model Intercomparison Project for CMIP6", - "LS3MIP":"Land Surface, Snow and Soil Moisture", - "LUMIP":"Land-Use Model Intercomparison Project", - "OMIP":"Ocean Model Intercomparison Project", - "PAMIP":"Polar Amplification Model Intercomparison Project", - "PMIP":"Palaeoclimate Modelling Intercomparison Project", - "RFMIP":"Radiative Forcing Model Intercomparison Project", - "SIMIP":"Sea Ice Model Intercomparison Project", - "ScenarioMIP":"Scenario Model Intercomparison Project", - "VIACSAB":"Vulnerability, Impacts, Adaptation and Climate Services Advisory Board", - "VolMIP":"Volcanic Forcings Model Intercomparison Project" - }, - "archive_id":{ - "WCRP":"a collection of datasets from the AMIP and CMIP project phases, along with project supporting datasets from the input4MIPs (forcing datasets used to drive CMIP simulations) and obs4MIPs (observational datasets used to evaluate CMIP simulations, and numerous other supporting activities" - }, - "area_label":{ - "air":"air", - "ccl":"convective cloud", - "cl":"cloud", - "crp":"crops", - "fis":"floating ice shelf", - "gis":"grounded ice sheet", - "ifs":"ice free sea", - "is":"ice sheet", - "li":"land ice", - "lnd":"land", - "lus":"sector (auxiliary coordinate for land-use area types", - "ng":"natural grasses", - "pst":"pasture", - "scl":"stratiform cloud", - "sea":"sea", - "shb":"shrubs", - "si":"sea ice", - "simp":"sea ice melt pond", - "sir":"sea ice ridge", - "sn":"snow", - "tree":"trees", - "u":"unmasked (no \"where\" directive included in cell_methods)", - "ufs":"unfrozen soil", - "veg":"vegetation", - "wl":"wetland" - }, - "branding_suffix":"", - "data_specs_version":"CMIP-7.0.0.0", - "drs_specs": { - "MIP-DRS7": "Data reference syntax (DRS) initially designed for use with CMIP7" - }, - "experiment_id": { - "historical": { - "activity_id": [ - "CMIP" - ], - "description": "DECK: historical simulation of the recent past (TODO: add details)", - "end_year": "2021 (TODO make clear it is end of 2021, not start)", - "experiment": "Simulation of the recent past", - "experiment_id": "historical", - "host_collection": "CMIP7", - "min_number_yrs_per_sim": 171, - "parent_activity_id": [ - "CMIP" - ], - "parent_experiment_id": [ - "piControl" - ], - "start_year": "1850", - "tier": 0 - }, - "piControl": { - "activity_id": [ - "CMIP" - ], - "description": "DECK: pre-industrial control simulation (TODO: add details)", - "end_year": "", - "experiment": "Simulation of the pre-industrial climate", - "experiment_id": "piControl", - "host_collection": "CMIP7", - "min_number_yrs_per_sim": 150, - "parent_activity_id": [], - "parent_experiment_id": [], - "start_year": "", - "tier": 0 - } - }, - "frequency":{ - "1hr":{ - "approx_interval":0.041666666666666664, - "description":"sampled hourly" - }, - "1hrCM":{ - "approx_interval":0.041666666666666664, - "description":"monthly-mean diurnal cycle resolving each day into 1-hour means" - }, - "3hr":{ - "approx_interval":0.125, - "description":"3 hourly samples" - }, - "6hr":{ - "approx_interval":0.25, - "description":"6 hourly samples" - }, - "day":{ - "approx_interval":1.0, - "description":"daily mean samples" - }, - "dec":{ - "approx_interval":3650.0, - "description":"decadal mean samples" - }, - "fx":"fixed (time invariant) field", - "mon":{ - "approx_interval":30.0, - "description":"monthly mean samples" - }, - "yr":{ - "approx_interval":365.0, - "description":"annual mean samples" - } - }, - "grid_label":{ - "gm":"global mean data", - "gn":"data reported on a model's native grid", - "gna":"data reported on a native grid in the region of Antarctica", - "gng":"data reported on a native grid in the region of Greenland", - "gnz":"zonal mean data reported on a model's native latitude grid", - "gr":"regridded data reported on the data provider's preferred target grid", - "gra":"regridded data in the region of Antarctica reported on the data provider's preferred target grid", - "grg":"regridded data in the region of Greenland reported on the data provider's preferred target grid", - "grz":"regridded zonal mean data reported on the data provider's preferred latitude target grid" - }, - "horizontal_label":{ - "hm":"horizontal mean", - "ht":"labeled areas", - "hxy":"gridded", - "hxys":"site values", - "hy":"zonal mean", - "hys":"basin mean" - }, - "institution_id":{ - "PCMDI":"Program for Climate Model Diagnosis and Intercomparison, Lawrence Livermore National Laboratory, Livermore, CA 94550, USA" - }, - "license":{ - "license_id":{ - "CC BY 4.0":{ - "license_type":"Creative Commons Attribution 4.0 International", - "license_url":"https://creativecommons.org/licenses/by/4.0/" - }, - "CC0 1.0":{ - "license_type":"Creative Commons CC0 1.0 Universal Public Domain Dedication", - "license_url":"https://creativecommons.org/publicdomain/zero/1.0/" - } - }, - "license_template":"; CMIP7 data produced by is licensed under a License (). Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/Guidance_for_users for terms of use governing CMIP7 output, including citation requirements and proper acknowledgment. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." - }, - "mip_era":"CMIP7", - "nominal_resolution":[ - "0.25 km", - "0.5 km", - "1 km", - "10 km", - "100 km", - "1000 km", - "10000 km", - "2.5 km", - "25 km", - "250 km", - "2500 km", - "5 km", - "50 km", - "500 km", - "5000 km" - ], - "product":[ - "model-output" - ], - "realm":{ - "aerosol":"Aerosol", - "atmos":"Atmosphere", - "atmosChem":"Atmospheric Chemistry", - "land":"Land Surface", - "landIce":"Land Ice", - "ocean":"Ocean", - "ocnBgchem":"Ocean Biogeochemistry", - "seaIce":"Sea Ice" - }, - "region":{ - "ant":"located around the South Pole, separated from other land masses by the Southern Ocean, and almost entirely south of 60 degrees South latitude", - "glb":"the complete Earth surface, 90 degrees North to 90 degrees South latitude, and all longitudes", - "gre":"located in the Northern Atlantic Ocean, separated from other land masses by the Labrador Sea and Straits, and almost entirely north of 60 degrees North latitude", - "nhem":"the complete Earth surface from the equator to the North Pole, 0 to 90 degrees North latitude", - "shem":"the complete Earth surface from the equator to the South Pole, 0 to 90 degrees South latitude" - }, - "required_global_attributes":[ - "activity_id", - "area_label", - "branded_variable", - "branding_suffix", - "Conventions", - "creation_date", - "data_specs_version", - "drs_specs", - "experiment_id", - "forcing_index", - "frequency", - "grid_label", - "horizontal_label", - "initialization_index", - "institution_id", - "license_id", - "mip_era", - "nominal_resolution", - "physics_index", - "product", - "realization_index", - "realm", - "region", - "source_id", - "temporal_label", - "tracking_id", - "variable_id", - "variant_label", - "vertical_label" - ], - "source_id":{ - "PCMDI-test-1-0":{ - "activity_participation":[ - "CMIP" - ], - "cohort":[ - "Registered" - ], - "institution_id":[ - "PCMDI" - ], - "label":"PCMDI-test 1.0", - "label_extended":"PCMDI-test 1.0 (This entry is free text for users to contribute verbose information)", - "model_component":{ - "aerosol":{ - "description":"none", - "native_nominal_resolution":"none" - }, - "atmos":{ - "description":"Earth1.0-gettingHotter (360 x 180 longitude/latitude; 50 levels; top level 0.1 mb)", - "native_nominal_resolution":"1x1 degree" - }, - "atmosChem":{ - "description":"none", - "native_nominal_resolution":"none" - }, - "land":{ - "description":"Earth1.0", - "native_nominal_resolution":"1x1 degree" - }, - "landIce":{ - "description":"none", - "native_nominal_resolution":"none" - }, - "ocean":{ - "description":"BlueMarble1.0-warming (360 x 180 longitude/latitude; 50 levels; top grid cell 0-10 m)", - "native_nominal_resolution":"1x1 degree" - }, - "ocnBgchem":{ - "description":"none", - "native_nominal_resolution":"none" - }, - "seaIce":{ - "description":"Declining1.0-warming (360 x 180 longitude/latitude)", - "native_nominal_resolution":"1x1 degree" - } - }, - "release_year":"1989", - "source":"PCMDI-test 1.0 (1989): \naerosol: none\natmos: Earth1.0-gettingHotter (360 x 180 longitude/latitude; 50 levels; top level 0.1 mb)\natmosChem: none\nland: Earth1.0\nlandIce: none\nocean: BlueMarble1.0-warming (360 x 180 longitude/latitude; 50 levels; top grid cell 0-10 m)\nocnBgchem: none\nseaIce: Declining1.0-warming (360 x 180 longitude/latitude)", - "source_id":"PCMDI-test-1-0" - } - }, - "temporal_label":{ - "tavg":"mean", - "tclm":"climatology", - "tclmdc":"diurnal cycle climatology", - "ti":"time independent", - "tpt":"point", - "tstat":"statistic", - "tsum":"sum" - }, - "tracking_id":[ - "hdl:21.14100/.*" - ], - "realization_index":[ - "^r[[:digit:]]\\{1,6\\}$" - ], - "initialization_index":[ - "^i[[:digit:]]\\{1,6\\}[abcde]\\{0,1\\}$" - ], - "physics_index":[ - "^p[[:digit:]]\\{1,6\\}$" - ], - "forcing_index":[ - "^f[[:digit:]]\\{1,6\\}$" - ], - "variant_label":[ - "^r[[:digit:]]\\{1,6\\}i[[:digit:]]\\{1,6\\}[abcde]\\{0,1\\}p[[:digit:]]\\{1,6\\}f[[:digit:]]\\{1,6\\}$" - ], - "vertical_label":{ - "1000hPa":"1000 hPa", - "100hPa":"100 hPa", - "10hPa":"10 hPa", - "220hPa":"220 hPa", - "500hPa":"500 hPa", - "560hPa":"560 hPa", - "700hPa":"700 hPa", - "840hPa":"840 hPa", - "850hPa":"850 hPa", - "d0m":"surface", - "d100m":"100m depth", - "d10cm":"1cm depth", - "d1m":"1m depth", - "d2000m":"2000m depth", - "d300m":"300m depth", - "d700m":"700m depth", - "h100m":"100m height", - "h10m":"10m height", - "h16":"16 height levels", - "h2m":"2m height", - "h40":"40 height levels", - "l":"model level", - "p19":"19 pressure levels", - "p27":"27 pressure levels", - "p3":"3 pressure levels", - "p39":"39 pressure levels", - "p4":"4 pressure levels", - "p7c":"7 pressure levels", - "p7h":"7 pressure levels", - "p8":"8 pressure levels", - "rho":"density surface", - "u":"unspecified (no vertical dimension)" - } - } -} \ No newline at end of file diff --git a/TestTables/CMIP7_atmos2d.json b/TestTables/CMIP7_atmos2d.json deleted file mode 100644 index 8e884330..00000000 --- a/TestTables/CMIP7_atmos2d.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "Header":{ - "Conventions":"CF-1.11 CMIP-7.0.0.0", - "checksum":"16d968eb7e89b5b95d1e119e32aaa0db", - "cmor_version":"3.10", - "generic_levels":"alevel alevhalf", - "int_missing_value":"-999", - "missing_value":"1e20", - "ok_max_mean_abs":"", - "ok_min_mean_abs":"", - "positive":"", - "product":"model-output", - "realm":"atmos", - "table_date":"2025-03-12", - "table_id":"atmos2d", - "type":"real", - "valid_max":"", - "valid_min":"" - }, - "variable_entry":{ - "pr_tavg-u-hxy-u":{ - "brand_description":"precipitation flux: time means reported on a 2-d horizontal grid", - "cell_measures":"area: areacella", - "cell_methods":"area: time: mean", - "comment":"includes both liquid and solid phases", - "dimensions":[ - "longitude", - "latitude", - "time" - ], - "out_name":"pr", - "modeling_realm":[ - "atmos", - "ocean" - ], - "standard_name":"precipitation_flux", - "units":"kg m-2 s-1", - "variable_title":"Precipitation" - }, - "tas_tavg-h2m-hxy-u":{ - "brand_description":"air temperature: time means at a nominal height of 2 m reported on a 2-d horizontal grid", - "cell_measures":"area: areacella", - "cell_methods":"area: time: mean", - "comment":"near-surface (usually, 2 meter) air temperature", - "dimensions":[ - "longitude", - "latitude", - "time", - "height2m" - ], - "ok_max_mean_abs":330.0, - "ok_min_mean_abs":-30.0, - "out_name":"tas", - "standard_name":"air_temperature", - "units":"K", - "valid_max":350.0, - "valid_min":240.0, - "variable_title":"Near-Surface Air Temperature" - } - } -} \ No newline at end of file diff --git a/TestTables/CMIP7_ocean2d.json b/TestTables/CMIP7_ocean2d.json deleted file mode 100644 index c67023b7..00000000 --- a/TestTables/CMIP7_ocean2d.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "Header":{ - "Conventions":"CF-1.11 CMIP-7.0.0.0", - "checksum":"0d05fb60cb5645eb4b581f5c77508f7c", - "cmor_version":"3.10", - "generic_levels":"", - "int_missing_value":"-999", - "missing_value":"1e20", - "ok_max_mean_abs":"", - "ok_min_mean_abs":"", - "positive":"", - "product":"model-output", - "realm":"ocean", - "table_date":"2025-03-12", - "table_id":"ocean2d", - "type":"real", - "valid_max":"", - "valid_min":"" - }, - "variable_entry":{ - "tos_tavg-u-hxy-sea":{ - "brand_description":"sea surface temperature: time means reported on a 2-d horizontal grid where sea", - "cell_measures":"area: areacello", - "cell_methods":"area: mean where sea time: mean", - "comment":"Temperature of upper boundary of the liquid ocean, including temperatures below sea-ice and floating ice shelves", - "dimensions":[ - "longitude", - "latitude", - "time" - ], - "ok_max_mean_abs":50.0, - "ok_min_mean_abs":-3.0, - "out_name":"tos", - "standard_name":"sea_surface_temperature", - "units":"degC", - "valid_max":100.0, - "valid_min":-50.0, - "variable_title":"Sea Surface Temperature" - } - } -} \ No newline at end of file diff --git a/TestTables/CMIP7_oceanLev.json b/TestTables/CMIP7_oceanLev.json deleted file mode 100644 index 561dfa83..00000000 --- a/TestTables/CMIP7_oceanLev.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "Header":{ - "Conventions":"CF-1.11 CMIP-7.0.0.0", - "checksum":"651bbe7b494203f2383f6feee44ad299", - "cmor_version":"3.10", - "generic_levels":"olevel olevhalf", - "int_missing_value":"-999", - "missing_value":"1e20", - "ok_max_mean_abs":"", - "ok_min_mean_abs":"", - "positive":"", - "product":"model-output", - "realm":"ocean", - "table_date":"2025-03-12", - "table_id":"oceanLev", - "type":"real", - "valid_max":"", - "valid_min":"" - }, - "variable_entry":{ - "thetao_tavg-l-hxy-sea":{ - "brand_description":"sea water potential temperature: time means provided on multiple model levels and reported on a 2-d horizontal grid where sea", - "cell_measures":"area: areacello volume: volcello", - "cell_methods":"area: mean where sea time: mean", - "comment":"Diagnostic should be contributed even for models using conservative temperature as prognostic field", - "dimensions":[ - "longitude", - "latitude", - "olevel", - "time" - ], - "modeling_realm":[ - "ocean" - ], - "ok_max_mean_abs":50.0, - "ok_min_mean_abs":-3.0, - "out_name":"thetao", - "standard_name":"sea_water_potential_temperature", - "units":"degC", - "valid_max":100.0, - "valid_min":-50.0, - "variable_title":"Sea Water Potential Temperature" - } - } -} \ No newline at end of file