Beispiel #1
0
def scene_meta(metafile):
    import dateutil.parser
    from xml.dom import minidom

    from acolite.shared import distance_se
    from numpy import linspace

    try:
        xmldoc = minidom.parse(metafile)
    except:
        print('Error opening metadata file.')
        sys.exit()

    xml_main = xmldoc.firstChild

    metadata = {}

    tags = ['PRODUCT_START_TIME','PRODUCT_STOP_TIME','PRODUCT_URI','PROCESSING_LEVEL',
            'PRODUCT_TYPE', 'PROCESSING_BASELINE', 'GENERATION_TIME','SPACECRAFT_NAME',
            'DATATAKE_SENSING_START', 'SENSING_ORBIT_NUMBER', 'SENSING_ORBIT_DIRECTION',
            'PRODUCT_FORMAT', 'QUANTIFICATION_VALUE', 'U']

    for tag in tags:
        tdom = xmldoc.getElementsByTagName(tag)
        if len(tdom) > 0:
            if tdom[0].firstChild is not None:
                metadata[tag] = tdom[0].firstChild.nodeValue

    ##
    tdom = xmldoc.getElementsByTagName('Special_Values')
    for t in tdom:
        fill = (t.getElementsByTagName('SPECIAL_VALUE_TEXT')[0].firstChild.nodeValue)
        fill_value = (t.getElementsByTagName('SPECIAL_VALUE_INDEX')[0].firstChild.nodeValue)
        metadata[fill] = fill_value

    ## get information for sensor bands
    banddata = {}
    banddata['F0'] = {}
    tdom = xmldoc.getElementsByTagName('SOLAR_IRRADIANCE')
    for t in tdom:
        band = t.getAttribute('bandId')
        banddata['F0'][band] = float(t.firstChild.nodeValue) # 'unit':t.getAttribute('unit')

    banddata['PHYSICAL_GAINS'] = {}
    tdom = xmldoc.getElementsByTagName('PHYSICAL_GAINS')
    for t in tdom:
        band = t.getAttribute('bandId')
        banddata['PHYSICAL_GAINS'][band] = float(t.firstChild.nodeValue)

    banddata['BandNames'] = {}
    banddata['Resolution'] = {}
    banddata['Wavelength'] = {}
    banddata['RSR'] = {}

    tdom = xmldoc.getElementsByTagName('Spectral_Information')
    for t in tdom:
        band = t.getAttribute('bandId')
        banddata['BandNames'][band] = t.getAttribute('physicalBand')
        banddata['Resolution'][band] = t.getElementsByTagName('RESOLUTION')[0].firstChild.nodeValue
        banddata['Wavelength'][band] = {tag:float(t.getElementsByTagName(tag)[0].firstChild.nodeValue) for tag in ['CENTRAL','MIN','MAX']}
        tag = t.getElementsByTagName('Spectral_Response')
        if len(tag) > 0:
            step = float(tag[0].getElementsByTagName('STEP')[0].firstChild.nodeValue)
            rsr = [float(rs) for rs in tag[0].getElementsByTagName('VALUES')[0].firstChild.nodeValue.split(' ')]
            wave = linspace(banddata['Wavelength'][band]['MIN'],banddata['Wavelength'][band]['MAX'], int((banddata['Wavelength'][band]['MAX']-banddata['Wavelength'][band]['MIN'])/step)+1)
        banddata['RSR'][band] = {'response':rsr, 'wave':wave}
    #print(banddata['Wavelength'])

    if len(banddata['BandNames']) == 0:
        bandnames = ['B1','B2','B3','B4','B5','B6','B7','B8','B8A','B9','B10','B11','B12']
        bandresolutions=[60,10,10,10,20,20,20,10,20,60,60,20,20]
        bandwaves = [{'CENTRAL': 443.9, 'MAX': 457.0, 'MIN': 430.0},
                     {'CENTRAL': 496.6, 'MAX': 538.0, 'MIN': 440.0},
                     {'CENTRAL': 560.0, 'MAX': 582.0, 'MIN': 537.0},
                     {'CENTRAL': 664.5, 'MAX': 684.0, 'MIN': 646.0},
                     {'CENTRAL': 703.9, 'MAX': 713.0, 'MIN': 694.0},
                     {'CENTRAL': 740.2, 'MAX': 749.0, 'MIN': 731.0},
                     {'CENTRAL': 782.5, 'MAX': 797.0, 'MIN': 769.0},
                     {'CENTRAL': 835.1, 'MAX': 908.0, 'MIN': 760.0},
                     {'CENTRAL': 864.8, 'MAX': 881.0, 'MIN': 848.0},
                     {'CENTRAL': 945.0, 'MAX': 958.0, 'MIN': 932.0},
                     {'CENTRAL': 1373.5, 'MAX': 1412.0, 'MIN': 1337.0},
                     {'CENTRAL': 1613.7, 'MAX': 1682.0, 'MIN': 1539.0},
                     {'CENTRAL': 2202.4, 'MAX': 2320.0, 'MIN': 2078.0}]

        for b,band in enumerate(bandnames):
            banddata['BandNames'][str(b)] = band
            banddata['Wavelength'][str(b)] = bandwaves[b]
            banddata['Resolution'][str(b)] = str(bandresolutions[b])

    ## some interpretation
    metadata['TIME'] = dateutil.parser.parse(metadata['PRODUCT_STOP_TIME'])
    metadata["DOY"] = metadata["TIME"].strftime('%j')
    metadata["SE_DISTANCE"] = distance_se(metadata['DOY'])

    metadata["SATELLITE"] = metadata['SPACECRAFT_NAME'] # 'Sentinel-2A'
    metadata["SENSOR"] = 'MSI'

    if metadata['SATELLITE'] == 'Sentinel-2A':
        metadata['SATELLITE_SENSOR'] = 'S2A_MSI'
        metadata['RGB_BANDS']= [497,560,664]
        metadata['WAVES']= ['444', '497', '560', '664', '704', '740', '782', '835', '865',  '945', '1374', '1614', '2202'] #

    if metadata['SATELLITE'] == 'Sentinel-2B':
        metadata['SATELLITE_SENSOR'] = 'S2B_MSI'
        metadata['RGB_BANDS']= [497,560,664]
        metadata['WAVES']= ['444', '497', '560', '664', '704', '740', '782', '835', '865',  '945', '1374', '1614', '2202'] #

    bands = list(banddata['BandNames'].keys())
    metadata['BANDS'] = bands
    waves = ['{0:0.0f}'.format(banddata['Wavelength'][i]['CENTRAL']) for i in bands]
    metadata['WAVES'] = [int(w) for w in waves]
    band_names = [banddata['BandNames'][i] for i in bands]
    metadata['BAND_NAMES'] = band_names
    metadata['BANDS_ALL'] = ['1','2','3','4','5','6','7','8','8A','11','12']
    metadata['BAND_NAMES_ALL'] = band_names
    metadata['BANDS_BESTFIT'] = ['11','12']

    return(metadata,banddata)
Beispiel #2
0
def metadata_parse(bundle):
    import dateutil.parser
    from acolite.shared import distance_se
    from acolite.landsat import metadata_read
    from acolite.landsat import bundle_test
    from acolite.ac import f0_sensor

    bundle_files = bundle_test(bundle)
    metafile = bundle_files['MTL']['path']
    mdata = metadata_read(metafile)

    metadata = {}
    if 'PRODUCT_METADATA' in mdata.keys():
        attkey = 'PRODUCT_METADATA'
    elif 'IMAGE_ATTRIBUTES' in mdata.keys():
        attkey = 'IMAGE_ATTRIBUTES'

    metadata["SATELLITE"] = mdata[attkey]['SPACECRAFT_ID'].strip('"')
    metadata["SENSOR"] = mdata[attkey]['SENSOR_ID'].strip('"')

    if 'IMAGE_ATTRIBUTES' in mdata.keys():
        metadata['NEW_STYLE'] = True
        metadata['AZI'] = float(mdata['IMAGE_ATTRIBUTES']['SUN_AZIMUTH'])
        metadata['THS'] = 90. - float(
            mdata['IMAGE_ATTRIBUTES']['SUN_ELEVATION'])
        metadata['THV'] = 0.
        metadata['ISODATE'] = '{}T{}Z'.format(
            mdata[attkey]['DATE_ACQUIRED'].strip('"'),
            mdata[attkey]['SCENE_CENTER_TIME'].strip('"'))

        if 'METADATA_FILE_INFO' in mdata.keys():
            prokey = 'METADATA_FILE_INFO'
            metadata['PROCESSING_DATE'] = mdata[prokey]['FILE_DATE']
            prjkey = 'PRODUCT_METADATA'
            sclkey = 'RADIOMETRIC_RESCALING'
        elif 'LEVEL1_PROCESSING_RECORD' in mdata.keys():
            prokey = 'LEVEL1_PROCESSING_RECORD'
            metadata['PROCESSING_DATE'] = mdata[prokey][
                'DATE_PRODUCT_GENERATED']
            prjkey = 'PROJECTION_ATTRIBUTES'
            sclkey = 'LEVEL1_RADIOMETRIC_RESCALING'

        metadata['SCENE'] = mdata[prokey]['LANDSAT_SCENE_ID']
        if 'LANDSAT_PRODUCT_ID' in mdata[prokey].keys():
            metadata['PRODUCT'] = mdata[prokey]['LANDSAT_PRODUCT_ID']

        if 'LEVEL1_THERMAL_CONSTANTS' in mdata:
            for k in mdata['LEVEL1_THERMAL_CONSTANTS']:
                metadata[k] = mdata['LEVEL1_THERMAL_CONSTANTS'][k]

        ### get projection info
        metadata["PATH"] = mdata[attkey]['WRS_PATH'].strip('"')
        metadata["ROW"] = mdata[attkey]['WRS_ROW'].strip('"')

        metadata["DIMS"] = [
            int(mdata[prjkey]['REFLECTIVE_SAMPLES'].strip('"')),
            int(mdata[prjkey]['REFLECTIVE_LINES'].strip('"'))
        ]

        tags = [
            'CORNER_LL_PROJECTION_X_PRODUCT', 'CORNER_LL_PROJECTION_Y_PRODUCT',
            'CORNER_LR_PROJECTION_X_PRODUCT', 'CORNER_LR_PROJECTION_Y_PRODUCT',
            'CORNER_UL_PROJECTION_X_PRODUCT', 'CORNER_UL_PROJECTION_Y_PRODUCT',
            'CORNER_UR_PROJECTION_X_PRODUCT', 'CORNER_UR_PROJECTION_Y_PRODUCT'
        ]
        for tag in tags:
            metadata[tag] = float(mdata[prjkey][tag])

        tags = [
            'CORNER_LL_LAT_PRODUCT', 'CORNER_LL_LON_PRODUCT',
            'CORNER_LR_LAT_PRODUCT', 'CORNER_LR_LON_PRODUCT',
            'CORNER_UL_LAT_PRODUCT', 'CORNER_UL_LON_PRODUCT',
            'CORNER_UR_LAT_PRODUCT', 'CORNER_UR_LON_PRODUCT'
        ]
        for tag in tags:
            metadata[tag] = float(mdata[prjkey][tag])
        ## get rescaling
        bands = set()
        for key in mdata[sclkey].keys():
            metadata[key] = float(mdata[sclkey][key])
            if 'REFLECTANCE' in key:
                bands.add(key.split('_')[3])  ## add optical bands to list
            if 'RADIANCE' in key:
                bands.add(key.split('_')[3])  ## add optical bands to list
    else:
        metadata['NEW_STYLE'] = False
        metadata['SENSOR'] = mdata['PRODUCT_METADATA']['SENSOR_ID']
        spacecraft = mdata['PRODUCT_METADATA']['SPACECRAFT_ID']
        if spacecraft == 'Landsat5': metadata["SATELLITE"] = 'LANDSAT_5'
        if spacecraft == 'Landsat7': metadata["SATELLITE"] = 'LANDSAT_7'
        metadata['AZI'] = float(mdata['PRODUCT_PARAMETERS']['SUN_AZIMUTH'])
        metadata['THS'] = 90. - float(
            mdata['PRODUCT_PARAMETERS']['SUN_ELEVATION'])
        metadata['THV'] = 0.
        metadata['SCENE'] = mdata['PRODUCT_METADATA']['METADATA_L1_FILE_NAME']

        metadata['PROCESSING_DATE'] = mdata['METADATA_FILE_INFO'][
            'PRODUCT_CREATION_TIME']

        ## ALI image
        if (metadata["SATELLITE"] == 'EO1') & (metadata["SENSOR"] == 'ALI'):
            metadata['ISODATE'] = '{}T{}Z'.format(
                mdata['PRODUCT_METADATA']['ACQUISITION_DATE'].replace(
                    '-', '/'),
                mdata['PRODUCT_METADATA']['START_TIME'].split()[-1])

            metadata["PATH"] = 'UNK'
            metadata["ROW"] = 'UNK'
            metadata["DIMS"] = [
                int(mdata['PRODUCT_METADATA']['PRODUCT_SAMPLES_REF'].strip(
                    '"')),
                int(mdata['PRODUCT_METADATA']['PRODUCT_LINES_REF'].strip('"'))
            ]
            ## get rescaling
            ali_bands = {
                'BAND1': 'Pan',
                'BAND2': '1p',
                'BAND3': '1',
                'BAND4': '2',
                'BAND5': '3',
                'BAND6': '4',
                'BAND7': '4p',
                'BAND8': '5p',
                'BAND9': '5',
                'BAND10': '7'
            }

            bands = set()
            for key in mdata['RADIANCE_SCALING'].keys():
                metadata[key] = float(mdata['RADIANCE_SCALING'][key])
                band = key.split('_')[0]
                bands.add(ali_bands[band])
            bands = list(bands)
            bands.sort()
        else:
            metadata['ISODATE'] = '{}T{}Z'.format(
                mdata['PRODUCT_METADATA']['ACQUISITION_DATE'].strip('"'),
                mdata['PRODUCT_METADATA']['SCENE_CENTER_SCAN_TIME'].strip('"'))

            ### get projection info
            metadata["PATH"] = mdata['PRODUCT_METADATA']['WRS_PATH'].strip('"')
            metadata["ROW"] = mdata['PRODUCT_METADATA']['STARTING_ROW'].strip(
                '"')
            metadata["DIMS"] = [
                int(mdata['PRODUCT_METADATA']['PRODUCT_SAMPLES_REF'].strip(
                    '"')),
                int(mdata['PRODUCT_METADATA']['PRODUCT_LINES_REF'].strip('"'))
            ]

            ## get rescaling
            bands = set()
            for key in mdata['MIN_MAX_RADIANCE'].keys():
                metadata[key] = float(mdata['MIN_MAX_RADIANCE'][key])
                bands.add(key[-1])  ## add optical bands to list
            for key in mdata['MIN_MAX_PIXEL_VALUE'].keys():
                metadata[key] = float(mdata['MIN_MAX_PIXEL_VALUE'][key])
            print(bands)

        ### get scene extent
        tags = [
            "PRODUCT_UL_CORNER_LAT", "PRODUCT_UL_CORNER_LON",
            "PRODUCT_UR_CORNER_LAT", "PRODUCT_UR_CORNER_LON",
            "PRODUCT_LL_CORNER_LAT", "PRODUCT_LL_CORNER_LON",
            "PRODUCT_LR_CORNER_LAT", "PRODUCT_LR_CORNER_LON",
            "PRODUCT_UL_CORNER_MAPX", "PRODUCT_UL_CORNER_MAPY",
            "PRODUCT_UR_CORNER_MAPX", "PRODUCT_UR_CORNER_MAPY",
            "PRODUCT_LL_CORNER_MAPX", "PRODUCT_LL_CORNER_MAPY",
            "PRODUCT_LR_CORNER_MAPX", "PRODUCT_LR_CORNER_MAPY"
        ]
        for tag in tags:
            metadata[tag] = float(mdata['PRODUCT_METADATA'][tag])

    ### common things
    metadata["TIME"] = dateutil.parser.parse(''.join([metadata["ISODATE"]
                                                      ]).replace("Z", ''))
    metadata["DOY"] = metadata["TIME"].strftime('%j')
    metadata["SE_DISTANCE"] = distance_se(metadata['DOY'])

    if 'PROJECTION_PARAMETERS' in mdata.keys():
        for key in mdata['PROJECTION_PARAMETERS'].keys():
            metadata[key] = mdata['PROJECTION_PARAMETERS'][key]
    elif 'LEVEL1_PROJECTION_PARAMETERS' in mdata.keys():
        for key in mdata['LEVEL1_PROJECTION_PARAMETERS'].keys():
            metadata[key] = mdata['LEVEL1_PROJECTION_PARAMETERS'][key]
    if 'UTM_PARAMETERS' in mdata:
        metadata['UTM_ZONE'] = mdata['UTM_PARAMETERS']['ZONE_NUMBER']

    ## set up bands
    metadata['BANDS'] = list(bands)
    metadata['BANDS'].sort()
    metadata['BAND_NAMES'] = metadata['BANDS']

    ## some sensor specific config
    if metadata["SATELLITE"] == 'LANDSAT_8':
        ## get TIRS for L8
        if 'TIRS_THERMAL_CONSTANTS' in mdata:
            for key in mdata['TIRS_THERMAL_CONSTANTS'].keys():
                metadata[key] = float(mdata['TIRS_THERMAL_CONSTANTS'][key])
        ## bands to remove
        remove_bands = ['8', '9', '10', '11']  ## pan cirrus thermal x2
        for rb in remove_bands:
            if rb in metadata['BANDS']: metadata['BANDS'].remove(rb)
        metadata['SATELLITE_SENSOR'] = 'L8_OLI'
        metadata['RGB_BANDS'] = [483, 561, 655]
        metadata['WAVES'] = [443, 483, 561, 655, 865, 1609, 2201]
        metadata['BANDS_ALL'] = [
            '1', '2', '3', '4', '5', '6', '7', '9', '10', '11'
        ]
        metadata['BANDS_BESTFIT'] = ['6', '7']
        metadata['BANDS_THERMAL'] = ['10', '11']
        metadata['BAND_NAMES_ALL'] = [
            '1', '2', '3', '4', '5', '6', '7', '9', '10', '11'
        ]
        metadata['WAVES_ALL'] = [
            443, 483, 561, 655, 865, 1609, 2201, 1375, 10900, 11500
        ]

    if metadata["SATELLITE"] == 'LANDSAT_5':
        remove_bands = ['6']  ## thermal
        for rb in remove_bands:
            if rb in metadata['BANDS']: metadata['BANDS'].remove(rb)
        metadata['SATELLITE_SENSOR'] = 'L5_TM' if metadata[
            'SENSOR'] == 'TM' else 'L5_MSS'
        metadata['RGB_BANDS'] = [486, 571, 660]
        metadata['WAVES'] = [486, 571, 660, 839, 1678, 2217]
        metadata['BANDS_ALL'] = ['1', '2', '3', '4', '5', '6', '7']
        metadata['BANDS_BESTFIT'] = ['5', '7']
        metadata['BANDS_THERMAL'] = ['6']
        metadata['BAND_NAMES_ALL'] = ['1', '2', '3', '4', '5', '6', '7']
        metadata['WAVES_ALL'] = [486, 571, 660, 839, 1678, 10000, 2217]

    if metadata["SATELLITE"] == 'LANDSAT_7':
        remove_bands = ['6', '8']  ## thermal pan
        for rb in remove_bands:
            if rb in metadata['BANDS']: metadata['BANDS'].remove(rb)
        metadata['SATELLITE_SENSOR'] = 'L7_ETM'
        metadata['RGB_BANDS'] = [479, 561, 661]
        metadata['WAVES'] = [479, 561, 661, 835, 1650, 2208]
        metadata['BANDS_ALL'] = ['1', '2', '3', '4', '5', '6', '7']
        metadata['BANDS_BESTFIT'] = ['5', '7']
        metadata['BANDS_THERMAL'] = ['6']
        metadata['BAND_NAMES_ALL'] = ['1', '2', '3', '4', '5', '6', '7']
        metadata['WAVES_ALL'] = [479, 561, 661, 835, 1650, 10000, 2208]

    if metadata['SATELLITE'] == 'EO1':
        metadata['SATELLITE_SENSOR'] = 'EO1_ALI'
        metadata['BANDS_BESTFIT'] = ['5', '7']
        metadata['BANDS_ALL'] = [
            '1p', '1', '2', '3', '4', '4p', '5p', '5', '7'
        ]  # 'Pan'
        metadata['WAVES_ALL'] = [
            442, 485, 567, 660, 790, 866, 1244, 1640, 2226
        ]

    ## make F0 for bands
    f0 = f0_sensor(metadata['SATELLITE_SENSOR'])
    for band in f0.keys():
        metadata['B{}_F0'.format(band)] = f0[band]

    ## get FILE names for bands and test if they exist in the bundle
    if 'PRODUCT_CONTENTS' in mdata:
        product_key = 'PRODUCT_CONTENTS'
    elif 'PRODUCT_METADATA' in mdata:
        product_key = 'PRODUCT_METADATA'

    for par in mdata[product_key]:
        if 'FILE_NAME' in par:
            fname = mdata[product_key][par]
            exists = False
            for file in bundle_files:
                if bundle_files[file]['fname'] == fname:
                    exists = True
                    metadata[file] = bundle_files[file]['path']

    return (metadata)
Beispiel #3
0
def granule_meta(metafile):

    import dateutil.parser
    from xml.dom import minidom

    from acolite.shared import distance_se
    from acolite.sentinel import safe_tile_grid

    from numpy import linspace, zeros, isfinite, isnan, where

    try:
        xmldoc = minidom.parse(metafile)
    except:
        print('Error opening metadata file.')
        sys.exit()

    xml_main = xmldoc.firstChild

    metadata = {}

    tags = ['TILE_ID', 'DATASTRIP_ID', 'SENSING_TIME']
    for tag in tags:
        tdom = xmldoc.getElementsByTagName(tag)
        if len(tdom) > 0: metadata[tag] = tdom[0].firstChild.nodeValue

    #Geometric_Info
    grids = {'10': {}, '20': {}, '60': {}}
    Geometric_Info = xmldoc.getElementsByTagName('n1:Geometric_Info')
    if len(Geometric_Info) > 0:
        for tg in Geometric_Info[0].getElementsByTagName('Tile_Geocoding'):
            tags = ['HORIZONTAL_CS_NAME', 'HORIZONTAL_CS_CODE']
            for tag in tags:
                tdom = tg.getElementsByTagName(tag)
                if len(tdom) > 0: metadata[tag] = tdom[0].firstChild.nodeValue

            for sub in tg.getElementsByTagName('Size'):
                res = sub.getAttribute('resolution')
                grids[res]['RESOLUTION'] = float(res)
                tags = ['NROWS', 'NCOLS']
                for tag in tags:
                    tdom = sub.getElementsByTagName(tag)
                    if len(tdom) > 0:
                        grids[res][tag] = int(tdom[0].firstChild.nodeValue)

            for sub in tg.getElementsByTagName('Geoposition'):
                res = sub.getAttribute('resolution')
                tags = ['ULX', 'ULY', 'XDIM', 'YDIM']
                for tag in tags:
                    tdom = sub.getElementsByTagName(tag)
                    if len(tdom) > 0:
                        grids[res][tag] = int(tdom[0].firstChild.nodeValue)

        for ta in Geometric_Info[0].getElementsByTagName('Tile_Angles'):
            ## sun angles
            sun_angles = {}
            for tag in ['Zenith', 'Azimuth']:
                for sub in ta.getElementsByTagName(
                        'Sun_Angles_Grid')[0].getElementsByTagName(tag):
                    sun_angles[tag] = safe_tile_grid(sub)

            for sub in ta.getElementsByTagName('Mean_Sun_Angle'):
                sun_angles['Mean_Zenith'] = float(
                    sub.getElementsByTagName('ZENITH_ANGLE')
                    [0].firstChild.nodeValue)
                sun_angles['Mean_Azimuth'] = float(
                    sub.getElementsByTagName('AZIMUTH_ANGLE')
                    [0].firstChild.nodeValue)

            ## view angles (merge detectors)
            view_angles = {}
            for sub in ta.getElementsByTagName(
                    'Viewing_Incidence_Angles_Grids'):
                band = sub.getAttribute('bandId')
                detector = sub.getAttribute('detectorId')

                band_view = {}
                for tag in ['Zenith', 'Azimuth']:
                    band_view[tag] = safe_tile_grid(
                        sub.getElementsByTagName(tag)[0])

                if band not in view_angles.keys():
                    view_angles[band] = band_view
                else:
                    for tag in ['Zenith', 'Azimuth']:
                        mask = isfinite(band_view[tag]) & isnan(
                            view_angles[band][tag])
                        view_angles[band][tag][mask] = band_view[tag][mask]

            ## average view angle grid
            ave = {}
            for b, band in enumerate(view_angles.keys()):
                for tag in ['Zenith', 'Azimuth']:
                    data = view_angles[band][tag]
                    count = isfinite(data) * 1
                    if b == 0:
                        ave[tag] = data
                        ave['{}_Count'.format(tag)] = count
                    else:
                        ave[tag] += data
                        ave['{}_Count'.format(tag)] += count
            for tag in ['Zenith', 'Azimuth']:
                view_angles['Average_View_{}'.format(
                    tag)] = ave[tag] / ave['{}_Count'.format(tag)]

    metadata["GRIDS"] = grids
    metadata["VIEW"] = view_angles
    metadata["SUN"] = sun_angles

    ## some interpretation
    metadata['TIME'] = dateutil.parser.parse(metadata['SENSING_TIME'])
    metadata["DOY"] = metadata["TIME"].strftime('%j')
    metadata["SE_DISTANCE"] = distance_se(metadata['DOY'])

    return (metadata)
Beispiel #4
0
def metadata_parse(bundle):
    import dateutil.parser
    from acolite.shared import distance_se
    from acolite.landsat import metadata_read
    from acolite.landsat import bundle_test
    from acolite.ac import f0_sensor

    bundle_files = bundle_test(bundle)
    metafile = bundle_files['MTL']['path']
    mdata = metadata_read(metafile)

    metadata = {}

    metadata["SATELLITE"] = mdata['PRODUCT_METADATA']['SPACECRAFT_ID'].strip(
        '"')
    metadata["SENSOR"] = mdata['PRODUCT_METADATA']['SENSOR_ID'].strip('"')

    if 'IMAGE_ATTRIBUTES' in mdata.keys():
        metadata['NEW_STYLE'] = True
        metadata['AZI'] = float(mdata['IMAGE_ATTRIBUTES']['SUN_AZIMUTH'])
        metadata['THS'] = 90. - float(
            mdata['IMAGE_ATTRIBUTES']['SUN_ELEVATION'])
        metadata['THV'] = 0.
        #metadata['THV'] = 3.5
        metadata['SCENE'] = mdata['METADATA_FILE_INFO']['LANDSAT_SCENE_ID']
        if 'LANDSAT_PRODUCT_ID' in mdata['METADATA_FILE_INFO'].keys():
            metadata['PRODUCT'] = mdata['METADATA_FILE_INFO'][
                'LANDSAT_PRODUCT_ID']

        metadata['PROCESSING_DATE'] = mdata['METADATA_FILE_INFO']['FILE_DATE']
        metadata['ISODATE'] = '{}T{}Z'.format(
            mdata['PRODUCT_METADATA']['DATE_ACQUIRED'].strip('"'),
            mdata['PRODUCT_METADATA']['SCENE_CENTER_TIME'].strip('"'))

        ### get projection info
        metadata["PATH"] = mdata['PRODUCT_METADATA']['WRS_PATH'].strip('"')
        metadata["ROW"] = mdata['PRODUCT_METADATA']['WRS_ROW'].strip('"')
        metadata["DIMS"] = [
            int(mdata['PRODUCT_METADATA']['REFLECTIVE_SAMPLES'].strip('"')),
            int(mdata['PRODUCT_METADATA']['REFLECTIVE_LINES'].strip('"'))
        ]

        tags = [
            'CORNER_LL_PROJECTION_X_PRODUCT', 'CORNER_LL_PROJECTION_Y_PRODUCT',
            'CORNER_LR_PROJECTION_X_PRODUCT', 'CORNER_LR_PROJECTION_Y_PRODUCT',
            'CORNER_UL_PROJECTION_X_PRODUCT', 'CORNER_UL_PROJECTION_Y_PRODUCT',
            'CORNER_UR_PROJECTION_X_PRODUCT', 'CORNER_UR_PROJECTION_Y_PRODUCT'
        ]
        for tag in tags:
            metadata[tag] = float(mdata['PRODUCT_METADATA'][tag])

        tags = [
            'CORNER_LL_LAT_PRODUCT', 'CORNER_LL_LON_PRODUCT',
            'CORNER_LR_LAT_PRODUCT', 'CORNER_LR_LON_PRODUCT',
            'CORNER_UL_LAT_PRODUCT', 'CORNER_UL_LON_PRODUCT',
            'CORNER_UR_LAT_PRODUCT', 'CORNER_UR_LON_PRODUCT'
        ]
        for tag in tags:
            metadata[tag] = float(mdata['PRODUCT_METADATA'][tag])

        ## get rescaling
        bands = set()
        for key in mdata['RADIOMETRIC_RESCALING'].keys():
            metadata[key] = float(mdata['RADIOMETRIC_RESCALING'][key])
            if 'REFLECTANCE' in key:
                bands.add(key.split('_')[3])  ## add optical bands to list
            if 'RADIANCE' in key:
                bands.add(key.split('_')[3])  ## add optical bands to list
    else:
        metadata['NEW_STYLE'] = False
        metadata['SENSOR'] = mdata['PRODUCT_METADATA']['SENSOR_ID']
        spacecraft = mdata['PRODUCT_METADATA']['SPACECRAFT_ID']
        if spacecraft == 'Landsat5': metadata["SATELLITE"] = 'LANDSAT_5'
        if spacecraft == 'Landsat7': metadata["SATELLITE"] = 'LANDSAT_7'
        metadata['AZI'] = float(mdata['PRODUCT_PARAMETERS']['SUN_AZIMUTH'])
        metadata['THS'] = 90. - float(
            mdata['PRODUCT_PARAMETERS']['SUN_ELEVATION'])
        metadata['THV'] = 0.
        metadata['SCENE'] = mdata['PRODUCT_METADATA']['METADATA_L1_FILE_NAME']

        metadata['PROCESSING_DATE'] = mdata['METADATA_FILE_INFO'][
            'PRODUCT_CREATION_TIME']
        metadata['ISODATE'] = '{}T{}Z'.format(
            mdata['PRODUCT_METADATA']['ACQUISITION_DATE'].strip('"'),
            mdata['PRODUCT_METADATA']['SCENE_CENTER_SCAN_TIME'].strip('"'))

        ### get projection info
        metadata["PATH"] = mdata['PRODUCT_METADATA']['WRS_PATH'].strip('"')
        metadata["ROW"] = mdata['PRODUCT_METADATA']['STARTING_ROW'].strip('"')
        metadata["DIMS"] = [
            int(mdata['PRODUCT_METADATA']['PRODUCT_SAMPLES_REF'].strip('"')),
            int(mdata['PRODUCT_METADATA']['PRODUCT_LINES_REF'].strip('"'))
        ]
        tags = [
            "PRODUCT_UL_CORNER_LAT", "PRODUCT_UL_CORNER_LON",
            "PRODUCT_UR_CORNER_LAT", "PRODUCT_UR_CORNER_LON",
            "PRODUCT_LL_CORNER_LAT", "PRODUCT_LL_CORNER_LON",
            "PRODUCT_LR_CORNER_LAT", "PRODUCT_LR_CORNER_LON",
            "PRODUCT_UL_CORNER_MAPX", "PRODUCT_UL_CORNER_MAPY",
            "PRODUCT_UR_CORNER_MAPX", "PRODUCT_UR_CORNER_MAPY",
            "PRODUCT_LL_CORNER_MAPX", "PRODUCT_LL_CORNER_MAPY",
            "PRODUCT_LR_CORNER_MAPX", "PRODUCT_LR_CORNER_MAPY"
        ]
        for tag in tags:
            metadata[tag] = float(mdata['PRODUCT_METADATA'][tag])

        ## get rescaling
        bands = set()
        for key in mdata['MIN_MAX_RADIANCE'].keys():
            metadata[key] = float(mdata['MIN_MAX_RADIANCE'][key])
            bands.add(key[-1])  ## add optical bands to list
        for key in mdata['MIN_MAX_PIXEL_VALUE'].keys():
            metadata[key] = float(mdata['MIN_MAX_PIXEL_VALUE'][key])
        print(bands)

    ### common things
    metadata["TIME"] = dateutil.parser.parse(''.join([metadata["ISODATE"]]))
    metadata["DOY"] = metadata["TIME"].strftime('%j')
    metadata["SE_DISTANCE"] = distance_se(metadata['DOY'])
    for key in mdata['PROJECTION_PARAMETERS'].keys():
        metadata[key] = mdata['PROJECTION_PARAMETERS'][key]

    ## set up bands
    metadata['BANDS'] = list(bands)
    metadata['BANDS'].sort()

    metadata['BAND_NAMES'] = metadata['BANDS']

    ## some sensor specific config
    if metadata["SATELLITE"] == 'LANDSAT_8':
        ## get TIRS for L8
        for key in mdata['TIRS_THERMAL_CONSTANTS'].keys():
            metadata[key] = float(mdata['TIRS_THERMAL_CONSTANTS'][key])
        ## bands to remove
        remove_bands = ['8', '9', '10', '11']  ## pan cirrus thermal x2
        for rb in remove_bands:
            if rb in metadata['BANDS']: metadata['BANDS'].remove(rb)

        #metadata['BANDS'].remove('8') ## remove Pan band
        #metadata['BANDS'].remove('9') ## remove Cirrus band
        #metadata['BANDS'].remove('10') ## remove Thermal band
        #metadata['BANDS'].remove('11') ## remove Thermal band
        metadata['SATELLITE_SENSOR'] = 'L8_OLI'
        #metadata['RGB_BANDS']= {'rhot':{'blue':'rhot_483','green':'rhot_561','red':'rhot_655'},
        #                        'rhos':{'blue':'rhos_483','green':'rhos_561','red':'rhos_655'}}
        metadata['RGB_BANDS'] = [483, 561, 655]
        metadata['WAVES'] = [443, 483, 561, 655, 865, 1609, 2201]

        ## some defaults here - probably not used any more
        metadata['BANDS_REDNIR'] = ['4', '5']
        metadata['BANDS_VIS'] = ['1', '2', '3', '4']
        metadata['BANDS_NIR'] = ['5', '6', '7']
        metadata['BANDS_BESTFIT'] = ['6', '7']
        #metadata['BANDS_ALL'] = ['1','2','3','4','5','6','7','9','10','11']
        metadata['BANDS_ALL'] = [
            '1', '2', '3', '4', '5', '6', '7', '9', '10', '11'
        ]
        metadata['BANDS_PAN'] = ['8']
        metadata['BANDS_CIRRUS'] = ['9']
        metadata['BANDS_THERMAL'] = ['10', '11']
        metadata['BAND_NAMES_ALL'] = [
            '1', '2', '3', '4', '5', '6', '7', '9', '10', '11'
        ]
        metadata['WAVES_ALL'] = [
            443, 483, 561, 655, 865, 1609, 2201, 1375, 10900, 11500
        ]

    if metadata["SATELLITE"] == 'LANDSAT_5':
        #metadata['BANDS'].remove('6') ## remove Thermal band
        remove_bands = ['6']  ## thermal
        for rb in remove_bands:
            if rb in metadata['BANDS']: metadata['BANDS'].remove(rb)
        metadata['SATELLITE_SENSOR'] = 'L5_TM' if metadata[
            'SENSOR'] == 'TM' else 'L5_MSS'
        #metadata['RGB_BANDS']= {'rhot':{'blue':'rhot_486','green':'rhot_571','red':'rhot_660'},
        #                        'rhos':{'blue':'rhos_486','green':'rhos_571','red':'rhos_660'}}
        metadata['RGB_BANDS'] = [486, 571, 660]
        metadata['WAVES'] = [486, 571, 660, 839, 1678, 2217]

        ## some defaults here - probably not used any more
        metadata['BANDS_REDNIR'] = ['3', '4']
        metadata['BANDS_VIS'] = ['1', '2', '3']
        metadata['BANDS_NIR'] = ['4', '5', '7']
        metadata['BANDS_BESTFIT'] = ['5', '7']
        metadata['BANDS_ALL'] = ['1', '2', '3', '4', '5', '6', '7']
        metadata['BANDS_PAN'] = []
        metadata['BANDS_CIRRUS'] = []
        metadata['BANDS_THERMAL'] = ['6']
        metadata['BAND_NAMES_ALL'] = ['1', '2', '3', '4', '5', '6', '7']
        metadata['WAVES_ALL'] = [486, 571, 660, 839, 1678, 10000, 2217]

    if metadata["SATELLITE"] == 'LANDSAT_7':
        #metadata['BANDS'].remove('6') ## remove Thermal band
        #metadata['BANDS'].remove('8') ## remove Pan band
        remove_bands = ['6', '8']  ## thermal pan
        for rb in remove_bands:
            if rb in metadata['BANDS']: metadata['BANDS'].remove(rb)
        metadata['SATELLITE_SENSOR'] = 'L7_ETM'
        #metadata['RGB_BANDS']= {'rhot':{'blue':'rhot_479','green':'rhot_561','red':'rhot_661'},
        #                        'rhos':{'blue':'rhos_479','green':'rhos_561','red':'rhos_661'}}
        metadata['RGB_BANDS'] = [479, 561, 661]
        metadata['WAVES'] = [479, 561, 661, 835, 1650, 2208]

        ## some defaults here - probably not used any more
        metadata['BANDS_REDNIR'] = ['3', '4']
        metadata['BANDS_VIS'] = ['1', '2', '3']
        metadata['BANDS_NIR'] = ['4', '5', '7']
        metadata['BANDS_BESTFIT'] = ['5', '7']
        metadata['BANDS_ALL'] = ['1', '2', '3', '4', '5', '6', '7']
        metadata['BANDS_PAN'] = ['8']
        metadata['BANDS_CIRRUS'] = []
        metadata['BANDS_THERMAL'] = ['6']
        metadata['BAND_NAMES_ALL'] = ['1', '2', '3', '4', '5', '6', '7']
        metadata['WAVES_ALL'] = [479, 561, 661, 835, 1650, 10000, 2208]

    ## make F0 for bands
    f0 = f0_sensor(metadata['SATELLITE_SENSOR'])
    for band in f0.keys():
        metadata['B{}_F0'.format(band)] = f0[band]

    ## get FILE names for bands and test if they exist in the bundle
    for par in mdata['PRODUCT_METADATA']:
        if 'FILE_NAME' in par:
            fname = mdata['PRODUCT_METADATA'][par]
            #                print(fname)
            exists = False
            for file in bundle_files:
                #                    print(bundle_files[file]['fname'])
                if bundle_files[file]['fname'] == fname:
                    exists = True
                    metadata[file] = bundle_files[file]['path']

    return (metadata)
Beispiel #5
0
def parse_metadata(metafile):
    import os
    from acolite.shared import rsr_read, f0_band, rsr_convolute, distance_se
    from acolite import config

    from xml.dom import minidom
    import dateutil.parser

    xmldoc = minidom.parse(metafile)

    metadata = {}

    ## get platform info
    main_tag = 'eop:Platform'
    tags = ["eop:shortName", "eop:serialIdentifier", "eop:orbitType"]
    tags_out = ["platform", 'platform_id', 'orbit']
    for t in xmldoc.getElementsByTagName('eop:Platform'):
        for i, tag in enumerate(tags):
            node = t.getElementsByTagName(tag)
            if len(node) > 0:
                metadata[tags_out[i]] = node[0].firstChild.nodeValue

    if "RapidEye" in metadata['platform_id']:
        metadata['SATELLITE_ID'] = metadata['platform']
        metadata['SATELLITE_SENSOR'] = metadata['platform_id']
        metadata['LUT_SENSOR'] = "RapidEye"
        metadata['SENSOR'] = 'RapidEye'
        metadata['SATELLITE_PREFIX'] = 're'
        bnames = {1: 'Blue', 2: 'Green', 3: 'Red', 4: 'RedEdge', 5: 'NIR'}
        metadata['BANDS_REDNIR'] = ['Red', 'RedEdge', 'NIR']
        metadata['BANDS_VIS'] = ['Blue', 'Green', 'Red']
        metadata['BANDS_NIR'] = ['RedEdge', 'NIR']
        metadata['BANDS_BESTFIT'] = ['Red', 'RedEdge', 'NIR']
        metadata['BANDS_ALL'] = ['Blue', 'Green', 'Red', 'RedEdge', 'NIR']

    if 'PlanetScope' in metadata['platform']:
        metadata['SATELLITE_ID'] = metadata['platform_id'][0:2]
        if metadata['SATELLITE_ID'] == '10': metadata['SATELLITE_ID'] = "0f"
        if metadata['SATELLITE_ID'] == '11': metadata['SATELLITE_ID'] = "0f"
        if metadata['SATELLITE_ID'] == '0d': metadata['SATELLITE_ID'] = "0c"

        metadata['SATELLITE_SENSOR'] = '{}_{}'.format(metadata['platform'],
                                                      metadata['platform_id'])
        metadata['LUT_SENSOR'] = '{}_{}'.format(metadata['platform'],
                                                metadata['SATELLITE_ID'])
        metadata['SENSOR'] = 'PlanetScope'
        metadata['SATELLITE_PREFIX'] = 'ps'
        bnames = {1: 'Blue', 2: 'Green', 3: 'Red', 4: 'NIR'}
        metadata['BANDS_REDNIR'] = ['Red', 'NIR']
        metadata['BANDS_VIS'] = ['Blue', 'Green', 'Red']
        metadata['BANDS_NIR'] = ['NIR']
        metadata['BANDS_BESTFIT'] = ['Red', 'NIR']
        metadata['BANDS_ALL'] = ['Blue', 'Green', 'Red', 'NIR']

    ## get acquisition info
    main_tag = 'eop:acquisitionParameters'

    tags = [
        "eop:orbitDirection", "eop:incidenceAngle",
        "opt:illuminationAzimuthAngle", "opt:illuminationElevationAngle",
        "{}:azimuthAngle".format(metadata['SATELLITE_PREFIX']),
        "{}:spaceCraftViewAngle".format(metadata['SATELLITE_PREFIX']),
        "{}:acquisitionDateTime".format(metadata['SATELLITE_PREFIX'])
    ]
    tags_out = [
        "orbit", 'ViewingIncidence', 'SunAzimuth', 'SunElevation',
        'ViewingAzimuth', 'ViewZenith', 'isotime'
    ]

    for t in xmldoc.getElementsByTagName(main_tag):
        for i, tag in enumerate(tags):
            node = t.getElementsByTagName(tag)
            if len(node) > 0:
                if tag in [
                        "eop:orbitDirection", "{}:acquisitionDateTime".format(
                            metadata['SATELLITE_PREFIX'])
                ]:
                    val = node[0].firstChild.nodeValue
                else:
                    val = float(node[0].firstChild.nodeValue)
                metadata[tags_out[i]] = val

    metadata['THS'] = 90. - metadata['SunElevation']
    metadata['PHIS'] = metadata['SunAzimuth']
    metadata['THV'] = abs(metadata['ViewZenith'])
    metadata['PHIV'] = metadata['ViewingAzimuth']
    metadata['AZI'] = abs(metadata['PHIS'] - metadata['PHIV'])
    while (metadata['AZI'] > 180):
        metadata['AZI'] = abs(180 - metadata['AZI'])

    metadata["TIME"] = dateutil.parser.parse(metadata["isotime"])
    metadata["DOY"] = metadata["TIME"].strftime('%j')
    metadata["SE_DISTANCE"] = distance_se(metadata['DOY'])
    metadata["isodate"] = metadata["TIME"].strftime('%Y-%m-%dT%H:%M:%SZ')

    ## get band data
    main_tag = '{}:bandSpecificMetadata'.format(metadata['SATELLITE_PREFIX'])
    bands = {}
    tags = [
        "{}:bandNumber".format(metadata['SATELLITE_PREFIX']),
        '{}:radiometricScaleFactor'.format(metadata['SATELLITE_PREFIX']),
        '{}:reflectanceCoefficient'.format(metadata['SATELLITE_PREFIX'])
    ]
    tags_out = ["band_idx", 'to_radiance', 'to_reflectance']

    ## import RSR to get F0
    #pp_path = os.path.dirname(pp.__file__)
    #if metadata['LUT_SENSOR'] == 'PlanetScope_0d':
    #    print('Sensor {} not yet supported'.format(metadata['LUT_SENSOR']))
    #    return(metadata)

    rsr_file = "{}/RSR/{}.txt".format(config['pp_data_dir'],
                                      metadata['LUT_SENSOR'])
    rsr, rsr_bands = rsr_read(file=rsr_file)

    for t in xmldoc.getElementsByTagName(main_tag):
        band = {}
        for i, tag in enumerate(tags):
            node = t.getElementsByTagName(tag)
            if len(node) > 0:
                val = float(node[0].firstChild.nodeValue)
                band[tags_out[i]] = val

        band['band_name'] = bnames[band['band_idx']]

        band_rsr = rsr[band['band_name']]['response']
        band_wave = [float(i * 1000) for i in rsr[band['band_name']]['wave']]

        f0 = f0_band(band_wave, band_rsr)
        wave = rsr_convolute(rsr[band['band_name']]['wave'],
                             rsr[band['band_name']]['wave'], band_rsr,
                             rsr[band['band_name']]['wave'])

        band['f0'] = f0
        band['wave'] = wave
        band['wave_name'] = str(round(int(band['wave'] * 1000.), 2))

        bands[band['band_name']] = band

    #metadata['bands']=bands
    for band in bands:
        for key in bands[band]:
            bk = '{}-{}'.format(band, key)
            metadata[bk] = bands[band][key]

    ## get product info
    main_tag = '{}:spatialReferenceSystem'.format(metadata['SATELLITE_PREFIX'])
    tags = [
        "{}:epsgCode".format(metadata['SATELLITE_PREFIX']),
        "{}:geodeticDatum".format(metadata['SATELLITE_PREFIX']),
        "{}:projection".format(metadata['SATELLITE_PREFIX']),
        "{}:projectionZone".format(metadata['SATELLITE_PREFIX'])
    ]
    tags_out = ["epsg", 'datum', 'projection', 'zone']
    for t in xmldoc.getElementsByTagName(main_tag):
        for i, tag in enumerate(tags):
            node = t.getElementsByTagName(tag)
            if len(node) > 0:
                val = node[0].firstChild.nodeValue
                metadata[tags_out[i]] = val

    ## get resolution info
    #main_tag = 'ps:Sensor'
    #tags = ["eop:resolution"]
    #tags_out = ["resolution"]
    main_tag = '{}:ProductInformation'.format(metadata['SATELLITE_PREFIX'])
    tags = [
        "{}:numRows".format(metadata['SATELLITE_PREFIX']),
        "{}:numColumns".format(metadata['SATELLITE_PREFIX']),
        "{}:numBands".format(metadata['SATELLITE_PREFIX']),
        "{}:rowGsd".format(metadata['SATELLITE_PREFIX']),
        "{}:columnGsd".format(metadata['SATELLITE_PREFIX'])
    ]
    tags_out = ["nrow", "ncol", "nband", "resolution_row", "resolution_col"]
    for t in xmldoc.getElementsByTagName(main_tag):
        for i, tag in enumerate(tags):
            node = t.getElementsByTagName(tag)
            if len(node) > 0:
                val = node[0].firstChild.nodeValue
                metadata[tags_out[i]] = val
    metadata['resolution'] = (float(metadata['resolution_row']),
                              float(metadata['resolution_col']))
    metadata['dims'] = (int(metadata['ncol']), int(metadata['nrow']))

    ## get bounding box
    main_tag = '{}:geographicLocation'.format(metadata['SATELLITE_PREFIX'])
    tags = [
        "{}:topLeft".format(metadata['SATELLITE_PREFIX']),
        "{}:topRight".format(metadata['SATELLITE_PREFIX']),
        "{}:bottomRight".format(metadata['SATELLITE_PREFIX']),
        "{}:bottomLeft".format(metadata['SATELLITE_PREFIX'])
    ]
    tags_out = ["UL", 'UR', 'LR', 'LL']
    for t in xmldoc.getElementsByTagName(main_tag):
        for i, tag in enumerate(tags):
            node = t.getElementsByTagName(tag)
            for j, tag2 in enumerate([
                    '{}:latitude'.format(metadata['SATELLITE_PREFIX']),
                    '{}:longitude'.format(metadata['SATELLITE_PREFIX'])
            ]):
                node2 = node[0].getElementsByTagName(tag2)
                if len(node2) > 0:
                    val = node2[0].firstChild.nodeValue
                    tout = '{}_{}'.format(tags_out[i],
                                          tag2.split(':')[1].upper())
                    metadata[tout] = float(val)

    return (metadata)