Ejemplo n.º 1
0
def _deweight_array(input_data, weight_array, oversample_rate, dimension):
    """
    Uniformly weight complex SAR data along the given dimension.

    Parameters
    ----------
    input_data : numpy.ndarray
    weight_array : numpy.ndarray
    oversample_rate : int|float
    dimension : int

    Returns
    -------
    numpy.ndarray
    """

    if weight_array is None:
        # nothing to be done
        return input_data

    weight_size = round(input_data.shape[dimension]/oversample_rate)
    if weight_array.ndim != 1:
        raise ValueError('weight_array must be one dimensional.')
    if weight_array.size != weight_size:
        weight_array = scipy.signal.resample(weight_array, weight_size)
    weight_ind_start = int_func(numpy.floor(0.5*(input_data.shape[dimension] - weight_size)))
    weight_ind_end = weight_ind_start + weight_size

    output_data = fftshift(fft(input_data, axis=dimension), axes=dimension)
    if dimension == 0:
        output_data[weight_ind_start:weight_ind_end, :] /= weight_array[:, numpy.newaxis]
    else:
        output_data[:, weight_ind_start:weight_ind_end] /= weight_array
    return ifft(ifftshift(output_data, axes=dimension), axis=dimension)
Ejemplo n.º 2
0
def apply_weight_array(input_data,
                       weight_array,
                       oversample_rate,
                       dimension,
                       inverse=False):
    """
    Apply the weight array along the given dimension.

    Parameters
    ----------
    input_data : numpy.ndarray
        The complex data array to weight.
    weight_array : numpy.ndarray
        The weight array.
    oversample_rate : int|float
        The oversample rate.
    dimension : int
        Along which dimension to apply the weighting? Must be one of `{0, 1}`.
    inverse : bool
        If `True`, this divides the weight (i.e. de-weight), otherwise it multiplies.

    Returns
    -------
    numpy.ndarray
    """

    if not (isinstance(input_data, numpy.ndarray) and input_data.ndim == 2):
        raise ValueError('The data array must be two-dimensional')

    if weight_array is None:
        # nothing to be done
        return input_data

    weight_array, weight_ind_start, weight_ind_end = determine_weight_array(
        input_data.shape, weight_array, oversample_rate, dimension)

    if inverse and numpy.any(weight_array == 0):
        raise ValueError(
            'inverse=True and the weight array contains some zero entries.')

    output_data = fftshift(fft(input_data, axis=dimension), axes=dimension)
    if dimension == 0:
        if inverse:
            output_data[weight_ind_start:
                        weight_ind_end, :] /= weight_array[:, numpy.newaxis]
        else:
            output_data[weight_ind_start:
                        weight_ind_end, :] *= weight_array[:, numpy.newaxis]
    else:
        if inverse:
            output_data[:, weight_ind_start:weight_ind_end] /= weight_array
        else:
            output_data[:, weight_ind_start:weight_ind_end] *= weight_array
    return ifft(ifftshift(output_data, axes=dimension), axis=dimension)
Ejemplo n.º 3
0
    def do_dimension(dimension):
        if dimension == 0:
            dir_params = sicd.Grid.Row
            aperture_in = row_aperture
            weighting_in = row_weighting
            dimension_limits = row_limits
        else:
            dir_params = sicd.Grid.Col
            aperture_in = column_aperture
            weighting_in = column_weighting
            dimension_limits = column_limits

        not_skewed = is_not_skewed(sicd, dimension)
        uniform_weight = is_uniform_weight(sicd, dimension)
        delta_kcoa = dir_params.DeltaKCOAPoly.get_array(dtype='float64')

        st_beam_comp = sicd.ImageFormation.STBeamComp if sicd.ImageFormation is not None else None

        if dimension == 1 and (not uniform_weight or weighting_in is not None):
            if st_beam_comp is None:
                logger.warning(
                    'Processing along the column direction requires modification\n\t'
                    'of the original weighting scheme, and the value for\n\t'
                    'ImageFormation.STBeamComp is not populated.\n\t'
                    'It is unclear how imperfect the de-weighting effort along the column may be.'
                )
            elif st_beam_comp == 'NO':
                logger.warning(
                    'Processing along the column direction requires modification\n\t'
                    'of the original weighting scheme, and the value for\n\t'
                    'ImageFormation.STBeamComp is populated as `NO`.\n\t'
                    'It is likely that the de-weighting effort along the column is imperfect.'
                )

        if aperture_in is None and weighting_in is None:
            # nothing to be done in this dimension
            return noise_adjustment_multiplier

        new_weight = None if weighting_in is None else weighting_in['WgtFunct']
        dimension_limits, cur_aperture_limits, cur_weight_function, \
            new_aperture_limits, new_weight_function = aperture_dimension_params(
                old_sicd, dimension, dimension_limits=dimension_limits,
                aperture_limits=aperture_in, new_weight_function=new_weight)
        index_count = dimension_limits[1] - dimension_limits[0]
        cur_center_index = 0.5 * (cur_aperture_limits[0] +
                                  cur_aperture_limits[1])
        new_center_index = 0.5 * (new_aperture_limits[0] +
                                  new_aperture_limits[1])
        noise_multiplier = noise_scaling(cur_aperture_limits,
                                         cur_weight_function,
                                         new_aperture_limits,
                                         new_weight_function)

        # perform deskew, if necessary
        if not not_skewed:
            if dimension == 0:
                row_array = get_direction_array_meters(0, 0, out_data_shape[0])
                for (_start_ind, _stop_ind) in col_iterations:
                    col_array = get_direction_array_meters(
                        1, _start_ind, _stop_ind)
                    working_data[:, _start_ind:_stop_ind] = apply_skew_poly(
                        working_data[:, _start_ind:_stop_ind],
                        delta_kcoa,
                        row_array,
                        col_array,
                        dir_params.Sgn,
                        0,
                        forward=False)
            else:
                col_array = get_direction_array_meters(1, 0, out_data_shape[1])
                for (_start_ind, _stop_ind) in row_iterations:
                    row_array = get_direction_array_meters(
                        0, _start_ind, _stop_ind)
                    working_data[_start_ind:_stop_ind, :] = apply_skew_poly(
                        working_data[_start_ind:_stop_ind, :],
                        delta_kcoa,
                        row_array,
                        col_array,
                        dir_params.Sgn,
                        1,
                        forward=False)

        # perform fourier transform along the given dimension
        if dimension == 0:
            for (_start_ind, _stop_ind) in col_iterations:
                working_data[:, _start_ind:_stop_ind] = fftshift(
                    fft_sicd(working_data[:, _start_ind:_stop_ind], dimension,
                             sicd),
                    axes=dimension)
        else:
            for (_start_ind, _stop_ind) in row_iterations:
                working_data[_start_ind:_stop_ind, :] = fftshift(
                    fft_sicd(working_data[_start_ind:_stop_ind, :], dimension,
                             sicd),
                    axes=dimension)

        # perform deweight, if necessary
        if not uniform_weight:
            if dimension == 0:
                working_data[cur_aperture_limits[0]:cur_aperture_limits[
                    1], :] /= cur_weight_function[:, numpy.newaxis]
            else:
                working_data[:, cur_aperture_limits[0]:
                             cur_aperture_limits[1]] /= cur_weight_function

        # do sub-aperture, if necessary
        if aperture_in is not None:
            if dimension == 0:
                working_data[:new_aperture_limits[0], :] = 0
                working_data[new_aperture_limits[1]:, :] = 0
            else:
                working_data[:, :new_aperture_limits[0]] = 0
                working_data[:, new_aperture_limits[1]:] = 0

            the_ratio = float(new_aperture_limits[1] - new_aperture_limits[0]) / \
                float(cur_aperture_limits[1] - cur_aperture_limits[0])
            # modify the ImpRespBW value (derived ImpRespWid handled at the end)
            dir_params.ImpRespBW *= the_ratio

        # perform reweight, if necessary
        if weighting_in is not None:
            if dimension == 0:
                working_data[new_aperture_limits[0]:new_aperture_limits[
                    1], :] *= new_weight_function[:, numpy.newaxis]
            else:
                working_data[:, new_aperture_limits[0]:
                             new_aperture_limits[1]] *= new_weight_function
            # modify the weight definition
            dir_params.WgtType = WgtTypeType(
                WindowName=weighting_in['WindowName'],
                Parameters=weighting_in.get('Parameters', None))
            dir_params.WgtFunct = weighting_in['WgtFunct'].copy()
        elif not uniform_weight:
            if dimension == 0:
                working_data[new_aperture_limits[0]:new_aperture_limits[
                    1], :] *= new_weight_function[:, numpy.newaxis]
            else:
                working_data[:, new_aperture_limits[0]:
                             new_aperture_limits[1]] *= new_weight_function

        # perform inverse fourier transform along the given dimension
        if dimension == 0:
            for (_start_ind, _stop_ind) in col_iterations:
                working_data[:, _start_ind:_stop_ind] = ifft_sicd(
                    ifftshift(working_data[:, _start_ind:_stop_ind],
                              axes=dimension), dimension, sicd)
        else:
            for (_start_ind, _stop_ind) in row_iterations:
                working_data[_start_ind:_stop_ind, :] = ifft_sicd(
                    ifftshift(working_data[_start_ind:_stop_ind, :],
                              axes=dimension), dimension, sicd)

        # perform the (original) reskew, if necessary
        if not numpy.all(delta_kcoa == 0):
            if dimension == 0:
                row_array = get_direction_array_meters(0, 0, out_data_shape[0])
                for (_start_ind, _stop_ind) in col_iterations:
                    col_array = get_direction_array_meters(
                        1, _start_ind, _stop_ind)
                    working_data[:, _start_ind:_stop_ind] = apply_skew_poly(
                        working_data[:, _start_ind:_stop_ind],
                        delta_kcoa,
                        row_array,
                        col_array,
                        dir_params.Sgn,
                        0,
                        forward=True)
            else:
                col_array = get_direction_array_meters(1, 0, out_data_shape[1])
                for (_start_ind, _stop_ind) in row_iterations:
                    row_array = get_direction_array_meters(
                        0, _start_ind, _stop_ind)
                    working_data[_start_ind:_stop_ind, :] = apply_skew_poly(
                        working_data[_start_ind:_stop_ind, :],
                        delta_kcoa,
                        row_array,
                        col_array,
                        dir_params.Sgn,
                        1,
                        forward=True)

        # modify the delta_kcoa_poly - introduce the shift necessary for additional offset
        if new_center_index != cur_center_index:
            additional_shift = dir_params.Sgn * (
                cur_center_index - new_center_index) / float(
                    index_count * dir_params.SS)
            delta_kcoa[0, 0] += additional_shift
            dir_params.DeltaKCOAPoly = delta_kcoa

        return noise_adjustment_multiplier * noise_multiplier
Ejemplo n.º 4
0
    def do_dimension(dimension):
        if dimension == 0:
            dir_params = sicd.Grid.Row
            aperture_in = row_aperture
            weighting_in = row_weighting
            index_count = sicd.ImageData.NumRows
        else:
            dir_params = sicd.Grid.Col
            aperture_in = column_aperture
            weighting_in = column_weighting
            index_count = sicd.ImageData.NumCols

        not_skewed = is_not_skewed(sicd, dimension)
        uniform_weight = is_uniform_weight(sicd, dimension)
        delta_kcoa = dir_params.DeltaKCOAPoly.get_array(dtype='float64')

        st_beam_comp = sicd.ImageFormation.STBeamComp if sicd.ImageFormation is not None else None

        if dimension == 1 and (not uniform_weight or weighting_in is not None):
            if st_beam_comp is None:
                logger.warning(
                    'Processing along the column direction requires modification\n\t'
                    'of the original weighting scheme, and the value for\n\t'
                    'ImageFormation.STBeamComp is not populated.\n\t'
                    'It is unclear how imperfect the de-weighting effort along the column may be.'
                )
            elif st_beam_comp == 'NO':
                logger.warning(
                    'Processing along the column direction requires modification\n\t'
                    'of the original weighting scheme, and the value for\n\t'
                    'ImageFormation.STBeamComp is populated as `NO`.\n\t'
                    'It is likely that the de-weighting effort along the column is imperfect.'
                )

        if aperture_in is None and weighting_in is None:
            # nothing to be done in this dimension
            return

        oversample = max(1., 1. / (dir_params.SS * dir_params.ImpRespBW))

        old_weight, start_index, end_index = determine_weight_array(
            out_data_shape, dir_params.WgtFunct.copy(), oversample, dimension)
        center_index = 0.5 * (start_index + end_index)

        # perform deskew, if necessary
        if not not_skewed:
            if dimension == 0:
                row_array = get_direction_array_meters(0, 0, out_data_shape[0])
                for (_start_ind, _stop_ind) in col_iterations:
                    col_array = get_direction_array_meters(
                        1, _start_ind, _stop_ind)
                    working_data[:, _start_ind:_stop_ind] = apply_skew_poly(
                        working_data[:, _start_ind:_stop_ind],
                        delta_kcoa,
                        row_array,
                        col_array,
                        dir_params.Sgn,
                        0,
                        forward=False)
            else:
                col_array = get_direction_array_meters(1, 0, out_data_shape[1])
                for (_start_ind, _stop_ind) in row_iterations:
                    row_array = get_direction_array_meters(
                        0, _start_ind, _stop_ind)
                    working_data[_start_ind:_stop_ind, :] = apply_skew_poly(
                        working_data[_start_ind:_stop_ind, :],
                        delta_kcoa,
                        row_array,
                        col_array,
                        dir_params.Sgn,
                        1,
                        forward=False)

        # perform fourier transform along the given dimension
        if dimension == 0:
            for (_start_ind, _stop_ind) in col_iterations:
                working_data[:, _start_ind:_stop_ind] = fftshift(
                    fft_sicd(working_data[:, _start_ind:_stop_ind], dimension,
                             sicd),
                    axes=dimension)
        else:
            for (_start_ind, _stop_ind) in row_iterations:
                working_data[_start_ind:_stop_ind, :] = fftshift(
                    fft_sicd(working_data[_start_ind:_stop_ind, :], dimension,
                             sicd),
                    axes=dimension)

        # perform deweight, if necessary
        if not uniform_weight:
            if dimension == 0:
                working_data[
                    start_index:end_index, :] /= old_weight[:, numpy.newaxis]
            else:
                working_data[:, start_index:end_index] /= old_weight

        # do sub-aperture, if necessary
        if aperture_in is not None:
            new_start_index = max(int(aperture_in[0]), start_index)
            new_end_index = min(int(aperture_in[1]), end_index)
            new_center_index = 0.5 * (new_start_index + new_end_index)
            if dimension == 0:
                working_data[:new_start_index, :] = 0
                working_data[new_end_index:, :] = 0
            else:
                working_data[:, :new_start_index] = 0
                working_data[:, new_end_index:] = 0

            new_oversample = oversample * float(
                end_index - start_index) / float(new_end_index -
                                                 new_start_index)
            the_ratio = new_oversample / oversample
            # modify the ImpRespBW value (derived ImpRespWid handled at the end)
            dir_params.ImpRespBW /= the_ratio
        else:
            new_center_index = center_index
            new_oversample = oversample

        # perform reweight, if necessary
        if weighting_in is not None:
            new_weight, start_index, end_index = determine_weight_array(
                out_data_shape, weighting_in['WgtFunction'].copy(),
                new_oversample, dimension)
            start_index += int(new_center_index - center_index)
            end_index += int(new_center_index - center_index)

            if dimension == 0:
                working_data[
                    start_index:end_index, :] *= new_weight[:, numpy.newaxis]
            else:
                working_data[:, start_index:end_index] *= new_weight
            # modify the weight definition
            dir_params.WgtType = WgtTypeType(
                WindowName=weighting_in['WindowName'],
                Parameters=weighting_in.get('Parameters', None))
            dir_params.WgtFunct = weighting_in['WgtFunction'].copy()
        elif not uniform_weight:
            # weight remained the same, and it's not uniform
            new_weight, start_index, end_index = determine_weight_array(
                out_data_shape, dir_params.WgtFunct.copy(), new_oversample,
                dimension)
            if dimension == 0:
                working_data[
                    start_index:end_index, :] *= new_weight[:, numpy.newaxis]
            else:
                working_data[:, start_index:end_index] *= new_weight

        # perform inverse fourier transform along the given dimension
        if dimension == 0:
            for (_start_ind, _stop_ind) in col_iterations:
                working_data[:, _start_ind:_stop_ind] = ifft_sicd(
                    ifftshift(working_data[:, _start_ind:_stop_ind],
                              axes=dimension), dimension, sicd)
        else:
            for (_start_ind, _stop_ind) in row_iterations:
                working_data[_start_ind:_stop_ind, :] = ifft_sicd(
                    ifftshift(working_data[_start_ind:_stop_ind, :],
                              axes=dimension), dimension, sicd)

        # perform the (original) reskew, if necessary
        if not numpy.all(delta_kcoa == 0):
            if dimension == 0:
                row_array = get_direction_array_meters(0, 0, out_data_shape[0])
                for (_start_ind, _stop_ind) in col_iterations:
                    col_array = get_direction_array_meters(
                        1, _start_ind, _stop_ind)
                    working_data[:, _start_ind:_stop_ind] = apply_skew_poly(
                        working_data[:, _start_ind:_stop_ind],
                        delta_kcoa,
                        row_array,
                        col_array,
                        dir_params.Sgn,
                        0,
                        forward=True)
            else:
                col_array = get_direction_array_meters(1, 0, out_data_shape[1])
                for (_start_ind, _stop_ind) in row_iterations:
                    row_array = get_direction_array_meters(
                        0, _start_ind, _stop_ind)
                    working_data[_start_ind:_stop_ind, :] = apply_skew_poly(
                        working_data[_start_ind:_stop_ind, :],
                        delta_kcoa,
                        row_array,
                        col_array,
                        dir_params.Sgn,
                        1,
                        forward=True)

        # modify the delta_kcoa_poly - introduce the shift necessary for additional offset
        if center_index != new_center_index:
            additional_shift = dir_params.Sgn * (
                center_index - new_center_index) / float(
                    index_count * dir_params.SS)
            delta_kcoa[0, 0] += additional_shift
            dir_params.DeltaKCOAPoly = delta_kcoa

        # re-derive the various ImpResp parameters
        sicd.Grid.derive_direction_params(sicd.ImageData, populate=True)