Esempio n. 1
0
def _stft(data, sampling_rate):
    """
    Take the specified short time fourier transform of the provided data.

    Parameters
    ----------
    data : numpy.ndarray
        Must be one-dimensional
    sampling_rate : float
        The sampling rate.

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

    if not (isinstance(data, numpy.ndarray) and data.ndim == 1):
        raise ValueError(
            'This short time fourier transform function only applies to a '
            'one-dimensional numpy array')

    nfft = 2**int(numpy.ceil(numpy.log2(numpy.sqrt(data.shape[0]))) + 2)
    nperseg = int(0.97 * nfft)
    window = kaiser(nperseg, 5)
    noverlap = int(0.9 * nfft)
    frequencies, times, trans_data = spectrogram(data,
                                                 sampling_rate,
                                                 window=window,
                                                 nperseg=nperseg,
                                                 noverlap=noverlap,
                                                 nfft=nfft,
                                                 return_onesided=False)
    return times, fftshift(frequencies, axes=0), fftshift(trans_data, axes=0)
Esempio n. 2
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)
Esempio n. 3
0
def subaperture_processing_array(array,
                                 aperture_indices,
                                 output_resolution,
                                 dimension=0):
    """
    Perform the sub-aperture processing on the given complex array data.

    Parameters
    ----------
    array : numpy.ndarray
        The complex array data. Dimension other than 2 is not supported.
    aperture_indices : Tuple[int, int]
        The start/stop indices for the subaperture processing.
    output_resolution : int
        The output resolution parameter.
    dimension : int
        The dimension along which to perform the sub-aperture processing. Must be
        one of 0 or 1.

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

    array = _validate_input(array)
    dimension = _validate_dimension(dimension)

    return subaperture_processing_phase_history(fftshift(fft(array,
                                                             axis=dimension),
                                                         axes=dimension),
                                                aperture_indices,
                                                output_resolution,
                                                dimension=dimension)
Esempio n. 4
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)
Esempio n. 5
0
    def _get_fft_complex_data(self, cdata):
        """
        Transform the complex image data to phase history data.

        Parameters
        ----------
        cdata : numpy.ndarray

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

        return fftshift(fft2_sicd(cdata, self.sicd))
Esempio n. 6
0
def create_deskewed_transform(reader, dimension=0, suffix='.sarpy.cache'):
    """
    Performs the Fourier transform of the deskewed entirety of the given
    ComplexImageReader contents.

    Parameters
    ----------
    reader : SICDTypeCanvasImageReader
        The reader object.
    dimension : int
        One of [0, 1], which dimension to deskew along.
    suffix : None|str
        The suffix for the created file name (created using the tempfile module).

    Returns
    -------
    (str, numpy.ndarray, numpy.ndarray)
        A file name, numpy memmap of the given object, and mean along the given dimension.
        Care should be taken to ensure that the file is deleted when the usage is complete.
    """

    # set up a true file for the memmap
    # NB: it should be noted that the tempfile usage which clean themselves up
    #     cannot (as of 2021-04-23) be opened multiple times on Windows, which
    #     means that such a "file" cannot be used in conjunction with a numpy
    #     memmap.
    data_size = reader.data_size
    sicd = reader.get_sicd()
    _, file_name = mkstemp(suffix=suffix, text=False)
    logger.debug('Creating temp file % s' % file_name)
    # set up the memmap
    memmap = numpy.memmap(file_name, dtype='complex64', mode='r+', offset=0, shape=data_size)
    calculator = DeskewCalculator(
        reader.base_reader, dimension=dimension, index=reader.index,
        apply_deskew=True, apply_deweighting=False, apply_off_axis=False)
    mean_value = numpy.zeros((data_size[0], ), dtype='float64') if dimension == 0 else \
        numpy.zeros((data_size[1],), dtype='float64')

    # we'll proceed in blocks of approximately this number of pixels
    pixels_threshold = 2**20
    # is our whole reader sufficiently small to just do it all in one fell-swoop?
    if data_size[0]*data_size[1] <= 4*pixels_threshold:
        data = fftshift(fft2_sicd(calculator[:, :], sicd))
        memmap[:, :] = data
        mean_value[:] = numpy.mean(numpy.abs(data), axis=1-dimension)
        return file_name, memmap, mean_value

    # fetch full rows, and transform then shift along the row direction
    block_size = int(numpy.ceil(pixels_threshold/data_size[1]))
    start_col = 0
    while start_col < data_size[1]:
        end_col = min(start_col+block_size, data_size[1])
        data = fftshift(fft_sicd(calculator[:, start_col:end_col], 0, sicd), axes=0)
        memmap[:, start_col:end_col] = data
        if dimension == 0:
            mean_value += numpy.sum(numpy.abs(data), axis=1)
        start_col = end_col
    # fetch full columns, and transform then shift along the column direction
    block_size = int(numpy.ceil(pixels_threshold/data_size[0]))
    start_row = 0
    while start_row < data_size[0]:
        end_row = min(start_row+block_size, data_size[0])
        data = fftshift(fft_sicd(memmap[start_row:end_row, :], 1, sicd), axes=1)
        memmap[start_row:end_row, :] = data
        if dimension == 1:
            mean_value += numpy.sum(numpy.abs(data), axis=0)
        start_row = end_row

    if dimension == 0:
        mean_value /= data_size[1]
    else:
        mean_value /= data_size[0]
    return file_name, memmap, mean_value
Esempio n. 7
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
Esempio n. 8
0
def csi_array(array, dimension=0, platform_direction='R', fill=1, filter_map=None):
    """
    Creates a color subaperture array from a complex array.

    .. Note: this ignores any potential sign issues for the fft and ifft, because
        the results would be identical - fft followed by ifft versus ifft followed
        by fft.

    Parameters
    ----------
    array : numpy.ndarray
        The complex valued SAR data, assumed to be in the "image" domain.
        Required to be two-dimensional.
    dimension : int
        The dimension over which to split the sub-aperture.
    platform_direction : str
        The (case insensitive) platform direction, required to be one of `('R', 'L')`.
    fill : float
        The fill factor. This will be ignored if `filter_map` is provided.
    filter_map : None|numpy.ndarray
        The RGB filter mapping. This is assumed constructed using :func:`filter_map_construction`.

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

    if not (isinstance(array, numpy.ndarray) and len(array.shape) == 2 and numpy.iscomplexobj(array)):
        raise ValueError('array must be a two-dimensional numpy array of complex dtype')

    dimension = int_func(dimension)
    if dimension not in [0, 1]:
        raise ValueError('dimension must be 0 or 1, got {}'.format(dimension))
    if dimension == 0:
        array = array.T

    pdir_func = platform_direction.upper()[0]
    if pdir_func not in ['R', 'L']:
        raise ValueError('It is expected that pdir is one of "R" or "L". Got {}'.format(platform_direction))

    # get our filter construction data
    if filter_map is None:
        fill = max(1.0, float(fill))
        filter_map = filter_map_construction(array.shape[1]/fill)
    if not (isinstance(filter_map, numpy.ndarray) and
            filter_map.dtype.name in ['float32', 'float64'] and
            filter_map.ndim == 2 and filter_map.shape[1] == 3):
        raise ValueError('filter_map must be a N x 3 numpy array of float dtype.')

    # move to phase history domain
    ph_indices = int(numpy.floor(0.5*(array.shape[1] - filter_map.shape[0]))) + \
                 numpy.arange(filter_map.shape[0], dtype=numpy.int32)
    ph0 = fftshift(ifft(numpy.cast[numpy.complex128](array), axis=1), axes=1)[:, ph_indices]
    # construct the filtered workspace
    # NB: processing is more efficient with color band in the first dimension
    ph0_RGB = numpy.zeros((3, array.shape[0], filter_map.shape[0]), dtype=numpy.complex128)
    for i in range(3):
        ph0_RGB[i, :, :] = ph0*filter_map[:, i]
    del ph0

    # Shift phase history to avoid having zeropad in middle of filter, to alleviate
    # the purple sidelobe artifact.
    filter_shift = int(numpy.ceil(0.25*filter_map.shape[0]))
    ph0_RGB[0, :] = numpy.roll(ph0_RGB[0, :], -filter_shift)
    ph0_RGB[2, :] = numpy.roll(ph0_RGB[2, :], filter_shift)
    # NB: the green band is already centered

    # FFT back to the image domain
    im0_RGB = fft(fftshift(ph0_RGB, axes=2), n=array.shape[1], axis=2)
    del ph0_RGB

    # Replace the intensity with the original image intensity to main full resolution
    # (in intensity, but not in color).
    scale_factor = numpy.abs(array)/numpy.abs(im0_RGB).max(axis=0)
    im0_RGB = numpy.abs(im0_RGB)*scale_factor

    # reorient image so that the color segment is in the final dimension
    if dimension == 0:
        im0_RGB = im0_RGB.transpose([2, 1, 0])
    else:
        im0_RGB = im0_RGB.transpose([1, 2, 0])
    if pdir_func == 'R':
        # reverse the color band order
        im0_RGB = im0_RGB[:, :, ::-1]
    return im0_RGB
Esempio n. 9
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)
Esempio n. 10
0
    def update_displayed_selection(self):
        def get_extent(coords):
            return min(coords[0::2]), max(coords[0::2]), min(coords[1::2]), max(coords[1::2])

        def draw_row_delta_lines():
            deltak1 = (row_count - 1)*(0.5 + the_sicd.Grid.Row.SS*the_sicd.Grid.Row.DeltaK1) + 1
            deltak2 = (row_count - 1)*(0.5 + the_sicd.Grid.Row.SS*the_sicd.Grid.Row.DeltaK2) + 1

            self.frequency_panel.canvas.modify_existing_shape_using_image_coords(
                self.variables.row_deltak1, (deltak1, 0, deltak1, col_count))
            self.frequency_panel.canvas.modify_existing_shape_using_image_coords(
                self.variables.row_deltak2, (deltak2, 0, deltak2, col_count))

        def draw_col_delta_lines():
            deltak1 = (col_count - 1)*(0.5 + the_sicd.Grid.Col.SS*the_sicd.Grid.Col.DeltaK1) + 1
            deltak2 = (col_count - 1)*(0.5 + the_sicd.Grid.Col.SS*the_sicd.Grid.Col.DeltaK2) + 1

            self.frequency_panel.canvas.modify_existing_shape_using_image_coords(
                self.variables.col_deltak1, (0, deltak1, row_count, deltak1))
            self.frequency_panel.canvas.modify_existing_shape_using_image_coords(
                self.variables.col_deltak2, (0, deltak2, row_count, deltak2))

        def draw_row_bandwidth_lines():
            try:
                delta_kcoa_center = the_sicd.Grid.Row.DeltaKCOAPoly(row_phys, col_phys)
            except Exception:
                delta_kcoa_center = 0.0

            row_bw_low = (row_count - 1)*(
                    0.5 + the_sicd.Grid.Row.SS*(delta_kcoa_center - 0.5*the_sicd.Grid.Row.ImpRespBW)) + 1
            row_bw_high = (row_count - 1)*(
                    0.5 + the_sicd.Grid.Row.SS*(delta_kcoa_center + 0.5*the_sicd.Grid.Row.ImpRespBW)) + 1

            row_bw_low = (row_bw_low % row_count)
            row_bw_high = (row_bw_high % row_count)

            self.frequency_panel.canvas.modify_existing_shape_using_image_coords(
                self.variables.row_line_low, (row_bw_low, 0, row_bw_low, col_count))
            self.frequency_panel.canvas.modify_existing_shape_using_image_coords(
                self.variables.row_line_high, (row_bw_high, 0, row_bw_high, col_count))

        def draw_col_bandwidth_lines():
            try:
                delta_kcoa_center = the_sicd.Grid.Col.DeltaKCOAPoly(row_phys, col_phys)
            except Exception:
                delta_kcoa_center = 0.0

            col_bw_low = (col_count - 1) * (
                    0.5 + the_sicd.Grid.Col.SS*(delta_kcoa_center - 0.5*the_sicd.Grid.Col.ImpRespBW)) + 1
            col_bw_high = (col_count - 1) * (
                    0.5 + the_sicd.Grid.Col.SS*(delta_kcoa_center + 0.5*the_sicd.Grid.Col.ImpRespBW)) + 1

            col_bw_low = (col_bw_low % col_count)
            col_bw_high = (col_bw_high % col_count)

            self.frequency_panel.canvas.modify_existing_shape_using_image_coords(
                self.variables.col_line_low, (0, col_bw_low, row_count, col_bw_low))
            self.frequency_panel.canvas.modify_existing_shape_using_image_coords(
                self.variables.col_line_high, (0, col_bw_high, row_count, col_bw_high))

        threshold = self.image_panel.canvas.variables.config.select_size_threshold
        select_id = self.image_panel.canvas.variables.select_rect.uid
        rect_coords = self.image_panel.canvas.get_shape_image_coords(select_id)
        extent = get_extent(rect_coords)  # left, right, bottom, top
        row_count = extent[1] - extent[0]
        col_count = extent[3] - extent[2]

        the_sicd = self.variables.image_reader.get_sicd()
        row_phys, col_phys = get_physical_coordinates(
            the_sicd, 0.5*(extent[0]+extent[1]), 0.5*(extent[2]+extent[3]))

        if row_count < threshold or col_count < threshold:
            junk_data = numpy.zeros((100, 100), dtype='uint8')
            self.frequency_panel.set_image_reader(NumpyImageReader(junk_data))
            self._initialize_bandwidth_lines()
        else:
            image_data = self.variables.image_reader.base_reader[extent[0]:extent[1], extent[2]:extent[3]]
            if image_data is not None:
                self.frequency_panel.set_image_reader(
                    NumpyImageReader(remap.density(fftshift(fft2_sicd(image_data, the_sicd)))))
                self._initialize_bandwidth_lines()
                draw_row_delta_lines()
                draw_col_delta_lines()
                draw_row_bandwidth_lines()
                draw_col_bandwidth_lines()
            else:
                junk_data = numpy.zeros((100, 100), dtype='uint8')
                self.frequency_panel.set_image_reader(NumpyImageReader(junk_data))
                self._initialize_bandwidth_lines()
Esempio n. 11
0
    def subaperture_generator(self, row_range, col_range, frames=None):
        # type: (tuple, tuple, Union[None, int, list, tuple, numpy.ndarray]) -> Generator[numpy.ndarray]
        """
        Supplies a generator for the given row and column ranges and frames collection.
        **Note that this IGNORES the block_size parameter in fetching, and fetches the
        entire required block.**

        The full resolution data in the processing dimension is required, even if
        down-sampled by the row_range or col_range parameter.

        Parameters
        ----------
        row_range : Tuple[int, int, int]
            The row range.
        col_range : Tuple[int, int, int]
            The column range.
        frames : None|int|list|tuple|numpy.ndarray
            The frame or frame collection.

        Returns
        -------
        Generator[numpy.ndarray]
        """
        def get_dimension_details(the_range):
            the_snip = -1 if the_range[2] < 0 else 1
            t_full_range = (the_range[0], the_range[1], the_snip)
            t_full_size = the_range[1] - the_range[0]
            t_step = abs(the_range[2])
            return t_full_range, t_full_size, t_step

        if self._fill is None:
            raise ValueError(
                'Unable to proceed unless the index and dimension are set.')

        frames = self._parse_frame_argument(frames)
        if isinstance(frames, integer_types):
            frames = [
                frames,
            ]

        if self.dimension == 0:
            # determine the full resolution block of data to fetch
            this_row_range, full_size, step = get_dimension_details(row_range)
            # fetch the necessary data block
            data = self.reader[
                this_row_range[0]:this_row_range[1]:this_row_range[2],
                col_range[0]:col_range[1]:col_range[2], self.index]
        else:
            # determine the full resolution block of data to fetch
            this_col_range, full_size, step = get_dimension_details(col_range)
            # fetch the necessary data block, and transform to phase space
            data = self.reader[
                row_range[0]:row_range[1]:row_range[2],
                this_col_range[0]:this_col_range[1]:this_col_range[2],
                self.index]
        # handle any nonsense data as 0
        data[~numpy.isfinite(data)] = 0
        # transform the data to phase space
        data = fftshift(fft(data, axis=self.dimension), axes=self.dimension)
        # define our frame collection
        frame_collection, output_resolution = frame_definition(
            full_size,
            frame_count=self.frame_count,
            aperture_fraction=self.aperture_fraction,
            fill=self.fill,
            method=self.method)
        # iterate over frames and generate the results
        for frame_index in frames:
            frame_def = frame_collection[int_func(frame_index)]
            this_subap_data = subaperture_processing_phase_history(
                data,
                frame_def,
                output_resolution=output_resolution,
                dimension=self.dimension)
            if step == 1:
                yield this_subap_data
            elif self.dimension == 0:
                yield this_subap_data[::step, :]
            else:
                yield this_subap_data[:, ::step]