def apply_linear_correction(rasterlist, factor, offset, suffix = 'lc',
                            outdir = None, floor = -999999):
    """
    Applies a linear correction to a raster dataset.
    New offset rasters are saved in the output directory with a suffix of "lc"
    unless one is specified. This may be used to apply any kind of linear relationship
    that can be described with "mx + b" such as conversion between between K,C, and F.
    Also useful when ground truthing satellite data and discovering linear errors.
    All outputs are 32 bit floating point values.

    :param rasterlist:  list of rasters, a single raster, or a directory full of tiffs to
                        Have a linear correction applied to them.
    :param factor:      every pixel in the raster will be MULTIPLIED by this value.
    :param offset:      this offset value will be ADDED to every pixel in the raster.
    :param suffix:      output files will take the same name as input files with this string
                        appended to the end. So input "FILE.tif" outputs "FILE_suffix.tif"
    :param outdir:      directory to save output rasters. "None" will save output images
                        in the same folder as the input images.
    :param floor:       Used to manage NoData. All values less than floor are set to floor
                        then floor is set to the new NoData value. defaults to -999,999


    return outputpath:  filepath to output files created by this function

    Example Usage
    to convert from MODIS Land surface temperature from digital number to kelvin, you
    must simply multiply by 0.02 as the stated scale factor listed at the link below
    [https://lpdaac.usgs.gov/products/modis_products_table/myd11a1].

    Now that it is in kelvin, converting to Celsius can be done by adding (-273.15)
    So, use this function with::

        factor = 0.02
        offset = -273.15

    and one may convert MODIS land surface temperature digital numbers directly to
    celsius!
    """

    output_filelist = []

    if outdir is not None and not os.path.isdir(outdir):
        os.makedirs(outdir)
    rasterlist = enf_rastlist(rasterlist)

    for raster in rasterlist:
        print("applying a linear correction to " + raster)
        image, metadata = to_numpy(raster, "float32")
        new_NoData = floor
        
        output = image * factor + offset
        low_value_indices = output < new_NoData
        output[low_value_indices] = new_NoData

        outname = core.create_outname(outdir,raster,suffix)
        from_numpy(output, metadata, outname, new_NoData)
        output_filelist.append(outname)

    print("Finished! \n ")
    return output_filelist
Example #2
0
def gap_fill_temporal(rasterlist, outdir = None, continuous = True,
                      NoData_Value = None, numpy_datatype = "float32"):
    """
    This function is designed to input a time sequence of rasters with partial voids and
    output a copy of each input image with every pixel equal to the last good value taken.
    This function will step forward in time through each raster and fill voids from the values
    of previous rasters. The resulting output image will contain all the data that was in the
    original image, with the voids filled with older data. A second output image will be
    generated where the pixel values are equal to the age of each pixel in the image. So
    if a void was filled with data that's 5 days old, the "age" raster will have a value of
    "5" at that location.

    Inputs:
    :param rasterlist:      a list of filepaths for rasters with which to fill gaps. THESE IMAGES
                            MUST BE ORDERED FROM OLDEST TO NEWEST (ascending time).
    :param outdir:          the path to the desired output folder, if left "None", outputs will be
                            saved right next to respective inputs.
    :param continuous:      if "True" an output raster will be generated for every single input raster,
                            which can be used to fill gaps in an entire time series. So, for example
                            output raster 2 will have all the good points in input raster 2, with gaps
                            filled with data from raster 1. output raster 3 will then be gap filled with
                            output raster 2, which might contain some fill values from raster 1, and so
                            forth. If "False" an output raster will only be generated for the LAST raster
                            in the input rasterlist.
    :param numpy_datatype   the numpy datatype of the output raster. usually "float32"

    :returns            a list of filepaths to new files created by this function.
    """

    # enforce the list of rasters to ensure it's sanitized
    rasterlist = enf_rastlist(rasterlist)

    # create an empty list to store output arrays in
    output_filelist = []

    # grab the first raster, then start stepping through the list
    old_rast, old_meta = to_numpy(rasterlist[0])
    rastfig = raster_fig(old_rast)

    for i, araster in enumerate(rasterlist[1:]):

        new_rast, new_meta = to_numpy(araster)

        # combine new and old data and mask matrices
        outrast = new_rast
        outrast.data[new_rast.mask] = old_rast.data[new_rast.mask]
        outrast.mask[new_rast.mask] = old_rast.mask[new_rast.mask]

        # only save output if continuous is true or is last raster in series
        if continuous is True or i == (len(rasterlist[1:]) - 1):

            # create output name and save it
            if outdir is None:
                this_outdir = os.path.dirname(araster)
            else:
                this_outdir = outdir

            # update the figure
            rastfig.update_fig(outrast)

            outpath = core.create_outname(this_outdir, araster, "gft", "tif")
            print("Filled gaps in {0}".format(os.path.basename(araster)))
            outrast = outrast.astype(numpy_datatype)
            from_numpy(outrast, new_meta, outpath, NoData_Value)
            output_filelist.append(outpath)

        # prepare for next time step by setting current to old
        old_rast = new_rast

    return output_filelist
Example #3
0
def gap_fill_temporal(rasterlist,
                      outdir=None,
                      continuous=True,
                      NoData_Value=None,
                      numpy_datatype="float32"):
    """
    This function is designed to input a time sequence of rasters with partial voids and
    output a copy of each input image with every pixel equal to the last good value taken.
    This function will step forward in time through each raster and fill voids from the values
    of previous rasters. The resulting output image will contain all the data that was in the
    original image, with the voids filled with older data. A second output image will be
    generated where the pixel values are equal to the age of each pixel in the image. So
    if a void was filled with data that's 5 days old, the "age" raster will have a value of
    "5" at that location.

    :param rasterlist:      A list of filepaths for rasters with which to fill gaps. THESE IMAGES
                            MUST BE ORDERED FROM OLDEST TO NEWEST (ascending time).
    :param outdir:          the path to the desired output folder, if left "None", outputs will be
                            saved right next to respective inputs.
    :param continuous:      if "True" an output raster will be generated for every single input raster,
                            which can be used to fill gaps in an entire time series. So, for example
                            output raster 2 will have all the good points in input raster 2, with gaps
                            filled with data from raster 1. output raster 3 will then be gap filled with
                            output raster 2, which might contain some fill values from raster 1, and so
                            forth. If "False" an output raster will only be generated for the LAST raster
                            in the input rasterlist.
    :param numpy_datatype:  the numpy datatype of the output raster. usually "float32"

    :return output_filelist: returns a list of filepaths to new files created by this function.
    """

    # enforce the list of rasters to ensure it's sanitized
    rasterlist = enf_rastlist(rasterlist)

    # create an empty list to store output arrays in
    output_filelist = []

    # grab the first raster, then start stepping through the list
    old_rast, old_meta = to_numpy(rasterlist[0])
    rastfig = raster_fig(old_rast)

    for i, araster in enumerate(rasterlist[1:]):

        new_rast, new_meta = to_numpy(araster)

        # combine new and old data and mask matrices
        outrast = new_rast
        outrast.data[new_rast.mask] = old_rast.data[new_rast.mask]
        outrast.mask[new_rast.mask] = old_rast.mask[new_rast.mask]

        # only save output if continuous is true or is last raster in series
        if continuous is True or i == (len(rasterlist[1:]) - 1):

            # create output name and save it
            if outdir is None:
                this_outdir = os.path.dirname(araster)
            else:
                this_outdir = outdir

            # update the figure
            rastfig.update_fig(outrast)

            outpath = core.create_outname(this_outdir, araster, "gft", "tif")
            print("Filled gaps in {0}".format(os.path.basename(araster)))
            outrast = outrast.astype(numpy_datatype)
            from_numpy(outrast, new_meta, outpath, NoData_Value)
            output_filelist.append(outpath)

        # prepare for next time step by setting current to old
        old_rast = new_rast

    return output_filelist