diff --git a/doc/python/source/rsgislib_tools.rst b/doc/python/source/rsgislib_tools.rst index 03e92fab..e2334cde 100644 --- a/doc/python/source/rsgislib_tools.rst +++ b/doc/python/source/rsgislib_tools.rst @@ -11,6 +11,7 @@ RSGISLib Tools rsgislib_tools_projection rsgislib_tools_plotting rsgislib_tools_stats + rsgislib_tools_maths rsgislib_tools_imagetools rsgislib_tools_sensors rsgislib_tools_sysprofile diff --git a/doc/python/source/rsgislib_tools_maths.rst b/doc/python/source/rsgislib_tools_maths.rst new file mode 100644 index 00000000..cf08ab3e --- /dev/null +++ b/doc/python/source/rsgislib_tools_maths.rst @@ -0,0 +1,12 @@ +RSGISLib Maths Tools +============================= + +Normalisation +---------------- +.. autofunction:: rsgislib.tools.maths.round_to_nearest_val + + + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/python/rsgislib/__init__.py b/python/rsgislib/__init__.py index 3460020a..2debabd2 100644 --- a/python/rsgislib/__init__.py +++ b/python/rsgislib/__init__.py @@ -163,6 +163,12 @@ * VAR_TYPE_CONTINUOUS = 1 * VAR_TYPE_CATEGORICAL = 2 + +Options for rounding numbers: + * ROUND_NEAREST = 1 + * ROUND_UP = 2 + * ROUND_DOWN = 3 + """ from __future__ import print_function @@ -301,6 +307,10 @@ VAR_TYPE_CONTINUOUS = 1 VAR_TYPE_CATEGORICAL = 2 +ROUND_NEAREST = 1 +ROUND_UP = 2 +ROUND_DOWN = 3 + def get_install_base_path() -> pathlib.PurePath: """ diff --git a/python/rsgislib/tools/ftptools.py b/python/rsgislib/tools/ftptools.py index 683896bd..ca95bc7d 100644 --- a/python/rsgislib/tools/ftptools.py +++ b/python/rsgislib/tools/ftptools.py @@ -417,12 +417,13 @@ def download_curl_ftp_file( ) ) success = True - except: + except pycurl.error as e: print( "An error occurred when downloading {}.".format( os.path.join(ftp_url, remote_file) ) ) + print(e) success = False return success diff --git a/python/rsgislib/tools/mapping.py b/python/rsgislib/tools/mapping.py index 56d76f79..013bef03 100644 --- a/python/rsgislib/tools/mapping.py +++ b/python/rsgislib/tools/mapping.py @@ -698,19 +698,29 @@ def create_raster_img_map( "Manual stretch requires user parameters to be passed" ) img_data_strch = rsgislib.tools.plotting.manual_stretch_np_arr( - img_data, min_max_vals=stch_min_max_vals, no_data_val=img_no_data_val, no_data_clr=no_data_out_clr, + img_data, + min_max_vals=stch_min_max_vals, + no_data_val=img_no_data_val, + no_data_clr=no_data_out_clr, ) elif img_stch == rsgislib.IMG_STRETCH_LINEAR: img_data_strch = rsgislib.tools.plotting.linear_stretch_np_arr( - img_data, no_data_val=img_no_data_val, no_data_clr=no_data_out_clr, + img_data, + no_data_val=img_no_data_val, + no_data_clr=no_data_out_clr, ) elif img_stch == rsgislib.IMG_STRETCH_STDEV: img_data_strch = rsgislib.tools.plotting.stdev_stretch_np_arr( - img_data, n_stdevs=stch_n_stdevs, no_data_val=img_no_data_val, no_data_clr=no_data_out_clr, + img_data, + n_stdevs=stch_n_stdevs, + no_data_val=img_no_data_val, + no_data_clr=no_data_out_clr, ) elif img_stch == rsgislib.IMG_STRETCH_CUMULATIVE: img_data_strch = rsgislib.tools.plotting.cumulative_stretch_np_arr( - img_data, no_data_val=img_no_data_val, no_data_clr=no_data_out_clr, + img_data, + no_data_val=img_no_data_val, + no_data_clr=no_data_out_clr, ) else: print("No stretch is being used - is this what you intended?!") diff --git a/python/rsgislib/tools/maths.py b/python/rsgislib/tools/maths.py new file mode 100644 index 00000000..c700a151 --- /dev/null +++ b/python/rsgislib/tools/maths.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +""" +The tools.maths module contains some useful tools for maths operations which aren't +easily available else where. + +""" +from typing import Union, List + +import numpy + +import rsgislib + + +def round_to_nearest_val( + input_val: Union[numpy.array, int, float, List[int], List[float]], + round_val: int = 1, + round_direction: int = rsgislib.ROUND_NEAREST, +): + """ + Rounds elements of a NumPy array to the nearest multiple of the value specified, + with options for rounding up, down or to the nearest value. For example, if a + round_val of 5 is provided then the numbers will be rounded to intervals of 5. + + :param input_val: A NumPy array of numbers. + :param round_val: The value by which the input is to be rounded to. + :param round_direction: Specify the round direction (rsgislib.ROUND_NEAREST, + rsgislib.ROUND_UP, or rsgislib.ROUND_DOWN). The + default is rsgislib.ROUND_NEAREST. + :return: a single value or a numpy array of the rounded values. + + """ + if isinstance(input_val, list): + input_val = numpy.array(input_val, dtype=float) + + round_val_flt = float(round_val) + round_val_int = int(round_val) + if round_direction == rsgislib.ROUND_NEAREST: + return numpy.round(input_val / round_val_flt) * round_val_int + elif round_direction == rsgislib.ROUND_UP: + return numpy.ceil(input_val / round_val_flt) * round_val_int + elif round_direction == rsgislib.ROUND_DOWN: + return numpy.floor(input_val / round_val_flt) * round_val_int + else: + raise rsgislib.RSGISPyException( + f"Invalid round_direction: '{round_direction}'. Please use " + f"rsgislib.ROUND_NEAREST, rsgislib.ROUND_UP, or rsgislib.ROUND_DOWN." + ) diff --git a/python/rsgislib/tools/plotting.py b/python/rsgislib/tools/plotting.py index 5c8f9986..97126f86 100644 --- a/python/rsgislib/tools/plotting.py +++ b/python/rsgislib/tools/plotting.py @@ -1044,7 +1044,7 @@ def linear_stretch_np_arr( out_int_type: bool = False, min_out_val: float = 0, max_out_val: float = 1, - no_data_clr:Tuple[float, float, float] = None, + no_data_clr: Tuple[float, float, float] = None, ) -> numpy.array: """ A function which performs a linear stretch using the min-max values on a per @@ -1145,7 +1145,7 @@ def cumulative_stretch_np_arr( out_int_type: bool = False, min_out_val: float = 0, max_out_val: float = 1, - no_data_clr:Tuple[float, float, float] = None, + no_data_clr: Tuple[float, float, float] = None, ) -> numpy.array: """ A function which performs a cumulative stretch using an upper and lower @@ -1245,7 +1245,7 @@ def stdev_stretch_np_arr( out_int_type: bool = False, min_out_val: float = 0, max_out_val: float = 1, - no_data_clr:Tuple[float, float, float] = None, + no_data_clr: Tuple[float, float, float] = None, ) -> numpy.array: """ A function which performs a standard deviation stretch using an upper and lower @@ -1369,7 +1369,7 @@ def manual_stretch_np_arr( out_int_type: bool = False, min_out_val: float = 0, max_out_val: float = 1, - no_data_clr:Tuple[float, float, float] = None, + no_data_clr: Tuple[float, float, float] = None, ) -> numpy.array: """ A function which performs a linear stretch using the min-max values provided diff --git a/python/rsgislib/tools/stats.py b/python/rsgislib/tools/stats.py index 17eafa17..93335545 100644 --- a/python/rsgislib/tools/stats.py +++ b/python/rsgislib/tools/stats.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -The tools.stats module contains some useful tools for calculating useful statistics which aren't -easily available else where. +The tools.stats module contains some useful tools for calculating useful statistics +which aren't easily available else where. """ from typing import Union, List