diff --git a/compass/landice/mesh.py b/compass/landice/mesh.py index 9c2a125c53..c82640987e 100644 --- a/compass/landice/mesh.py +++ b/compass/landice/mesh.py @@ -2,6 +2,7 @@ import re import sys import time +import uuid from shutil import copyfile import jigsawpy @@ -14,6 +15,7 @@ from mpas_tools.mesh.conversion import convert, cull from mpas_tools.mesh.creation import build_planar_mesh from mpas_tools.mesh.creation.sort_mesh import sort_mesh +from mpas_tools.scrip.from_mpas import scrip_from_mpas from netCDF4 import Dataset from scipy.interpolate import NearestNDInterpolator, interpn @@ -636,13 +638,10 @@ def build_cell_width(self, section_name, gridded_dataset, f.close() - # Get bounds defined by user, or use bound of gridded dataset - bnds = [np.min(x1), np.max(x1), np.min(y1), np.max(y1)] - bnds_options = ['x_min', 'x_max', 'y_min', 'y_max'] - for index, option in enumerate(bnds_options): - bnd = section.get(option) - if bnd != 'None': - bnds[index] = float(bnd) + # Get bounds defined by user, or use bounds from the gridded dataset. + bnds = get_mesh_config_bounding_box( + section, + default_bounds=[np.min(x1), np.max(x1), np.min(y1), np.max(y1)]) geom_points, geom_edges = set_rectangular_geom_points_and_edges(*bnds) @@ -1191,3 +1190,267 @@ def clean_up_after_interp(fname): data.variables['observedSurfaceVelocityUncertainty'][:] == 0.0) data.variables['observedSurfaceVelocityUncertainty'][0, mask[0, :]] = 1.0 data.close() + + +def get_optional_interp_datasets(section, logger): + """ + Determine whether optional interpolation inputs are configured. + + Parameters + ---------- + section : configparser.SectionProxy + Config section containing optional interpolation options + + logger : logging.Logger + Logger for status messages + + Returns + ------- + bedmachine_dataset : str or None + Path to BedMachine dataset if configured, otherwise ``None`` + + measures_dataset : str or None + Path to MEaSUREs dataset if configured, otherwise ``None`` + """ + + def _specified(value): + return value is not None and str(value).strip().lower() not in [ + '', 'none'] + + data_path = section.get('data_path', fallback=None) + bedmachine_filename = section.get('bedmachine_filename', fallback=None) + measures_filename = section.get('measures_filename', fallback=None) + + use_bedmachine_interp = _specified(data_path) and \ + _specified(bedmachine_filename) + use_measures_interp = _specified(data_path) and \ + _specified(measures_filename) + + if use_bedmachine_interp: + bedmachine_dataset = os.path.join(data_path, bedmachine_filename) + else: + bedmachine_dataset = None + logger.info('Skipping BedMachine interpolation because ' + '`data_path` and/or `bedmachine_filename` are ' + 'not specified in config.') + + if use_measures_interp: + measures_dataset = os.path.join(data_path, measures_filename) + else: + measures_dataset = None + logger.info('Skipping MEaSUREs interpolation because ' + '`data_path` and/or `measures_filename` are ' + 'not specified in config.') + + return bedmachine_dataset, measures_dataset + + +def get_mesh_config_bounding_box(section, default_bounds=None): + """ + Get bounding-box coordinates from a mesh config section. + + Parameters + ---------- + section : configparser.SectionProxy + Mesh config section containing ``x_min``, ``x_max``, ``y_min``, + and ``y_max`` + + default_bounds : list of float, optional + Default bounds in the form ``[x_min, x_max, y_min, y_max]`` to use + when config values are missing or set to ``None`` + + Returns + ------- + bounding_box : list of float + Bounding box in the form ``[x_min, x_max, y_min, y_max]`` + """ + + if default_bounds is None: + default_bounds = [None, None, None, None] + + def _get_bound(option, default): + value = section.get(option, fallback=None) + if value is None or str(value).strip().lower() in ['', 'none']: + if default is None: + raise ValueError( + f'Missing required config option `{option}` and no ' + 'default was provided.') + return float(default) + return float(value) + + return [ + _get_bound('x_min', default_bounds[0]), + _get_bound('x_max', default_bounds[1]), + _get_bound('y_min', default_bounds[2]), + _get_bound('y_max', default_bounds[3])] + + +def subset_gridded_dataset_to_bounds( + source_dataset, bounding_box, subset_tag, logger): + """ + Subset a gridded source dataset to a bounding box. + + Parameters + ---------- + source_dataset : str + Path to source gridded dataset + + bounding_box : list of float + Bounding box in the form ``[x_min, x_max, y_min, y_max]`` + + subset_tag : str + Tag to include in the subset filename + + logger : logging.Logger + Logger for status messages + + Returns + ------- + subset_dataset : str + Path to subsetted gridded dataset written to the current directory + """ + + x_min, x_max, y_min, y_max = bounding_box + ds = xarray.open_dataset(source_dataset) + + if 'x1' in ds and 'y1' in ds: + x_name = 'x1' + y_name = 'y1' + elif 'x' in ds and 'y' in ds: + x_name = 'x' + y_name = 'y' + else: + ds.close() + raise ValueError( + f'Could not find x/y coordinates in {source_dataset}. ' + 'Expected either x1/y1 or x/y.') + + subset = ds.where( + (ds[x_name] >= x_min) & (ds[x_name] <= x_max) & + (ds[y_name] >= y_min) & (ds[y_name] <= y_max), + drop=True) + + # Check for empty subset, handling possible mismatch + # between variable and dimension names + x_dim = x_name if x_name in subset.sizes else ( + 'x' if 'x' in subset.sizes else None) + y_dim = y_name if y_name in subset.sizes else ( + 'y' if 'y' in subset.sizes else None) + if x_dim is None or y_dim is None or subset.sizes[x_dim] == 0 or subset.sizes[y_dim] == 0: # noqa + subset.close() + ds.close() + raise ValueError( + f'Bounding box {bounding_box} produced an empty subset for ' + f'{source_dataset}. Dimension names in subset: ' + f'{list(subset.sizes.keys())}') + + base = os.path.splitext(os.path.basename(source_dataset))[0] + unique_id = uuid.uuid4().hex + subset_dataset = f'{base}_{subset_tag}_{unique_id}_subset.nc' + logger.info(f'Writing subset dataset: {subset_dataset}') + subset.to_netcdf(subset_dataset) + + subset.close() + ds.close() + return subset_dataset + + +def run_optional_interpolation( + self, mesh_filename, src_proj, parallel_executable, nProcs, + bedmachine_dataset=None, measures_dataset=None, subset_bounds=None): + """ + Run optional interpolation from high-resolution BedMachine and MEaSUREs + datasets and perform some necessary cleanup. This can require many + more resources than the rest of the mesh generation process, so it is + usually desirable to skip this step when prototyping meshes. This step + is only run if `interpolate_data` is set to True in the config file + and the necessary dataset paths are provided. + + Parameters + ---------- + self : compass.step.Step + Step instance providing logger and context + + mesh_filename : str + Destination MALI mesh file to interpolate to + + src_proj : str + Source dataset projection for SCRIP generation + + parallel_executable : str + Parallel launcher executable (e.g. ``srun``/``mpirun``) + + nProcs : int or str + Number of processes for regridding weight generation + + bedmachine_dataset : str, optional + BedMachine dataset path; if ``None`` this interpolation is skipped + + measures_dataset : str, optional + MEaSUREs dataset path; if ``None`` this interpolation is skipped + + subset_bounds : list of float, optional + Optional source-dataset subset bounds in the form + ``[x_min, x_max, y_min, y_max]``. If provided, BedMachine and + MEaSUREs datasets are subsetted before SCRIP generation and + interpolation. + """ + + logger = self.logger + do_optional_interp = bedmachine_dataset is not None or \ + measures_dataset is not None + if not do_optional_interp: + return + + if nProcs is None: + raise ValueError("nProcs must be provided as an int or str") + nProcs = str(nProcs) + + subset_files = [] + + try: + if subset_bounds is not None: + if bedmachine_dataset is not None: + bedmachine_dataset = subset_gridded_dataset_to_bounds( + bedmachine_dataset, + subset_bounds, + 'bedmachine', + logger) + subset_files.append(bedmachine_dataset) + if measures_dataset is not None: + measures_dataset = subset_gridded_dataset_to_bounds( + measures_dataset, + subset_bounds, + 'measures', + logger) + subset_files.append(measures_dataset) + + logger.info('creating scrip file for destination mesh') + mesh_base = os.path.splitext(mesh_filename)[0] + dst_scrip_file = f'{mesh_base}_scrip.nc' + scrip_from_mpas(mesh_filename, dst_scrip_file) + + if bedmachine_dataset is not None: + interp_gridded2mali(self, bedmachine_dataset, dst_scrip_file, + parallel_executable, nProcs, + mesh_filename, src_proj, variables='all') + + if measures_dataset is not None: + measures_vars = ['observedSurfaceVelocityX', + 'observedSurfaceVelocityY', + 'observedSurfaceVelocityUncertainty'] + interp_gridded2mali(self, measures_dataset, dst_scrip_file, + parallel_executable, nProcs, + mesh_filename, src_proj, + variables=measures_vars) + + clean_up_after_interp(mesh_filename) + finally: + for subset_file in subset_files: + if os.path.exists(subset_file): + logger.info(f'Removing subset dataset: {subset_file}') + try: + os.remove(subset_file) + except OSError as exc: + logger.warning('Could not remove subset dataset ' + f'{subset_file}: {exc}') diff --git a/compass/landice/tests/antarctica/mesh.py b/compass/landice/tests/antarctica/mesh.py index 57a8d82b39..a6cff224f2 100644 --- a/compass/landice/tests/antarctica/mesh.py +++ b/compass/landice/tests/antarctica/mesh.py @@ -1,17 +1,14 @@ -import os - import netCDF4 from mpas_tools.logging import check_call -from mpas_tools.scrip.from_mpas import scrip_from_mpas from compass.landice.mesh import ( add_bedmachine_thk_to_ais_gridded_data, build_cell_width, build_mali_mesh, - clean_up_after_interp, - interp_gridded2mali, + get_optional_interp_datasets, make_region_masks, preprocess_ais_data, + run_optional_interpolation, ) from compass.model import make_graph_file from compass.step import Step @@ -48,8 +45,8 @@ def __init__(self, test_case): self.add_output_file( filename=f'{self.mesh_filename[:-3]}_ismip6_regionMasks.nc') self.add_input_file( - filename='antarctica_8km_2024_01_29.nc', - target='antarctica_8km_2024_01_29.nc', + filename='antarctica_1km_2024_01_29.nc', + target='antarctica_1km_2024_01_29.nc', database='') # no setup() method is needed @@ -66,20 +63,22 @@ def run(self): parallel_executable = config.get('parallel', 'parallel_executable') nProcs = section_ais.get('nProcs') src_proj = section_ais.get("src_proj") - data_path = section_ais.get('data_path') - measures_filename = section_ais.get("measures_filename") - bedmachine_filename = section_ais.get("bedmachine_filename") - - measures_dataset = os.path.join(data_path, measures_filename) - bedmachine_dataset = os.path.join(data_path, bedmachine_filename) + bedmachine_dataset, measures_dataset = get_optional_interp_datasets( + section_ais, logger) section_name = 'mesh' # TODO: do we want to add this to the config file? - source_gridded_dataset = 'antarctica_8km_2024_01_29.nc' + source_gridded_dataset = 'antarctica_1km_2024_01_29.nc' - bm_updated_gridded_dataset = add_bedmachine_thk_to_ais_gridded_data( - self, source_gridded_dataset, bedmachine_dataset) + if bedmachine_dataset is not None: + bm_updated_gridded_dataset = ( + add_bedmachine_thk_to_ais_gridded_data( + self, + source_gridded_dataset, + bedmachine_dataset)) + else: + bm_updated_gridded_dataset = source_gridded_dataset logger.info('calling build_cell_width') cell_width, x1, y1, geom_points, geom_edges, floodFillMask = \ @@ -92,7 +91,7 @@ def run(self): self, cell_width, x1, y1, geom_points, geom_edges, mesh_name=self.mesh_filename, section_name=section_name, gridded_dataset=bm_updated_gridded_dataset, - projection=src_proj, geojson_file=None) + projection='ais-bedmap2', geojson_file=None) # Now that we have base mesh with standard interpolation # perform advanced interpolation for specific fields @@ -132,28 +131,15 @@ def run(self): 'observedThicknessTendencyUncertainty', 'thickness'] check_call(args, logger=logger) - # Create scrip file for the newly generated mesh - logger.info('creating scrip file for destination mesh') - dst_scrip_file = f"{self.mesh_filename.split('.')[:-1][0]}_scrip.nc" - scrip_from_mpas(self.mesh_filename, dst_scrip_file) - - # Now perform bespoke interpolation of geometry and velocity data - # from their respective sources - interp_gridded2mali(self, bedmachine_dataset, dst_scrip_file, - parallel_executable, nProcs, - self.mesh_filename, src_proj, variables="all") - - # only interpolate a subset of MEaSUREs variables onto the MALI mesh - measures_vars = ['observedSurfaceVelocityX', - 'observedSurfaceVelocityY', - 'observedSurfaceVelocityUncertainty'] - interp_gridded2mali(self, measures_dataset, dst_scrip_file, - parallel_executable, nProcs, - self.mesh_filename, src_proj, - variables=measures_vars) - - # perform some final cleanup details - clean_up_after_interp(self.mesh_filename) + # Only interpolate data if interpolate_data is True in mesh_gen.cfg + interpolate_data = section_ais.getboolean( + 'interpolate_data', fallback=False) + if interpolate_data: + run_optional_interpolation( + self, self.mesh_filename, src_proj, + parallel_executable, nProcs, + bedmachine_dataset=bedmachine_dataset, + measures_dataset=measures_dataset) # create graph file logger.info('creating graph.info') diff --git a/compass/landice/tests/antarctica/mesh_gen/mesh_gen.cfg b/compass/landice/tests/antarctica/mesh_gen/mesh_gen.cfg index cca24f5acd..2bd37b74b9 100644 --- a/compass/landice/tests/antarctica/mesh_gen/mesh_gen.cfg +++ b/compass/landice/tests/antarctica/mesh_gen/mesh_gen.cfg @@ -48,6 +48,8 @@ use_dist_to_edge = False use_bed = False [antarctica] +# Whether to interpolate data (controls run_optional_interpolation) +interpolate_data = True # path to directory containing BedMachine and Measures datasets # (default value is for Perlmutter) data_path = /global/cfs/cdirs/fanssie/standard_datasets/AIS_datasets diff --git a/compass/landice/tests/crane/mesh.py b/compass/landice/tests/crane/mesh.py index 002e03283d..649b2eb309 100644 --- a/compass/landice/tests/crane/mesh.py +++ b/compass/landice/tests/crane/mesh.py @@ -1,4 +1,10 @@ -from compass.landice.mesh import build_cell_width, build_mali_mesh +from compass.landice.mesh import ( + build_cell_width, + build_mali_mesh, + get_mesh_config_bounding_box, + get_optional_interp_datasets, + run_optional_interpolation, +) from compass.model import make_graph_file from compass.step import Step @@ -38,8 +44,13 @@ def run(self): Run this step of the test case """ logger = self.logger + config = self.config mesh_name = 'Crane.nc' section_name = 'mesh' + section = config[section_name] + src_proj = section.get('src_proj') + bedmachine_dataset, measures_dataset = get_optional_interp_datasets( + section, logger) logger.info('calling build_cell_width') cell_width, x1, y1, geom_points, geom_edges, floodMask = \ @@ -54,6 +65,18 @@ def run(self): projection='ais-bedmap2', geojson_file='Crane.geojson', cores=self.cpus_per_task) + parallel_executable = config.get('parallel', 'parallel_executable') + nProcs = section.get('nProcs') + # Only interpolate data if interpolate_data is True in mesh_gen.cfg + interpolate_data = section.getboolean( + 'interpolate_data', fallback=False) + if interpolate_data: + run_optional_interpolation( + self, mesh_name, src_proj, parallel_executable, nProcs, + subset_bounds=get_mesh_config_bounding_box(section), + bedmachine_dataset=bedmachine_dataset, + measures_dataset=measures_dataset) + logger.info('creating graph.info') make_graph_file(mesh_filename=mesh_name, graph_filename='graph.info') diff --git a/compass/landice/tests/crane/mesh_gen/mesh_gen.cfg b/compass/landice/tests/crane/mesh_gen/mesh_gen.cfg index bd23901804..5bd3630dc5 100644 --- a/compass/landice/tests/crane/mesh_gen/mesh_gen.cfg +++ b/compass/landice/tests/crane/mesh_gen/mesh_gen.cfg @@ -46,3 +46,26 @@ use_speed = True use_dist_to_grounding_line = True use_dist_to_edge = False use_bed = False + +# Optional interpolation inputs (skip when set to None) +# Whether to interpolate data (controls run_optional_interpolation) +interpolate_data = False + +# path to directory containing BedMachine and Measures datasets +# (default value is for Perlmutter) +data_path = /global/cfs/cdirs/fanssie/standard_datasets/AIS_datasets + +# filename of the BedMachine thickness and bedTopography dataset +# (default value is for Perlmutter) +bedmachine_filename = BedMachineAntarctica_2020-07-15_v02_edits_floodFill_extrap_fillVostok.nc + +# filename of the MEASURES ice velocity dataset +# (default value is for Perlmutter) +measures_filename = antarctica_ice_velocity_450m_v2_edits_extrap.nc + +# projection of the source datasets, according to the dictionary keys +# create_scrip_file_from_planar_rectangular_grid from MPAS_Tools +src_proj = ais-bedmap2 + +# number of processors to use for ESMF_RegridWeightGen +nProcs = 128 diff --git a/compass/landice/tests/greenland/mesh.py b/compass/landice/tests/greenland/mesh.py index e7a6a64e1f..029ac3444e 100644 --- a/compass/landice/tests/greenland/mesh.py +++ b/compass/landice/tests/greenland/mesh.py @@ -1,15 +1,13 @@ -import os - import numpy as np import xarray as xr -from mpas_tools.scrip.from_mpas import scrip_from_mpas from compass.landice.mesh import ( build_cell_width, build_mali_mesh, - clean_up_after_interp, - interp_gridded2mali, + get_mesh_config_bounding_box, + get_optional_interp_datasets, make_region_masks, + run_optional_interpolation, ) from compass.model import make_graph_file from compass.step import Step @@ -78,15 +76,23 @@ def run(self): parallel_executable = config.get('parallel', 'parallel_executable') nProcs = section_gis.get('nProcs') src_proj = section_gis.get("src_proj") - data_path = section_gis.get('data_path') - measures_filename = section_gis.get("measures_filename") - bedmachine_filename = section_gis.get("bedmachine_filename") geojson_filename = section_gis.get('geojson_filename') - measures_dataset = os.path.join(data_path, measures_filename) - bedmachine_dataset = os.path.join(data_path, bedmachine_filename) - - bounding_box = self._get_bedmachine_bounding_box(bedmachine_dataset) + bedmachine_dataset, measures_dataset = get_optional_interp_datasets( + section_gis, logger) + + if bedmachine_dataset is not None: + ds_bm = xr.open_dataset(bedmachine_dataset) + default_bounds = [ + float(ds_bm.x1.min()), + float(ds_bm.x1.max()), + float(ds_bm.y1.min()), + float(ds_bm.y1.max())] + ds_bm.close() + bounding_box = get_mesh_config_bounding_box( + section_gis, default_bounds=default_bounds) + else: + bounding_box = None section_name = 'mesh' @@ -104,33 +110,21 @@ def run(self): build_mali_mesh( self, cell_width, x1, y1, geom_points, geom_edges, mesh_name=self.mesh_filename, section_name=section_name, - gridded_dataset=source_gridded_dataset_1km, projection=src_proj, + gridded_dataset=source_gridded_dataset_1km, + projection='gis-gimp', geojson_file=geojson_filename, bounding_box=bounding_box, ) - # Create scrip file for the newly generated mesh - logger.info('creating scrip file for destination mesh') - dst_scrip_file = f"{self.mesh_filename.split('.')[:-1][0]}_scrip.nc" - scrip_from_mpas(self.mesh_filename, dst_scrip_file) - - # Now perform bespoke interpolation of geometry and velocity data - # from their respective sources - interp_gridded2mali(self, bedmachine_dataset, dst_scrip_file, - parallel_executable, nProcs, - self.mesh_filename, src_proj, variables="all") - - # only interpolate a subset of MEaSUREs variables onto the MALI mesh - measures_vars = ['observedSurfaceVelocityX', - 'observedSurfaceVelocityY', - 'observedSurfaceVelocityUncertainty'] - interp_gridded2mali(self, measures_dataset, dst_scrip_file, - parallel_executable, nProcs, - self.mesh_filename, src_proj, - variables=measures_vars) - - # perform some final cleanup details - clean_up_after_interp(self.mesh_filename) + # Only interpolate data if interpolate_data is True in mesh_gen.cfg + interpolate_data = section_gis.getboolean( + 'interpolate_data', fallback=False) + if interpolate_data: + run_optional_interpolation( + self, self.mesh_filename, src_proj, + parallel_executable, nProcs, + bedmachine_dataset=bedmachine_dataset, + measures_dataset=measures_dataset) # create graph file logger.info('creating graph.info') @@ -176,14 +170,3 @@ def run(self): ds["observedThicknessTendencyUncertainty"] = dHdtErr # Write the data to disk ds.to_netcdf(self.mesh_filename, 'a') - - def _get_bedmachine_bounding_box(self, bedmachine_filepath): - - ds = xr.open_dataset(bedmachine_filepath) - - x_min = ds.x1.min() - x_max = ds.x1.max() - y_min = ds.y1.min() - y_max = ds.y1.max() - - return [x_min, x_max, y_min, y_max] diff --git a/compass/landice/tests/greenland/mesh_gen/mesh_gen.cfg b/compass/landice/tests/greenland/mesh_gen/mesh_gen.cfg index 2115294d24..c1b7250a50 100644 --- a/compass/landice/tests/greenland/mesh_gen/mesh_gen.cfg +++ b/compass/landice/tests/greenland/mesh_gen/mesh_gen.cfg @@ -17,9 +17,6 @@ y_max = None # to cull based on distance from margin. cull_distance = 10.0 -# number of processors to use for ESMF_RegridWeightGen -nProcs = 128 - # mesh density parameters # minimum cell spacing (meters) min_spac = 3.e3 @@ -49,6 +46,8 @@ use_dist_to_edge = True use_bed = True [greenland] +# Whether to interpolate data (controls run_optional_interpolation) +interpolate_data = True # path to directory containing BedMachine and Measures datasets # (default value is for Perlmutter) data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ diff --git a/compass/landice/tests/humboldt/mesh.py b/compass/landice/tests/humboldt/mesh.py index 33c4e34eef..11e1eb639e 100644 --- a/compass/landice/tests/humboldt/mesh.py +++ b/compass/landice/tests/humboldt/mesh.py @@ -1,4 +1,10 @@ -from compass.landice.mesh import build_cell_width, build_mali_mesh +from compass.landice.mesh import ( + build_cell_width, + build_mali_mesh, + get_mesh_config_bounding_box, + get_optional_interp_datasets, + run_optional_interpolation, +) from compass.model import make_graph_file from compass.step import Step @@ -48,8 +54,13 @@ def run(self): Run this step of the test case """ logger = self.logger + config = self.config section_name = 'mesh' + section = config[section_name] mesh_name = 'Humboldt.nc' + src_proj = section.get('src_proj') + bedmachine_dataset, measures_dataset = get_optional_interp_datasets( + section, logger) logger.info('calling build_cell_width') cell_width, x1, y1, geom_points, geom_edges, floodMask = \ @@ -64,6 +75,18 @@ def run(self): projection='gis-gimp', geojson_file='Humboldt.geojson', cores=self.cpus_per_task) + parallel_executable = config.get('parallel', 'parallel_executable') + nProcs = section.get('nProcs') + # Only interpolate data if interpolate_data is True in mesh_gen.cfg + interpolate_data = section.getboolean( + 'interpolate_data', fallback=False) + if interpolate_data: + run_optional_interpolation( + self, mesh_name, src_proj, parallel_executable, nProcs, + subset_bounds=get_mesh_config_bounding_box(section), + bedmachine_dataset=bedmachine_dataset, + measures_dataset=measures_dataset) + logger.info('creating graph.info') make_graph_file(mesh_filename=mesh_name, graph_filename='graph.info') diff --git a/compass/landice/tests/humboldt/mesh_gen/mesh_gen.cfg b/compass/landice/tests/humboldt/mesh_gen/mesh_gen.cfg index 6927514134..1f3791019c 100644 --- a/compass/landice/tests/humboldt/mesh_gen/mesh_gen.cfg +++ b/compass/landice/tests/humboldt/mesh_gen/mesh_gen.cfg @@ -42,3 +42,26 @@ use_speed = True use_dist_to_grounding_line = False use_dist_to_edge = True use_bed = True + +# Optional interpolation inputs (skip when set to None) +# Whether to interpolate data (controls run_optional_interpolation) +interpolate_data = False + +# path to directory containing BedMachine and Measures datasets +# (default value is for Perlmutter) +data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + +# filename of the BedMachine thickness and bedTopography dataset +# (default value is for Perlmutter) +bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + +# filename of the MEaSUREs ice velocity dataset +# (default value is for Perlmutter) +measures_filename = greenland_vel_mosaic500_extrap.nc + +# projection of the source datasets, according to the dictionary keys +# create_scrip_file_from_planar_rectangular_grid from MPAS_Tools +src_proj = gis-gimp + +# number of processors to use for ESMF_RegridWeightGen +nProcs = 128 diff --git a/compass/landice/tests/isunnguata_sermia/mesh.py b/compass/landice/tests/isunnguata_sermia/mesh.py index bd7a9bf2e0..e2c50ed1db 100644 --- a/compass/landice/tests/isunnguata_sermia/mesh.py +++ b/compass/landice/tests/isunnguata_sermia/mesh.py @@ -1,4 +1,10 @@ -from compass.landice.mesh import build_cell_width, build_mali_mesh +from compass.landice.mesh import ( + build_cell_width, + build_mali_mesh, + get_mesh_config_bounding_box, + get_optional_interp_datasets, + run_optional_interpolation, +) from compass.model import make_graph_file from compass.step import Step @@ -48,8 +54,13 @@ def run(self): Run this step of the test case """ logger = self.logger + config = self.config section_name = 'mesh' + section = config[section_name] mesh_name = 'Isunnguata_Sermia.nc' + src_proj = section.get('src_proj') + bedmachine_dataset, measures_dataset = get_optional_interp_datasets( + section, logger) logger.info('calling build_cell_width') cell_width, x1, y1, geom_points, geom_edges, floodMask = \ @@ -63,6 +74,18 @@ def run(self): gridded_dataset='greenland_1km_2024_01_29.epsg3413.icesheetonly.nc', # noqa projection='gis-gimp', geojson_file='Isunnguata_Sermia.geojson') + parallel_executable = config.get('parallel', 'parallel_executable') + nProcs = section.get('nProcs') + # Only interpolate data if interpolate_data is True in mesh_gen.cfg + interpolate_data = section.getboolean( + 'interpolate_data', fallback=False) + if interpolate_data: + run_optional_interpolation( + self, mesh_name, src_proj, parallel_executable, nProcs, + subset_bounds=get_mesh_config_bounding_box(section), + bedmachine_dataset=bedmachine_dataset, + measures_dataset=measures_dataset) + logger.info('creating graph.info') make_graph_file(mesh_filename=mesh_name, graph_filename='graph.info') diff --git a/compass/landice/tests/isunnguata_sermia/mesh_gen/mesh_gen.cfg b/compass/landice/tests/isunnguata_sermia/mesh_gen/mesh_gen.cfg index 27c2988eac..c432495dae 100644 --- a/compass/landice/tests/isunnguata_sermia/mesh_gen/mesh_gen.cfg +++ b/compass/landice/tests/isunnguata_sermia/mesh_gen/mesh_gen.cfg @@ -42,3 +42,26 @@ use_speed = True use_dist_to_grounding_line = False use_dist_to_edge = False use_bed = False + +# Optional interpolation inputs (skip when set to None) +# Whether to interpolate data (controls run_optional_interpolation) +interpolate_data = False + +# path to directory containing BedMachine and Measures datasets +# (default value is for Perlmutter) +data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + +# filename of the BedMachine thickness and bedTopography dataset +# (default value is for Perlmutter) +bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + +# filename of the MEaSUREs ice velocity dataset +# (default value is for Perlmutter) +measures_filename = greenland_vel_mosaic500_extrap.nc + +# projection of the source datasets, according to the dictionary keys +# create_scrip_file_from_planar_rectangular_grid from MPAS_Tools +src_proj = gis-gimp + +# number of processors to use for ESMF_RegridWeightGen +nProcs = 128 diff --git a/compass/landice/tests/kangerlussuaq/mesh.py b/compass/landice/tests/kangerlussuaq/mesh.py index 19430ca41f..94bac4d727 100644 --- a/compass/landice/tests/kangerlussuaq/mesh.py +++ b/compass/landice/tests/kangerlussuaq/mesh.py @@ -1,4 +1,10 @@ -from compass.landice.mesh import build_cell_width, build_mali_mesh +from compass.landice.mesh import ( + build_cell_width, + build_mali_mesh, + get_mesh_config_bounding_box, + get_optional_interp_datasets, + run_optional_interpolation, +) from compass.model import make_graph_file from compass.step import Step @@ -49,8 +55,13 @@ def run(self): Run this step of the test case """ logger = self.logger + config = self.config mesh_name = 'Kangerlussuaq.nc' section_name = 'mesh' + section = config[section_name] + src_proj = section.get('src_proj') + bedmachine_dataset, measures_dataset = get_optional_interp_datasets( + section, logger) logger.info('calling build_cell_width') cell_width, x1, y1, geom_points, geom_edges, floodMask = \ @@ -65,6 +76,18 @@ def run(self): projection='gis-gimp', geojson_file='Kangerlussuaq.geojson', cores=self.cpus_per_task) + parallel_executable = config.get('parallel', 'parallel_executable') + nProcs = section.get('nProcs') + # Only interpolate data if interpolate_data is True in mesh_gen.cfg + interpolate_data = section.getboolean( + 'interpolate_data', fallback=False) + if interpolate_data: + run_optional_interpolation( + self, mesh_name, src_proj, parallel_executable, nProcs, + subset_bounds=get_mesh_config_bounding_box(section), + bedmachine_dataset=bedmachine_dataset, + measures_dataset=measures_dataset) + logger.info('creating graph.info') make_graph_file(mesh_filename=mesh_name, graph_filename='graph.info') diff --git a/compass/landice/tests/kangerlussuaq/mesh_gen/mesh_gen.cfg b/compass/landice/tests/kangerlussuaq/mesh_gen/mesh_gen.cfg index 72c5a9da2f..b609542dc8 100644 --- a/compass/landice/tests/kangerlussuaq/mesh_gen/mesh_gen.cfg +++ b/compass/landice/tests/kangerlussuaq/mesh_gen/mesh_gen.cfg @@ -42,3 +42,26 @@ use_speed = True use_dist_to_grounding_line = False use_dist_to_edge = True use_bed = True + +# Optional interpolation inputs (skip when set to None) +# Whether to interpolate data (controls run_optional_interpolation) +interpolate_data = False + +# path to directory containing BedMachine and Measures datasets +# (default value is for Perlmutter) +data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + +# filename of the BedMachine thickness and bedTopography dataset +# (default value is for Perlmutter) +bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + +# filename of the MEaSUREs ice velocity dataset +# (default value is for Perlmutter) +measures_filename = greenland_vel_mosaic500_extrap.nc + +# projection of the source datasets, according to the dictionary keys +# create_scrip_file_from_planar_rectangular_grid from MPAS_Tools +src_proj = gis-gimp + +# number of processors to use for ESMF_RegridWeightGen +nProcs = 128 diff --git a/compass/landice/tests/koge_bugt_s/mesh.py b/compass/landice/tests/koge_bugt_s/mesh.py index 65492095ae..61c4f8f940 100644 --- a/compass/landice/tests/koge_bugt_s/mesh.py +++ b/compass/landice/tests/koge_bugt_s/mesh.py @@ -1,4 +1,10 @@ -from compass.landice.mesh import build_cell_width, build_mali_mesh +from compass.landice.mesh import ( + build_cell_width, + build_mali_mesh, + get_mesh_config_bounding_box, + get_optional_interp_datasets, + run_optional_interpolation, +) from compass.model import make_graph_file from compass.step import Step @@ -49,8 +55,13 @@ def run(self): Run this step of the test case """ logger = self.logger + config = self.config mesh_name = 'Koge_Bugt_S.nc' section_name = 'mesh' + section = config[section_name] + src_proj = section.get('src_proj') + bedmachine_dataset, measures_dataset = get_optional_interp_datasets( + section, logger) logger.info('calling build_cell_width') cell_width, x1, y1, geom_points, geom_edges, floodMask = \ @@ -65,6 +76,18 @@ def run(self): projection='gis-gimp', geojson_file='Koge_Bugt_S.geojson', cores=self.cpus_per_task) + parallel_executable = config.get('parallel', 'parallel_executable') + nProcs = section.get('nProcs') + # Only interpolate data if interpolate_data is True in mesh_gen.cfg + interpolate_data = section.getboolean( + 'interpolate_data', fallback=False) + if interpolate_data: + run_optional_interpolation( + self, mesh_name, src_proj, parallel_executable, nProcs, + subset_bounds=get_mesh_config_bounding_box(section), + bedmachine_dataset=bedmachine_dataset, + measures_dataset=measures_dataset) + logger.info('creating graph.info') make_graph_file(mesh_filename=mesh_name, graph_filename='graph.info') diff --git a/compass/landice/tests/koge_bugt_s/mesh_gen/mesh_gen.cfg b/compass/landice/tests/koge_bugt_s/mesh_gen/mesh_gen.cfg index 770432a6d8..e4afcbba1d 100644 --- a/compass/landice/tests/koge_bugt_s/mesh_gen/mesh_gen.cfg +++ b/compass/landice/tests/koge_bugt_s/mesh_gen/mesh_gen.cfg @@ -44,3 +44,26 @@ use_speed = True use_dist_to_grounding_line = False use_dist_to_edge = True use_bed = False + +# Optional interpolation inputs (skip when set to None) +# Whether to interpolate data (controls run_optional_interpolation) +interpolate_data = False + +# path to directory containing BedMachine and Measures datasets +# (default value is for Perlmutter) +data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + +# filename of the BedMachine thickness and bedTopography dataset +# (default value is for Perlmutter) +bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + +# filename of the MEaSUREs ice velocity dataset +# (default value is for Perlmutter) +measures_filename = greenland_vel_mosaic500_extrap.nc + +# projection of the source datasets, according to the dictionary keys +# create_scrip_file_from_planar_rectangular_grid from MPAS_Tools +src_proj = gis-gimp + +# number of processors to use for ESMF_RegridWeightGen +nProcs = 128 diff --git a/compass/landice/tests/thwaites/mesh.py b/compass/landice/tests/thwaites/mesh.py index 342febacf9..0c1b6a439b 100644 --- a/compass/landice/tests/thwaites/mesh.py +++ b/compass/landice/tests/thwaites/mesh.py @@ -1,4 +1,10 @@ -from compass.landice.mesh import build_cell_width, build_mali_mesh +from compass.landice.mesh import ( + build_cell_width, + build_mali_mesh, + get_mesh_config_bounding_box, + get_optional_interp_datasets, + run_optional_interpolation, +) from compass.model import make_graph_file from compass.step import Step @@ -38,8 +44,13 @@ def run(self): Run this step of the test case """ logger = self.logger + config = self.config mesh_name = 'Thwaites.nc' section_name = 'mesh' + section = config[section_name] + src_proj = section.get('src_proj') + bedmachine_dataset, measures_dataset = get_optional_interp_datasets( + section, logger) logger.info('calling build_cell_width') cell_width, x1, y1, geom_points, geom_edges, floodMask = \ @@ -54,6 +65,18 @@ def run(self): projection='ais-bedmap2', geojson_file='thwaites_minimal.geojson', cores=self.cpus_per_task) + parallel_executable = config.get('parallel', 'parallel_executable') + nProcs = section.get('nProcs') + # Only interpolate data if interpolate_data is True in mesh_gen.cfg + interpolate_data = section.getboolean( + 'interpolate_data', fallback=False) + if interpolate_data: + run_optional_interpolation( + self, mesh_name, src_proj, parallel_executable, nProcs, + subset_bounds=get_mesh_config_bounding_box(section), + bedmachine_dataset=bedmachine_dataset, + measures_dataset=measures_dataset) + logger.info('creating graph.info') make_graph_file(mesh_filename=mesh_name, graph_filename='graph.info') diff --git a/compass/landice/tests/thwaites/mesh_gen/mesh_gen.cfg b/compass/landice/tests/thwaites/mesh_gen/mesh_gen.cfg index 98ae96049e..a21fcb0461 100644 --- a/compass/landice/tests/thwaites/mesh_gen/mesh_gen.cfg +++ b/compass/landice/tests/thwaites/mesh_gen/mesh_gen.cfg @@ -46,3 +46,26 @@ use_speed = True use_dist_to_grounding_line = True use_dist_to_edge = False use_bed = False + +# Optional interpolation inputs (skip when set to None) +# Whether to interpolate data (controls run_optional_interpolation) +interpolate_data = False + +# path to directory containing BedMachine and Measures datasets +# (default value is for Perlmutter) +data_path = /global/cfs/cdirs/fanssie/standard_datasets/AIS_datasets + +# filename of the BedMachine thickness and bedTopography dataset +# (default value is for Perlmutter) +bedmachine_filename = BedMachineAntarctica_2020-07-15_v02_edits_floodFill_extrap_fillVostok.nc + +# filename of the MEASURES ice velocity dataset +# (default value is for Perlmutter) +measures_filename = antarctica_ice_velocity_450m_v2_edits_extrap.nc + +# projection of the source datasets, according to the dictionary keys +# create_scrip_file_from_planar_rectangular_grid from MPAS_Tools +src_proj = ais-bedmap2 + +# number of processors to use for ESMF_RegridWeightGen +nProcs = 128 diff --git a/docs/developers_guide/landice/api.rst b/docs/developers_guide/landice/api.rst index 2c83287ad6..2c50f44335 100644 --- a/docs/developers_guide/landice/api.rst +++ b/docs/developers_guide/landice/api.rst @@ -493,12 +493,16 @@ Landice Framework mesh.add_bedmachine_thk_to_ais_gridded_data mesh.clean_up_after_interp mesh.clip_mesh_to_bounding_box + mesh.get_mesh_config_bounding_box + mesh.get_optional_interp_datasets mesh.gridded_flood_fill mesh.interp_gridded2mali mesh.mpas_flood_fill mesh.preprocess_ais_data + mesh.run_optional_interpolation mesh.set_rectangular_geom_points_and_edges mesh.set_cell_width + mesh.subset_gridded_dataset_to_bounds mesh.get_dist_to_edge_and_gl mesh.build_cell_width mesh.build_mali_mesh diff --git a/docs/developers_guide/landice/framework.rst b/docs/developers_guide/landice/framework.rst index 0b603fdb2e..9749cf7200 100644 --- a/docs/developers_guide/landice/framework.rst +++ b/docs/developers_guide/landice/framework.rst @@ -110,16 +110,14 @@ not necessarily with the same values shown here, which are the defaults for the Humboldt mesh): .. code-block:: cfg - + # config options for humboldt test cases [mesh] # number of levels in the mesh levels = 10 - # Bounds of Humboldt domain. If you want the extent - # of the gridded dataset to determine the extent of - # the MALI domain, set these to None. + # Bounds of Humboldt domain x_min = -630000. x_max = 84000. y_min = -1560000. @@ -143,8 +141,6 @@ Humboldt mesh): high_dist = 1.e5 # distance within which cell spacing = min_spac (meters) low_dist = 1.e4 - - # These *_bed settings are only applied when use_bed = True. # distance at which bed topography has no effect high_dist_bed = 1.e5 # distance within which bed topography has maximum effect @@ -159,3 +155,32 @@ Humboldt mesh): use_dist_to_grounding_line = False use_dist_to_edge = True use_bed = True + + # Optional interpolation inputs (skip when set to None) + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = False + + # path to directory containing BedMachine and Measures datasets + # (default value is for Perlmutter) + data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + + # filename of the BedMachine thickness and bedTopography dataset + # (default value is for Perlmutter) + bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + + # filename of the MEaSUREs ice velocity dataset + # (default value is for Perlmutter) + measures_filename = greenland_vel_mosaic500_extrap.nc + + # projection of the source datasets, according to the dictionary keys + # create_scrip_file_from_planar_rectangular_grid from MPAS_Tools + src_proj = gis-gimp + + # number of processors to use for ESMF_RegridWeightGen + nProcs = 128 + +For mesh prototyping, it is a good idea to use `interpolate_data = False`, +as the interpolation step can be slow and require many more resources than +the rest of the mesh generation process. For instance, a 1–10km Greenland mesh +can be created on a single Perlmutter CPU node, but data interpolation may +require up to 16 nodes. \ No newline at end of file diff --git a/docs/developers_guide/landice/test_groups/antarctica.rst b/docs/developers_guide/landice/test_groups/antarctica.rst index 76041d0cb9..55f5ef4613 100644 --- a/docs/developers_guide/landice/test_groups/antarctica.rst +++ b/docs/developers_guide/landice/test_groups/antarctica.rst @@ -47,6 +47,13 @@ Third, ``preprocess_ais_data`` is called to perform a series of adjustments to the AIS datasets needed to work with the rest of the workflow. From here, dataset interpolation happens, starting with the standard -interpolation script applied to the standard dataset, followed by bespoke +interpolation script applied to the standard dataset, followed by optional interpolation of the high resolution BedMachine and MEASURES datasets. The step completes with some clean up and creation of a graph file. + +The BedMachine and MEaSUREs remapping steps are optional and are controlled by +``[antarctica]`` config options. If ``data_path`` or the corresponding +filename is unset (empty or ``None``), that dataset interpolation is skipped. +The default config includes both datasets, so interpolation is enabled by +default. +The base-mesh projection in ``build_mali_mesh()`` is fixed for this test case. diff --git a/docs/developers_guide/landice/test_groups/crane.rst b/docs/developers_guide/landice/test_groups/crane.rst index 7636cea85a..1e337e8325 100644 --- a/docs/developers_guide/landice/test_groups/crane.rst +++ b/docs/developers_guide/landice/test_groups/crane.rst @@ -28,3 +28,12 @@ mesh_gen The :py:class:`compass.landice.tests.crane.mesh_gen.MeshGen` calls the :py:class:`compass.landice.tests.crane.mesh.Mesh` to create the variable resolution Crane Glacier mesh. + +Optional BedMachine and MEaSUREs interpolation can be enabled through +``[mesh]`` config options ``nProcs``, ``src_proj``, ``data_path``, +``bedmachine_filename``, and ``measures_filename``. If enabled, source +datasets are subset to the +configured mesh bounding box before SCRIP generation and conservative +remapping. +The ``src_proj`` option is used for optional remapping only; the +base-mesh projection in ``build_mali_mesh()`` is fixed for this test case. diff --git a/docs/developers_guide/landice/test_groups/greenland.rst b/docs/developers_guide/landice/test_groups/greenland.rst index cdc7e1a3d2..8beb16f9f4 100644 --- a/docs/developers_guide/landice/test_groups/greenland.rst +++ b/docs/developers_guide/landice/test_groups/greenland.rst @@ -101,3 +101,9 @@ velocity observations are conservatively remapped from BedMachine v5 and MEaSUREs 2006-2010 data sets. Finally, there is some cleanup to set large velocity uncertainties outside the ice mask, check the sign of the basal heat flux, and set reasonable values for dH/dt and its uncertainty. + +The BedMachine and MEaSUREs remapping steps are optional and are controlled by +``[greenland]`` config options. If ``data_path`` or the corresponding filename +is unset (empty or ``None``), that dataset interpolation is skipped. The +default config includes both datasets, so interpolation is enabled by default. +The base-mesh projection in ``build_mali_mesh()`` is fixed for this test case. diff --git a/docs/developers_guide/landice/test_groups/humboldt.rst b/docs/developers_guide/landice/test_groups/humboldt.rst index 1836091e19..bfd30883f1 100644 --- a/docs/developers_guide/landice/test_groups/humboldt.rst +++ b/docs/developers_guide/landice/test_groups/humboldt.rst @@ -30,6 +30,15 @@ The :py:class:`compass.landice.tests.humboldt.mesh_gen.MeshGen` calls the :py:class:`compass.landice.tests.humboldt.mesh.Mesh` to create the 1-10 km variable resolution Humboldt Glacier mesh. +Optional BedMachine and MEaSUREs interpolation can be enabled through +``[mesh]`` config options ``nProcs``, ``src_proj``, ``data_path``, +``bedmachine_filename``, and ``measures_filename``. If enabled, source +datasets are subset to the +configured mesh bounding box before SCRIP generation and conservative +remapping. +The ``src_proj`` option is used for optional remapping only; the +base-mesh projection in ``build_mali_mesh()`` is fixed for this test case. + run_model --------- The :py:class:`compass.landice.tests.humboldt.run_model.RunModel` defines diff --git a/docs/developers_guide/landice/test_groups/isunnguata_sermia.rst b/docs/developers_guide/landice/test_groups/isunnguata_sermia.rst index d76d6e4753..3515f1d761 100644 --- a/docs/developers_guide/landice/test_groups/isunnguata_sermia.rst +++ b/docs/developers_guide/landice/test_groups/isunnguata_sermia.rst @@ -28,3 +28,12 @@ mesh_gen The :py:class:`compass.landice.tests.isunnguata_sermia.mesh_gen.MeshGen` calls the :py:class:`compass.landice.tests.isunnguata_sermia.mesh.Mesh` to create the variable resolution Isunnguata Sermia mesh. + +Optional BedMachine and MEaSUREs interpolation can be enabled through +``[mesh]`` config options ``nProcs``, ``src_proj``, ``data_path``, +``bedmachine_filename``, and ``measures_filename``. If enabled, source +datasets are subset to the +configured mesh bounding box before SCRIP generation and conservative +remapping. +The ``src_proj`` option is used for optional remapping only; the +base-mesh projection in ``build_mali_mesh()`` is fixed for this test case. diff --git a/docs/developers_guide/landice/test_groups/kangerlussuaq.rst b/docs/developers_guide/landice/test_groups/kangerlussuaq.rst index ff33ddf537..d26936c814 100644 --- a/docs/developers_guide/landice/test_groups/kangerlussuaq.rst +++ b/docs/developers_guide/landice/test_groups/kangerlussuaq.rst @@ -28,3 +28,12 @@ mesh_gen The :py:class:`compass.landice.tests.kangerlussuaq.mesh_gen.MeshGen` calls the :py:class:`compass.landice.tests.kangerlussuaq.mesh.Mesh` to create the variable resolution Kangerlussuaq Glacier mesh. + +Optional BedMachine and MEaSUREs interpolation can be enabled through +``[mesh]`` config options ``nProcs``, ``src_proj``, ``data_path``, +``bedmachine_filename``, and ``measures_filename``. If enabled, source +datasets are subset to the +configured mesh bounding box before SCRIP generation and conservative +remapping. +The ``src_proj`` option is used for optional remapping only; the +base-mesh projection in ``build_mali_mesh()`` is fixed for this test case. diff --git a/docs/developers_guide/landice/test_groups/koge_bugt_s.rst b/docs/developers_guide/landice/test_groups/koge_bugt_s.rst index 4f88a16d0a..ce8f6bf613 100644 --- a/docs/developers_guide/landice/test_groups/koge_bugt_s.rst +++ b/docs/developers_guide/landice/test_groups/koge_bugt_s.rst @@ -28,3 +28,12 @@ mesh_gen The :py:class:`compass.landice.tests.koge_bugt_s.mesh_gen.MeshGen` calls the :py:class:`compass.landice.tests.koge_bugt_s.mesh.Mesh` to create the variable resolution Koge Bugt S mesh. + +Optional BedMachine and MEaSUREs interpolation can be enabled through +``[mesh]`` config options ``nProcs``, ``src_proj``, ``data_path``, +``bedmachine_filename``, and ``measures_filename``. If enabled, source +datasets are subset to the +configured mesh bounding box before SCRIP generation and conservative +remapping. +The ``src_proj`` option is used for optional remapping only; the +base-mesh projection in ``build_mali_mesh()`` is fixed for this test case. diff --git a/docs/developers_guide/landice/test_groups/thwaites.rst b/docs/developers_guide/landice/test_groups/thwaites.rst index 7217d948d4..66795739dc 100644 --- a/docs/developers_guide/landice/test_groups/thwaites.rst +++ b/docs/developers_guide/landice/test_groups/thwaites.rst @@ -76,3 +76,12 @@ mesh_gen The :py:class:`compass.landice.tests.thwaites.mesh_gen.MeshGen` calls the :py:class:`compass.landice.tests.thwaites.mesh.Mesh` to create the variable resolution Thwaites Glacier mesh. + +Optional BedMachine and MEaSUREs interpolation can be enabled through +``[mesh]`` config options ``nProcs``, ``src_proj``, ``data_path``, +``bedmachine_filename``, and ``measures_filename``. If enabled, source +datasets are subset to the +configured mesh bounding box before SCRIP generation and conservative +remapping. +The ``src_proj`` option is used for optional remapping only; the +base-mesh projection in ``build_mali_mesh()`` is fixed for this test case. diff --git a/docs/users_guide/landice/test_groups/antarctica.rst b/docs/users_guide/landice/test_groups/antarctica.rst index ec49e5f1df..115d7ade26 100644 --- a/docs/users_guide/landice/test_groups/antarctica.rst +++ b/docs/users_guide/landice/test_groups/antarctica.rst @@ -70,6 +70,8 @@ the mesh generation options are adjusted through the config file. use_bed = False [antarctica] + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = True # path to directory containing BedMachine and Measures datasets # (default value is for Perlmutter) data_path = /global/cfs/cdirs/fanssie/standard_datasets/AIS_datasets @@ -115,4 +117,11 @@ or the processed data files could be added to the server on Anvil and downloaded as needed. However, until then, this test case provides a reproducible workflow for setting up Antarctic meshes at varying resolutions +The BedMachine and MEaSUREs interpolation is optional. If ``data_path`` or the +corresponding filename in ``[antarctica]`` is unset (empty or ``None``), that +dataset interpolation step is skipped. The default config values include both +datasets, so interpolation is enabled by default. +The base-mesh projection used in ``build_mali_mesh()`` is fixed for this test +case. + There is no model integration step. diff --git a/docs/users_guide/landice/test_groups/crane.rst b/docs/users_guide/landice/test_groups/crane.rst index 019482763a..2e8166e68a 100644 --- a/docs/users_guide/landice/test_groups/crane.rst +++ b/docs/users_guide/landice/test_groups/crane.rst @@ -73,6 +73,27 @@ the mesh generation options are adjusted through the config file. use_dist_to_edge = False use_bed = False + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = False + # path to directory containing BedMachine and Measures datasets + # (default value is for Perlmutter) + data_path = /global/cfs/cdirs/fanssie/standard_datasets/AIS_datasets + + # filename of the BedMachine thickness and bedTopography dataset + # (default value is for Perlmutter) + bedmachine_filename = BedMachineAntarctica_2020-07-15_v02_edits_floodFill_extrap_fillVostok.nc + + # filename of the MEASURES ice velocity dataset + # (default value is for Perlmutter) + measures_filename = antarctica_ice_velocity_450m_v2_edits_extrap.nc + + # projection of the source datasets, according to the dictionary keys + # create_scrip_file_from_planar_rectangular_grid from MPAS_Tools + src_proj = ais-bedmap2 + + # number of processors to use for ESMF_RegridWeightGen + nProcs = 128 + mesh_gen -------- @@ -80,3 +101,9 @@ mesh_gen The default is 500m-1km resolution with mesh density determined by observed ice speed and distance to grounding line. There is no model integration step. + +If optional BedMachine and/or MEaSUREs datasets are configured, they are +subset to the mesh bounding box from ``[mesh]`` before SCRIP generation and +conservative remapping to reduce memory and runtime. +The base-mesh projection used in ``build_mali_mesh()`` is fixed for this test +case. diff --git a/docs/users_guide/landice/test_groups/greenland.rst b/docs/users_guide/landice/test_groups/greenland.rst index d50f2f2a46..d8950c634e 100644 --- a/docs/users_guide/landice/test_groups/greenland.rst +++ b/docs/users_guide/landice/test_groups/greenland.rst @@ -55,9 +55,6 @@ The other test cases do not use config options. # to cull based on distance from margin. cull_distance = 10.0 - # number of processors to use for ESMF_RegridWeightGen - nProcs = 128 - # mesh density parameters # minimum cell spacing (meters) min_spac = 3.e3 @@ -87,15 +84,20 @@ The other test cases do not use config options. use_bed = True [greenland] + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = True # path to directory containing BedMachine and Measures datasets # (default value is for Perlmutter) data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + # geojson used to create the cull mask in mesh generation + geojson_filename = greenland_only_outline_45km_buffer_latlon_singlepart.geojson + # filename of the BedMachine thickness and bedTopography dataset # (default value is for Perlmutter) bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc - # filename of the MEASURES ice velocity dataset + # filename of the MEaSUREs ice velocity dataset # (default value is for Perlmutter) measures_filename = greenland_vel_mosaic500_extrap.nc @@ -156,3 +158,10 @@ that pre-processing could be integrated into a new step in COMPASS, or the processed data files could be added to the server on Anvil and downloaded as needed. However, until then, this test case provides a reproducible workflow for setting up Greenland meshes at varying resolutions. + +The BedMachine and MEaSUREs interpolation is optional. If ``data_path`` or the +corresponding filename in ``[greenland]`` is unset (empty or ``None``), that +dataset interpolation step is skipped. The default config values include both +datasets, so interpolation is enabled by default. +The base-mesh projection used in ``build_mali_mesh()`` is fixed for this test +case. diff --git a/docs/users_guide/landice/test_groups/humboldt.rst b/docs/users_guide/landice/test_groups/humboldt.rst index 724ff9cf04..1972859daf 100644 --- a/docs/users_guide/landice/test_groups/humboldt.rst +++ b/docs/users_guide/landice/test_groups/humboldt.rst @@ -65,12 +65,42 @@ the mesh generation options are adjusted through the config file. use_dist_to_grounding_line = False use_dist_to_edge = True + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = False + # path to directory containing BedMachine and Measures datasets + # (default value is for Perlmutter) + data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + + # geojson used to create the cull mask in mesh generation + geojson_filename = greenland_only_outline_45km_buffer_latlon_singlepart.geojson + + # filename of the BedMachine thickness and bedTopography dataset + # (default value is for Perlmutter) + bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + + # filename of the MEaSUREs ice velocity dataset + # (default value is for Perlmutter) + measures_filename = greenland_vel_mosaic500_extrap.nc + + # projection of the source datasets, according to the dictionary keys + # create_scrip_file_from_planar_rectangular_grid from MPAS_Tools + src_proj = gis-gimp + + # number of processors to use for ESMF_RegridWeightGen + nProcs = 128 + mesh_gen -------- ``landice/humboldt/default`` creates a 1-10km variable resolution mesh. There is no model integration step. +If optional BedMachine and/or MEaSUREs datasets are configured, they are +subset to the mesh bounding box from ``[mesh]`` before SCRIP generation and +conservative remapping to reduce memory and runtime. +The base-mesh projection used in ``build_mali_mesh()`` is fixed for this test +case. + decomposition_tests ------------------- diff --git a/docs/users_guide/landice/test_groups/isunnguata_sermia.rst b/docs/users_guide/landice/test_groups/isunnguata_sermia.rst index 3cb66b0936..30ab9e92de 100644 --- a/docs/users_guide/landice/test_groups/isunnguata_sermia.rst +++ b/docs/users_guide/landice/test_groups/isunnguata_sermia.rst @@ -69,9 +69,39 @@ the mesh generation options are adjusted through the config file. use_dist_to_edge = False use_bed = False + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = False + # path to directory containing BedMachine and Measures datasets + # (default value is for Perlmutter) + data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + + # geojson used to create the cull mask in mesh generation + geojson_filename = greenland_only_outline_45km_buffer_latlon_singlepart.geojson + + # filename of the BedMachine thickness and bedTopography dataset + # (default value is for Perlmutter) + bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + + # filename of the MEaSUREs ice velocity dataset + # (default value is for Perlmutter) + measures_filename = greenland_vel_mosaic500_extrap.nc + + # projection of the source datasets, according to the dictionary keys + # create_scrip_file_from_planar_rectangular_grid from MPAS_Tools + src_proj = gis-gimp + + # number of processors to use for ESMF_RegridWeightGen + nProcs = 128 + mesh_gen -------- ``landice/isunnguata_sermia/mesh_gen`` creates a variable resolution mesh. The default is 1-10km resolution with mesh density determined by observed ice speed. There is no model integration step. + +If optional BedMachine and/or MEaSUREs datasets are configured, they are +subset to the mesh bounding box from ``[mesh]`` before SCRIP generation and +conservative remapping to reduce memory and runtime. +The base-mesh projection used in ``build_mali_mesh()`` is fixed for this test +case. diff --git a/docs/users_guide/landice/test_groups/kangerlussuaq.rst b/docs/users_guide/landice/test_groups/kangerlussuaq.rst index 5c91bd16a6..c00130390a 100644 --- a/docs/users_guide/landice/test_groups/kangerlussuaq.rst +++ b/docs/users_guide/landice/test_groups/kangerlussuaq.rst @@ -53,6 +53,30 @@ the mesh generation options are adjusted through the config file. use_dist_to_grounding_line = False use_dist_to_edge = True + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = False + # path to directory containing BedMachine and Measures datasets + # (default value is for Perlmutter) + data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + + # geojson used to create the cull mask in mesh generation + geojson_filename = greenland_only_outline_45km_buffer_latlon_singlepart.geojson + + # filename of the BedMachine thickness and bedTopography dataset + # (default value is for Perlmutter) + bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + + # filename of the MEaSUREs ice velocity dataset + # (default value is for Perlmutter) + measures_filename = greenland_vel_mosaic500_extrap.nc + + # projection of the source datasets, according to the dictionary keys + # create_scrip_file_from_planar_rectangular_grid from MPAS_Tools + src_proj = gis-gimp + + # number of processors to use for ESMF_RegridWeightGen + nProcs = 128 + mesh_gen -------- @@ -60,3 +84,9 @@ mesh_gen The default is 1-10km resolution with mesh density determined by observed ice speed and distance to ice margin. There is no model integration step. + +If optional BedMachine and/or MEaSUREs datasets are configured, they are +subset to the mesh bounding box from ``[mesh]`` before SCRIP generation and +conservative remapping to reduce memory and runtime. +The base-mesh projection used in ``build_mali_mesh()`` is fixed for this test +case. diff --git a/docs/users_guide/landice/test_groups/koge_bugt_s.rst b/docs/users_guide/landice/test_groups/koge_bugt_s.rst index 4f65ad5009..5053982d64 100644 --- a/docs/users_guide/landice/test_groups/koge_bugt_s.rst +++ b/docs/users_guide/landice/test_groups/koge_bugt_s.rst @@ -53,6 +53,30 @@ the mesh generation options are adjusted through the config file. use_dist_to_grounding_line = False use_dist_to_edge = True + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = False + # path to directory containing BedMachine and Measures datasets + # (default value is for Perlmutter) + data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ + + # geojson used to create the cull mask in mesh generation + geojson_filename = greenland_only_outline_45km_buffer_latlon_singlepart.geojson + + # filename of the BedMachine thickness and bedTopography dataset + # (default value is for Perlmutter) + bedmachine_filename = BedMachineGreenland-v6_edits_floodFill_extrap.nc + + # filename of the MEaSUREs ice velocity dataset + # (default value is for Perlmutter) + measures_filename = greenland_vel_mosaic500_extrap.nc + + # projection of the source datasets, according to the dictionary keys + # create_scrip_file_from_planar_rectangular_grid from MPAS_Tools + src_proj = gis-gimp + + # number of processors to use for ESMF_RegridWeightGen + nProcs = 128 + mesh_gen -------- @@ -60,3 +84,9 @@ mesh_gen The default is 500m-4km resolution with mesh density determined by observed ice speed and distance to ice margin. There is no model integration step. + +If optional BedMachine and/or MEaSUREs datasets are configured, they are +subset to the mesh bounding box from ``[mesh]`` before SCRIP generation and +conservative remapping to reduce memory and runtime. +The base-mesh projection used in ``build_mali_mesh()`` is fixed for this test +case. diff --git a/docs/users_guide/landice/test_groups/thwaites.rst b/docs/users_guide/landice/test_groups/thwaites.rst index 9a7c4bf0b1..5e0f0e7c92 100644 --- a/docs/users_guide/landice/test_groups/thwaites.rst +++ b/docs/users_guide/landice/test_groups/thwaites.rst @@ -66,6 +66,27 @@ The other test cases do not use config options. use_dist_to_grounding_line = True use_dist_to_edge = True + # Whether to interpolate data (controls run_optional_interpolation) + interpolate_data = False + # path to directory containing BedMachine and Measures datasets + # (default value is for Perlmutter) + data_path = /global/cfs/cdirs/fanssie/standard_datasets/AIS_datasets + + # filename of the BedMachine thickness and bedTopography dataset + # (default value is for Perlmutter) + bedmachine_filename = BedMachineAntarctica_2020-07-15_v02_edits_floodFill_extrap_fillVostok.nc + + # filename of the MEASURES ice velocity dataset + # (default value is for Perlmutter) + measures_filename = antarctica_ice_velocity_450m_v2_edits_extrap.nc + + # projection of the source datasets, according to the dictionary keys + # create_scrip_file_from_planar_rectangular_grid from MPAS_Tools + src_proj = ais-bedmap2 + + # number of processors to use for ESMF_RegridWeightGen + nProcs = 128 + decomposition_test ------------------ @@ -92,3 +113,9 @@ on the the config options listed above. This will not be the same as the pre-generated 4-14km mesh used in ``decomposition_test`` and ``restart_test`` because it uses a newer version of Jigsaw. Note that the basal friction optimization is performed separately and is not part of this test case. + +If optional BedMachine and/or MEaSUREs datasets are configured, they are +subset to the mesh bounding box from ``[mesh]`` before SCRIP generation and +conservative remapping to reduce memory and runtime. +The base-mesh projection used in ``build_mali_mesh()`` is fixed for this test +case.