Esempio n. 1
0
def read_geometry(inps):
    ts_obj = timeseries(inps.timeseries_file)
    ts_obj.open(print_msg=False)

    # 2D / 3D geometry
    if inps.geom_file:
        geom_obj = geometry(inps.geom_file)
        geom_obj.open()
        if 'incidenceAngle' not in geom_obj.datasetNames:
            inps.incAngle = ut.incidence_angle(ts_obj.metadata, dimension=0)
            inps.rangeDist = ut.range_distance(ts_obj.metadata, dimension=0)
        else:
            print(('read 2D incidenceAngle,slantRangeDistance from {} file:'
                   ' {}').format(geom_obj.name, os.path.basename(geom_obj.file)))
            inps.incAngle = geom_obj.read(datasetName='incidenceAngle', print_msg=False).flatten()
            inps.rangeDist = geom_obj.read(datasetName='slantRangeDistance', print_msg=False).flatten()
        if 'bperp' in geom_obj.datasetNames:
            print('read 3D bperp from {} file: {} ...'.format(geom_obj.name, os.path.basename(geom_obj.file)))
            dset_list = ['bperp-{}'.format(d) for d in ts_obj.dateList]
            inps.pbase = geom_obj.read(datasetName=dset_list, print_msg=False).reshape((ts_obj.numDate, -1))
            inps.pbase -= np.tile(inps.pbase[ts_obj.refIndex, :].reshape(1, -1), (ts_obj.numDate, 1))
        else:
            print('read mean bperp from {} file'.format(ts_obj.name))
            inps.pbase = ts_obj.pbase.reshape((-1, 1))

    # 0D geometry
    else:
        print('read mean incidenceAngle,slantRangeDistance,bperp value from {} file'.format(ts_obj.name))
        inps.incAngle = ut.incidence_angle(ts_obj.metadata, dimension=0)
        inps.rangeDist = ut.range_distance(ts_obj.metadata, dimension=0)
        inps.pbase = ts_obj.pbase.reshape((-1, 1))

    inps.sinIncAngle = np.sin(inps.incAngle * np.pi / 180.)
    return inps
Esempio n. 2
0
def read_geometry(ts_file, geom_file=None, box=None):
    """Read the following geometry info in 0/2/3D
    Parameters: ts_file       - str, path of time-series file
                geom_file     - str, path of geometry file
                box           - tuple of 4 int for (x0, y0, x1, y1) of the area of interest
    Returns:    sin_inc_angle - 0/2D array, sin(inc_angle)
                range_dist    - 0/2D array, slant range distance in meter
                pbase         - 0/3D array, perp baseline in meter
    """
    ts_obj = timeseries(ts_file)
    ts_obj.open(print_msg=False)

    # 0/2/3D geometry
    if geom_file:
        geom_obj = geometry(geom_file)
        geom_obj.open()

        # 0/2D incidence angle / slant range distance
        if 'incidenceAngle' not in geom_obj.datasetNames:
            inc_angle = ut.incidence_angle(ts_obj.metadata, dimension=0)
            range_dist = ut.range_distance(ts_obj.metadata, dimension=0)
        else:
            print(
                'read 2D incidenceAngle, slantRangeDistance from {} file: {}'.
                format(geom_obj.name, os.path.basename(geom_obj.file)))
            inc_angle = geom_obj.read(datasetName='incidenceAngle',
                                      box=box,
                                      print_msg=False).flatten()
            range_dist = geom_obj.read(datasetName='slantRangeDistance',
                                       box=box,
                                       print_msg=False).flatten()

        # 0/3D perp baseline
        if 'bperp' in geom_obj.datasetNames:
            print('read 3D bperp from {} file: {} ...'.format(
                geom_obj.name, os.path.basename(geom_obj.file)))
            dset_list = ['bperp-{}'.format(d) for d in ts_obj.dateList]
            pbase = geom_obj.read(datasetName=dset_list,
                                  box=box,
                                  print_msg=False).reshape(
                                      (ts_obj.numDate, -1))
            pbase -= np.tile(pbase[ts_obj.refIndex, :].reshape(1, -1),
                             (ts_obj.numDate, 1))
        else:
            print('read mean bperp from {} file'.format(ts_obj.name))
            pbase = ts_obj.pbase.reshape((-1, 1))

    # 0D geometry
    else:
        print(
            'read mean incidenceAngle, slantRangeDistance, bperp value from {} file'
            .format(ts_obj.name))
        inc_angle = ut.incidence_angle(ts_obj.metadata, dimension=0)
        range_dist = ut.range_distance(ts_obj.metadata, dimension=0)
        pbase = ts_obj.pbase.reshape((-1, 1))

    sin_inc_angle = np.sin(inc_angle * np.pi / 180.)
    return sin_inc_angle, range_dist, pbase
Esempio n. 3
0
def main(iargs=None):
    inps = cmd_line_parse(iargs)

    # Calculate look angle
    atr = readfile.read_attribute(inps.file)
    dem = None
    if inps.dem_file:
        dem = readfile.read(inps.dem_file, datasetName='height')[0]
    angle = ut.incidence_angle(atr, dem=dem, dimension=2)

    # Geo coord
    if 'Y_FIRST' in atr.keys():
        print(
            'Input file is geocoded, only center incident angle is calculated: '
        )
        print(angle)
        length = int(atr['LENGTH'])
        width = int(atr['WIDTH'])
        angle_mat = np.zeros((length, width), np.float32)
        angle_mat[:] = angle
        angle = angle_mat

    atr['FILE_TYPE'] = 'mask'
    atr['UNIT'] = 'degree'
    if 'REF_DATE' in atr.keys():
        atr.pop('REF_DATE')

    if not inps.outfile:
        inps.outfile = 'incidenceAngle.h5'
    writefile.write(angle, out_file=inps.outfile, metadata=atr)
    return inps.outfile
Esempio n. 4
0
def get_design_matrix(atr1, atr2, az_angle=90):
    """Get the design matrix A to convert asc/desc to hz/up.
    Only asc + desc -> hz + up is implemented for now.

    Project displacement from LOS to Horizontal and Vertical components
        math for 3D: cos(theta)*Uz - cos(alpha)*sin(theta)*Ux + sin(alpha)*sin(theta)*Uy = Ulos
        math for 2D: cos(theta)*Uv - sin(alpha-az)*sin(theta)*Uh = Ulos   #Uh_perp = 0.0
    This could be easily modified to support multiple view geometry
        (e.g. two adjcent tracks from asc & desc) to resolve 3D

    Parameters: atr1/2 : dict, metadata of input LOS files
    Returns:    A : 2D matrix in size of (2,2)

    """
    atr_list = [atr1, atr2]
    A = np.zeros((2, 2))
    for i in range(len(atr_list)):
        atr = atr_list[i]

        # incidence angle
        inc_angle = float(ut.incidence_angle(atr, dimension=0, print_msg=False))
        print('incidence angle: '+str(inc_angle))
        inc_angle *= np.pi/180.

        # heading angle
        head_angle = float(atr['HEADING'])
        if head_angle < 0.:
            head_angle += 360.
        print('heading angle: '+str(head_angle))
        head_angle *= np.pi/180.

        # construct design matrix
        A[i, 0] = np.cos(inc_angle)
        A[i, 1] = np.sin(inc_angle) * np.sin(head_angle - az_angle)
    return A
Esempio n. 5
0
    def get_los_geometry(self, geom_obj, print_msg=False):
        lat, lon = self.get_stat_lat_lon(print_msg=print_msg)

        # get LOS geometry
        if isinstance(geom_obj, str):
            # geometry file
            atr = readfile.read_attribute(geom_obj)
            coord = ut.coordinate(atr, lookup_file=geom_obj)
            y, x = coord.geo2radar(lat, lon, print_msg=print_msg)[0:2]
            box = (x, y, x + 1, y + 1)
            inc_angle = readfile.read(geom_obj,
                                      datasetName='incidenceAngle',
                                      box=box,
                                      print_msg=print_msg)[0][0, 0]
            az_angle = readfile.read(geom_obj,
                                     datasetName='azimuthAngle',
                                     box=box,
                                     print_msg=print_msg)[0][0, 0]
            head_angle = ut.azimuth2heading_angle(az_angle)
        elif isinstance(geom_obj, dict):
            # use mean inc/head_angle from metadata
            inc_angle = ut.incidence_angle(geom_obj,
                                           dimension=0,
                                           print_msg=print_msg)
            head_angle = float(geom_obj['HEADING'])
            # for old reading of los.rdr band2 data into headingAngle directly
            if (head_angle + 180.) > 45.:
                head_angle = ut.azimuth2heading_angle(head_angle)
        else:
            raise ValueError(
                'input geom_obj is neight str nor dict: {}'.format(geom_obj))
        return inc_angle, head_angle
Esempio n. 6
0
 def get_incidence_angle(self, box=None):
     if not self.extraMetadata or 'Y_FIRST' in self.extraMetadata.keys():
         return None
     if 'height' in self.dsNames:
         dem = readfile.read(self.datasetDict['height'], datasetName='height')[0]
     else:
         dem = None
     data = ut.incidence_angle(self.extraMetadata,
                               dem=dem,
                               dimension=2,
                               print_msg=False)
     if box is not None:
         data = data[box[1]:box[3], box[0]:box[2]]
     return data
Esempio n. 7
0
 def get_incidence_angle(self, box=None):
     if not self.extraMetadata or 'Y_FIRST' in self.extraMetadata.keys():
         return None
     if 'height' in self.dsNames:
         dem = readfile.read(self.datasetDict['height'], datasetName='height')[0]
     else:
         dem = None
     data = ut.incidence_angle(self.extraMetadata,
                               dem=dem,
                               dimension=2,
                               print_msg=False)
     if box is not None:
         data = data[box[1]:box[3], box[0]:box[2]]
     return data
Esempio n. 8
0
def get_design_matrix(atr1, atr2, az_angle=90):
    """Get the design matrix A to convert asc/desc to hz/up.
    Only asc + desc -> hz + up is implemented for now.

    Project displacement from LOS to Horizontal and Vertical components:
    Math for 3D:
        Ulos =   sin(inc_angle) * cos(head_angle) * Ux * -1
               + sin(inc_angle) * sin(head_angle) * Uy
               + cos(inc_angle) * Uz
    Math for 2D:
        Ulos =   sin(inc_angle) * sin(head_angle - az) * Uhorz * -1
               + cos(inc_angle) * Uvert
        with Uhorz_perp = 0.0
    This could be easily modified to support multiple view geometry
        (e.g. two adjcent tracks from asc & desc) to resolve 3D

    Parameters: atr1/2   : dict, metadata of input LOS files
                az_angle : float, azimuth angle for the horizontal direction of interest in degrees.
                           Default is 90 (for east-west direction)
    Returns:    A        : 2D matrix in size of (2, 2)

    """
    # degree to radian
    az_angle *= np.pi / 180.

    atr_list = [atr1, atr2]
    A = np.zeros((2, 2))
    for i in range(len(atr_list)):
        atr = atr_list[i]

        # incidence angle
        inc_angle = float(ut.incidence_angle(atr, dimension=0,
                                             print_msg=False))
        print('incidence angle: ' + str(inc_angle))
        inc_angle *= np.pi / 180.

        # heading angle
        head_angle = float(atr['HEADING'])
        if head_angle < 0.:
            head_angle += 360.
        print('heading angle: ' + str(head_angle))
        head_angle *= np.pi / 180.

        # construct design matrix
        A[i, 0] = np.cos(inc_angle)
        A[i, 1] = np.sin(inc_angle) * np.sin(head_angle - az_angle)

    return A
Esempio n. 9
0
def get_design_matrix(atr1, atr2, azimuth=-90):
    """Get the design matrix A to convert asc/desc to hz/up.
    Only asc + desc -> hz + up is implemented for now.

    Project displacement from LOS to Horizontal and Vertical components:
    Math for 3D:
        dLOS =   dE * sin(inc_angle) * sin(az_angle) * -1
               + dN * sin(inc_angle) * cos(az_angle)
               + dU * cos(inc_angle)
    Math for 2D:
        dLOS =   dH * sin(inc_angle) * cos(az_angle - az)
               + dV * cos(inc_angle)
        with dH_perp = 0.0
    This could be easily modified to support multiple view geometry
        (e.g. two adjcent tracks from asc & desc) to resolve 3D

    Parameters: atr1/2   - dict, metadata of input LOS files
                azimuth  - float, azimuth angle for the horizontal direction of interest in degrees.
                           Measured from the north with anti-clockwise direction as positive.
    Returns:    A        - 2D matrix in size of (2, 2)

    """
    # degree to radian
    azimuth *= np.pi / 180.

    atr_list = [atr1, atr2]
    A = np.zeros((2, 2))
    for i in range(len(atr_list)):
        atr = atr_list[i]

        # LOS incidence angle
        los_inc_angle = float(
            ut.incidence_angle(atr, dimension=0, print_msg=False))
        print('LOS incidence angle: {} deg'.format(los_inc_angle))
        los_inc_angle *= np.pi / 180.

        # LOS azimuth angle
        los_az_angle = ut.heading2azimuth_angle(float(atr['HEADING']))
        print('LOS azimuth angle: {} deg'.format(los_az_angle))
        los_az_angle *= np.pi / 180.

        # construct design matrix
        A[i, 0] = np.cos(los_inc_angle)
        A[i, 1] = np.sin(los_inc_angle) * np.cos(los_az_angle - azimuth)

    return A
Esempio n. 10
0
    def get_los_geometry(self, insar_obj, print_msg=False):
        lat, lon = self.get_stat_lat_lon(print_msg=print_msg)

        # get LOS geometry
        if isinstance(insar_obj, str):
            # geometry file
            atr = readfile.read_attribute(insar_obj)
            coord = ut.coordinate(atr, lookup_file=insar_obj)
            y, x = coord.geo2radar(lat, lon, print_msg=print_msg)[0:2]
            box = (x, y, x+1, y+1)
            inc_angle = readfile.read(insar_obj, datasetName='incidenceAngle', box=box, print_msg=print_msg)[0][0,0]
            az_angle  = readfile.read(insar_obj, datasetName='azimuthAngle', box=box, print_msg=print_msg)[0][0,0]
            head_angle = ut.azimuth2heading_angle(az_angle)
        elif isinstance(insar_obj, dict):
            # use mean inc/head_angle from metadata
            inc_angle = ut.incidence_angle(insar_obj, dimension=0, print_msg=print_msg)
            head_angle = float(insar_obj['HEADING'])
            # for old reading of los.rdr band2 data into headingAngle directly
            if (head_angle + 180.) > 45.:
                head_angle = ut.azimuth2heading_angle(head_angle)
        else:
            raise ValueError('input insar_obj is neight str nor dict: {}'.format(insar_obj))
        return inc_angle, head_angle
Esempio n. 11
0
def check_inputs(inps):
    parser = create_parser()

    # output directories/files
    atr = dict()
    mintpy_dir = None
    if inps.timeseries_file:
        atr = readfile.read_attribute(inps.timeseries_file)
        mintpy_dir = os.path.dirname(inps.timeseries_file)
        if not inps.outfile:
            fbase = os.path.splitext(inps.timeseries_file)[0]
            inps.outfile = '{}_{}.h5'.format(fbase, inps.trop_model)
    elif inps.geom_file:
        atr = readfile.read_attribute(inps.geom_file)
        mintpy_dir = os.path.join(os.path.dirname(inps.geom_file), '..')
    else:
        mintpy_dir = os.path.abspath(os.getcwd())

    # trop_file
    inps.trop_file = os.path.join(mintpy_dir, 'inputs/{}.h5'.format(inps.trop_model))
    print('output tropospheric delay file: {}'.format(inps.trop_file))

    # hour
    if not inps.hour:
        if 'CENTER_LINE_UTC' in atr.keys():
            inps.hour = ptime.closest_weather_product_time(atr['CENTER_LINE_UTC'], inps.trop_model)
        else:
            parser.print_usage()
            raise Exception('no input for hour')
    print('time of cloest available product: {}:00 UTC'.format(inps.hour))

    # date list
    if inps.timeseries_file:
        print('read date list from timeseries file: {}'.format(inps.timeseries_file))
        ts_obj = timeseries(inps.timeseries_file)
        ts_obj.open(print_msg=False)
        inps.date_list = ts_obj.dateList
    elif len(inps.date_list) == 1:
        if os.path.isfile(inps.date_list[0]):
            print('read date list from text file: {}'.format(inps.date_list[0]))
            inps.date_list = ptime.yyyymmdd(np.loadtxt(inps.date_list[0],
                                                       dtype=bytes,
                                                       usecols=(0,)).astype(str).tolist())
        else:
            parser.print_usage()
            raise Exception('ERROR: input date list < 2')

    # Grib data directory
    inps.grib_dir = os.path.join(inps.weather_dir, inps.trop_model)
    if not os.path.isdir(inps.grib_dir):
        os.makedirs(inps.grib_dir)
        print('making directory: '+inps.grib_dir)

    # Date list to grib file list
    inps.grib_file_list = date_list2grib_file(inps.date_list,
                                              inps.hour,
                                              inps.trop_model,
                                              inps.grib_dir)

    if 'REF_Y' in atr.keys():
        inps.ref_yx = [int(atr['REF_Y']), int(atr['REF_X'])]
        print('reference pixel: {}'.format(inps.ref_yx))

    # Coordinate system: geocoded or not
    inps.geocoded = False
    if 'Y_FIRST' in atr.keys():
        inps.geocoded = True
    print('geocoded: {}'.format(inps.geocoded))

    # Prepare DEM, inc_angle, lat/lon file for PyAPS to read
    if inps.geom_file:
        geom_obj = geometry(inps.geom_file)
        geom_obj.open()

        print('converting DEM/incAngle for PyAPS to read')
        # DEM
        dem = readfile.read(inps.geom_file, datasetName='height', print_msg=False)[0]
        inps.dem_file = 'pyapsDem.hgt'
        writefile.write(dem, inps.dem_file, metadata=atr)

        # inc_angle
        if 'incidenceAngle' in geom_obj.datasetNames:
            inps.inc_angle = readfile.read(inps.geom_file, datasetName='incidenceAngle', print_msg=False)[0]
        else:
            atr = readfile.read_attribute(inps.timeseries_file)
            inps.inc_angle = ut.incidence_angle(atr, dem=dem, dimension=0)
            inps.inc_angle = np.ones(dem.shape, dtype=np.float32) * inps.inc_angle
        inps.inc_angle_file = 'pyapsIncAngle.flt'
        writefile.write(inps.inc_angle, inps.inc_angle_file, metadata=atr)

        # latitude
        if 'latitude' in geom_obj.datasetNames:
            data = readfile.read(inps.geom_file, datasetName='latitude', print_msg=False)[0]
            print('converting lat for PyAPS to read')
            inps.lat_file = 'pyapsLat.flt'
            writefile.write(data, inps.lat_file, metadata=atr)
        else:
            inps.lat_file = None

        # longitude
        if 'longitude' in geom_obj.datasetNames:
            data = readfile.read(inps.geom_file, datasetName='longitude', print_msg=False)[0]
            print('converting lon for PyAPS to read')
            inps.lon_file = 'pyapsLon.flt'
            writefile.write(data, inps.lon_file, metadata=atr)
        else:
            inps.lon_file = None
    return inps, atr
Esempio n. 12
0
def run_asc_desc2horz_vert(inps):
    """Decompose asc / desc LOS files into horz / vert file(s).
    Parameters: inps         - namespace, input parameters
    Returns:    inps.outfile - str(s) output file(s)
    """

    ## 1. calculate the overlaping area in lat/lon
    atr_list = [
        readfile.read_attribute(fname, datasetName=inps.ds_name)
        for fname in inps.file
    ]
    S, N, W, E = get_overlap_lalo(atr_list)
    lat_step = float(atr_list[0]['Y_STEP'])
    lon_step = float(atr_list[0]['X_STEP'])
    length = int(round((S - N) / lat_step))
    width = int(round((E - W) / lon_step))
    print('overlaping area in SNWE: {}'.format((S, N, W, E)))

    ## 2. read LOS data and geometry
    num_file = len(inps.file)
    num_pixel = length * width
    dlos = np.zeros((num_file, length, width), dtype=np.float32)
    if inps.geom_file:
        los_inc_angle = np.zeros((num_file, length, width), dtype=np.float32)
        los_az_angle = np.zeros((num_file, length, width), dtype=np.float32)
    else:
        los_inc_angle = np.zeros(num_file, dtype=np.float32)
        los_az_angle = np.zeros(num_file, dtype=np.float32)

    for i, (atr, fname) in enumerate(zip(atr_list, inps.file)):
        # overlap SNWE --> box to read for each specific file
        coord = ut.coordinate(atr)
        x0 = coord.lalo2yx(W, coord_type='lon')
        y0 = coord.lalo2yx(N, coord_type='lat')
        box = (x0, y0, x0 + width, y0 + length)

        # read data
        dlos[i, :] = readfile.read(fname, box=box, datasetName=inps.ds_name)[0]
        msg = f'{inps.ds_name} ' if inps.ds_name else ''
        print(f'read {msg} from file: {fname}')

        # read geometry
        if inps.geom_file:
            los_inc_angle[i, :] = readfile.read(
                inps.geom_file[i], box=box, datasetName='incidenceAngle')[0]
            los_az_angle[i, :] = readfile.read(inps.geom_file[i],
                                               box=box,
                                               datasetName='azimuthAngle')[0]
            print(
                f'read 2D LOS incidence / azimuth angles from file: {inps.geom_file[i]}'
            )
        else:
            los_inc_angle[i] = ut.incidence_angle(atr,
                                                  dimension=0,
                                                  print_msg=False)
            los_az_angle[i] = ut.heading2azimuth_angle(float(atr['HEADING']))
            print(
                'calculate the constant LOS incidence / azimuth angles from metadata as:'
            )
            print(f'LOS incidence angle: {los_inc_angle[i]:.1f} deg')
            print(f'LOS azimuth   angle: {los_az_angle[i]:.1f} deg')

    ## 3. decompose LOS displacements into horizontal / Vertical displacements
    print('---------------------')
    dhorz, dvert = asc_desc2horz_vert(dlos, los_inc_angle, los_az_angle,
                                      inps.horz_az_angle)

    ## 4. write outputs
    print('---------------------')
    # Update attributes
    atr = atr_list[0].copy()
    if inps.ds_name and atr['FILE_TYPE'] in [
            'ifgramStack', 'timeseries', 'HDFEOS'
    ]:
        atr['FILE_TYPE'] = 'displacement'

    atr['WIDTH'] = str(width)
    atr['LENGTH'] = str(length)
    atr['X_STEP'] = str(lon_step)
    atr['Y_STEP'] = str(lat_step)
    atr['X_FIRST'] = str(W)
    atr['Y_FIRST'] = str(N)

    # update REF_X/Y
    ref_lat, ref_lon = float(atr['REF_LAT']), float(atr['REF_LON'])
    [ref_y, ref_x] = ut.coordinate(atr).geo2radar(ref_lat, ref_lon)[0:2]
    atr['REF_Y'] = int(ref_y)
    atr['REF_X'] = int(ref_x)

    # use ref_file for time-series file writing
    ref_file = inps.file[0] if atr_list[0][
        'FILE_TYPE'] == 'timeseries' else None

    if inps.one_outfile:
        print('write asc/desc/horz/vert datasets into {}'.format(
            inps.one_outfile))
        dsDict = {}
        for i, atr in enumerate(atr_list):
            # dataset name for LOS data
            track_num = atr.get('trackNumber', None)
            proj_name = atr.get('PROJECT_NAME', None)
            if proj_name in ['none', 'None', None]:
                proj_name = atr.get('FILE_PATH', None)
            proj_name = sensor.project_name2sensor_name(proj_name)[0]

            ds_name = proj_name if proj_name else ''
            ds_name += 'A' if atr['ORBIT_DIRECTION'].lower().startswith(
                'asc') else 'D'
            ds_name += f'T{track_num}' if track_num else ''
            ds_name += '_{}'.format(atr['DATE12'])

            # assign dataset value
            dsDict[ds_name] = dlos[i]
        dsDict['horizontal'] = dhorz
        dsDict['vertical'] = dvert
        writefile.write(dsDict,
                        out_file=inps.one_outfile,
                        metadata=atr,
                        ref_file=ref_file)

    else:
        print('writing horizontal component to file: ' + inps.outfile[0])
        writefile.write(dhorz,
                        out_file=inps.outfile[0],
                        metadata=atr,
                        ref_file=ref_file)
        print('writing vertical   component to file: ' + inps.outfile[1])
        writefile.write(dvert,
                        out_file=inps.outfile[1],
                        metadata=atr,
                        ref_file=ref_file)

    return inps.outfile
Esempio n. 13
0
def main(iargs=None):
    inps = cmd_line_parse(iargs)

    # 1. Extract the common area of two input files
    # Basic info
    atr1 = readfile.read_attribute(inps.file[0])
    atr2 = readfile.read_attribute(inps.file[1])

    # check coordinates
    if any('X_FIRST' not in i for i in [atr1, atr2]):
        raise Exception('Not all input files are geocoded.')
    # check spatial resolution
    if any(atr1[i] != atr2[i] for i in ['X_STEP','Y_STEP']):
        msg = 'file1: {}\n'.format(inps.file[0])
        msg += 'Y_STEP: {} m, X_STEP: {} m\n'.format(atr1['Y_STEP'], atr1['X_STEP'])
        msg += 'file2: {}\n'.format(inps.file[1])
        msg += 'Y_STEP: {} m, X_STEP: {} m'.format(atr2['Y_STEP'], atr2['X_STEP'])
        raise ValueError('input files do not have the same spatial resolution\n{}'.format(msg))

    k1 = atr1['FILE_TYPE']
    print('Input 1st file is '+k1)

    # Common AOI in lalo
    west, east, south, north = get_overlap_lalo(atr1, atr2)
    lon_step = float(atr1['X_STEP'])
    lat_step = float(atr1['Y_STEP'])
    width = int(round((east - west) / lon_step))
    length = int(round((south - north) / lat_step))

    # Read data in common AOI: LOS displacement, heading angle, incident angle
    u_los = np.zeros((2, width*length))
    heading = []
    incidence = []
    for i in range(len(inps.file)):
        fname = inps.file[i]
        print('---------------------')
        print('reading '+fname)
        atr = readfile.read_attribute(fname)

        coord = ut.coordinate(atr)
        [x0, x1] = coord.lalo2yx([west, east], coord_type='lon')
        [y0, y1] = coord.lalo2yx([north, south], coord_type='lat')
        V = readfile.read(fname, box=(x0, y0, x1, y1))[0]
        u_los[i, :] = V.flatten(0)

        heading_angle = float(atr['HEADING'])
        if heading_angle < 0.:
            heading_angle += 360.
        print('heading angle: '+str(heading_angle))
        heading_angle *= np.pi/180.
        heading.append(heading_angle)

        inc_angle = float(ut.incidence_angle(atr, dimension=0))
        inc_angle *= np.pi/180.
        incidence.append(inc_angle)

    # 2. Project displacement from LOS to Horizontal and Vertical components
    # math for 3D: cos(theta)*Uz - cos(alpha)*sin(theta)*Ux + sin(alpha)*sin(theta)*Uy = Ulos
    # math for 2D: cos(theta)*Uv - sin(alpha-az)*sin(theta)*Uh = Ulos   #Uh_perp = 0.0
    # This could be easily modified to support multiple view geometry
    # (e.g. two adjcent tracks from asc & desc) to resolve 3D

    # Design matrix
    A = np.zeros((2, 2))
    for i in range(len(inps.file)):
        A[i, 0] = np.cos(incidence[i])
        A[i, 1] = np.sin(incidence[i]) * np.sin(heading[i]-inps.azimuth)

    A_inv = np.linalg.pinv(A)
    u_vh = np.dot(A_inv, u_los)

    u_v = np.reshape(u_vh[0, :], (length, width))
    u_h = np.reshape(u_vh[1, :], (length, width))

    # 3. Output
    # Attributes
    atr = atr1.copy()
    atr['WIDTH'] = str(width)
    atr['LENGTH'] = str(length)
    atr['X_FIRST'] = str(west)
    atr['Y_FIRST'] = str(north)
    atr['X_STEP'] = str(lon_step)
    atr['Y_STEP'] = str(lat_step)

    print('---------------------')
    horz_file = inps.outfile[0]
    print('writing horizontal component to file: '+horz_file)
    writefile.write(u_h, out_file=horz_file, metadata=atr)

    vert_file = inps.outfile[1]
    print('writing   vertical component to file: '+vert_file)
    writefile.write(u_v, out_file=vert_file, metadata=atr)

    print('Done.')
    return inps.outfile
Esempio n. 14
0
def main(iargs=None):
    inps = cmd_line_parse(iargs)

    # 1. Extract the common area of two input files
    # Basic info
    atr1 = readfile.read_attribute(inps.file[0])
    atr2 = readfile.read_attribute(inps.file[1])
    if any('X_FIRST' not in i for i in [atr1, atr2]):
        raise Exception('ERROR: Not all input files are geocoded.')

    k1 = atr1['FILE_TYPE']
    print('Input 1st file is '+k1)

    # Common AOI in lalo
    west, east, south, north = get_overlap_lalo(atr1, atr2)
    lon_step = float(atr1['X_STEP'])
    lat_step = float(atr1['Y_STEP'])
    width = int(round((east - west) / lon_step))
    length = int(round((south - north) / lat_step))

    # Read data in common AOI: LOS displacement, heading angle, incident angle
    u_los = np.zeros((2, width*length))
    heading = []
    incidence = []
    for i in range(len(inps.file)):
        fname = inps.file[i]
        print('---------------------')
        print('reading '+fname)
        atr = readfile.read_attribute(fname)

        coord = ut.coordinate(atr)
        [x0, x1] = coord.lalo2yx([west, east], coord_type='lon')
        [y0, y1] = coord.lalo2yx([north, south], coord_type='lat')
        V = readfile.read(fname, box=(x0, y0, x1, y1))[0]
        u_los[i, :] = V.flatten(0)

        heading_angle = float(atr['HEADING'])
        if heading_angle < 0.:
            heading_angle += 360.
        print('heading angle: '+str(heading_angle))
        heading_angle *= np.pi/180.
        heading.append(heading_angle)

        inc_angle = float(ut.incidence_angle(atr, dimension=0))
        inc_angle *= np.pi/180.
        incidence.append(inc_angle)

    # 2. Project displacement from LOS to Horizontal and Vertical components
    # math for 3D: cos(theta)*Uz - cos(alpha)*sin(theta)*Ux + sin(alpha)*sin(theta)*Uy = Ulos
    # math for 2D: cos(theta)*Uv - sin(alpha-az)*sin(theta)*Uh = Ulos   #Uh_perp = 0.0
    # This could be easily modified to support multiple view geometry
    # (e.g. two adjcent tracks from asc & desc) to resolve 3D

    # Design matrix
    A = np.zeros((2, 2))
    for i in range(len(inps.file)):
        A[i, 0] = np.cos(incidence[i])
        A[i, 1] = np.sin(incidence[i]) * np.sin(heading[i]-inps.azimuth)

    A_inv = np.linalg.pinv(A)
    u_vh = np.dot(A_inv, u_los)

    u_v = np.reshape(u_vh[0, :], (length, width))
    u_h = np.reshape(u_vh[1, :], (length, width))

    # 3. Output
    # Attributes
    atr = atr1.copy()
    atr['WIDTH'] = str(width)
    atr['LENGTH'] = str(length)
    atr['X_FIRST'] = str(west)
    atr['Y_FIRST'] = str(north)
    atr['X_STEP'] = str(lon_step)
    atr['Y_STEP'] = str(lat_step)

    print('---------------------')
    outname = inps.outfile[0]
    print('writing   vertical component to file: '+outname)
    writefile.write(u_v, out_file=outname, metadata=atr)

    outname = inps.outfile[1]
    print('writing horizontal component to file: '+outname)
    writefile.write(u_h, out_file=outname, metadata=atr)

    print('Done.')
    return