diff --git a/src/polartoolkit/fetch.py b/src/polartoolkit/fetch.py index de096e24..fbdc76f2 100644 --- a/src/polartoolkit/fetch.py +++ b/src/polartoolkit/fetch.py @@ -270,45 +270,205 @@ def __call__(self, url: str, output_file: str, dataset: typing.Any) -> None: raise error -def sample_shp(name: str) -> str: +class SampleShp: """ - Load the file path of sample shapefiles + Retrieve some sample shapefiles. Parameters ---------- - name : str + version : str chose which sample shapefile to load, either 'Disco_deep_transect' or 'Roosevelt_Island' - Returns - ------- - str - file path as a string + Attributes + ---------- + version : str + chosen version of the data + description : str + short description of the data + url : str + url data is downloaded from + known_hash : str + hash of the requested file + path : str + path to the downloaded file + """ + + def __init__(self, version) -> None: + self.version = version + self.description = "shapefiles for using in the polartoolkit tutorials" + self.url = f"doi:10.6084/m9.figshare.26039578.v1/{self.version}.zip" + + if self.version == "Disco_deep_transect" or self.version == "Roosevelt_Island": + self.known_hash = None + else: + msg = "invalid name string" + raise ValueError(msg) + + path = pooch.retrieve( + url=self.url, + path=f"{pooch.os_cache('pooch')}/polartoolkit/shapefiles", + fname=self.version, + processor=pooch.Unzip(), + known_hash=self.known_hash, + ) + self.path: str = next(p for p in path if p.endswith(".shp")) + + def __call__(self): + return self.path + + +@deprecation.deprecated( + deprecated_in="0.5.0", + removed_in="0.10.0", + current_version=polartoolkit.__version__, + details="Use the new class SampleShp instead", +) +def sample_shp(name: str) -> str: + """deprecated function, use class SampleShp instead""" + return SampleShp(name)() + +class MassChange: + """ + Ice-sheet height and thickness changes from ICESat to ICESat-2 for both Antarctica + and Greenland + from :footcite:t:`smithpervasive2020`. + + Choose a version of the data to download with the format: "ICESHEET_VERSION_TYPE" + where ICESHEET is "ais" or "gris", for Antarctica or Greenland, which is + automatically set via the hemisphere variable. VERSION is "dhdt" for total thickness + change or "dmdt" for corrected for firn-air content. For Antarctica data, TYPE is + "floating" or "grounded". + + add "_filt" to retrieve a filtered version of the data. + + accessed from https://digital.lib.washington.edu/researchworks/handle/1773/45388 + + Units are in m/yr + + Parameters + ---------- + version : str, optional, + choose which version to retrieve, by default is "dhdt_grounded" for Antarctica + and "dhdt" for Greenland. + hemisphere : str, optional + choose which hemisphere to retrieve data for, "north" or "south", by default + None + + Attributes + ---------- + version : str + chosen version of the data + description : str + short description of the data + url : str + url data is downloaded from + known_hash : str + hash of the requested file + path : str + path to the downloaded file + original_info : tuple + tuple of the info of the original data, (spacing, region, min, max, + registration) + info: tuple + tuple of the info on the loaded grids, (spacing, region, min, max, + registration) + + References + ---------- + .. footbibliography:: """ - if name == "Disco_deep_transect": - known_hash = ( - None # "ffffeef15d7556cd60305e6222852e3b4e09da3b6c628a094c1e99ac6d605303" + def __init__( + self, + version: str | None = None, + hemisphere: str | None = None, + ): + self.version = version + self.description = ( + "Ice-sheet height and thickness changes from ICESat to ICESat-2" ) - elif name == "Roosevelt_Island": - known_hash = ( - None # "f3821b8a4d24dd676f75db4b7f2b532a328de18e0bdcce8cee6a6abb3b3e70f6" + self.url = ( + "https://digital.lib.washington.edu/researchworks/bitstream/handle/1773/" + "45388/ICESat1_ICESat2_mass_change_updated_2_2021%20%281%29.zip?sequence" + "=4&isAllowed=y" + ) + self.doi = "https://doi.org/10.1126/science.aaz5845" + self.known_hash = None + self.original_info = ( + 5000.0, + (-2526157.06916, 2648842.93084, -2124966.01441, 2180033.98559), + -27.9492435455, + 1.03691923618, + "p", ) - else: - msg = "invalid name string" - raise ValueError(msg) - path = pooch.retrieve( - url=f"doi:10.6084/m9.figshare.26039578.v1/{name}.zip", - path=f"{pooch.os_cache('pooch')}/polartoolkit/shapefiles", - fname=name, - processor=pooch.Unzip(), - known_hash=known_hash, - ) - val: str = next(p for p in path if p.endswith(".shp")) - return val + hemisphere = utils.default_hemisphere(hemisphere) + zip_fname = "ICESat1_ICESat2_mass_change_updated_2_2021.zip" + + if self.version is None: + if hemisphere == "south": + self.version = "dhdt_grounded" + elif hemisphere == "north": + self.version = "dhdt" + + if hemisphere == "south": + self.version = f"ais_{self.version}" + elif hemisphere == "north": + self.version = f"gris_{self.version}" + + if "dhdt" in self.version: # type: ignore[operator] + fname = f"dhdt/{self.version}.tif" + elif "dmdt" in version: # type: ignore[operator] + fname = f"dmdt/{self.version}.tif" + + fpath = pooch.retrieve( + url=self.url, + fname=zip_fname, + path=f"{pooch.os_cache('pooch')}/polartoolkit/mass_change", + known_hash=self.known_hash, + progressbar=True, + processor=pooch.Unzip( + extract_dir="Smith_2020", + ), + ) + self.path = next(p for p in fpath if p.endswith(fname)) + + def __call__( + self, + region: tuple[float, float, float, float] | None = None, + spacing: float | None = None, + registration: str | None = None, + ): + grid = ( + xr.load_dataarray( + self.path, + engine="rasterio", + ) + .squeeze() + .drop_vars(["band", "spatial_ref"]) + ) + + resampled = resample_grid( + grid, + initial_spacing=self.original_info[0], + initial_region=self.original_info[1], + initial_registration=self.original_info[4], + spacing=spacing, + region=region, + registration=registration, + ) + self.info = utils.get_grid_info(resampled) + + return resampled +@deprecation.deprecated( + deprecated_in="0.5.0", + removed_in="0.10.0", + current_version=polartoolkit.__version__, + details="Use the new class MassChange instead", +) def mass_change( version: str | None = None, hemisphere: str | None = None, @@ -348,53 +508,8 @@ def mass_change( ---------- .. footbibliography:: """ - hemisphere = utils.default_hemisphere(hemisphere) - - # This is the path to the processed (magnitude) grid - url = ( - "https://digital.lib.washington.edu/researchworks/bitstream/handle/1773/" - "45388/ICESat1_ICESat2_mass_change_updated_2_2021%20%281%29.zip?sequence" - "=4&isAllowed=y" - ) - - zip_fname = "ICESat1_ICESat2_mass_change_updated_2_2021.zip" - if version is None: - if hemisphere == "south": - version = "dhdt_grounded" - elif hemisphere == "north": - version = "dhdt" - - if hemisphere == "south": - version = f"ais_{version}" - elif hemisphere == "north": - version = f"gris_{version}" - - if "dhdt" in version: # type: ignore[operator] - fname = f"dhdt/{version}.tif" - elif "dmdt" in version: # type: ignore[operator] - fname = f"dmdt/{version}.tif" - - path = pooch.retrieve( - url=url, - fname=zip_fname, - path=f"{pooch.os_cache('pooch')}/polartoolkit/mass_change", - known_hash=None, - progressbar=True, - processor=pooch.Unzip( - extract_dir="Smith_2020", - ), - ) - fname1 = next(p for p in path if p.endswith(fname)) - - return ( - xr.load_dataarray( - fname1, - engine="rasterio", - ) - .squeeze() - .drop_vars(["band", "spatial_ref"]) - ) + return MassChange(version=version, hemisphere=hemisphere)() def basal_melt(variable: str = "w_b") -> typing.Any: diff --git a/tests/test_fetch.py b/tests/test_fetch.py index 8d391727..333d5e35 100644 --- a/tests/test_fetch.py +++ b/tests/test_fetch.py @@ -60,6 +60,12 @@ def test_measures_boundaries(): fetch.measures_boundaries("Coastline") +@pytest.mark.fetch() +@deprecation.fail_if_not_removed +def test_sample_shp(): + fetch.sample_shp(name="Disco_deep_transect") + + # %% resample_grid resample_test = [ # no inputs @@ -1128,6 +1134,7 @@ def test_magnetics(test_input, expected): @pytest.mark.fetch() @pytest.mark.issue() +@deprecation.fail_if_not_removed @pytest.mark.filterwarnings("ignore::RuntimeWarning") @pytest.mark.parametrize(("test_input", "expected", "hemisphere"), mass_change_test) def test_mass_change(test_input, expected, hemisphere):