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)
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)
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
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)