diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 518de3672c..203d7b487a 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -69,3 +69,4 @@ cdf40d265cc82775607a1bf25f5f527bacc97405 742cfa606039ab89602fde5fef46458516f56fd4 4ad46f46de7dde753b4653c15f05326f55116b73 75db098206b064b8b7b2a0604d3f0bf8fdb950cc +84609494b54ea9732f64add43b2f1dd035632b4c diff --git a/python/ctsm/longitude.py b/python/ctsm/longitude.py index fb5998524d..96fd134082 100644 --- a/python/ctsm/longitude.py +++ b/python/ctsm/longitude.py @@ -177,6 +177,13 @@ def __ge__(self, other): self._check_lons_same_type(other) return self._lon >= other._lon + def __str__(self): + """ + We don't allow implicit string conversion because the user should always specify the + Longitude type they want + """ + raise NotImplementedError("Use Longitude.get_str() instead of implicit string conversion") + def get(self, lon_type_out): """ Get the longitude value, converting longitude type if needed @@ -189,6 +196,14 @@ def get(self, lon_type_out): return _convert_lon_type_180_to_360(self._lon) raise RuntimeError(f"Add handling for lon_type_out {lon_type_out}") + def get_str(self, lon_type_out): + """ + Get the longitude value as a string, converting longitude type if needed + """ + lon_out = self.get(lon_type_out) + # Use float() because the standard in CTSM filenames is to put .0 after whole-number values + return str(float(lon_out)) + def lon_type(self): """ Getter method for self._lon_type diff --git a/python/ctsm/site_and_regional/regional_case.py b/python/ctsm/site_and_regional/regional_case.py index ed91f3d474..1b52e72ab4 100644 --- a/python/ctsm/site_and_regional/regional_case.py +++ b/python/ctsm/site_and_regional/regional_case.py @@ -160,6 +160,20 @@ def _subset_lon_lat(self, x_dim, y_dim, f_in): f_out = f_in.isel({y_dim: yind, x_dim: xind}) return f_out + def _get_lon_strings(self): + """ + Get the string versions of the region's longitudes + """ + if isinstance(self.lon1, Longitude): + lon1_str = self.lon1.get_str(self.lon1.lon_type()) + else: + lon1_str = str(self.lon1) + if isinstance(self.lon2, Longitude): + lon2_str = self.lon2.get_str(self.lon2.lon_type()) + else: + lon2_str = str(self.lon2) + return lon1_str, lon2_str + def create_tag(self): """ Create a tag for a region which is either the region name @@ -169,9 +183,8 @@ def create_tag(self): if self.reg_name: self.tag = self.reg_name else: - self.tag = "{}-{}_{}-{}".format( - str(self.lon1), str(self.lon2), str(self.lat1), str(self.lat2) - ) + lon1_str, lon2_str = self._get_lon_strings() + self.tag = "{}-{}_{}-{}".format(lon1_str, lon2_str, str(self.lat1), str(self.lat2)) def check_region_bounds(self): """ @@ -179,10 +192,11 @@ def check_region_bounds(self): """ # If you're calling this, lat/lon bounds need to have been provided if any(x is None for x in [self.lon1, self.lon2, self.lat1, self.lat2]): + lon1_str, lon2_str = self._get_lon_strings() raise argparse.ArgumentTypeError( "Latitude and longitude bounds must be provided and not None.\n" - + f" lon1: {self.lon1}\n" - + f" lon2: {self.lon2}\n" + + f" lon1: {lon1_str}\n" + + f" lon2: {lon2_str}\n" + f" lat1: {self.lat1}\n" + f" lat2: {self.lat2}" ) diff --git a/python/ctsm/site_and_regional/single_point_case.py b/python/ctsm/site_and_regional/single_point_case.py index d71d014f36..c99a240513 100644 --- a/python/ctsm/site_and_regional/single_point_case.py +++ b/python/ctsm/site_and_regional/single_point_case.py @@ -159,9 +159,12 @@ def convert_plon_to_filetype_if_needed(self, lon_da): plon_orig = plon_in.get(plon_type) plon_out = plon_in.get(f_lon_type) if plon_orig != plon_out: - print( - f"Converted plon from type {plon_type} (value {plon_orig}) " - f"to type {f_lon_type} (value {plon_out})" + logger.info( + "Converted plon from type %s (value %f) to type %s (value %f)", + plon_type, + plon_orig, + f_lon_type, + plon_out, ) return plon_out @@ -173,7 +176,7 @@ def create_tag(self): if self.site_name: self.tag = self.site_name else: - self.tag = "{}_{}".format(str(self.plon), str(self.plat)) + self.tag = "{}_{}".format(self.plon.get_str(self.plon.lon_type()), str(self.plat)) def check_dom_pft(self): """ @@ -333,7 +336,11 @@ def create_domain_at_point(self, indir, file): Create domain file for this SinglePointCase class. """ logger.info("----------------------------------------------------------------------") - logger.info("Creating domain file at %s, %s.", str(self.plon), str(self.plat)) + logger.info( + "Creating domain file at %s, %s.", + self.plon.get_str(self.plon.lon_type()), + str(self.plat), + ) # specify files fdomain_in = os.path.join(indir, file) @@ -367,7 +374,7 @@ def create_landuse_at_point(self, indir, file, user_mods_dir): logger.info("----------------------------------------------------------------------") logger.info( "Creating land use file at %s, %s.", - str(self.plon), + self.plon.get_str(self.plon.lon_type()), str(self.plat), ) @@ -502,7 +509,7 @@ def create_surfdata_at_point(self, indir, file, user_mods_dir, specify_fsurf_out logger.info("----------------------------------------------------------------------") logger.info( "Creating surface dataset file at %s, %s", - str(self.plon), + self.plon.get_str(self.plon.lon_type()), str(self.plat), ) @@ -577,7 +584,7 @@ def create_datmdomain_at_point(self, datm_tuple: DatmFiles): logger.info("----------------------------------------------------------------------") logger.info( "Creating DATM domain file at %s, %s", - str(self.plon), + self.plon.get_str(self.plon.lon_type()), str(self.plat), ) @@ -646,7 +653,9 @@ def write_shell_commands(self, file, datm_syr, datm_eyr): with open(file, "w") as nl_file: self.write_to_file("# Change below line if you move the subset data directory", nl_file) self.write_to_file("./xmlchange {}={}".format(USRDAT_DIR, self.out_dir), nl_file) - self.write_to_file("./xmlchange PTS_LON={}".format(str(self.plon)), nl_file) + self.write_to_file( + "./xmlchange PTS_LON={}".format(self.plon.get_str(self.plon.lon_type())), nl_file + ) self.write_to_file("./xmlchange PTS_LAT={}".format(str(self.plat)), nl_file) self.write_to_file("./xmlchange MPILIB=mpi-serial", nl_file) if self.create_datm: @@ -672,7 +681,9 @@ def create_datm_at_point(self, datm_tuple: DatmFiles, datm_syr, datm_eyr, datm_s Create all of a DATM dataset at a point. """ logger.info("----------------------------------------------------------------------") - logger.info("Creating DATM files at %s, %s", str(self.plon), str(self.plat)) + logger.info( + "Creating DATM files at %s, %s", self.plon.get_str(self.plon.lon_type()), str(self.plat) + ) # -- create data files infile = [] diff --git a/python/ctsm/subset_data.py b/python/ctsm/subset_data.py index 1fe7f8c580..ed9282ef46 100644 --- a/python/ctsm/subset_data.py +++ b/python/ctsm/subset_data.py @@ -822,7 +822,7 @@ def subset_region(args, file_dict: dict): print("\nFor running this regional case with the created user_mods : ") print( "./create_newcase --case case --res CLM_USRDAT --compset I2000Clm60BgcCrop", - "--run-unsupported --user-mods-dirs ", + "--run-unsupported --user-mods-dir ", args.user_mods_dir, "\n\n", ) diff --git a/python/ctsm/test/test_sys_subset_data.py b/python/ctsm/test/test_sys_subset_data.py index 39d448cccd..453df7c18e 100644 --- a/python/ctsm/test/test_sys_subset_data.py +++ b/python/ctsm/test/test_sys_subset_data.py @@ -12,6 +12,7 @@ import tempfile import inspect import xarray as xr +from CIME.scripts.create_newcase import _main_func as create_newcase # pylint: disable=import-error # -- add python/ctsm to path (needed if we want to run the test stand-alone) _CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir) @@ -23,19 +24,52 @@ from ctsm.utils import find_one_file_matching_pattern +def _get_sitename_str_point(include_sitename, sitename, lon, lat): + """ + Given a site, return the string to use in output filenames + """ + if include_sitename: + sitename_str = sitename + else: + sitename_str = f"{float(lon)}_{float(lat)}" + return sitename_str + + class TestSubsetDataSys(unittest.TestCase): """ Basic class for testing subset_data.py. """ def setUp(self): + self.previous_dir = os.getcwd() self.temp_dir_out = tempfile.TemporaryDirectory() self.temp_dir_umd = tempfile.TemporaryDirectory() + self.temp_dir_caseparent = tempfile.TemporaryDirectory() self.inputdata_dir = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir) def tearDown(self): self.temp_dir_out.cleanup() self.temp_dir_umd.cleanup() + os.chdir(self.previous_dir) + + def _check_create_newcase(self): + """ + Check that you can call create_newcase using the usermods from subset_data + """ + case_dir = os.path.join(self.temp_dir_caseparent.name, "case") + sys.argv = [ + "create_newcase", + "--case", + case_dir, + "--res", + "CLM_USRDAT", + "--compset", + "I2000Clm60Bgc", + "--run-unsupported", + "--user-mods-dir", + self.temp_dir_umd.name, + ] + create_newcase() def _check_result_file_matches_expected(self, expected_output_files, caller_n): """ @@ -46,9 +80,18 @@ def _check_result_file_matches_expected(self, expected_output_files, caller_n): caller_n = 1. If the test is calling a function that calls this function, caller_n = 2. Etc. """ all_files_present_and_match = True + result_file_found = True + expected_file_found = True for basename in expected_output_files: + + # Check whether result (output) file exists. If not, note it but continue. result_file = os.path.join(self.temp_dir_out.name, basename) - result_file = find_one_file_matching_pattern(result_file) + try: + result_file = find_one_file_matching_pattern(result_file) + except FileNotFoundError: + result_file_found = False + + # Check whether expected file exists. If not, note it but continue. expected_file = os.path.join( os.path.dirname(__file__), "testinputs", @@ -56,7 +99,27 @@ def _check_result_file_matches_expected(self, expected_output_files, caller_n): inspect.stack()[caller_n][3], # Name of calling function (i.e., test name) basename, ) - expected_file = find_one_file_matching_pattern(expected_file) + try: + expected_file = find_one_file_matching_pattern(expected_file) + except FileNotFoundError: + expected_file_found = False + + # Raise an AssertionError if either file was not found + if not (result_file_found and expected_file_found): + msg = "" + if not result_file_found: + this_dir = os.path.dirname(result_file) + msg += f"\nResult file '{result_file}' not found. " + msg += f"Contents of directory '{this_dir}':\n\t" + msg += "\n\t".join(os.listdir(this_dir)) + if not expected_file_found: + this_dir = os.path.dirname(expected_file) + msg += f"\nExpected file '{expected_file}' not found. " + msg += f"Contents of directory '{this_dir}':\n\t" + msg += "\n\t".join(os.listdir(this_dir)) + raise AssertionError(msg) + + # Compare the two files ds_result = xr.open_dataset(result_file) ds_expected = xr.open_dataset(expected_file) if not ds_result.equals(ds_expected): @@ -66,10 +129,15 @@ def _check_result_file_matches_expected(self, expected_output_files, caller_n): all_files_present_and_match = False return all_files_present_and_match - def test_subset_data_reg_amazon(self): + def _do_test_subset_data_reg_amazon(self, include_regname=True): """ - Test subset_data for Amazon region + Convenience function for multiple tests of subset_data region for the Amazon """ + regname = "TMP" + lat1 = -12 + lat2 = -7 + lon1 = 291 + lon2 = 299 cfg_file = os.path.join( self.inputdata_dir, "ctsm", @@ -82,15 +150,13 @@ def test_subset_data_reg_amazon(self): "subset_data", "region", "--lat1", - "-12", + str(lat1), "--lat2", - "-7", + str(lat2), "--lon1", - "291", + str(lon1), "--lon2", - "299", - "--reg", - "TMP", + str(lon2), "--create-mesh", "--create-domain", "--create-surface", @@ -107,16 +173,40 @@ def test_subset_data_reg_amazon(self): cfg_file, "--overwrite", ] + if include_regname: + sys.argv += ["--reg", regname] subset_data.main() # Loop through all the output files, making sure they match what we expect. daystr = "[0-9][0-9][0-9][0-9][0-9][0-9]" # 6-digit day code, yymmdd + if include_regname: + regname_str = regname + else: + regname_str = f"{float(lon1)}-{float(lon2)}_{float(lat1)}-{float(lat2)}" expected_output_files = [ - f"domain.lnd.5x5pt-amazon_navy_TMP_c{daystr}_ESMF_UNSTRUCTURED_MESH.nc", - f"domain.lnd.5x5pt-amazon_navy_TMP_c{daystr}.nc", - f"surfdata_TMP_amazon_hist_16pfts_CMIP6_2000_c{daystr}.nc", + f"domain.lnd.5x5pt-amazon_navy_{regname_str}_c{daystr}_ESMF_UNSTRUCTURED_MESH.nc", + f"domain.lnd.5x5pt-amazon_navy_{regname_str}_c{daystr}.nc", + f"surfdata_{regname_str}_amazon_hist_16pfts_CMIP6_2000_c{daystr}.nc", ] - self.assertTrue(self._check_result_file_matches_expected(expected_output_files, 1)) + self.assertTrue(self._check_result_file_matches_expected(expected_output_files, 2)) + + # Check that create_newcase works + # SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES + self._check_create_newcase() + + def test_subset_data_reg_amazon(self): + """ + Test subset_data for Amazon region + SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES + """ + self._do_test_subset_data_reg_amazon() + + def test_subset_data_reg_amazon_noregname(self): + """ + Test subset_data for Amazon region + SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES + """ + self._do_test_subset_data_reg_amazon(include_regname=False) def test_subset_data_reg_infile_detect360(self): """ @@ -189,10 +279,11 @@ def test_subset_data_reg_infile_detect180_error(self): ): subset_data.main() - def _do_test_subset_data_pt_surface(self, lon): + def _do_test_subset_data_pt_surface(self, lon, include_sitename=True): """ Given a longitude, test subset_data point --create-surface """ + lat = -12 cfg_file = os.path.join( self.inputdata_dir, "ctsm", @@ -205,11 +296,9 @@ def _do_test_subset_data_pt_surface(self, lon): "subset_data", "point", "--lat", - "-12", + str(lat), "--lon", str(lon), - "--site", - "TMP", "--create-domain", "--create-surface", "--surf-year", @@ -225,31 +314,51 @@ def _do_test_subset_data_pt_surface(self, lon): cfg_file, "--overwrite", ] + sitename = "TMP" + if include_sitename: + sys.argv += ["--site", sitename] subset_data.main() # Loop through all the output files, making sure they match what we expect. daystr = "[0-9][0-9][0-9][0-9][0-9][0-9]" # 6-digit day code, yymmdd + sitename_str = _get_sitename_str_point(include_sitename, sitename, lon, lat) expected_output_files = [ - f"surfdata_TMP_amazon_hist_16pfts_CMIP6_2000_c{daystr}.nc", + f"surfdata_{sitename_str}_amazon_hist_16pfts_CMIP6_2000_c{daystr}.nc", ] self.assertTrue(self._check_result_file_matches_expected(expected_output_files, 2)) + # Check that create_newcase works + # SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES + self._check_create_newcase() + def test_subset_data_pt_surface_amazon_type360(self): """ Test subset_data --create-surface for Amazon point with longitude type 360 + SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES """ self._do_test_subset_data_pt_surface(291) def test_subset_data_pt_surface_amazon_type180(self): """ Test subset_data --create-surface for Amazon point with longitude type 180 + SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES """ self._do_test_subset_data_pt_surface(-69) - def _do_test_subset_data_pt_landuse(self, lon): + def test_subset_data_pt_surface_amazon_type180_nositename(self): + """ + Test subset_data --create-surface for Amazon point with longitude type 180 + without specifying a site name + SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES + """ + self._do_test_subset_data_pt_surface(-69, include_sitename=False) + + def _do_test_subset_data_pt_landuse(self, lon, include_sitename=True): """ Given a longitude, test subset_data point --create-landuse """ + lat = -12 + sitename = "TMP" cfg_file = os.path.join( self.inputdata_dir, "ctsm", @@ -262,11 +371,9 @@ def _do_test_subset_data_pt_landuse(self, lon): "subset_data", "point", "--lat", - "-12", + str(lat), "--lon", str(lon), - "--site", - "TMP", "--create-domain", "--create-surface", "--surf-year", @@ -283,45 +390,60 @@ def _do_test_subset_data_pt_landuse(self, lon): cfg_file, "--overwrite", ] + if include_sitename: + sys.argv += ["--site", sitename] subset_data.main() # Loop through all the output files, making sure they match what we expect. daystr = "[0-9][0-9][0-9][0-9][0-9][0-9]" # 6-digit day code, yymmdd + sitename_str = _get_sitename_str_point(include_sitename, sitename, lon, lat) expected_output_files = [ - f"surfdata_TMP_amazon_hist_1850_78pfts_c{daystr}.nc", - f"landuse.timeseries_TMP_amazon_hist_1850-1853_78pfts_c{daystr}.nc", + f"surfdata_{sitename_str}_amazon_hist_1850_78pfts_c{daystr}.nc", + f"landuse.timeseries_{sitename_str}_amazon_hist_1850-1853_78pfts_c{daystr}.nc", ] self.assertTrue(self._check_result_file_matches_expected(expected_output_files, 2)) + # Check that create_newcase works + # SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES + self._check_create_newcase() + def test_subset_data_pt_landuse_amazon_type360(self): """ Test subset_data --create-landuse for Amazon point with longitude type 360 + SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES """ self._do_test_subset_data_pt_landuse(291) + def test_subset_data_pt_landuse_amazon_type360_nositename(self): + """ + Test subset_data --create-landuse for Amazon point with longitude type 360 and no site name + SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES + """ + self._do_test_subset_data_pt_landuse(291, include_sitename=False) + def test_subset_data_pt_landuse_amazon_type180(self): """ Test subset_data --create-landuse for Amazon point with longitude type 180 + SHOULD WORK ONLY ON CESM-SUPPORTED MACHINES """ self._do_test_subset_data_pt_landuse(-69) - def _do_test_subset_data_pt_datm(self, lon): + def _do_test_subset_data_pt_datm(self, lon, include_sitename=True): """ Given a longitude, test subset_data point --create-datm """ start_year = 1986 end_year = 1988 sitename = "TMP" + lat = -12 outdir = self.temp_dir_out.name sys.argv = [ "subset_data", "point", "--lat", - "-12", + str(lat), "--lon", str(lon), - "--site", - sitename, "--create-datm", "--datm-syr", str(start_year), @@ -334,21 +456,27 @@ def _do_test_subset_data_pt_datm(self, lon): self.temp_dir_umd.name, "--overwrite", ] + if include_sitename: + sys.argv += ["--site", sitename] subset_data.main() # Loop through all the output files, making sure they match what we expect. daystr = "[0-9][0-9][0-9][0-9][0-9][0-9]" # 6-digit day code, yymmdd + sitename_str = _get_sitename_str_point(include_sitename, sitename, lon, lat) expected_output_files = [ - f"domain.crujra_v2.3_0.5x0.5_{sitename}_c{daystr}.nc", + f"domain.crujra_v2.3_0.5x0.5_{sitename_str}_c{daystr}.nc", ] for year in list(range(start_year, end_year + 1)): for forcing in ["Solr", "Prec", "TPQWL"]: expected_output_files.append( - f"clmforc.CRUJRAv2.5_0.5x0.5.{forcing}.{sitename}.{year}.nc" + f"clmforc.CRUJRAv2.5_0.5x0.5.{forcing}.{sitename_str}.{year}.nc" ) expected_output_files = [os.path.join("datmdata", x) for x in expected_output_files] self.assertTrue(self._check_result_file_matches_expected(expected_output_files, 2)) + # Check that create_newcase works + self._check_create_newcase() + def test_subset_data_pt_datm_amazon_type360(self): """ Test subset_data --create-datm for Amazon point with longitude type 360 @@ -363,6 +491,14 @@ def test_subset_data_pt_datm_amazon_type180(self): """ self._do_test_subset_data_pt_datm(-69) + def test_subset_data_pt_datm_amazon_type180_nositename(self): + """ + Test subset_data --create-datm for Amazon point with longitude type 180 without providing + site name. + FOR NOW CAN ONLY BE RUN ON DERECHO/CASPER + """ + self._do_test_subset_data_pt_datm(-69, include_sitename=False) + if __name__ == "__main__": unit_testing.setup_for_tests() diff --git a/python/ctsm/test/test_unit_longitude.py b/python/ctsm/test/test_unit_longitude.py index 6766f90764..2382b2c303 100644 --- a/python/ctsm/test/test_unit_longitude.py +++ b/python/ctsm/test/test_unit_longitude.py @@ -446,6 +446,27 @@ def test_lon_type_getter(self): lon = Longitude(55, 180) self.assertEqual(lon.lon_type(), 180) + def test_no_implicit_string_conversion(self): + """Ensure that implicit string conversion is disallowed""" + lon = Longitude(55, 180) + with self.assertRaisesRegex( + NotImplementedError, r"Use Longitude\.get_str\(\) instead of implicit string conversion" + ): + _ = f"{lon}" + with self.assertRaisesRegex( + NotImplementedError, r"Use Longitude\.get_str\(\) instead of implicit string conversion" + ): + _ = str(lon) + + def test_get_str(self): + """Ensure that explicit string conversion works as expected""" + lon = Longitude(55, 180) + self.assertEqual(lon.get_str(180), "55.0") + self.assertEqual(lon.get_str(360), "55.0") + lon = Longitude(-55, 180) + self.assertEqual(lon.get_str(180), "-55.0") + self.assertEqual(lon.get_str(360), "305.0") + if __name__ == "__main__": unit_testing.setup_for_tests() diff --git a/python/ctsm/test/test_unit_singlept_data.py b/python/ctsm/test/test_unit_singlept_data.py index bf29ced331..489763282d 100755 --- a/python/ctsm/test/test_unit_singlept_data.py +++ b/python/ctsm/test/test_unit_singlept_data.py @@ -19,6 +19,7 @@ from ctsm import unit_testing from ctsm.site_and_regional.single_point_case import SinglePointCase from ctsm.pft_utils import MAX_PFT_GENERICCROPS, MAX_PFT_MANAGEDCROPS +from ctsm.longitude import Longitude # pylint: disable=invalid-name @@ -29,7 +30,7 @@ class TestSinglePointCase(unittest.TestCase): """ plat = 20.1 - plon = 50.5 + plon = Longitude(50.5, lon_type=180) site_name = None create_domain = True create_surfdata = True diff --git a/python/ctsm/test/test_unit_singlept_data_surfdata.py b/python/ctsm/test/test_unit_singlept_data_surfdata.py index d163c29e4f..11ee416d4a 100755 --- a/python/ctsm/test/test_unit_singlept_data_surfdata.py +++ b/python/ctsm/test/test_unit_singlept_data_surfdata.py @@ -24,6 +24,7 @@ from ctsm import unit_testing from ctsm.site_and_regional.single_point_case import SinglePointCase from ctsm.pft_utils import MAX_PFT_GENERICCROPS, MAX_PFT_MANAGEDCROPS +from ctsm.longitude import Longitude # pylint: disable=invalid-name # pylint: disable=too-many-lines @@ -37,7 +38,7 @@ class TestSinglePointCaseSurfaceNoCrop(unittest.TestCase): """ plat = 20.1 - plon = 50.5 + plon = Longitude(50.5, lon_type=180) site_name = None create_domain = True create_surfdata = True @@ -658,7 +659,7 @@ class TestSinglePointCaseSurfaceCrop(unittest.TestCase): """ plat = 20.1 - plon = 50.5 + plon = Longitude(50.5, lon_type=180) site_name = None create_domain = True create_surfdata = True diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1986.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1986.nc new file mode 120000 index 0000000000..0e14bd986a --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1986.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.Prec.TMP.1986.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1987.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1987.nc new file mode 120000 index 0000000000..28b7abf80d --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1987.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.Prec.TMP.1987.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1988.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1988.nc new file mode 120000 index 0000000000..a238ab07c2 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Prec.-69.0_-12.0.1988.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.Prec.TMP.1988.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1986.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1986.nc new file mode 120000 index 0000000000..a2045e914c --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1986.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.Solr.TMP.1986.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1987.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1987.nc new file mode 120000 index 0000000000..24cc171353 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1987.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.Solr.TMP.1987.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1988.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1988.nc new file mode 120000 index 0000000000..00eacece43 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.Solr.-69.0_-12.0.1988.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.Solr.TMP.1988.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1986.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1986.nc new file mode 120000 index 0000000000..3806e36151 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1986.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.TMP.1986.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1987.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1987.nc new file mode 120000 index 0000000000..44ce035a2a --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1987.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.TMP.1987.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1988.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1988.nc new file mode 120000 index 0000000000..cd8cdfb7c9 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.-69.0_-12.0.1988.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//clmforc.CRUJRAv2.5_0.5x0.5.TPQWL.TMP.1988.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/domain.crujra_v2.3_0.5x0.5_-69.0_-12.0_c250620.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/domain.crujra_v2.3_0.5x0.5_-69.0_-12.0_c250620.nc new file mode 120000 index 0000000000..1dc0d0d5f2 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_datm_amazon_type180_nositename/datmdata/domain.crujra_v2.3_0.5x0.5_-69.0_-12.0_c250620.nc @@ -0,0 +1 @@ +../../test_subset_data_pt_datm_amazon_type180/datmdata//domain.crujra_v2.3_0.5x0.5_TMP_c250620.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_landuse_amazon_type360_nositename/landuse.timeseries_291.0_-12.0_amazon_hist_1850-1853_78pfts_c250618.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_landuse_amazon_type360_nositename/landuse.timeseries_291.0_-12.0_amazon_hist_1850-1853_78pfts_c250618.nc new file mode 120000 index 0000000000..8678639d98 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_landuse_amazon_type360_nositename/landuse.timeseries_291.0_-12.0_amazon_hist_1850-1853_78pfts_c250618.nc @@ -0,0 +1 @@ +../test_subset_data_pt_landuse_amazon_type360/landuse.timeseries_TMP_amazon_hist_1850-1853_78pfts_c250618.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_landuse_amazon_type360_nositename/surfdata_291.0_-12.0_amazon_hist_1850_78pfts_c250618.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_landuse_amazon_type360_nositename/surfdata_291.0_-12.0_amazon_hist_1850_78pfts_c250618.nc new file mode 120000 index 0000000000..2efbb745f4 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_landuse_amazon_type360_nositename/surfdata_291.0_-12.0_amazon_hist_1850_78pfts_c250618.nc @@ -0,0 +1 @@ +../test_subset_data_pt_landuse_amazon_type360/surfdata_TMP_amazon_hist_1850_78pfts_c250618.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_surface_amazon_type180_nositename/surfdata_-69.0_-12.0_amazon_hist_16pfts_CMIP6_2000_c250617.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_surface_amazon_type180_nositename/surfdata_-69.0_-12.0_amazon_hist_16pfts_CMIP6_2000_c250617.nc new file mode 120000 index 0000000000..9e811ca9c3 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_pt_surface_amazon_type180_nositename/surfdata_-69.0_-12.0_amazon_hist_16pfts_CMIP6_2000_c250617.nc @@ -0,0 +1 @@ +../test_subset_data_pt_surface_amazon_type180/surfdata_TMP_amazon_hist_16pfts_CMIP6_2000_c250617.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/domain.lnd.5x5pt-amazon_navy_291.0-299.0_-12.0--7.0_c250508.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/domain.lnd.5x5pt-amazon_navy_291.0-299.0_-12.0--7.0_c250508.nc new file mode 120000 index 0000000000..99d8401b46 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/domain.lnd.5x5pt-amazon_navy_291.0-299.0_-12.0--7.0_c250508.nc @@ -0,0 +1 @@ +../test_subset_data_reg_amazon/domain.lnd.5x5pt-amazon_navy_TMP_c250508.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/domain.lnd.5x5pt-amazon_navy_291.0-299.0_-12.0--7.0_c250508_ESMF_UNSTRUCTURED_MESH.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/domain.lnd.5x5pt-amazon_navy_291.0-299.0_-12.0--7.0_c250508_ESMF_UNSTRUCTURED_MESH.nc new file mode 120000 index 0000000000..6f8ca4e665 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/domain.lnd.5x5pt-amazon_navy_291.0-299.0_-12.0--7.0_c250508_ESMF_UNSTRUCTURED_MESH.nc @@ -0,0 +1 @@ +../test_subset_data_reg_amazon/domain.lnd.5x5pt-amazon_navy_TMP_c250508_ESMF_UNSTRUCTURED_MESH.nc \ No newline at end of file diff --git a/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/surfdata_291.0-299.0_-12.0--7.0_amazon_hist_16pfts_CMIP6_2000_c250508.nc b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/surfdata_291.0-299.0_-12.0--7.0_amazon_hist_16pfts_CMIP6_2000_c250508.nc new file mode 120000 index 0000000000..73bde404b0 --- /dev/null +++ b/python/ctsm/test/testinputs/expected_result_files/test_subset_data_reg_amazon_noregname/surfdata_291.0-299.0_-12.0--7.0_amazon_hist_16pfts_CMIP6_2000_c250508.nc @@ -0,0 +1 @@ +../test_subset_data_reg_amazon/surfdata_TMP_amazon_hist_16pfts_CMIP6_2000_c250508.nc \ No newline at end of file