def extract_alosStack_metadata(meta_file, geom_dir): import isce import isceobj from isceobj.Planet.Planet import Planet track = load_track(os.path.dirname(meta_file), os.path.basename(meta_file).strip('.track.xml')) rlooks, alooks, width, length = extract_image_size_alosStack(geom_dir) spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = alos2_acquisition_modes( ) meta = {} meta['prf'] = track.prf meta['startUTC'] = track.sensingStart + datetime.timedelta( seconds=(alooks - 1.0) / 2.0 * track.azimuthLineInterval) meta['stopUTC'] = meta['startUTC'] + datetime.timedelta( seconds=(length - 1) * alooks * track.azimuthLineInterval) meta['radarWavelength'] = track.radarWavelength meta['startingRange'] = track.startingRange + ( rlooks - 1.0) / 2.0 * track.rangePixelSize meta['passDirection'] = track.passDirection.upper() meta['polarization'] = track.frames[0].swaths[0].polarization #meta['trackNumber'] = track.trackNumber #meta['orbitNumber'] = track.orbitNumber meta['PLATFORM'] = sensor.standardize_sensor_name('alos2') sensingMid = meta['startUTC'] + datetime.timedelta( seconds=(meta['stopUTC'] - meta['startUTC']).total_seconds() / 2.0) time_seconds = (sensingMid.hour * 3600.0 + sensingMid.minute * 60.0 + sensingMid.second) meta['CENTER_LINE_UTC'] = time_seconds peg = track.orbit.interpolateOrbit(sensingMid, method='hermite') Vs = np.linalg.norm(peg.getVelocity()) meta['azimuthPixelSize'] = Vs * track.azimuthLineInterval meta['rangePixelSize'] = track.rangePixelSize azBandwidth = track.prf * 0.8 if track.operationMode in scansarNominalModes: azBandwidth /= 5.0 if track.operationMode in scansarWideModes: azBandwidth /= 7.0 #use a mean burst synchronizatino here if track.operationMode in scansarModes: azBandwidth *= 0.85 meta['azimuthResolution'] = Vs * (1.0 / azBandwidth) meta['rangeResolution'] = 0.5 * SPEED_OF_LIGHT * ( 1.0 / track.frames[0].swaths[0].rangeBandwidth) elp = Planet(pname='Earth').ellipsoid llh = elp.xyz_to_llh(peg.getPosition()) elp.setSCH(llh[0], llh[1], track.orbit.getENUHeading(sensingMid)) meta['HEADING'] = track.orbit.getENUHeading(sensingMid) meta['earthRadius'] = elp.pegRadCur meta['altitude'] = llh[2] meta['beam_mode'] = track.operationMode meta['swathNumber'] = ''.join( str(swath.swathNumber) for swath in track.frames[0].swaths) meta['firstFrameNumber'] = track.frames[0].frameNumber meta['lastFrameNumber'] = track.frames[-1].frameNumber meta['ALOOKS'] = alooks meta['RLOOKS'] = rlooks # NCORRLOOKS for coherence calibration rgfact = float(meta['rangeResolution']) / float(meta['rangePixelSize']) azfact = float(meta['azimuthResolution']) / float(meta['azimuthPixelSize']) meta['NCORRLOOKS'] = meta['RLOOKS'] * meta['ALOOKS'] / (rgfact * azfact) # update pixel_size for multilooked data meta['rangePixelSize'] *= meta['RLOOKS'] meta['azimuthPixelSize'] *= meta['ALOOKS'] edge = 3 lat_file = glob.glob( os.path.join(geom_dir, '*_{}rlks_{}alks.lat'.format(rlooks, alooks)))[0] img = isceobj.createImage() img.load(lat_file + '.xml') width = img.width length = img.length data = np.memmap(lat_file, dtype='float64', mode='r', shape=(length, width)) meta['LAT_REF1'] = str(data[0 + edge, 0 + edge]) meta['LAT_REF2'] = str(data[0 + edge, -1 - edge]) meta['LAT_REF3'] = str(data[-1 - edge, 0 + edge]) meta['LAT_REF4'] = str(data[-1 - edge, -1 - edge]) lon_file = glob.glob( os.path.join(geom_dir, '*_{}rlks_{}alks.lon'.format(rlooks, alooks)))[0] data = np.memmap(lon_file, dtype='float64', mode='r', shape=(length, width)) meta['LON_REF1'] = str(data[0 + edge, 0 + edge]) meta['LON_REF2'] = str(data[0 + edge, -1 - edge]) meta['LON_REF3'] = str(data[-1 - edge, 0 + edge]) meta['LON_REF4'] = str(data[-1 - edge, -1 - edge]) los_file = glob.glob( os.path.join(geom_dir, '*_{}rlks_{}alks.los'.format(rlooks, alooks)))[0] data = np.memmap(los_file, dtype='float32', mode='r', shape=(length * 2, width))[0:length * 2:2, :] inc_angle = data[int(length / 2), int(width / 2)] meta['CENTER_INCIDENCE_ANGLE'] = str(inc_angle) pointingDirection = {'right': -1, 'left': 1} meta['ANTENNA_SIDE'] = str(pointingDirection[track.pointingDirection]) return meta, track
def extract_tops_metadata(xml_file): """Read metadata from xml file for Sentinel-1/TOPS Parameters: xml_file : str, path of the .xml file, i.e. reference/IW1.xml Returns: meta : dict, metadata burst : isceobj.Sensor.TOPS.BurstSLC.BurstSLC object """ import isce import isceobj from isceobj.Planet.Planet import Planet obj = load_product(xml_file) burst = obj.bursts[0] burstEnd = obj.bursts[-1] meta = {} meta['prf'] = burst.prf meta['startUTC'] = burst.burstStartUTC meta['stopUTC'] = burstEnd.burstStopUTC meta['radarWavelength'] = burst.radarWavelength meta['startingRange'] = burst.startingRange meta['passDirection'] = burst.passDirection meta['polarization'] = burst.polarization meta['trackNumber'] = burst.trackNumber meta['orbitNumber'] = burst.orbitNumber try: meta['PLATFORM'] = sensor.standardize_sensor_name(obj.spacecraftName) except: if os.path.basename(xml_file).startswith('IW'): meta['PLATFORM'] = 'sen' time_seconds = (burst.sensingMid.hour * 3600.0 + burst.sensingMid.minute * 60.0 + burst.sensingMid.second) meta['CENTER_LINE_UTC'] = time_seconds orbit = burst.orbit peg = orbit.interpolateOrbit(burst.sensingMid, method='hermite') # Sentinel-1 TOPS pixel spacing Vs = np.linalg.norm(peg.getVelocity()) #satellite speed meta['azimuthPixelSize'] = Vs * burst.azimuthTimeInterval meta['rangePixelSize'] = burst.rangePixelSize # Sentinel-1 TOPS spatial resolution iw_str = 'IW2' if os.path.basename(xml_file).startswith('IW'): iw_str = os.path.splitext(os.path.basename(xml_file))[0] meta['azimuthResolution'] = sensor.SENSOR_DICT['sen'][iw_str][ 'azimuth_resolution'] meta['rangeResolution'] = sensor.SENSOR_DICT['sen'][iw_str][ 'range_resolution'] elp = Planet(pname='Earth').ellipsoid llh = elp.xyz_to_llh(peg.getPosition()) elp.setSCH(llh[0], llh[1], orbit.getENUHeading(burst.sensingMid)) meta['HEADING'] = orbit.getENUHeading(burst.sensingMid) meta['earthRadius'] = elp.pegRadCur meta['altitude'] = llh[2] # for Sentinel-1 meta['beam_mode'] = 'IW' meta['swathNumber'] = burst.swathNumber # 1. multipel subswaths xml_files = glob.glob(os.path.join(os.path.dirname(xml_file), 'IW*.xml')) if len(xml_files) > 1: swath_num = [ load_product(fname).bursts[0].swathNumber for fname in xml_files ] meta['swathNumber'] = ''.join(str(i) for i in sorted(swath_num)) # 2. calculate ASF frame number for Sentinel-1 meta['firstFrameNumber'] = int( 0.2 * (burst.burstStartUTC - obj.ascendingNodeTime).total_seconds()) meta['lastFrameNumber'] = int( 0.2 * (burstEnd.burstStopUTC - obj.ascendingNodeTime).total_seconds()) return meta, burst
def extract_stripmap_metadata(meta_file): """Read metadata from shelve file for StripMap stack from ISCE Parameters: meta_file : str, path of the shelve file, i.e. referenceShelve/data.dat Returns: meta : dict, metadata frame : isceobj.Scene.Frame.Frame object """ import isce import isceobj from isceobj.Planet.Planet import Planet if os.path.basename(meta_file).startswith('data'): # shelve file from stripmapStack # referenceShelve/data for uavsar # referenceShelve/data.dat for all the others fbase = os.path.splitext(meta_file)[0] with shelve.open(fbase, flag='r') as mdb: frame = mdb['frame'] elif meta_file.endswith(".xml"): #XML file from stripmapApp frame = load_product(meta_file) else: raise ValueError( 'un-recognized isce/stripmap metadata file: {}'.format(meta_file)) meta = {} meta['prf'] = frame.PRF meta['startUTC'] = frame.sensingStart meta['stopUTC'] = frame.sensingStop meta['radarWavelength'] = frame.radarWavelegth meta['startingRange'] = frame.startingRange meta['trackNumber'] = frame.trackNumber meta['orbitNumber'] = frame.orbitNumber meta['PLATFORM'] = sensor.standardize_sensor_name( frame.platform.getSpacecraftName()) meta['polarization'] = str(frame.polarization).replace('/', '') if meta['polarization'].startswith("b'"): meta['polarization'] = meta['polarization'][2:4] time_seconds = (frame.sensingMid.hour * 3600.0 + frame.sensingMid.minute * 60.0 + frame.sensingMid.second) meta['CENTER_LINE_UTC'] = time_seconds orbit = frame.orbit peg = orbit.interpolateOrbit(frame.sensingMid, method='hermite') Vs = np.linalg.norm(peg.getVelocity()) #satellite speed meta['azimuthResolution'] = frame.platform.antennaLength / 2.0 meta['azimuthPixelSize'] = Vs / frame.PRF frame.getInstrument() rgBandwidth = frame.instrument.pulseLength * frame.instrument.chirpSlope meta['rangeResolution'] = abs(SPEED_OF_LIGHT / (2.0 * rgBandwidth)) meta['rangePixelSize'] = frame.instrument.rangePixelSize elp = Planet(pname='Earth').ellipsoid llh = elp.xyz_to_llh(peg.getPosition()) elp.setSCH(llh[0], llh[1], orbit.getENUHeading(frame.sensingMid)) meta['HEADING'] = orbit.getENUHeading(frame.sensingMid) meta['earthRadius'] = elp.pegRadCur meta['altitude'] = llh[2] # for StripMap meta['beam_mode'] = 'SM' return meta, frame
def extract_snap_metadata(fname): ''' read and extract attributes from a SNAP .dim file Parameters: fname - str, path of SNAP .dim file Returns: atr - dict, metadata ''' # Read XML and extract required vals - using basic file reader # xmltree or minidom might be better but this works with open(fname, 'r') as f: lines = f.readlines() # use lists so that elements where there are more than one, only the first mention can be extracted - # Usually the first mention (list item 0) is the final subsetted/geocoded product metadata bp, azimuth_looks, range_looks, az_pixel, rg_pixel, dates, x, y, z = [], [], [], [], [], [], [], [], [] for line in lines: if "Perp Baseline" in line: bp.append(line.split(">")[1].split("<")[0]) if "Master: " in line: dates.append(line.split(": ")[1].split('">')[0]) if "radar_frequency" in line: freq = float(line.split(">")[1].split("<")[0]) * 1e6 wvl = SPEED_OF_LIGHT / freq if "NROWS" in line: length = int(line.split(">")[1].split("<")[0]) if "NCOLS" in line: width = int(line.split(">")[1].split("<")[0]) if "DATA_TYPE" in line: data_type = line.split(">")[1].split("<")[0] if "IMAGE_TO_MODEL_TRANSFORM" in line: transform = str(line.split(">")[1].split("<")[0]).split(",") if "antenna_pointing" in line: looking = line.split(">")[1].split("<")[0] if looking == "right": antenna_side = "-1" if "PRODUCT_SCENE_RASTER_START_TIME" in line: first_time = line.split(">")[1].split("<")[0] if "PRODUCT_SCENE_RASTER_STOP_TIME" in line: last_time = line.split(">")[1].split("<")[0] if "first_near_lat" in line: first_near_lat = line.split(">")[1].split("<")[0] if "first_near_long" in line: first_near_long = line.split(">")[1].split("<")[0] if "first_far_lat" in line: first_far_lat = line.split(">")[1].split("<")[0] if "first_far_long" in line: first_far_long = line.split(">")[1].split("<")[0] if "last_near_lat" in line: last_near_lat = line.split(">")[1].split("<")[0] if "last_near_long" in line: last_near_long = line.split(">")[1].split("<")[0] if "last_far_lat" in line: last_far_lat = line.split(">")[1].split("<")[0] if "last_far_long" in line: last_far_long = line.split(">")[1].split("<")[0] if "ASCENDING or DESCENDING" in line: direction = line.split(">")[1].split("<")[0] if "azimuth_looks" in line: azimuth_looks.append(line.split(">")[1].split("<")[0]) if "range_looks" in line: range_looks.append(line.split(">")[1].split("<")[0]) if "pulse_repetition_frequency" in line: prf = line.split(">")[1].split("<")[0] if "slant_range_to_first_pixel" in line: starting_range = line.split(">")[1].split("<")[0] if "Satellite mission" in line: platform = line.split(">")[1].split("<")[0] if "platformHeading" in line: heading = line.split(">")[1].split("<")[0] if "Azimuth sample spacing" in line: az_pixel.append(line.split(">")[1].split("<")[0]) if "Range sample spacing" in line: rg_pixel.append(line.split(">")[1].split("<")[0]) if "incidenceAngleMidSwath" in line: inc_angle_mid = line.split(">")[1].split("<")[0] if "x_pos" in line: x.append(line.split(">")[1].split("<")[0]) if "y_pos" in line: y.append(line.split(">")[1].split("<")[0]) if "z_pos" in line: z.append(line.split(">")[1].split("<")[0]) atr = {} # Calculate the center of the scene as floating point seconds start_utc = datetime.datetime.strptime(first_time, '%d-%b-%Y %H:%M:%S.%f') end_utc = datetime.datetime.strptime(last_time, '%d-%b-%Y %H:%M:%S.%f') center_utc = start_utc + ((end_utc - start_utc) / 2) center_seconds = (center_utc.hour * 3600.0 + center_utc.minute * 60. + center_utc.second) atr["CENTER_LINE_UTC"] = center_seconds # Extract reference / secondary date in yymmdd format date1 = datetime.datetime.strptime(dates[0], "%d%b%Y").strftime("%Y%m%d")[2:8] date2 = datetime.datetime.strptime(dates[1], "%d%b%Y").strftime("%Y%m%d")[2:8] atr["DATE12"] = "{}-{}".format(date1, date2) # calculate ellipsoid radius and satellite height from state vector # using first state vector for simplicity xyz = (float(x[0]), float(y[0]), float(z[0])) height, earth_radius = get_ellpsoid_local_radius(xyz) # Calculate range/azimuth pixel sizes range_pixel_size = float(rg_pixel[0]) * math.sin(float(inc_angle_mid)) azimuth_pixel_size = float(az_pixel[0]) * ( (earth_radius + height) / earth_radius) # Add values to dict atr['PROCESSOR'] = 'snap' atr['FILE_TYPE'] = os.path.basename(fname).split('_')[ -2] # yyyymmdd_yyyymmdd_type_tc.dim atr["WIDTH"] = width atr["LENGTH"] = length atr["DATA_TYPE"] = data_type atr["WAVELENGTH"] = wvl atr["P_BASELINE_TOP_HDR"] = bp[1] atr["P_BASELINE_BOTTOM_HDR"] = bp[1] atr["ANTENNA_SIDE"] = antenna_side atr["LAT_REF1"], atr["LONG_REF1"] = first_near_lat, first_near_long atr["LAT_REF2"], atr["LONG_REF2"] = first_far_lat, first_far_long atr["LAT_REF3"], atr["LONG_REF3"] = last_near_lat, last_near_long atr["LAT_REF4"], atr["LONG_REF4"] = last_far_lat, last_far_long atr["ORBIT_DIRECTION"] = direction atr["ALOOKS"] = int(float(azimuth_looks[0])) atr["RLOOKS"] = int(float(range_looks[0])) atr["PRF"] = prf atr["PLATFORM"] = standardize_sensor_name(platform) atr["HEADING"] = heading atr["EARTH_RADIUS"] = earth_radius atr["HEIGHT"] = height atr["RANGE_PIXEL_SIZE"] = range_pixel_size atr["AZIMUTH_PIXEL_SIZE"] = azimuth_pixel_size atr['INCIDENCE_ANGLE'] = inc_angle_mid atr["STARTING_RANGE"] = starting_range atr["SLANT_RANGE_DISTANCE"] = ut.incidence_angle2slant_range_distance( atr, inc_angle_mid) # Convert 3.333e-4 to 0.0003333 transform = [str(float(i)) for i in transform] atr["X_STEP"], atr["Y_STEP"] = transform[0], transform[3] atr["X_FIRST"], atr["Y_FIRST"] = transform[4], transform[5] atr["X_UNIT"] = "degrees" atr["Y_UNIT"] = "degrees" # convert all key value in string format to ensure the --update checking in write_rsc() for key, value in atr.items(): atr[key] = str(value) return atr