def f0_band(wave, rsr, f0file=None): from acolite.shared import f0_get, rsr_convolute from numpy import linspace f0 = f0_get(f0file=f0file) band_f0 = rsr_convolute(f0['data'], f0['wave'], rsr, wave) return band_f0
def ko3_band(wave, rsr, ko3file=None): from acolite.shared import ko3_get, rsr_convolute from numpy import linspace ko3 = ko3_get(ko3file=ko3file) band_ko3 = rsr_convolute(ko3['data'], ko3['wave'], rsr, wave) return band_ko3
def f0_wave(wave, width=1, f0file=None): from acolite.shared import f0_get, rsr_convolute from numpy import linspace f0 = f0_get(f0file=f0file) off = width / 2. band_wave = linspace(wave - off, wave + off, width + 1) band_rsr = [1] * len(band_wave) band_f0 = rsr_convolute(f0['data'], f0['wave'], band_rsr, band_wave) return band_f0
def parse_metadata(metafile): from acolite.shared import rsr_read, f0_band, rsr_convolute import acolite as ac import os, sys, fnmatch, dateutil.parser from xml.dom import minidom if not os.path.isfile(metafile): print('Metadata file not found.') sys.exit() try: xmldoc = minidom.parse(metafile) except: print('Error opening metadata file.') sys.exit() metadata = {} #metadata['SATELLITE'] = 'WorldView2' #metadata['SENSOR'] = 'WorldView2' ## get image information metadata_tags = [ 'SATID', 'FIRSTLINETIME', 'NUMROWS', 'NUMCOLUMNS', 'PRODUCTLEVEL' "MININTRACKVIEWANGLE", "MAXINTRACKVIEWANGLE", "MEANINTRACKVIEWANGLE", "MINCROSSTRACKVIEWANGLE", "MAXCROSSTRACKVIEWANGLE", "MEANCROSSTRACKVIEWANGLE", "MINOFFNADIRVIEWANGLE", "MAXOFFNADIRVIEWANGLE", "MEANOFFNADIRVIEWANGLE", "MINSUNAZ", "MAXSUNAZ", "MEANSUNAZ", "MINSUNEL", "MAXSUNEL", "MEANSUNEL", "MINSATAZ", "MAXSATAZ", "MEANSATAZ", "MINSATEL", "MAXSATEL", "MEANSATEL", "EARLIESTACQTIME", "LATESTACQTIME" ] for tag in metadata_tags: node = xmldoc.getElementsByTagName(tag) if len(node) > 0: metadata[tag] = node[0].firstChild.nodeValue if 'SATID' in metadata: if metadata['SATID'] == 'WV03': metadata['SATELLITE'] = 'WorldView3' metadata['SENSOR'] = 'WorldView3' metadata["TIME"] = dateutil.parser.parse(metadata["FIRSTLINETIME"]) band_names = [ 'COASTAL', 'BLUE', 'GREEN', 'YELLOW', 'RED', 'REDEDGE', 'NIR1', 'NIR2', 'SWIR1', 'SWIR2', 'SWIR3', 'SWIR4', 'SWIR5', 'SWIR6', 'SWIR7', 'SWIR8' ] band_indices = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ] band_indices = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8] band_tag_names = [ "BAND_C", "BAND_B", "BAND_G", "BAND_Y", "BAND_R", "BAND_RE", "BAND_N", "BAND_N2", "BAND_S1", "BAND_S2", "BAND_S3", "BAND_S4", "BAND_S5", "BAND_S6", "BAND_S7", "BAND_S8" ] if metadata['SATID'] == 'WV02': metadata['SATELLITE'] = 'WorldView2' metadata['SENSOR'] = 'WorldView2' try: ## "L2A" data metadata["TIME"] = dateutil.parser.parse( metadata["EARLIESTACQTIME"]) except: ## "L1B" data metadata["TIME"] = dateutil.parser.parse( metadata["FIRSTLINETIME"]) band_names = [ 'COASTAL', 'BLUE', 'GREEN', 'YELLOW', 'RED', 'REDEDGE', 'NIR1', 'NIR2' ] band_indices = [1, 2, 3, 4, 5, 6, 7, 8] band_tag_names = [ "BAND_C", "BAND_B", "BAND_G", "BAND_Y", "BAND_R", "BAND_RE", "BAND_N", "BAND_N2" ] ## common stuff metadata["DOY"] = metadata["TIME"].strftime('%j') metadata["THS"] = 90. - float(metadata['MEANSUNEL']) metadata["THV"] = 90. - float(metadata['MEANSATEL']) metadata["AZI"] = abs( float(metadata['MEANSATAZ']) - float(metadata['MEANSUNAZ'])) if metadata["AZI"] > 180.: metadata["AZI"] -= 180. band_tags = [ "ULLON", "ULLAT", "ULHAE", "URLON", "URLAT", "URHAE", "LRLON", "LRLAT", "LRHAE", "LLLON", "LLLAT", "LLHAE", "ABSCALFACTOR", "EFFECTIVEBANDWIDTH", "TDILEVEL" ] ## import RSR to get F0 sensor = metadata['SENSOR'] pp_path = ac.config['pp_data_dir'] rsr_file = pp_path + '/RSR/' + sensor + '.txt' rsr, rsr_bands = rsr_read(file=rsr_file) ## read band information of spatial extent band_values = {} for b, band_tag in enumerate(band_tag_names): band_rsr = rsr[band_names[b]]['response'] band_wave = [i * 1000 for i in rsr[band_names[b]]['wave']] f0 = f0_band(band_wave, band_rsr) wave = rsr_convolute(rsr[band_names[b]]['wave'], rsr[band_names[b]]['wave'], band_rsr, band_wave) band_data = { 'F0': f0, 'wave': wave, 'name': band_names[b], 'index': band_indices[b] } band_data['wave_name'] = str(round(int(band_data['wave'] * 1000.), 2)) ## there are two tags in WV3 metadata for t in xmldoc.getElementsByTagName(band_tag): for tag in band_tags: node = t.getElementsByTagName(tag) if len(node) > 0: band_data[tag] = float(node[0].firstChild.nodeValue) #band_data['band_index']=t if len(band_data) > 5: band_values[band_tag] = band_data metadata['BAND_INFO'] = band_values ## get tile information tile_tags = [ "FILENAME", "ULCOLOFFSET", "ULROWOFFSET", "URCOLOFFSET", "URROWOFFSET", "LRCOLOFFSET", "LRROWOFFSET", "LLCOLOFFSET", "LLROWOFFSET", "ULLON", "ULLAT", "URLON", "URLAT", "LRLON", "LRLAT", "LLLON", "LLLAT", "ULX", "ULY", "URX", "URY", "LRX", "LRY", "LLX", "LLY" ] tile_values = [] for t in xmldoc.getElementsByTagName('TILE'): tile = {} for tag in tile_tags: node = t.getElementsByTagName(tag) if len(node) > 0: if tag == "FILENAME": val = node[0].firstChild.nodeValue else: val = float(node[0].firstChild.nodeValue) tile[tag] = val tile_values.append(tile) metadata['TILE_INFO'] = tile_values 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)