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)
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)
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)
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)
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)