コード例 #1
0
def atsat_bright_temp_8(meta_path, outdir = False):
    """
    Converts Landsat 8 TIRS bands to at satellite brightnes temperature in Kelvins

    To be performed on raw Landsat 8 level 1 data. See link below for details
    see here http://landsat.usgs.gov/Landsat8_Using_Product.php

    :param band_nums:   A list of desired band numbers, which should be [10,11]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files. If left False it will save ouput
                        files in the same directory as input files.

    :return output_filelist: A list of all files created by this function
    """
    
    #enforce the list of band numbers and grab metadata from the MTL file
    band_nums = ["10", "11"]
    meta_path = os.path.abspath(meta_path)
    meta = landsat_metadata(meta_path)

    output_filelist = []

    #cycle through each band in the list for calculation, ensuring each is in the list of TIRS bands
    for band_num in band_nums:

        #scrape data from the given file path and attributes in the MTL file
        band_path = meta_path.replace("MTL.txt","B{0}.tif".format(band_num))
        Qcal = arcpy.Raster(band_path)
        
        #get rid of the zero values that show as the black background to avoid skewing values
        null_raster = arcpy.sa.SetNull(Qcal, Qcal, "VALUE = 0")

        #requires first converting to radiance
        Ml   = getattr(meta,"RADIANCE_MULT_BAND_{0}".format(band_num)) # multiplicative scaling factor
        Al   = getattr(meta,"RADIANCE_ADD_BAND_{0}".format(band_num))  # additive rescaling factor

        TOA_rad = (null_raster * Ml) + Al
        
        #now convert to at-sattelite brightness temperature
        K1   = getattr(meta,"K1_CONSTANT_BAND_{0}".format(band_num))  # thermal conversion constant 1
        K2   = getattr(meta,"K2_CONSTANT_BAND_{0}".format(band_num))  # thermal conversion constant 2

        #calculate brightness temperature at the satellite
        Bright_Temp = K2/(arcpy.sa.Ln((K1/TOA_rad) + 1))

        #save the data to the automated name if outdir is given or in the parent folder if not
        if outdir:
            outdir = os.path.abspath(outdir)
            outname = core.create_outname(outdir, band_path, "ASBTemp", "tif")
        else:
            folder = os.path.split(meta_path)[0]
            outname = core.create_outname(folder, band_path, "ASBTemp", "tif")
            
        Bright_Temp.save(outname)
        output_filelist.append(outname)

        print("Saved output at {0}".format(outname))
        del TOA_rad, null_raster
            
    return output_filelist
コード例 #2
0
ファイル: toa_reflectance.py プロジェクト: henrykironde/dnppy
def toa_reflectance_8(band_nums, meta_path, outdir = None):
    """
    Converts Landsat 8 bands to Top-of-Atmosphere reflectance. To be performed
    on raw Landsat 8 level 1 data. See link below for details
    see here [http://landsat.usgs.gov/Landsat8_Using_Product.php]

    :param band_nums:   A list of desired band numbers such as [3,4,5]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files. If left False it will save ouput
                        files in the same directory as input files.

    :return output_filelist:    List of files created by this function
    """

    output_filelist = []

    # enforce the list of band numbers and grab metadata from the MTL file
    band_nums = core.enf_list(band_nums)
    band_nums = map(str, band_nums)
    OLI_bands = ['1','2','3','4','5','6','7','8','9']
    meta_path = os.path.abspath(meta_path)
    meta = landsat_metadata(meta_path)

    # cycle through each band in the list for calculation, ensuring each is in the list of OLI bands
    for band_num in band_nums:
        if band_num in OLI_bands:

            # scrape data from the given file path and attributes in the MTL file
            band_path = meta_path.replace("MTL.txt","B{0}.tif".format(band_num))
            Qcal = arcpy.Raster(band_path)                        
            Mp   = getattr(meta,"REFLECTANCE_MULT_BAND_{0}".format(band_num)) # multiplicative scaling factor
            Ap   = getattr(meta,"REFLECTANCE_ADD_BAND_{0}".format(band_num))  # additive rescaling factor
            SEA  = getattr(meta,"SUN_ELEVATION")*(math.pi/180)       # sun elevation angle theta_se

            # get rid of the zero values that show as the black background to avoid skewing values
            null_raster = arcpy.sa.SetNull(Qcal, Qcal, "VALUE = 0")

            # calculate top-of-atmosphere reflectance
            TOA_ref = (((null_raster * Mp) + Ap)/(math.sin(SEA)))


            # save the data to the automated name if outdir is given or in the parent folder if not
            if outdir is not None:
                outdir = os.path.abspath(outdir)
                outname = core.create_outname(outdir, band_path, "TOA_Ref", "tif")
            else:
                folder = os.path.split(meta_path)[0]
                outname = core.create_outname(folder, band_path, "TOA_Ref", "tif")
                
            TOA_ref.save(outname)
            output_filelist.append(outname)
            print("Saved output at {0}".format(outname))

        # if listed band is not an OLI sensor band, skip it and print message
        else:
            print("Can only perform reflectance conversion on OLI sensor bands")
            print("Skipping band {0}".format(band_num))

    return output_filelist
コード例 #3
0
ファイル: grab_meta.py プロジェクト: kmcdonald1494/dnppy
def grab_meta(filename):
    """
    Legacy metadata function simply wraps the newer landsat_metadata class.
    You should use ``landsat_metadata`` instead of this function, and can
    refer to that class for further explanation.

    :param filename:            filepath to an MTL file
    :return landsat_metadata:   Metadata object with MTL attributes.
    """

    return landsat_metadata(filename)
コード例 #4
0
ファイル: scene.py プロジェクト: waynechao128/dnppy
    def __init__(self, MTL_path, tif_dir = None):
        """
        builds the scene.

        In some cases, users may have their MTL file located somewhere other than
        their landsat data. In this instance, users should input the path to
        the landsat images as tif_dir.
        """

        self.mtl_dir    = os.path.dirname(MTL_path)     # directory of MTL file
        self.meta       = landsat_metadata(MTL_path)    # dnppy landsat_metadata object
        self.in_paths   = {}                            # dict of filepaths to tifs
        self.rasts      = {}                            # dict of arcpy raster objects

        if not tif_dir:
            self.tif_dir = self.mtl_dir

        self._find_bands()   
        return
コード例 #5
0
def toa_radiance_457(band_nums, meta_path, outdir=None):
    """
    Top of Atmosphere radiance (in Watts/(square meter x steradians x micrometers))
    conversion for Landsat 4, 5, and 7 data. To be performed on raw
    Landsat 4, 5, or 7 level 1 data.

    :param band_nums:   A list of desired band numbers such as [3, 4, 5]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files.

    :return output_filelist:    List of filepaths created by this function.
    """

    output_filelist = []
    meta_path = os.path.abspath(meta_path)

    band_nums = core.enf_list(band_nums)
    band_nums = map(str, band_nums)

    #metadata format was changed August 29, 2012. This tool can process either the new or old format
    f = open(meta_path)
    MText = f.read()

    metadata = landsat_metadata(meta_path)

    #the presence of a PRODUCT_CREATION_TIME category is used to identify old metadata
    #if this is not present, the meta data is considered new.
    #Band6length refers to the length of the Band 6 name string. In the new metadata this string is longer
    if "PRODUCT_CREATION_TIME" in MText:
        Meta = "oldMeta"
        Band6length = 2
    else:
        Meta = "newMeta"
        Band6length = 8

    #The tilename is located using the newMeta/oldMeta indixes and the date of capture is recorded
    if Meta == "newMeta":
        TileName = getattr(metadata, "LANDSAT_SCENE_ID")
        year = TileName[9:13]
        jday = TileName[13:16]
        date = getattr(metadata, "DATE_ACQUIRED")

    elif Meta == "oldMeta":
        TileName = getattr(metadata, "BAND1_FILE_NAME")
        year = TileName[13:17]
        jday = TileName[17:20]
        date = getattr(metadata, "ACQUISITION_DATE")

    #the spacecraft from which the imagery was capture is identified
    #this info determines the solar exoatmospheric irradiance (ESun) for each band
    spacecraft = getattr(metadata, "SPACECRAFT_ID")

    if "7" in spacecraft:
        ESun = (1969.0, 1840.0, 1551.0, 1044.0, 255.700, 0., 82.07, 1368.00)
        TM_ETM_bands = ['1', '2', '3', '4', '5', '7', '8']

    elif "5" in spacecraft:
        ESun = (1957.0, 1826.0, 1554.0, 1036.0, 215.0, 0., 80.67)
        TM_ETM_bands = ['1', '2', '3', '4', '5', '7']

    elif "4" in spacecraft:
        ESun = (1957.0, 1825.0, 1557.0, 1033.0, 214.9, 0., 80.72)
        TM_ETM_bands = ['1', '2', '3', '4', '5', '7']

    else:
        arcpy.AddError("This tool only works for Landsat 4, 5, or 7")
        raise arcpy.ExecuteError()

    #Calculating values for each band
    for band_num in band_nums:
        if band_num in TM_ETM_bands:

            print("Processing Band {0}".format(band_num))
            pathname = meta_path.replace("MTL.txt",
                                         "B{0}.tif".format(band_num))
            Oraster = arcpy.Raster(pathname)

            null_raster = arcpy.sa.SetNull(Oraster, Oraster, "VALUE = 0")

            #using the oldMeta/newMeta indixes to pull the min/max for radiance/Digital numbers
            if Meta == "newMeta":
                LMax = getattr(metadata,
                               "RADIANCE_MAXIMUM_BAND_{0}".format(band_num))
                LMin = getattr(metadata,
                               "RADIANCE_MINIMUM_BAND_{0}".format(band_num))
                QCalMax = getattr(metadata,
                                  "QUANTIZE_CAL_MAX_BAND_{0}".format(band_num))
                QCalMin = getattr(metadata,
                                  "QUANTIZE_CAL_MIN_BAND_{0}".format(band_num))

            elif Meta == "oldMeta":
                LMax = getattr(metadata, "LMAX_BAND{0}".format(band_num))
                LMin = getattr(metadata, "LMIN_BAND{0}".format(band_num))
                QCalMax = getattr(metadata, "QCALMAX_BAND{0}".format(band_num))
                QCalMin = getattr(metadata, "QCALMIN_BAND{0}".format(band_num))

            Radraster = (((LMax - LMin) / (QCalMax - QCalMin)) *
                         (null_raster - QCalMin)) + LMin
            Oraster = 0
            del null_raster

            band_rad = "{0}_B{1}".format(TileName, band_num)

            #create the output name and save the TOA radiance tiff
            if outdir is not None:
                outdir = os.path.abspath(outdir)
                outname = core.create_outname(outdir, band_rad, "TOA_Rad",
                                              "tif")
            else:
                folder = os.path.split(meta_path)[0]
                outname = core.create_outname(folder, band_rad, "TOA_Rad",
                                              "tif")

            Radraster.save(outname)
            output_filelist.append(outname)

            del Radraster

            print("toa radiance saved for Band {0}".format(band_num))

        #if listed band is not a TM/ETM+ sensor band, skip it and print message
        else:
            print(
                "Can only perform reflectance conversion on TM/ETM+ sensor bands"
            )
            print("Skipping band {0}".format(band_num))

    f.close()
    return output_filelist
コード例 #6
0
def toa_radiance_8(band_nums, meta_path, outdir=None):
    """
    Top of Atmosphere radiance (in Watts/(square meter x steradians x micrometers))
    conversion for landsat 8 data. To be performed on raw Landsat 8
    level 1 data. See link below for details:
    see here http://landsat.usgs.gov/Landsat8_Using_Product.php

    :param band_nums:   A list of desired band numbers such as [3, 4, 5]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files.

    :return output_filelist:    List of filepaths created by this function.
    """

    meta_path = os.path.abspath(meta_path)
    output_filelist = []

    #enforce list of band numbers and grab the metadata from the MTL file
    band_nums = core.enf_list(band_nums)
    band_nums = map(str, band_nums)
    meta = landsat_metadata(meta_path)

    OLI_bands = ['1', '2', '3', '4', '5', '6', '7', '8', '9']

    #loop through each band
    for band_num in band_nums:
        if band_num in OLI_bands:

            #create the band name
            band_path = meta_path.replace("MTL.txt",
                                          "B{0}.tif".format(band_num))
            Qcal = arcpy.Raster(band_path)

            null_raster = arcpy.sa.SetNull(Qcal, Qcal, "VALUE = 0")

            #scrape the attribute data
            Ml = getattr(meta, "RADIANCE_MULT_BAND_{0}".format(
                band_num))  # multiplicative scaling factor
            Al = getattr(meta, "RADIANCE_ADD_BAND_{0}".format(
                band_num))  # additive rescaling factor

            #calculate Top-of-Atmosphere radiance
            TOA_rad = (null_raster * Ml) + Al
            del null_raster

            # create the output name and save the TOA radiance tiff
            if "\\" in meta_path:
                name = meta_path.split("\\")[-1]
            elif "//" in meta_path:
                name = meta_path.split("//")[-1]

            rad_name = name.replace("_MTL.txt", "_B{0}".format(band_num))

            if outdir is not None:
                outdir = os.path.abspath(outdir)
                outname = core.create_outname(outdir, rad_name, "TOA_Rad",
                                              "tif")
            else:
                folder = os.path.split(meta_path)[0]
                outname = core.create_outname(folder, rad_name, "TOA_Rad",
                                              "tif")

            TOA_rad.save(outname)
            output_filelist.append(outname)
            print("Saved toa_radiance at {0}".format(outname))

        #if listed band is not a OLI sensor band, skip it and print message
        else:
            print(
                "Can only perform reflectance conversion on OLI sensor bands")
            print("Skipping band {0}".format(band_num))

    return output_filelist
コード例 #7
0
def surface_reflectance(meta_path, toa_folder, dem_path, dew_point, outdir = False, kt = 1.0):
    """
    This function will estimate surface reflectance for Landsat 4 TM, 5 TM, 7 ETM+, or 8 OLI data.

    Note this function will calculate surface reflectance for Landsat 4, 5, and 7
    bands 1, 2, 3, 4, 5, and 7 or Landsat 8 bands 2, 3, 4, 5, 6, and 7. All 6 bands should be in the
    toa_folder and have "TOA_Ref" in their filenames as per the landsat.toa_reflectance convention.

    The Landsat 8 Coastal Aerosol band (1) and Cirrus band (9) will not be calculated as they do not
    have a corresponding band in TM or ETM+. To be performed on Top-of-Atmosphere Reflectance data
    processed with the landsat.toa_reflectance_457 or the landsat.toa_reflectance_8 function.

    Resources
        - DEM
            - NASA Shuttle Radar Topography Mission (SRTM) up to 30m resolution.
              [http://www2.jpl.nasa.gov/srtm/cbanddataproducts.html]
            - NASA Advanced Spaceborne Thermal Emission and Reflection Radiometer (ASTER)
              Global Digital Elevation Model (GDEM) [http://asterweb.jpl.nasa.gov/gdem.asp]
            - USGS National Elevation Dataset (NED) [http://nationalmap.gov/elevation.html]
              downloadable in 30 meter resolution through The National Map Viewer

        - Dew Point
            - NOAA Daily Observational Data: Global Summary of the Day (GSOD) - GIS Data Locator
              [http://gis.ncdc.noaa.gov/map/viewer/#app=clim&cfg=cdo&theme=daily&layers=0001&node=gis].
              Select a weather station within the Landsat scene's extent, follow the link,
              and enter the scene's acquisition date. This will output a text file, with
              dew point under DEWP. More NOAA climatic data available at
              [https://www.climate.gov/data/maps-and-data]

    :param meta_path:       The full filepath to the metadata file (ending in MTL.txt) for the dataset
    :param toa_folder:      The filepath to the folder containing the TOA_Ref tiffs to be processed
    :param dem_path:        The full filepath to a DEM tif that covers the desired Landsat scene
                            Note that the DEM should be resampled to the Landsat bands' resolution (30m)
                            and pixel alignment. Also ensure there are no gaps in the dataset.
    :param dew_point:       The number (e.g. 57.7) for the dew point at the time and place of scene acquisition
    :param outdir:          Output directory to save converted files. If left False it will save
                            output files in the toa_folder directory.
    :param kt:              Unitless turbidity coefficient. Default set at 1.0 for clean air.
                            Set at 0.5 for extremely turbid, dusty, or polluted air.
                            
    :return output_filelist:  A list of all files created by this function                        
    """

    meta_path = os.path.abspath(meta_path)
    toa_folder = os.path.abspath(toa_folder)
    dem_path = os.path.abspath(dem_path)
    output_filelist = []

    #define the list of constants for effective narrowband transmissivity for incoming solar radiation
    constants_enbt1 = [[0.987, -0.00071, 0.000036, 0.0880, 0.0789],
                         [2.319, -0.00016, 0.000105, 0.0437, -1.2697],
                         [0.951, -0.00033, 0.000280, 0.0875, 0.1014],
                         [0.375, -0.00048, 0.005018, 0.1355, 0.6621],
                         [0.234, -0.00101, 0.004336, 0.0560, 0.7757],
                         [0.365, -0.00097, 0.004296, 0.0155, 0.6390]]

    #define the list of constants for effective narrowband transmissivity for shortwave radiation
    #reflected from the surface
    constants_enbt2 = [[0.987, -0.00071, 0.000036, 0.0880, 0.0789],
                         [2.319, -0.00016, 0.000105, 0.0437, -1.2697],
                         [0.951, -0.00033, 0.000280, 0.0875, 0.1014],
                         [0.375, -0.00048, 0.005018, 0.1355, 0.6621],
                         [0.234, -0.00101, 0.004336, 0.0560, 0.7757],
                         [0.365, -0.00097, 0.004296, 0.0155, 0.6390]]

    #enforce the list of band numbers, grab metadata from the MTL file, and define the band numbers needed from each sensor
    meta = landsat_metadata(meta_path)
    OLI_bands = ['2','3','4','5','6','7']
    TM_ETM_bands = ['1','2','3','4','5','7']

    #define the tile name for the landsat scene based on the metadata file's name

    #Open the metadata text file and read to set the scene's tilename
    f = open(meta_path)
    MText = f.read()

    if "PRODUCT_CREATION_TIME" in MText:
            tilename = getattr(meta, "BAND1_FILE_NAME")
    else:
            tilename = getattr(meta, "LANDSAT_SCENE_ID")

    #construct the list of TOA reflectance band tiffs and populate it based on the above definitions
    toa_list = []
    out_list = []
    n = 0
    for file in os.listdir(toa_folder):
            if ("TOA_Ref" in file) and (file[-4:] == ".tif" or file[-4:] == ".TIF"):
                    if "LC8" in meta_path:
                            tile = "{0}_B{1}".format(tilename, OLI_bands[n])
                            if tile in file:
                                    path = "{0}\\{1}".format(toa_folder, file)
                                    out_file = file.replace("TOA", "Surf")
                                    toa_list.append(path)
                                    out_list.append(out_file)
                                    n = n + 1
                                    if n > 5:
                                            break
                    elif ("LE7" in file) or ("LT5" in file) or ("LT4" in file):
                            tile = "{0}_B{1}".format(tilename, TM_ETM_bands[n])
                            if tile in file:
                                    path = "{0}\\{1}".format(toa_folder, file)
                                    out_file = file.replace("TOA", "Surf")
                                    toa_list.append(path)
                                    out_list.append(out_file)
                                    n = n + 1
                                    if n > 5:
                                            break

    #grab the corner lat/lon coordinates to calculate the approximate scene center lat/lon
    ul_lat = getattr(meta, "CORNER_UL_LAT_PRODUCT")
    ul_lon = getattr(meta, "CORNER_UL_LON_PRODUCT")
    ur_lat = getattr(meta, "CORNER_UR_LAT_PRODUCT")
    ur_lon = getattr(meta, "CORNER_UR_LON_PRODUCT")
    ll_lat = getattr(meta, "CORNER_LL_LAT_PRODUCT")
    ll_lon = getattr(meta, "CORNER_LL_LON_PRODUCT")
    lr_lat = getattr(meta, "CORNER_LR_LAT_PRODUCT")
    lr_lon = getattr(meta, "CORNER_LR_LON_PRODUCT")

    u_lon_avg = np.mean([ul_lon, ur_lon])
    l_lon_avg = np.mean([ll_lon, lr_lon])
    l_lat_avg = np.mean([ul_lat, ll_lat])
    r_lat_avg = np.mean([ur_lat, lr_lat])

    center_lat = np.mean([l_lat_avg, r_lat_avg])
    center_lon = np.mean([u_lon_avg, l_lon_avg])

    #construct the datetime object from the date acquired and scene center time attributes
    date = getattr(meta, "DATE_ACQUIRED")
    dl = date.split("-")
    time = getattr(meta, "SCENE_CENTER_TIME")
    tl = time.split(":")

    dt = datetime.datetime(int(dl[0]), int(dl[1]), int(dl[2]), int(tl[0]), int(tl[1]), int(tl[2][0:2]))

    #use the dnppy.solar module to calculate the solar characteristics at the scene center at the time of acquisition
    sc = solar.solar(center_lat, center_lon, dt, 0)
    sc.compute_all()

    #Cosine of Solar Zenith over horizontal surface
    declination = math.degrees(sc.get_declination())
    hour_angle = math.degrees(sc.get_hour_angle())
    lat = math.degrees(center_lat)

    cth = (math.sin(declination) * math.sin(lat)) + (math.cos(declination) * math.cos(center_lat) * math.cos(hour_angle))

    #Saturation Vapor Pressure
    svp = 0.6108 * math.exp((17.27 * dew_point) / (dew_point + 237.3))

    #Atmospheric Pressure
    DEM = arcpy.sa.Raster(dem_path)
    ap = 101.3 * ((( 293 - (0.0065 * DEM))/ 293) ** 5.26)

    #Water in Atmosphere
    wia = (0.14 * svp * ap) + 2.1

    #Effective Narrowband Transmittance for incoming solar radiation
    entisr_bands = []
    for i in xrange(6):
            c1 = constants_enbt1[i][0]
            c2 = constants_enbt1[i][1]
            c3 = constants_enbt1[i][2]
            c4 = constants_enbt1[i][3]
            c5 = constants_enbt1[i][4]
            enbt1 = c1 * ((arcpy.sa.Exp((c2 * ap)/(kt * cth))) - (((c3 * wia) + c4)/cth)) + c5
            entisr_bands.append(enbt1)

    #Effective Narrowband Transmittance for shortwave radiation reflected from surface
    entsrrs_bands = []

    #cos_n always 1 for sensor pointing straight nadir
    cos_n = 1

    for i in xrange(6):
            c1 = constants_enbt2[i][0]
            c2 = constants_enbt2[i][1]
            c3 = constants_enbt2[i][2]
            c4 = constants_enbt2[i][3]
            c5 = constants_enbt2[i][4]
            enbt2 = c1 * ((arcpy.sa.Exp((c2 * ap)/(kt * cos_n))) - (((c3 * wia) + c4))) + c5
            entsrrs_bands.append(enbt2)

    #Per Band Path Reflectance
    pr_bands = []
    pr_constants = [0.254, 0.149, 0.147, 0.311, 0.103, 0.036]
    for j in xrange(6):
            pr = pr_constants[j] * (1 - entisr_bands[j])
            pr_bands.append(pr)

    #Calculate and save At-Surface Reflectance band tiffs
    for k in xrange(6):
            if outdir:
                    outdir = os.path.abspath(outdir)
                    asr_path = "{0}\\{1}".format(outdir, out_list[k])
            else:
                    asr_path = "{0}\\{1}".format(toa_folder, out_list[k])
            refl_surf = (toa_list[k] - pr_bands[k])/(entisr_bands[k] * entsrrs_bands[k])
            refl_surf.save(asr_path)
            output_filelist.append(asr_path)

    return output_filelist
コード例 #8
0
def surface_temp_8(band4_toa, meta_path, path_rad, nbt, sky_rad, outdir = False, L = 0.5):
    """
    Calculates surface temperature from Landsat 8 OLI and TIRS data. Requires band 4 and 5
    Top-of-Atmosphere Reflectance tiffs and the unprocessed band 10 and 11 tiffs.

    Note: if the default values of 0, 1, and 0 are used for the Path Radiance, Narrowband \
    Transmissivity, and Sky Radiance constants, atmospheric conditions will not be accounted
    for and the surface values may be off. Values are attainable using MODTRAN.

    :param band4_toa:   Filepath to the Band 4 Top-of-Atmosphere Reflectance tiff.
                        use landsat.toa_reflectance_8
    :param meta_path:   Filepath to the metadata file (ending in _MTL.txt)
    :param path_rad:    Path Radiance constant (default 0)
    :param nbt:         Narrowband Transmissivity constant (default 1)
    :param sky_rad:     Sky Radiance constant (default 0)
    :param outdir:      Path to the desired output folder. If left False the
                        output tiff will be place in band4_toa's folder
    :param L:           Soil brightness correction factor, between 0 and 1. used to calculate
                        Soil Adjusted Vegetation Index. Default L = 0.5 works well in
                        most situations. when L = 0, SAVI = NDVI.

    :return surface_temp_8:    Full filepath of tif created by this function
    """

    band4_toa = os.path.abspath(band4_toa)
    meta_path = os.path.abspath(meta_path)

    # Grab metadata from the MTL file and set the pathnames for Band 5 TOA Reflectance and the raw Band 11 tiffs
    meta = landsat_metadata(meta_path)

    band5_toa = band4_toa.replace("_B4_", "_B5_")
    band10 = meta_path.replace("_MTL.txt", "_B10.tif")
    band11 = band10.replace("_B10.tif", "_B11.tif")

    # Soil Adjusted Vegetation Index
    red = arcpy.sa.Float(band4_toa)
    nir = arcpy.sa.Float(band5_toa)
    
    savi = ((1 + L) * (nir - red))/(L + (nir + red))

    # Leaf Area Index
    # assigns LAI for 0.1 <= SAVI <= 0.687
    lai_1 = ((arcpy.sa.Ln((0.69 - savi)/0.59))/(-0.91))
    # assigns LAI for SAVI >= 0.687
    lai_2 = arcpy.sa.Con(savi, lai_1, 6, "VALUE < 0.687")
    # assigns LAI for SAVI <= 0.1
    lai = arcpy.sa.Con(savi, lai_2, 0, "VALUE >= 0.1")

    # Narrow Band Emissivity
    remap = 0.97 + (0.0033 * lai)
    nbe = arcpy.sa.Con(lai, remap, 0.98, "VALUE <= 3")

    # Get the radiance mult/add bands for bands 10 and 11
    Ml_10 = getattr(meta, "RADIANCE_MULT_BAND_10")
    Al_10 = getattr(meta, "RADIANCE_ADD_BAND_10")
    Ml_11 = getattr(meta, "RADIANCE_MULT_BAND_11")
    Al_11 = getattr(meta, "RADIANCE_ADD_BAND_11")
    
    # Set values in the TIRS band tiffs to null
    null_10 = arcpy.sa.SetNull(band10, band10, "VALUE <= 1")
    null_11 = arcpy.sa.SetNull(band11, band11, "VALUE <= 1")

    # Initial Thermal Radiances
    itr_10 = (null_10 * Ml_10) + Al_10
    itr_11 = (null_11 * Ml_11) + Al_11

    # Corrected Thermal Radiances
    ctr_10 = ((itr_10 - path_rad)/nbt) - ((1 - nbe) * sky_rad)
    ctr_11 = ((itr_11 - path_rad)/nbt) - ((1 - nbe) * sky_rad)

    # Get the K1 and K2 constants for bands 10 and 11
    K1_10 = getattr(meta, "K1_CONSTANT_BAND_10")
    K2_10 = getattr(meta, "K2_CONSTANT_BAND_10")
    K1_11 = getattr(meta, "K1_CONSTANT_BAND_11")
    K2_11 = getattr(meta, "K2_CONSTANT_BAND_11")

    # Calculate surface temperature based on bands 10 and 11 and average them for final output
    st_10 = (K2_10/(arcpy.sa.Ln(((nbe * K1_10)/ctr_10) + 1)))
    st_11 = (K2_11/(arcpy.sa.Ln(((nbe * K1_11)/ctr_10) + 1)))

    st = (st_10 + st_11)/2

    # Create output name and save the Surface Temperature tiff
    tilename = getattr(meta, "LANDSAT_SCENE_ID")
    
    if outdir:
        outdir = os.path.abspath(outdir)
        surface_temp_8 = core.create_outname(outdir, tilename, "Surf_Temp", "tif")
    else:
        folder = os.path.split(band4_toa)[0]
        surface_temp_8 = core.create_outname(folder, tilename, "Surf_Temp", "tif")
        
    st.save(surface_temp_8)

    return surface_temp_8
コード例 #9
0
def surface_temp_457(band3_toa, meta_path, path_rad, nbt, sky_rad, outdir = False, L = 0.5):
    """
    Calculates surface temperature from Landsat 4/5 TM or 7 ETM+ data. Requires
    band 3 and 4 Top-of-Atmosphere Reflectance tiffs and the unprocessed band
    6 (or 6_VCID_1 for Landsat 7) tiff.

    Note: if the default values of 0, 1, and 0 are used for the Path Radiance, Narrowband
    Transmissivity, and Sky Radiance constants, atmospheric conditions will not be accounted
    for and the surface values may be off. Values are attainable using MODTRAN.

    :param band3_toa:   Filepath to the Band 3 Top-of-Atmosphere Reflectance tiff.
                        use landsat.toa_reflectance_457
    :param meta_path:   Filepath to the metadata file (ending in _MTL.txt)
    :param path_rad:    Path Radiance constant (default 0)
    :param nbt:         Narrowband Transmissivity constant (default 1)
    :param sky_rad:     Sky Radiance constant (default 0)
    :param outdir:      Path to the desired output folder. If left False the
                        output tiff will be place in band4_toa's folder
    :param L:           Soil brightness correction factor, between 0 and 1. used to calculate
                        Soil Adjusted Vegetation Index. Default L = 0.5 works well in
                        most situations. when L = 0, SAVI = NDVI.

    :return surface_temp_457:    Full filepath of tif created by this function
    """

    band3_toa = os.path.abspath(band3_toa)
    meta_path = os.path.abspath(meta_path)

    # Set the pathname for band 4
    band4_toa = band3_toa.replace("_B3_", "_B4_")

    # Grab metadata from the MTL file and identify the spacecraft ID
    meta = landsat_metadata(meta_path)
    spacecraft = getattr(meta, "SPACECRAFT_ID")

    # Set the band 6 number, K1 and K2 thermal constants, and band 6 pathname based on spacecraft ID
    if "4" in spacecraft or "5" in spacecraft:
        band_num = "6"
        K1 = 607.76
        K2 = 1260.56
        band6 = meta_path.replace("_MTL.txt", "_B6.tif")
    elif "7" in spacecraft:
        band_num = "6_VCID_1"
        K1 = 666.09
        K2 = 1282.71
        band6 = meta_path.replace("_MTL.txt", "_B6_VCID_1.tif")

    else:
        print("Enter the MTL file corresponding to a Landsat 4, 5, or 7 dataset")

    # Open the metadata text file and read to set the scene's tilename
    f = open(meta_path)
    MText = f.read()

    if "PRODUCT_CREATION_TIME" in MText:
        tilename = getattr(meta, "BAND1_FILE_NAME")
    else:
        tilename = getattr(meta, "LANDSAT_SCENE_ID")

    #Soil Adjusted Vegetation Index
    red = arcpy.sa.Float(band3_toa)
    nir = arcpy.sa.Float(band4_toa)
    
    savi = ((1 + L) * (nir - red))/(L + (nir - red))

    #Leaf Area Index
    #assigns LAI for 0.1 <= SAVI <= 0.687
    lai_1 = ((arcpy.sa.Ln((0.69 - savi)/0.59))/(-0.91))
    #assigns LAI for SAVI >= 0.687
    lai_2 = arcpy.sa.Con(savi, lai_1, 6, "VALUE < 0.687")
    #assigns LAI for SAVI <= 0.1
    lai = arcpy.sa.Con(savi, lai_2, 0, "VALUE >= 0.1")

    #Narrow Band Emissivity
    remap = 0.97 + (0.0033 * lai)
    nbe = arcpy.sa.Con(lai, remap, 0.98, "VALUE <= 3")

    #Get the radiance mult/add bands for bands 10 and 11
    Ml = getattr(meta, "RADIANCE_MULT_BAND_{0}".format(band_num))
    Al = getattr(meta, "RADIANCE_ADD_BAND_{0}".format(band_num))
 
    #Set values in the TIRS band tiffs to null
    null = arcpy.sa.SetNull(band6, band6, "VALUE <= 1")

    # Initial Thermal Radiances
    itr = (null * Ml) + Al

    # Corrected Thermal Radiances
    ctr = ((itr - path_rad)/nbt) - ((1 - nbe) * sky_rad)

    # Calculate surface temperature
    st = (K2/(arcpy.sa.Ln(((nbe * K1)/ctr) + 1)))

    #Create output name and save the surface temperature tiff   
    if outdir:
        outdir = os.path.abspath(outdir)
        surface_temp_457 = core.create_outname(outdir, tilename, "Surf_Temp", "tif")
    else:
        folder = os.path.split(band3_toa)[0]
        surface_temp_457 = core.create_outname(folder, tilename, "Surf_Temp", "tif")
        
    st.save(surface_temp_457)

    return surface_temp_457
コード例 #10
0
ファイル: toa_reflectance.py プロジェクト: henrykironde/dnppy
def toa_reflectance_457(band_nums, meta_path, outdir = None):
    """
    This function is used to convert Landsat 4, 5, or 7 pixel values from
    digital numbers to Top-of-Atmosphere Reflectance. To be performed on raw
    Landsat 4, 5, or 7 data.

    :param band_nums:   A list of desired band numbers such as [3,4,5]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files. If left False it will save ouput
                        files in the same directory as input files.

    :return output_filelist:    List of files created by this function
    """
   
    output_filelist = []

    band_nums = core.enf_list(band_nums)
    band_nums = map(str, band_nums)

    # metadata format was changed August 29, 2012. This tool can process either the new or old format
    f = open(meta_path)
    MText = f.read()

    meta_path = os.path.abspath(meta_path)
    metadata = landsat_metadata(meta_path)
    
    # the presence of a PRODUCT_CREATION_TIME category is used to identify old metadata
    # if this is not present, the meta data is considered new.
    # Band6length refers to the length of the Band 6 name string. In the new metadata this string is longer
    if "PRODUCT_CREATION_TIME" in MText:
        Meta = "oldMeta"
        Band6length = 2
    else:
        Meta = "newMeta"
        Band6length = 8

    # The tilename is located using the newMeta/oldMeta indixes and the date of capture is recorded
    if Meta == "newMeta":
        TileName = getattr(metadata, "LANDSAT_SCENE_ID")
        year = TileName[9:13]
        jday = TileName[13:16]
        date = getattr(metadata, "DATE_ACQUIRED")
    elif Meta == "oldMeta":
        TileName = getattr(metadata, "BAND1_FILE_NAME")
        year = TileName[13:17]
        jday = TileName[17:20]
        date = getattr(metadata, "ACQUISITION_DATE")

    # the spacecraft from which the imagery was capture is identified
    # this info determines the solar exoatmospheric irradiance (ESun) for each band
    spacecraft = getattr(metadata, "SPACECRAFT_ID")
    
    if "7" in spacecraft:
        ESun = (1969.0, 1840.0, 1551.0, 1044.0, 255.700, 0., 82.07, 1368.00)
        TM_ETM_bands = ['1','2','3','4','5','7','8']
    elif "5" in spacecraft:
         ESun = (1957.0, 1826.0, 1554.0, 1036.0, 215.0, 0. ,80.67)
         TM_ETM_bands = ['1','2','3','4','5','7']
    elif "4" in spacecraft:
        ESun = (1957.0, 1825.0, 1557.0, 1033.0, 214.9, 0. ,80.72)
        TM_ETM_bands = ['1','2','3','4','5','7']
    else:
        arcpy.AddError("This tool only works for Landsat 4, 5, or 7")
        raise arcpy.ExecuteError()

    # determing if year is leap year and setting the Days in year accordingly
    if float(year) % 4 == 0: DIY = 366.
    else: DIY=365.

    # using the date to determining the distance from the sun
    theta = 2 * math.pi * float(jday)/DIY

    dSun2 = (1.00011 + 0.034221 * math.cos(theta) + 0.001280 * math.sin(theta) +
           0.000719 * math.cos(2*theta)+ 0.000077 * math.sin(2 * theta))

    SZA = 90. - float(getattr(metadata, "SUN_ELEVATION"))
    
    # Calculating values for each band
    for band_num in band_nums:
        if band_num in TM_ETM_bands:

            print("Processing Band {0}".format(band_num))
            pathname = meta_path.replace("MTL.txt", "B{0}.tif".format(band_num))
            Oraster = arcpy.Raster(pathname)
         
            null_raster = arcpy.sa.SetNull(Oraster, Oraster, "VALUE = 0")

            # using the oldMeta/newMeta indices to pull the min/max for radiance/Digital numbers
            if Meta == "newMeta":
                LMax    = getattr(metadata, "RADIANCE_MAXIMUM_BAND_{0}".format(band_num))
                LMin    = getattr(metadata, "RADIANCE_MINIMUM_BAND_{0}".format(band_num))  
                QCalMax = getattr(metadata, "QUANTIZE_CAL_MAX_BAND_{0}".format(band_num))
                QCalMin = getattr(metadata, "QUANTIZE_CAL_MIN_BAND_{0}".format(band_num))
            elif Meta == "oldMeta":
                LMax    = getattr(metadata, "LMAX_BAND{0}".format(band_num))
                LMin    = getattr(metadata, "LMIN_BAND{0}".format(band_num))  
                QCalMax = getattr(metadata, "QCALMAX_BAND{0}".format(band_num))
                QCalMin = getattr(metadata, "QCALMIN_BAND{0}".format(band_num))
    
            Radraster = (((LMax - LMin)/(QCalMax-QCalMin)) * (null_raster - QCalMin)) + LMin
            Oraster = 0
            del null_raster
    
            # Calculating temperature for band 6 if present
            Refraster = (math.pi * Radraster * dSun2) / (ESun[int(band_num[0])-1] * math.cos(SZA*(math.pi/180)))

            # construc output names for each band based on whether outdir is set (default is False)
            if outdir is not None:
                outdir = os.path.abspath(outdir)
                BandPath = core.create_outname(outdir, pathname, "TOA_Ref", "tif")
            else:
                folder = os.path.split(meta_path)[0]
                BandPath = core.create_outname(folder, pathname, "TOA_Ref", "tif")

            Refraster.save(BandPath)
            output_filelist.append(BandPath)

            del Refraster, Radraster
            print("Reflectance Calculated for Band {0}".format(band_num))

        # if listed band is not a TM/ETM+ sensor band, skip it and print message
        else:
            print("Can only perform reflectance conversion on TM/ETM+ sensor bands")
            print("Skipping band {0}".format(band_num))
         
    f.close()
    return output_filelist
コード例 #11
0
ファイル: toa_radiance.py プロジェクト: ritviksahajpal/dnppy
def toa_radiance_457(band_nums, meta_path, outdir=None):
    """
    Top of Atmosphere radiance (in Watts/(square meter x steradians x micrometers))
    conversion for Landsat 4, 5, and 7 data. To be performed on raw
    Landsat 4, 5, or 7 level 1 data.

    :param band_nums:   A list of desired band numbers such as [3, 4, 5]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files.

    :return output_filelist:    List of filepaths created by this function.
    """

    output_filelist = []
    meta_path = os.path.abspath(meta_path)

    band_nums = core.enf_list(band_nums)
    band_nums = map(str, band_nums)

    # metadata format was changed August 29, 2012. This tool can process either the new or old format
    f = open(meta_path)
    MText = f.read()

    metadata = landsat_metadata(meta_path)

    # the presence of a PRODUCT_CREATION_TIME category is used to identify old metadata
    # if this is not present, the meta data is considered new.
    # Band6length refers to the length of the Band 6 name string. In the new metadata this string is longer
    if "PRODUCT_CREATION_TIME" in MText:
        Meta = "oldMeta"
        Band6length = 2
    else:
        Meta = "newMeta"
        Band6length = 8

    # The tilename is located using the newMeta/oldMeta indixes and the date of capture is recorded
    if Meta == "newMeta":
        TileName = getattr(metadata, "LANDSAT_SCENE_ID")
        year = TileName[9:13]
        jday = TileName[13:16]
        date = getattr(metadata, "DATE_ACQUIRED")

    elif Meta == "oldMeta":
        TileName = getattr(metadata, "BAND1_FILE_NAME")
        year = TileName[13:17]
        jday = TileName[17:20]
        date = getattr(metadata, "ACQUISITION_DATE")

    # the spacecraft from which the imagery was capture is identified
    # this info determines the solar exoatmospheric irradiance (ESun) for each band
    spacecraft = getattr(metadata, "SPACECRAFT_ID")

    if "7" in spacecraft:
        ESun = (1969.0, 1840.0, 1551.0, 1044.0, 255.700, 0.0, 82.07, 1368.00)
        TM_ETM_bands = ["1", "2", "3", "4", "5", "7", "8"]

    elif "5" in spacecraft:
        ESun = (1957.0, 1826.0, 1554.0, 1036.0, 215.0, 0.0, 80.67)
        TM_ETM_bands = ["1", "2", "3", "4", "5", "7"]

    elif "4" in spacecraft:
        ESun = (1957.0, 1825.0, 1557.0, 1033.0, 214.9, 0.0, 80.72)
        TM_ETM_bands = ["1", "2", "3", "4", "5", "7"]

    else:
        arcpy.AddError("This tool only works for Landsat 4, 5, or 7")
        raise arcpy.ExecuteError()

    # Calculating values for each band
    for band_num in band_nums:
        if band_num in TM_ETM_bands:

            print("Processing Band {0}".format(band_num))
            pathname = meta_path.replace("MTL.txt", "B{0}.tif".format(band_num))
            Oraster = arcpy.Raster(pathname)

            null_raster = arcpy.sa.SetNull(Oraster, Oraster, "VALUE = 0")

            # using the oldMeta/newMeta indixes to pull the min/max for radiance/Digital numbers
            if Meta == "newMeta":
                LMax = getattr(metadata, "RADIANCE_MAXIMUM_BAND_{0}".format(band_num))
                LMin = getattr(metadata, "RADIANCE_MINIMUM_BAND_{0}".format(band_num))
                QCalMax = getattr(metadata, "QUANTIZE_CAL_MAX_BAND_{0}".format(band_num))
                QCalMin = getattr(metadata, "QUANTIZE_CAL_MIN_BAND_{0}".format(band_num))

            elif Meta == "oldMeta":
                LMax = getattr(metadata, "LMAX_BAND{0}".format(band_num))
                LMin = getattr(metadata, "LMIN_BAND{0}".format(band_num))
                QCalMax = getattr(metadata, "QCALMAX_BAND{0}".format(band_num))
                QCalMin = getattr(metadata, "QCALMIN_BAND{0}".format(band_num))

            Radraster = (((LMax - LMin) / (QCalMax - QCalMin)) * (null_raster - QCalMin)) + LMin
            Oraster = 0
            del null_raster

            band_rad = "{0}_B{1}".format(TileName, band_num)

            # create the output name and save the TOA radiance tiff
            if outdir is not None:
                outdir = os.path.abspath(outdir)
                outname = core.create_outname(outdir, band_rad, "TOA_Rad", "tif")
            else:
                folder = os.path.split(meta_path)[0]
                outname = core.create_outname(folder, band_rad, "TOA_Rad", "tif")

            Radraster.save(outname)
            output_filelist.append(outname)

            del Radraster

            print("toa radiance saved for Band {0}".format(band_num))

        # if listed band is not a TM/ETM+ sensor band, skip it and print message
        else:
            print("Can only perform reflectance conversion on TM/ETM+ sensor bands")
            print("Skipping band {0}".format(band_num))

    f.close()
    return output_filelist
コード例 #12
0
ファイル: toa_radiance.py プロジェクト: ritviksahajpal/dnppy
def toa_radiance_8(band_nums, meta_path, outdir=None):
    """
    Top of Atmosphere radiance (in Watts/(square meter x steradians x micrometers))
    conversion for landsat 8 data. To be performed on raw Landsat 8
    level 1 data. See link below for details:
    see here http://landsat.usgs.gov/Landsat8_Using_Product.php

    :param band_nums:   A list of desired band numbers such as [3, 4, 5]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files.

    :return output_filelist:    List of filepaths created by this function.
    """

    meta_path = os.path.abspath(meta_path)
    output_filelist = []

    # enforce list of band numbers and grab the metadata from the MTL file
    band_nums = core.enf_list(band_nums)
    band_nums = map(str, band_nums)
    meta = landsat_metadata(meta_path)

    OLI_bands = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

    # loop through each band
    for band_num in band_nums:
        if band_num in OLI_bands:

            # create the band name
            band_path = meta_path.replace("MTL.txt", "B{0}.tif".format(band_num))
            Qcal = arcpy.Raster(band_path)

            null_raster = arcpy.sa.SetNull(Qcal, Qcal, "VALUE = 0")

            # scrape the attribute data
            Ml = getattr(meta, "RADIANCE_MULT_BAND_{0}".format(band_num))  # multiplicative scaling factor
            Al = getattr(meta, "RADIANCE_ADD_BAND_{0}".format(band_num))  # additive rescaling factor

            # calculate Top-of-Atmosphere radiance
            TOA_rad = (null_raster * Ml) + Al
            del null_raster

            # create the output name and save the TOA radiance tiff
            if "\\" in meta_path:
                name = meta_path.split("\\")[-1]
            elif "//" in meta_path:
                name = meta_path.split("//")[-1]

            rad_name = name.replace("_MTL.txt", "_B{0}".format(band_num))

            if outdir is not None:
                outdir = os.path.abspath(outdir)
                outname = core.create_outname(outdir, rad_name, "TOA_Rad", "tif")
            else:
                folder = os.path.split(meta_path)[0]
                outname = core.create_outname(folder, rad_name, "TOA_Rad", "tif")

            TOA_rad.save(outname)
            output_filelist.append(outname)
            print("Saved toa_radiance at {0}".format(outname))

        # if listed band is not a OLI sensor band, skip it and print message
        else:
            print("Can only perform reflectance conversion on OLI sensor bands")
            print("Skipping band {0}".format(band_num))

    return output_filelist
コード例 #13
0
ファイル: toa_reflectance.py プロジェクト: waynechao128/dnppy
def toa_reflectance_457(band_nums, meta_path, outdir=None):
    """
    This function is used to convert Landsat 4, 5, or 7 pixel values from
    digital numbers to Top-of-Atmosphere Reflectance. To be performed on raw
    Landsat 4, 5, or 7 data.

    :param band_nums:   A list of desired band numbers such as [3,4,5]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files. If left False it will save ouput
                        files in the same directory as input files.

    :return output_filelist:    List of files created by this function
    """

    output_filelist = []

    band_nums = core.enf_list(band_nums)
    band_nums = map(str, band_nums)

    # metadata format was changed August 29, 2012. This tool can process either the new or old format
    f = open(meta_path)
    MText = f.read()

    meta_path = os.path.abspath(meta_path)
    metadata = landsat_metadata(meta_path)

    # the presence of a PRODUCT_CREATION_TIME category is used to identify old metadata
    # if this is not present, the meta data is considered new.
    # Band6length refers to the length of the Band 6 name string. In the new metadata this string is longer
    if "PRODUCT_CREATION_TIME" in MText:
        Meta = "oldMeta"
        Band6length = 2
    else:
        Meta = "newMeta"
        Band6length = 8

    # The tilename is located using the newMeta/oldMeta indixes and the date of capture is recorded
    if Meta == "newMeta":
        TileName = getattr(metadata, "LANDSAT_SCENE_ID")
        year = TileName[9:13]
        jday = TileName[13:16]
        date = getattr(metadata, "DATE_ACQUIRED")
    elif Meta == "oldMeta":
        TileName = getattr(metadata, "BAND1_FILE_NAME")
        year = TileName[13:17]
        jday = TileName[17:20]
        date = getattr(metadata, "ACQUISITION_DATE")

    # the spacecraft from which the imagery was capture is identified
    # this info determines the solar exoatmospheric irradiance (ESun) for each band
    spacecraft = getattr(metadata, "SPACECRAFT_ID")

    if "7" in spacecraft:
        ESun = (1969.0, 1840.0, 1551.0, 1044.0, 255.700, 0., 82.07, 1368.00)
        TM_ETM_bands = ['1', '2', '3', '4', '5', '7', '8']
    elif "5" in spacecraft:
        ESun = (1957.0, 1826.0, 1554.0, 1036.0, 215.0, 0., 80.67)
        TM_ETM_bands = ['1', '2', '3', '4', '5', '7']
    elif "4" in spacecraft:
        ESun = (1957.0, 1825.0, 1557.0, 1033.0, 214.9, 0., 80.72)
        TM_ETM_bands = ['1', '2', '3', '4', '5', '7']
    else:
        arcpy.AddError("This tool only works for Landsat 4, 5, or 7")
        raise arcpy.ExecuteError()

    # determing if year is leap year and setting the Days in year accordingly
    if float(year) % 4 == 0: DIY = 366.
    else: DIY = 365.

    # using the date to determining the distance from the sun
    theta = 2 * math.pi * float(jday) / DIY

    dSun2 = (1.00011 + 0.034221 * math.cos(theta) +
             0.001280 * math.sin(theta) + 0.000719 * math.cos(2 * theta) +
             0.000077 * math.sin(2 * theta))

    SZA = 90. - float(getattr(metadata, "SUN_ELEVATION"))

    # Calculating values for each band
    for band_num in band_nums:
        if band_num in TM_ETM_bands:

            print("Processing Band {0}".format(band_num))
            pathname = meta_path.replace("MTL.txt",
                                         "B{0}.tif".format(band_num))
            Oraster = arcpy.Raster(pathname)

            null_raster = arcpy.sa.SetNull(Oraster, Oraster, "VALUE = 0")

            # using the oldMeta/newMeta indices to pull the min/max for radiance/Digital numbers
            if Meta == "newMeta":
                LMax = getattr(metadata,
                               "RADIANCE_MAXIMUM_BAND_{0}".format(band_num))
                LMin = getattr(metadata,
                               "RADIANCE_MINIMUM_BAND_{0}".format(band_num))
                QCalMax = getattr(metadata,
                                  "QUANTIZE_CAL_MAX_BAND_{0}".format(band_num))
                QCalMin = getattr(metadata,
                                  "QUANTIZE_CAL_MIN_BAND_{0}".format(band_num))
            elif Meta == "oldMeta":
                LMax = getattr(metadata, "LMAX_BAND{0}".format(band_num))
                LMin = getattr(metadata, "LMIN_BAND{0}".format(band_num))
                QCalMax = getattr(metadata, "QCALMAX_BAND{0}".format(band_num))
                QCalMin = getattr(metadata, "QCALMIN_BAND{0}".format(band_num))

            Radraster = (((LMax - LMin) / (QCalMax - QCalMin)) *
                         (null_raster - QCalMin)) + LMin
            Oraster = 0
            del null_raster

            # Calculating temperature for band 6 if present
            Refraster = (math.pi * Radraster * dSun2) / (
                ESun[int(band_num[0]) - 1] * math.cos(SZA * (math.pi / 180)))

            # construc output names for each band based on whether outdir is set (default is False)
            if outdir is not None:
                outdir = os.path.abspath(outdir)
                BandPath = core.create_outname(outdir, pathname, "TOA_Ref",
                                               "tif")
            else:
                folder = os.path.split(meta_path)[0]
                BandPath = core.create_outname(folder, pathname, "TOA_Ref",
                                               "tif")

            Refraster.save(BandPath)
            output_filelist.append(BandPath)

            del Refraster, Radraster
            print("Reflectance Calculated for Band {0}".format(band_num))

        # if listed band is not a TM/ETM+ sensor band, skip it and print message
        else:
            print(
                "Can only perform reflectance conversion on TM/ETM+ sensor bands"
            )
            print("Skipping band {0}".format(band_num))

    f.close()
    return output_filelist
コード例 #14
0
ファイル: toa_reflectance.py プロジェクト: waynechao128/dnppy
def toa_reflectance_8(band_nums, meta_path, outdir=None):
    """
    Converts Landsat 8 bands to Top-of-Atmosphere reflectance. To be performed
    on raw Landsat 8 level 1 data. See link below for details
    see here [http://landsat.usgs.gov/Landsat8_Using_Product.php]

    :param band_nums:   A list of desired band numbers such as [3,4,5]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files. If left False it will save ouput
                        files in the same directory as input files.

    :return output_filelist:    List of files created by this function
    """

    output_filelist = []

    # enforce the list of band numbers and grab metadata from the MTL file
    band_nums = core.enf_list(band_nums)
    band_nums = map(str, band_nums)
    OLI_bands = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    meta_path = os.path.abspath(meta_path)
    meta = landsat_metadata(meta_path)

    # cycle through each band in the list for calculation, ensuring each is in the list of OLI bands
    for band_num in band_nums:
        if band_num in OLI_bands:

            # scrape data from the given file path and attributes in the MTL file
            band_path = meta_path.replace("MTL.txt",
                                          "B{0}.tif".format(band_num))
            Qcal = arcpy.Raster(band_path)
            Mp = getattr(meta, "REFLECTANCE_MULT_BAND_{0}".format(
                band_num))  # multiplicative scaling factor
            Ap = getattr(meta, "REFLECTANCE_ADD_BAND_{0}".format(
                band_num))  # additive rescaling factor
            SEA = getattr(meta, "SUN_ELEVATION") * (
                math.pi / 180)  # sun elevation angle theta_se

            # get rid of the zero values that show as the black background to avoid skewing values
            null_raster = arcpy.sa.SetNull(Qcal, Qcal, "VALUE = 0")

            # calculate top-of-atmosphere reflectance
            TOA_ref = (((null_raster * Mp) + Ap) / (math.sin(SEA)))

            # save the data to the automated name if outdir is given or in the parent folder if not
            if outdir is not None:
                outdir = os.path.abspath(outdir)
                outname = core.create_outname(outdir, band_path, "TOA_Ref",
                                              "tif")
            else:
                folder = os.path.split(meta_path)[0]
                outname = core.create_outname(folder, band_path, "TOA_Ref",
                                              "tif")

            TOA_ref.save(outname)
            output_filelist.append(outname)
            print("Saved output at {0}".format(outname))

        # if listed band is not an OLI sensor band, skip it and print message
        else:
            print(
                "Can only perform reflectance conversion on OLI sensor bands")
            print("Skipping band {0}".format(band_num))

    return output_filelist
コード例 #15
0
def surface_reflectance(meta_path,
                        toa_folder,
                        dem_path,
                        dew_point,
                        outdir=False,
                        kt=1.0):
    """
    This function will estimate surface reflectance for Landsat 4 TM, 5 TM, 7 ETM+, or 8 OLI data.

    Note this function will calculate surface reflectance for Landsat 4, 5, and 7
    bands 1, 2, 3, 4, 5, and 7 or Landsat 8 bands 2, 3, 4, 5, 6, and 7. All 6 bands should be in the
    toa_folder and have "TOA_Ref" in their filenames as per the landsat.toa_reflectance convention.

    The Landsat 8 Coastal Aerosol band (1) and Cirrus band (9) will not be calculated as they do not
    have a corresponding band in TM or ETM+. To be performed on Top-of-Atmosphere Reflectance data
    processed with the landsat.toa_reflectance_457 or the landsat.toa_reflectance_8 function.

    Resources
        - DEM
            - NASA Shuttle Radar Topography Mission (SRTM) up to 30m resolution.
              [http://www2.jpl.nasa.gov/srtm/cbanddataproducts.html]
            - NASA Advanced Spaceborne Thermal Emission and Reflection Radiometer (ASTER)
              Global Digital Elevation Model (GDEM) [http://asterweb.jpl.nasa.gov/gdem.asp]
            - USGS National Elevation Dataset (NED) [http://nationalmap.gov/elevation.html]
              downloadable in 30 meter resolution through The National Map Viewer

        - Dew Point
            - NOAA Daily Observational Data: Global Summary of the Day (GSOD) - GIS Data Locator
              [http://gis.ncdc.noaa.gov/map/viewer/#app=clim&cfg=cdo&theme=daily&layers=0001&node=gis].
              Select a weather station within the Landsat scene's extent, follow the link,
              and enter the scene's acquisition date. This will output a text file, with
              dew point under DEWP. More NOAA climatic data available at
              [https://www.climate.gov/data/maps-and-data]

    :param meta_path:       The full filepath to the metadata file (ending in MTL.txt) for the dataset
    :param toa_folder:      The filepath to the folder containing the TOA_Ref tiffs to be processed
    :param dem_path:        The full filepath to a DEM tif that covers the desired Landsat scene
                            Note that the DEM should be resampled to the Landsat bands' resolution (30m)
                            and pixel alignment. Also ensure there are no gaps in the dataset.
    :param dew_point:       The number (e.g. 57.7) for the dew point at the time and place of scene acquisition
    :param outdir:          Output directory to save converted files. If left False it will save
                            output files in the toa_folder directory.
    :param kt:              Unitless turbidity coefficient. Default set at 1.0 for clean air.
                            Set at 0.5 for extremely turbid, dusty, or polluted air.
                            
    :return output_filelist:  A list of all files created by this function                        
    """

    meta_path = os.path.abspath(meta_path)
    toa_folder = os.path.abspath(toa_folder)
    dem_path = os.path.abspath(dem_path)
    output_filelist = []

    #define the list of constants for effective narrowband transmissivity for incoming solar radiation
    constants_enbt1 = [[0.987, -0.00071, 0.000036, 0.0880, 0.0789],
                       [2.319, -0.00016, 0.000105, 0.0437, -1.2697],
                       [0.951, -0.00033, 0.000280, 0.0875, 0.1014],
                       [0.375, -0.00048, 0.005018, 0.1355, 0.6621],
                       [0.234, -0.00101, 0.004336, 0.0560, 0.7757],
                       [0.365, -0.00097, 0.004296, 0.0155, 0.6390]]

    #define the list of constants for effective narrowband transmissivity for shortwave radiation
    #reflected from the surface
    constants_enbt2 = [[0.987, -0.00071, 0.000036, 0.0880, 0.0789],
                       [2.319, -0.00016, 0.000105, 0.0437, -1.2697],
                       [0.951, -0.00033, 0.000280, 0.0875, 0.1014],
                       [0.375, -0.00048, 0.005018, 0.1355, 0.6621],
                       [0.234, -0.00101, 0.004336, 0.0560, 0.7757],
                       [0.365, -0.00097, 0.004296, 0.0155, 0.6390]]

    #enforce the list of band numbers, grab metadata from the MTL file, and define the band numbers needed from each sensor
    meta = landsat_metadata(meta_path)
    OLI_bands = ['2', '3', '4', '5', '6', '7']
    TM_ETM_bands = ['1', '2', '3', '4', '5', '7']

    #define the tile name for the landsat scene based on the metadata file's name

    #Open the metadata text file and read to set the scene's tilename
    f = open(meta_path)
    MText = f.read()

    if "PRODUCT_CREATION_TIME" in MText:
        tilename = getattr(meta, "BAND1_FILE_NAME")
    else:
        tilename = getattr(meta, "LANDSAT_SCENE_ID")

    #construct the list of TOA reflectance band tiffs and populate it based on the above definitions
    toa_list = []
    out_list = []
    n = 0
    for file in os.listdir(toa_folder):
        if ("TOA_Ref" in file) and (file[-4:] == ".tif"
                                    or file[-4:] == ".TIF"):
            if "LC8" in meta_path:
                tile = "{0}_B{1}".format(tilename, OLI_bands[n])
                if tile in file:
                    path = "{0}\\{1}".format(toa_folder, file)
                    out_file = file.replace("TOA", "Surf")
                    toa_list.append(path)
                    out_list.append(out_file)
                    n = n + 1
                    if n > 5:
                        break
            elif ("LE7" in file) or ("LT5" in file) or ("LT4" in file):
                tile = "{0}_B{1}".format(tilename, TM_ETM_bands[n])
                if tile in file:
                    path = "{0}\\{1}".format(toa_folder, file)
                    out_file = file.replace("TOA", "Surf")
                    toa_list.append(path)
                    out_list.append(out_file)
                    n = n + 1
                    if n > 5:
                        break

    #grab the corner lat/lon coordinates to calculate the approximate scene center lat/lon
    ul_lat = getattr(meta, "CORNER_UL_LAT_PRODUCT")
    ul_lon = getattr(meta, "CORNER_UL_LON_PRODUCT")
    ur_lat = getattr(meta, "CORNER_UR_LAT_PRODUCT")
    ur_lon = getattr(meta, "CORNER_UR_LON_PRODUCT")
    ll_lat = getattr(meta, "CORNER_LL_LAT_PRODUCT")
    ll_lon = getattr(meta, "CORNER_LL_LON_PRODUCT")
    lr_lat = getattr(meta, "CORNER_LR_LAT_PRODUCT")
    lr_lon = getattr(meta, "CORNER_LR_LON_PRODUCT")

    u_lon_avg = np.mean([ul_lon, ur_lon])
    l_lon_avg = np.mean([ll_lon, lr_lon])
    l_lat_avg = np.mean([ul_lat, ll_lat])
    r_lat_avg = np.mean([ur_lat, lr_lat])

    center_lat = np.mean([l_lat_avg, r_lat_avg])
    center_lon = np.mean([u_lon_avg, l_lon_avg])

    #construct the datetime object from the date acquired and scene center time attributes
    date = getattr(meta, "DATE_ACQUIRED")
    dl = date.split("-")
    time = getattr(meta, "SCENE_CENTER_TIME")
    tl = time.split(":")

    dt = datetime.datetime(int(dl[0]), int(dl[1]), int(dl[2]), int(tl[0]),
                           int(tl[1]), int(tl[2][0:2]))

    #use the dnppy.solar module to calculate the solar characteristics at the scene center at the time of acquisition
    sc = solar.solar(center_lat, center_lon, dt, 0)
    sc.compute_all()

    #Cosine of Solar Zenith over horizontal surface
    declination = math.degrees(sc.get_declination())
    hour_angle = math.degrees(sc.get_hour_angle())
    lat = math.degrees(center_lat)

    cth = (math.sin(declination) * math.sin(lat)) + (
        math.cos(declination) * math.cos(center_lat) * math.cos(hour_angle))

    #Saturation Vapor Pressure
    svp = 0.6108 * math.exp((17.27 * dew_point) / (dew_point + 237.3))

    #Atmospheric Pressure
    DEM = arcpy.sa.Raster(dem_path)
    ap = 101.3 * (((293 - (0.0065 * DEM)) / 293)**5.26)

    #Water in Atmosphere
    wia = (0.14 * svp * ap) + 2.1

    #Effective Narrowband Transmittance for incoming solar radiation
    entisr_bands = []
    for i in xrange(6):
        c1 = constants_enbt1[i][0]
        c2 = constants_enbt1[i][1]
        c3 = constants_enbt1[i][2]
        c4 = constants_enbt1[i][3]
        c5 = constants_enbt1[i][4]
        enbt1 = c1 * ((arcpy.sa.Exp(
            (c2 * ap) / (kt * cth))) - (((c3 * wia) + c4) / cth)) + c5
        entisr_bands.append(enbt1)

    #Effective Narrowband Transmittance for shortwave radiation reflected from surface
    entsrrs_bands = []

    #cos_n always 1 for sensor pointing straight nadir
    cos_n = 1

    for i in xrange(6):
        c1 = constants_enbt2[i][0]
        c2 = constants_enbt2[i][1]
        c3 = constants_enbt2[i][2]
        c4 = constants_enbt2[i][3]
        c5 = constants_enbt2[i][4]
        enbt2 = c1 * ((arcpy.sa.Exp(
            (c2 * ap) / (kt * cos_n))) - (((c3 * wia) + c4))) + c5
        entsrrs_bands.append(enbt2)

    #Per Band Path Reflectance
    pr_bands = []
    pr_constants = [0.254, 0.149, 0.147, 0.311, 0.103, 0.036]
    for j in xrange(6):
        pr = pr_constants[j] * (1 - entisr_bands[j])
        pr_bands.append(pr)

    #Calculate and save At-Surface Reflectance band tiffs
    for k in xrange(6):
        if outdir:
            outdir = os.path.abspath(outdir)
            asr_path = "{0}\\{1}".format(outdir, out_list[k])
        else:
            asr_path = "{0}\\{1}".format(toa_folder, out_list[k])
        refl_surf = (toa_list[k] - pr_bands[k]) / (entisr_bands[k] *
                                                   entsrrs_bands[k])
        refl_surf.save(asr_path)
        output_filelist.append(asr_path)

    return output_filelist
コード例 #16
0
def atsat_bright_temp_8(meta_path, outdir=False):
    """
    Converts Landsat 8 TIRS bands to at satellite brightnes temperature in Kelvins

    To be performed on raw Landsat 8 level 1 data. See link below for details
    see here http://landsat.usgs.gov/Landsat8_Using_Product.php

    :param band_nums:   A list of desired band numbers, which should be [10,11]
    :param meta_path:   The full filepath to the metadata file for those bands
    :param outdir:      Output directory to save converted files. If left False it will save ouput
                        files in the same directory as input files.

    :return output_filelist: A list of all files created by this function
    """

    #enforce the list of band numbers and grab metadata from the MTL file
    band_nums = ["10", "11"]
    meta_path = os.path.abspath(meta_path)
    meta = landsat_metadata(meta_path)

    output_filelist = []

    #cycle through each band in the list for calculation, ensuring each is in the list of TIRS bands
    for band_num in band_nums:

        #scrape data from the given file path and attributes in the MTL file
        band_path = meta_path.replace("MTL.txt", "B{0}.tif".format(band_num))
        Qcal = arcpy.Raster(band_path)

        #get rid of the zero values that show as the black background to avoid skewing values
        null_raster = arcpy.sa.SetNull(Qcal, Qcal, "VALUE = 0")

        #requires first converting to radiance
        Ml = getattr(meta, "RADIANCE_MULT_BAND_{0}".format(
            band_num))  # multiplicative scaling factor
        Al = getattr(meta, "RADIANCE_ADD_BAND_{0}".format(
            band_num))  # additive rescaling factor

        TOA_rad = (null_raster * Ml) + Al

        #now convert to at-sattelite brightness temperature
        K1 = getattr(meta, "K1_CONSTANT_BAND_{0}".format(
            band_num))  # thermal conversion constant 1
        K2 = getattr(meta, "K2_CONSTANT_BAND_{0}".format(
            band_num))  # thermal conversion constant 2

        #calculate brightness temperature at the satellite
        Bright_Temp = K2 / (arcpy.sa.Ln((K1 / TOA_rad) + 1))

        #save the data to the automated name if outdir is given or in the parent folder if not
        if outdir:
            outdir = os.path.abspath(outdir)
            outname = core.create_outname(outdir, band_path, "ASBTemp", "tif")
        else:
            folder = os.path.split(meta_path)[0]
            outname = core.create_outname(folder, band_path, "ASBTemp", "tif")

        Bright_Temp.save(outname)
        output_filelist.append(outname)

        print("Saved output at {0}".format(outname))
        del TOA_rad, null_raster

    return output_filelist
コード例 #17
0
def atsat_bright_temp_457(meta_path, outdir=None):
    """
    Converts band 6 from Landsat 4 and 5 or bands 6 VCID 1 and 2 from Landsat 7
    to at satellite brightness temperature in Kelvins

    To be performed on raw Landsat 4, 5, or 7 level 1 data.

    :param meta_path:   The full filepath to the metadata file, labeled '_MTL.txt', which must
                        be in the same folder as band 6 or 6_VCID_1 and 6_VCID_2
    :param outdir:      Output directory to save converted files. If left False it will save ouput
                        files in the same directory as input files.

    :return output_filelist: A list of all files created by this function
    """

    output_filelist = []
    meta_path = os.path.abspath(meta_path)
    metadata = landsat_metadata(meta_path)
    spacecraft = getattr(metadata, "SPACECRAFT_ID")

    if "4" in spacecraft or "5" in spacecraft:
        band_nums = ["6"]
    elif "7" in spacecraft:
        band_nums = ["6_VCID_1", "6_VCID_2"]
    else:
        print(
            "Enter the MTL file corresponding to a Landsat 4, 5, or 7 dataset")

    # These lists will be used to parse the meta data text file and locate relevant information
    # metadata format was changed August 29, 2012. This tool can process either the new or old format
    f = open(meta_path)
    MText = f.read()

    # the presence of a PRODUCT_CREATION_TIME category is used to identify old metadata
    # if this is not present, the meta data is considered new.
    # Band6length refers to the length of the Band 6 name string. In the new metadata this string is longer
    if "PRODUCT_CREATION_TIME" in MText:
        Meta = "oldMeta"
    else:
        Meta = "newMeta"

    # The tile name is located using the newMeta/oldMeta indixes and the date of capture is recorded
    if Meta == "newMeta":
        TileName = getattr(metadata, "LANDSAT_SCENE_ID")
        year = TileName[9:13]
        jday = TileName[13:16]
        date = getattr(metadata, "DATE_ACQUIRED")

    elif Meta == "oldMeta":
        TileName = getattr(metadata, "BAND1_FILE_NAME")
        year = TileName[13:17]
        jday = TileName[17:20]
        date = getattr(metadata, "ACQUISITION_DATE")

    # the spacecraft from which the imagery was capture is identified
    # this info determines the solar exoatmospheric irradiance (ESun) for each band

    # Calculating values for each band
    for band_num in band_nums:
        print("Processing Band {0}".format(band_num))

        pathname = meta_path.replace("MTL.txt", "B{0}.tif".format(band_num))
        Oraster = arcpy.Raster(pathname)

        # get rid of the zero values that show as the black background to avoid skewing values
        null_raster = arcpy.sa.SetNull(Oraster, Oraster, "VALUE = 0")

        # using the oldMeta/newMeta indixes to pull the min/max for radiance/Digital numbers
        if Meta == "newMeta":
            LMax = getattr(metadata,
                           "RADIANCE_MAXIMUM_BAND_{0}".format(band_num))
            LMin = getattr(metadata,
                           "RADIANCE_MINIMUM_BAND_{0}".format(band_num))
            QCalMax = getattr(metadata,
                              "QUANTIZE_CAL_MAX_BAND_{0}".format(band_num))
            QCalMin = getattr(metadata,
                              "QUANTIZE_CAL_MIN_BAND_{0}".format(band_num))

        elif Meta == "oldMeta":
            LMax = getattr(metadata, "LMAX_BAND{0}".format(band_num))
            LMin = getattr(metadata, "LMIN_BAND{0}".format(band_num))
            QCalMax = getattr(metadata, "QCALMAX_BAND{0}".format(band_num))
            QCalMin = getattr(metadata, "QCALMIN_BAND{0}".format(band_num))

        Radraster = (((LMax - LMin) / (QCalMax - QCalMin)) *
                     (null_raster - QCalMin)) + LMin
        Oraster = 0

        # Calculating temperature for band 6 if present
        if "4" in spacecraft or "5" in spacecraft:
            Refraster = 1260.56 / (arcpy.sa.Ln((607.76 / Radraster) + 1.0))

        if "7" in spacecraft:
            Refraster = 1282.71 / (arcpy.sa.Ln((666.09 / Radraster) + 1.0))

        band_temp = "{0}_B{1}".format(TileName, band_num)

        # save the data to the automated name if outdir is given or in the parent folder if not
        if outdir:
            outdir = os.path.abspath(outdir)
            BandPath = core.create_outname(outdir, band_temp, "ASBTemp", "tif")
        else:
            folder = os.path.split(meta_path)[0]
            BandPath = core.create_outname(folder, band_temp, "ASBTemp", "tif")

        Refraster.save(BandPath)
        output_filelist.append(BandPath)

        del Refraster, Radraster, null_raster

        print("Temperature Calculated for Band {0}".format(band_num))

    f.close()
    return output_filelist
コード例 #18
0
def atsat_bright_temp_457(meta_path, outdir = None):
    """
    Converts band 6 from Landsat 4 and 5 or bands 6 VCID 1 and 2 from Landsat 7
    to at satellite brightness temperature in Kelvins

    To be performed on raw Landsat 4, 5, or 7 level 1 data.

    :param meta_path:   The full filepath to the metadata file, labeled '_MTL.txt', which must
                        be in the same folder as band 6 or 6_VCID_1 and 6_VCID_2
    :param outdir:      Output directory to save converted files. If left False it will save ouput
                        files in the same directory as input files.

    :return output_filelist: A list of all files created by this function
    """

    output_filelist = []
    meta_path = os.path.abspath(meta_path)
    metadata = landsat_metadata(meta_path)
    spacecraft = getattr(metadata, "SPACECRAFT_ID")

    if "4" in spacecraft or "5" in spacecraft:
        band_nums = ["6"]
    elif "7" in spacecraft:
        band_nums = ["6_VCID_1", "6_VCID_2"]
    else:
      print("Enter the MTL file corresponding to a Landsat 4, 5, or 7 dataset")

    # These lists will be used to parse the meta data text file and locate relevant information
    # metadata format was changed August 29, 2012. This tool can process either the new or old format
    f = open(meta_path)
    MText = f.read()

    # the presence of a PRODUCT_CREATION_TIME category is used to identify old metadata
    # if this is not present, the meta data is considered new.
    # Band6length refers to the length of the Band 6 name string. In the new metadata this string is longer
    if "PRODUCT_CREATION_TIME" in MText:
        Meta = "oldMeta"
    else:
        Meta = "newMeta"

    # The tile name is located using the newMeta/oldMeta indixes and the date of capture is recorded
    if Meta == "newMeta":
        TileName  = getattr(metadata, "LANDSAT_SCENE_ID")
        year      = TileName[9:13]
        jday      = TileName[13:16]
        date      = getattr(metadata, "DATE_ACQUIRED")

    elif Meta == "oldMeta":
        TileName  = getattr(metadata, "BAND1_FILE_NAME")
        year      = TileName[13:17]
        jday      = TileName[17:20]
        date      = getattr(metadata, "ACQUISITION_DATE")

    # the spacecraft from which the imagery was capture is identified
    # this info determines the solar exoatmospheric irradiance (ESun) for each band

    # Calculating values for each band
    for band_num in band_nums:
        print("Processing Band {0}".format(band_num))

        pathname = meta_path.replace("MTL.txt", "B{0}.tif".format(band_num))
        Oraster = arcpy.Raster(pathname)

        # get rid of the zero values that show as the black background to avoid skewing values
        null_raster = arcpy.sa.SetNull(Oraster, Oraster, "VALUE = 0")

        # using the oldMeta/newMeta indixes to pull the min/max for radiance/Digital numbers
        if Meta == "newMeta":
            LMax    = getattr(metadata, "RADIANCE_MAXIMUM_BAND_{0}".format(band_num))
            LMin    = getattr(metadata, "RADIANCE_MINIMUM_BAND_{0}".format(band_num))
            QCalMax = getattr(metadata, "QUANTIZE_CAL_MAX_BAND_{0}".format(band_num))
            QCalMin = getattr(metadata, "QUANTIZE_CAL_MIN_BAND_{0}".format(band_num))

        elif Meta == "oldMeta":
            LMax    = getattr(metadata, "LMAX_BAND{0}".format(band_num))
            LMin    = getattr(metadata, "LMIN_BAND{0}".format(band_num))
            QCalMax = getattr(metadata, "QCALMAX_BAND{0}".format(band_num))
            QCalMin = getattr(metadata, "QCALMIN_BAND{0}".format(band_num))

        Radraster = (((LMax - LMin)/(QCalMax-QCalMin)) * (null_raster - QCalMin)) + LMin
        Oraster = 0

        # Calculating temperature for band 6 if present
        if "4" in spacecraft or "5" in spacecraft:
            Refraster  = 1260.56/(arcpy.sa.Ln((607.76/Radraster) + 1.0))

        if "7" in spacecraft:
            Refraster  = 1282.71/(arcpy.sa.Ln((666.09/Radraster) + 1.0))

        band_temp = "{0}_B{1}".format(TileName, band_num)

        # save the data to the automated name if outdir is given or in the parent folder if not
        if outdir:
            outdir = os.path.abspath(outdir)
            BandPath = core.create_outname(outdir, band_temp, "ASBTemp", "tif")
        else:
            folder = os.path.split(meta_path)[0]
            BandPath = core.create_outname(folder, band_temp, "ASBTemp", "tif")

        Refraster.save(BandPath)
        output_filelist.append(BandPath)

        del Refraster, Radraster, null_raster

        print("Temperature Calculated for Band {0}".format(band_num))

    f.close()
    return output_filelist