Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multispectral tools: convert data to float32 dtype before doing calculations #755

Merged
merged 2 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions xrspatial/multispectral.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ def arvi(nir_agg: xr.DataArray,
cupy_func=_arvi_cupy,
dask_cupy_func=_arvi_dask_cupy)

out = mapper(red_agg)(nir_agg.data, red_agg.data, blue_agg.data)
out = mapper(red_agg)(
nir_agg.data.astype('f4'), red_agg.data.astype('f4'), blue_agg.data.astype('f4')
)

return DataArray(out,
name=name,
Expand Down Expand Up @@ -311,8 +313,10 @@ def evi(nir_agg: xr.DataArray,
cupy_func=_evi_cupy,
dask_cupy_func=_evi_dask_cupy)

out = mapper(red_agg)(nir_agg.data, red_agg.data, blue_agg.data, c1, c2,
soil_factor, gain)
out = mapper(red_agg)(
nir_agg.data.astype('f4'), red_agg.data.astype('f4'), blue_agg.data.astype('f4'),
c1, c2, soil_factor, gain
)

return DataArray(out,
name=name,
Expand Down Expand Up @@ -431,7 +435,7 @@ def gci(nir_agg: xr.DataArray,
cupy_func=_gci_cupy,
dask_cupy_func=_gci_dask_cupy)

out = mapper(nir_agg)(nir_agg.data, green_agg.data)
out = mapper(nir_agg)(nir_agg.data.astype('f4'), green_agg.data.astype('f4'))

return DataArray(out,
name=name,
Expand Down Expand Up @@ -510,7 +514,7 @@ def nbr(nir_agg: xr.DataArray,
dask_cupy_func=_run_normalized_ratio_dask_cupy,
)

out = mapper(nir_agg)(nir_agg.data, swir2_agg.data)
out = mapper(nir_agg)(nir_agg.data.astype('f4'), swir2_agg.data.astype('f4'))

return DataArray(out,
name=name,
Expand Down Expand Up @@ -594,7 +598,7 @@ def nbr2(swir1_agg: xr.DataArray,
dask_cupy_func=_run_normalized_ratio_dask_cupy,
)

out = mapper(swir1_agg)(swir1_agg.data, swir2_agg.data)
out = mapper(swir1_agg)(swir1_agg.data.astype('f4'), swir2_agg.data.astype('f4'))

return DataArray(out,
name=name,
Expand Down Expand Up @@ -671,7 +675,7 @@ def ndvi(nir_agg: xr.DataArray,
dask_cupy_func=_run_normalized_ratio_dask_cupy,
)

out = mapper(nir_agg)(nir_agg.data, red_agg.data)
out = mapper(nir_agg)(nir_agg.data.astype('f4'), red_agg.data.astype('f4'))

return DataArray(out,
name=name,
Expand Down Expand Up @@ -753,7 +757,7 @@ def ndmi(nir_agg: xr.DataArray,
dask_cupy_func=_run_normalized_ratio_dask_cupy,
)

out = mapper(nir_agg)(nir_agg.data, swir1_agg.data)
out = mapper(nir_agg)(nir_agg.data.astype('f4'), swir1_agg.data.astype('f4'))

return DataArray(out,
name=name,
Expand Down Expand Up @@ -937,7 +941,7 @@ def savi(nir_agg: xr.DataArray,
cupy_func=_savi_cupy,
dask_cupy_func=_savi_dask_cupy)

out = mapper(red_agg)(nir_agg.data, red_agg.data, soil_factor)
out = mapper(red_agg)(nir_agg.data.astype('f4'), red_agg.data.astype('f4'), soil_factor)

return DataArray(out,
name=name,
Expand Down Expand Up @@ -1071,7 +1075,9 @@ def sipi(nir_agg: xr.DataArray,
cupy_func=_sipi_cupy,
dask_cupy_func=_sipi_dask_cupy)

out = mapper(red_agg)(nir_agg.data, red_agg.data, blue_agg.data)
out = mapper(red_agg)(
nir_agg.data.astype('f4'), red_agg.data.astype('f4'), blue_agg.data.astype('f4')
)

return DataArray(out,
name=name,
Expand Down Expand Up @@ -1238,7 +1244,9 @@ def ebbi(red_agg: xr.DataArray,
cupy_func=_ebbi_cupy,
dask_cupy_func=_ebbi_dask_cupy)

out = mapper(red_agg)(red_agg.data, swir_agg.data, tir_agg.data)
out = mapper(red_agg)(
red_agg.data.astype('f4'), swir_agg.data.astype('f4'), tir_agg.data.astype('f4')
)

return DataArray(out,
name=name,
Expand Down Expand Up @@ -1298,7 +1306,7 @@ def _normalize_data(agg, pixel_max, c, th):
dask_func=_normalize_data_dask,
cupy_func=_normalize_data_cupy,
dask_cupy_func=_normalize_data_dask_cupy)
out = mapper(agg)(agg.data, pixel_max, c, th)
out = mapper(agg)(agg.data.astype('f4'), pixel_max, c, th)
return out


Expand Down
118 changes: 118 additions & 0 deletions xrspatial/tests/test_multispectral.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,60 @@ def result_ebbi():
return result


@pytest.fixture
def data_uint_dtype_normalized_ratio(dtype):
# test data for input data array of uint dtype
# normalized ratio is applied with different bands for NBR, NBR2, NDVI, NDMI.
band1 = xr.DataArray(np.array([[1, 1], [1, 1]], dtype=dtype))
band2 = xr.DataArray(np.array([[0, 2], [1, 2]], dtype=dtype))
result = np.array([[1, -0.33333334], [0, -0.33333334]], dtype=np.float32)
return band1, band2, result


@pytest.fixture
def data_uint_dtype_arvi(dtype):
nir = xr.DataArray(np.array([[1, 1], [1, 1]], dtype=dtype))
red = xr.DataArray(np.array([[0, 1], [0, 2]], dtype=dtype))
blue = xr.DataArray(np.array([[0, 2], [1, 2]], dtype=dtype))
result = np.array([[1, 0.2], [1, -0.14285715]], dtype=np.float32)
return nir, red, blue, result


@pytest.fixture
def data_uint_dtype_evi(dtype):
nir = xr.DataArray(np.array([[1, 1], [1, 1]], dtype=dtype))
red = xr.DataArray(np.array([[0, 1], [0, 2]], dtype=dtype))
blue = xr.DataArray(np.array([[0, 2], [1, 2]], dtype=dtype))
result = np.array([[1.25, 0.], [-0.45454547, 2.5]], dtype=np.float32)
return nir, red, blue, result


@pytest.fixture
def data_uint_dtype_savi(dtype):
nir = xr.DataArray(np.array([[1, 1], [1, 1]], dtype=dtype))
red = xr.DataArray(np.array([[0, 1], [0, 2]], dtype=dtype))
result = np.array([[0.25, 0.], [0.25, -0.125]], dtype=np.float32)
return nir, red, result


@pytest.fixture
def data_uint_dtype_sipi(dtype):
nir = xr.DataArray(np.array([[1, 1], [1, 1]], dtype=dtype))
red = xr.DataArray(np.array([[0, 0], [0, 2]], dtype=dtype))
blue = xr.DataArray(np.array([[0, 2], [1, 2]], dtype=dtype))
result = np.array([[1, -1], [0, 1]], dtype=np.float32)
return nir, red, blue, result


@pytest.fixture
def data_uint_dtype_ebbi(dtype):
red = xr.DataArray(np.array([[0, 0], [0, 2]], dtype=dtype))
swir = xr.DataArray(np.array([[1, 1], [1, 1]], dtype=dtype))
tir = xr.DataArray(np.array([[0, 2], [1, 2]], dtype=dtype))
result = np.array([[0.1, 0.05773503], [0.07071068, -0.05773503]], dtype=np.float32)
return red, swir, tir, result


# NDVI -------------
def test_ndvi_data_contains_valid_values():
_x = np.mgrid[1:0:21j]
Expand Down Expand Up @@ -275,6 +329,13 @@ def test_ndvi_cpu(nir_data, red_data, result_ndvi):
general_output_checks(nir_data, result, result_ndvi, verify_dtype=True)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_ndvi_uint_dtype(data_uint_dtype_normalized_ratio):
nir_data, red_data, result_ndvi = data_uint_dtype_normalized_ratio
result = ndvi(nir_data, red_data)
general_output_checks(nir_data, result, result_ndvi, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_ndvi_gpu(nir_data, red_data, result_ndvi):
Expand All @@ -290,6 +351,7 @@ def test_savi_zero_soil_factor_cpu(nir_data, red_data, result_ndvi):
general_output_checks(nir_data, result_savi, result_ndvi, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_savi_zero_soil_factor_gpu(nir_data, red_data, result_ndvi):
# savi should be same as ndvi at soil_factor=0
Expand All @@ -304,6 +366,13 @@ def test_savi_cpu(nir_data, red_data, result_savi):
general_output_checks(nir_data, result, result_savi)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_savi_uint_dtype(data_uint_dtype_savi):
nir_data, red_data, result_savi = data_uint_dtype_savi
result = savi(nir_data, red_data)
general_output_checks(nir_data, result, result_savi, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_savi_gpu(nir_data, red_data, result_savi):
Expand All @@ -319,6 +388,13 @@ def test_arvi_cpu(nir_data, red_data, blue_data, result_arvi):
general_output_checks(nir_data, result, result_arvi)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_arvi_uint_dtype(data_uint_dtype_arvi):
nir_data, red_data, blue_data, result_arvi = data_uint_dtype_arvi
result = arvi(nir_data, red_data, blue_data)
general_output_checks(nir_data, result, result_arvi, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_arvi_gpu(nir_data, red_data, blue_data, result_arvi):
Expand All @@ -333,6 +409,13 @@ def test_evi_cpu(nir_data, red_data, blue_data, result_evi):
general_output_checks(nir_data, result, result_evi)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_evi_uint_dtype(data_uint_dtype_evi):
nir_data, red_data, blue_data, result_evi = data_uint_dtype_evi
result = evi(nir_data, red_data, blue_data)
general_output_checks(nir_data, result, result_evi, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_evi_gpu(nir_data, red_data, blue_data, result_evi):
Expand Down Expand Up @@ -361,6 +444,13 @@ def test_sipi_cpu(nir_data, red_data, blue_data, result_sipi):
general_output_checks(nir_data, result, result_sipi)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_sipi_uint_dtype(data_uint_dtype_sipi):
nir_data, red_data, blue_data, result_sipi = data_uint_dtype_sipi
result = sipi(nir_data, red_data, blue_data)
general_output_checks(nir_data, result, result_sipi, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_sipi_gpu(nir_data, red_data, blue_data, result_sipi):
Expand All @@ -375,6 +465,13 @@ def test_nbr_cpu(nir_data, swir2_data, result_nbr):
general_output_checks(nir_data, result, result_nbr)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_nbr_uint_dtype(data_uint_dtype_normalized_ratio):
nir_data, red_data, result_nbr = data_uint_dtype_normalized_ratio
result = nbr(nir_data, red_data)
general_output_checks(nir_data, result, result_nbr, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_nbr_gpu(nir_data, swir2_data, result_nbr):
Expand All @@ -389,6 +486,13 @@ def test_nbr2_cpu(swir1_data, swir2_data, result_nbr2):
general_output_checks(swir1_data, result, result_nbr2)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_nbr2_uint_dtype(data_uint_dtype_normalized_ratio):
nir_data, red_data, result_nbr2 = data_uint_dtype_normalized_ratio
result = nbr2(nir_data, red_data)
general_output_checks(nir_data, result, result_nbr2, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_nbr2_gpu(swir1_data, swir2_data, result_nbr2):
Expand All @@ -403,6 +507,13 @@ def test_ndmi_cpu(nir_data, swir1_data, result_ndmi):
general_output_checks(nir_data, result, result_ndmi)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_ndmi_uint_dtype(data_uint_dtype_normalized_ratio):
nir_data, red_data, result_ndmi = data_uint_dtype_normalized_ratio
result = ndmi(nir_data, red_data)
general_output_checks(nir_data, result, result_ndmi, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_ndmi_gpu(nir_data, swir1_data, result_ndmi):
Expand All @@ -417,6 +528,13 @@ def test_ebbi_cpu(red_data, swir1_data, tir_data, result_ebbi):
general_output_checks(red_data, result, result_ebbi)


@pytest.mark.parametrize("dtype", ["uint8", "uint16"])
def test_ebbi_uint_dtype(data_uint_dtype_ebbi):
red_data, swir_data, tir_data, result_ebbi = data_uint_dtype_ebbi
result = ebbi(red_data, swir_data, tir_data)
general_output_checks(red_data, result, result_ebbi, verify_dtype=True)


@cuda_and_cupy_available
@pytest.mark.parametrize("backend", ["cupy", "dask+cupy"])
def test_ebbi_gpu(red_data, swir1_data, tir_data, result_ebbi):
Expand Down