Skip to content

Commit

Permalink
chore: improving testing and typehinting (#77)
Browse files Browse the repository at this point in the history
Signed-off-by: slowy07 <[email protected]>
  • Loading branch information
slowy07 authored Jul 17, 2024
1 parent 8ecb39d commit 6938393
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 72 deletions.
30 changes: 15 additions & 15 deletions hypercoast/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import List, Union, Dict, Optional, Tuple, Any


def github_raw_url(url):
def github_raw_url(url: str) -> str:
"""Get the raw URL for a GitHub file.
Args:
Expand All @@ -23,20 +23,20 @@ def github_raw_url(url):


def download_file(
url=None,
output=None,
quiet=False,
proxy=None,
speed=None,
use_cookies=True,
verify=True,
id=None,
fuzzy=False,
resume=False,
unzip=True,
overwrite=False,
subfolder=False,
):
url: Optional[str] = None,
output: Optional[str] = None,
quiet: Optional[bool] = False,
proxy: Optional[str] = None,
speed: Optional[float] = None,
use_cookies: Optional[bool] = True,
verify: Optional[bool] = True,
id: Optional[str] = None,
fuzzy: Optional[bool] = False,
resume: Optional[bool] = False,
unzip: Optional[bool] = True,
overwrite: Optional[bool] = False,
subfolder: Optional[bool] = False,
) -> str:
"""Download a file from URL, including Google Drive shared URL.
Args:
Expand Down
26 changes: 22 additions & 4 deletions hypercoast/desis.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
import xarray as xr
import pandas as pd
from .common import convert_coords
from typing import Optional, Union


def read_desis(filepath, wavelengths=None, method="nearest", **kwargs):
def read_desis(
filepath: str,
wavelengths: Optional[Union[list, tuple]] = None,
method: Optional[str] = "nearest",
**kwargs,
) -> xr.Dataset:
"""
Reads DESIS data from a given file and returns an xarray Dataset.
Expand Down Expand Up @@ -42,7 +48,13 @@ def read_desis(filepath, wavelengths=None, method="nearest", **kwargs):
return dataset


def desis_to_image(dataset, wavelengths=None, method="nearest", output=None, **kwargs):
def desis_to_image(
dataset: Union[xr.Dataset, str],
wavelengths: Union[list, tuple] = None,
method: Optional[str] = "nearest",
output: Optional[str] = None,
**kwargs,
):
"""
Converts an DESIS dataset to an image.
Expand Down Expand Up @@ -76,7 +88,7 @@ def desis_to_image(dataset, wavelengths=None, method="nearest", output=None, **k
)


def extract_desis(ds, lat, lon):
def extract_desis(ds: xr.Dataset, lat: float, lon: float) -> xr.DataArray:
"""
Extracts DESIS data from a given xarray Dataset.
Expand All @@ -102,7 +114,13 @@ def extract_desis(ds, lat, lon):
return da


def filter_desis(dataset, lat, lon, return_plot=False, **kwargs):
def filter_desis(
dataset: xr.Dataset,
lat: Union[float, tuple],
lon: Union[float, tuple],
return_plot: Optional[bool] = False,
**kwargs,
) -> xr.Dataset:
"""
Filters a DESIS dataset based on latitude and longitude.
Expand Down
134 changes: 81 additions & 53 deletions hypercoast/emit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@
import xarray as xr
import numpy as np
import geopandas as gpd
from typing import Optional, Union


def read_emit(filepath, ortho=True, wavelengths=None, method="nearest", **kwargs):
def read_emit(
filepath: str,
ortho: Optional[bool] = True,
wavelengths: Union[tuple, list] = None,
method: Optional[str] = "nearest",
**kwargs,
) -> xr.Dataset:
"""
Opens an EMIT dataset from a file path and assigns new coordinates to it.
Expand Down Expand Up @@ -58,21 +65,21 @@ def read_emit(filepath, ortho=True, wavelengths=None, method="nearest", **kwargs


def plot_emit(
ds,
longitude=None,
latitude=None,
downtrack=None,
crosstrack=None,
remove_nans=True,
x="wavelengths",
y="reflectance",
color="black",
frame_height=400,
frame_width=600,
title=None,
method="nearest",
ortho=True,
options={},
ds: Union[xr.Dataset, str],
longitude: Optional[float] = None,
latitude: Optional[float] = None,
downtrack: Optional[int] = None,
crosstrack: Optional[int] = None,
remove_nans: Optional[bool] = True,
x: str = "wavelengths",
y: str = "reflectance",
color: str = "black",
frame_height: Optional[int] = 400,
frame_width: Optional[int] = 600,
title: str = None,
method: Optional[str] = "nearest",
ortho: Optional[bool] = True,
options: Optional[dict] = {},
**kwargs,
):
"""
Expand Down Expand Up @@ -151,17 +158,17 @@ def plot_emit(


def viz_emit(
ds,
wavelengths,
cmap="viridis",
frame_width=720,
method="nearest",
ortho=True,
aspect="equal",
tiles="ESRI",
alpha=0.8,
title=None,
options={},
ds: Union[xr.Dataset, str],
wavelengths: Union[tuple, list],
cmap: Optional[str] = "viridis",
frame_width: int = 720,
method: Optional[str] = "nearest",
ortho: Optional[bool] = True,
aspect: Optional[str] = "equal",
tiles: str = "ESRI",
alpha: Optional[float] = 0.8,
title: Optional[str] = None,
options: Optional[dict] = {},
**kwargs,
):
"""
Expand Down Expand Up @@ -215,7 +222,7 @@ def viz_emit(
return image


def emit_to_netcdf(data, output, **kwargs):
def emit_to_netcdf(data: Union[xr.Dataset, str], output: str, **kwargs) -> None:
"""
Transposes an EMIT dataset and saves it as a NetCDF file.
Expand All @@ -232,7 +239,13 @@ def emit_to_netcdf(data, output, **kwargs):
ds_geo.to_netcdf(output, **kwargs)


def emit_to_image(data, wavelengths=None, method="nearest", output=None, **kwargs):
def emit_to_image(
data: Union[xr.Dataset, str],
wavelengths: Optional[Union[list, tuple]] = None,
method: Optional[str] = "nearest",
output: Optional[str] = None,
**kwargs,
):
"""
Converts an EMIT dataset to an image.
Expand All @@ -259,13 +272,13 @@ def emit_to_image(data, wavelengths=None, method="nearest", output=None, **kwarg


def emit_xarray(
filepath,
ortho=False,
qmask=None,
unpacked_bmask=None,
wavelengths=None,
method="nearest",
):
filepath: str,
ortho: Optional[bool] = False,
qmask: Optional[np.ndarray] = None,
unpacked_bmask: Optional[np.ndarray] = None,
wavelengths: Optional[Union[tuple, list]] = None,
method: Optional[str] = "nearest",
) -> xr.Dataset:
"""
Streamlines opening an EMIT dataset as an xarray.Dataset.
Expand Down Expand Up @@ -366,7 +379,7 @@ def emit_xarray(


# Function to Calculate the Lat and Lon Vectors/Coordinate Grid
def coord_vects(ds):
def coord_vects(ds: xr.Dataset) -> np.ndarray:
"""
This function calculates the Lat and Lon Coordinate Vectors using the GLT and Metadata from an EMIT dataset read into xarray.
Expand Down Expand Up @@ -395,7 +408,12 @@ def coord_vects(ds):
return lon, lat


def apply_glt(ds_array, glt_array, fill_value=-9999, GLT_NODATA_VALUE=0):
def apply_glt(
ds_array: np.ndarray,
glt_array: np.ndarray,
fill_value: int = -9999,
GLT_NODATA_VALUE: Optional[int] = 0,
) -> np.ndarray:
"""
Applies the GLT array to a numpy array of either 2 or 3 dimensions to orthorectify the data.
Expand Down Expand Up @@ -428,7 +446,11 @@ def apply_glt(ds_array, glt_array, fill_value=-9999, GLT_NODATA_VALUE=0):
return out_ds


def ortho_xr(ds, GLT_NODATA_VALUE=0, fill_value=-9999):
def ortho_xr(
ds: xr.Dataset,
GLT_NODATA_VALUE: Optional[int] = 0,
fill_value: Optional[int] = -9999,
) -> xr.Dataset:
"""
Uses `apply_glt` to create an orthorectified xarray dataset.
Expand Down Expand Up @@ -518,7 +540,7 @@ def ortho_xr(ds, GLT_NODATA_VALUE=0, fill_value=-9999):
return out_xr


def quality_mask(filepath, quality_bands):
def quality_mask(filepath: str, quality_bands: list) -> np.ndarray:
"""
Builds a single layer mask to apply based on the bands selected from an EMIT L2A Mask file.
Expand Down Expand Up @@ -551,7 +573,7 @@ def quality_mask(filepath, quality_bands):
return qmask


def band_mask(filepath):
def band_mask(filepath: str) -> np.ndarray:
"""
Unpacks the packed band mask to apply to the dataset. Can be used manually or as an input in the emit_xarray() function.
Expand All @@ -574,13 +596,13 @@ def band_mask(filepath):


def write_envi(
xr_ds,
output_dir,
overwrite=False,
extension=".img",
interleave="BIL",
glt_file=False,
):
xr_ds: xr.Dataset,
output_dir: str,
overwrite: Optional[bool] = False,
extension: str = ".img",
interleave: Optional[str] = "BIL",
glt_file: Optional[bool] = False,
) -> tuple:
"""
Takes an EMIT dataset read into an xarray dataset using the emit_xarray function and writes an ENVI file and header.
Expand Down Expand Up @@ -759,7 +781,7 @@ def write_envi(
).astype("int32")


def envi_header(inputpath):
def envi_header(inputpath: str) -> str:
"""
Convert a ENVI binary/header path to a header, handling extensions.
Expand Down Expand Up @@ -788,7 +810,7 @@ def envi_header(inputpath):
return inputpath + ".hdr"


def raw_spatial_crop(ds, shape):
def raw_spatial_crop(ds: xr.Dataset, shape: gpd) -> xr.Dataset:
"""
Use a polygon to clip the file GLT, then a bounding box to crop the spatially raw data. Regions clipped in the GLT are set to 0 so a mask will be applied when
used to orthorectify the data at a later point in a workflow.
Expand Down Expand Up @@ -864,7 +886,7 @@ def raw_spatial_crop(ds, shape):
return clipped_ds


def is_adjacent(scene: str, same_orbit: list):
def is_adjacent(scene: str, same_orbit: list) -> bool:
"""
Checks if the scene numbers from the same orbit are adjacent/sequential.
Expand All @@ -879,7 +901,7 @@ def is_adjacent(scene: str, same_orbit: list):
return all(b - a == 1 for a, b in zip(scene_nums[:-1], scene_nums[1:]))


def merge_emit(datasets: dict, gdf: gpd.GeoDataFrame):
def merge_emit(datasets: dict, gdf: gpd.GeoDataFrame) -> xr.Dataset:
"""
Merges xarray datasets formatted using emit_xarray. Note: GDF may only work with a single geometry.
Expand Down Expand Up @@ -965,7 +987,13 @@ def merge_emit(datasets: dict, gdf: gpd.GeoDataFrame):
return merged_ds


def ortho_browse(url, glt, spatial_ref, geotransform, white_background=True):
def ortho_browse(
url: str,
glt: np.ndarray,
spatial_ref: str,
geotransform: list,
white_background: Optional[bool] = True,
) -> xr.Dataset:
"""
Use an EMIT GLT, geotransform, and spatial ref to orthorectify a browse image. (browse images are in native resolution)
Expand Down
3 changes: 3 additions & 0 deletions tests/test_aviris.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import hypercoast
import os
import matplotlib
import pytest

matplotlib.use("Agg") # Use the Agg backend to suppress plots

Expand All @@ -15,6 +16,8 @@ def setUpClass(cls):
os.makedirs("test_data", exist_ok=True)
hypercoast.download_file(cls.url, cls.filepath)

# uncomment marker if testing download files
@pytest.mark.skip(reason="download takes long")
def test_download_file(self):
self.assertTrue(os.path.exists(self.filepath))

Expand Down
3 changes: 3 additions & 0 deletions tests/test_emit.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import unittest
import hypercoast
import os
import pytest


class TestHypercoastEmit(unittest.TestCase):
Expand All @@ -13,6 +14,8 @@ def setUpClass(cls):
hypercoast.download_file(cls.url, cls.filepath)
cls.dataset = hypercoast.read_emit(cls.filepath)

# uncomment marker if testing download files
@pytest.mark.skip(reason="download takes long")
def test_download_file(self):
self.assertTrue(os.path.exists(self.filepath))

Expand Down
Loading

0 comments on commit 6938393

Please sign in to comment.