Ejemplo n.º 1
0
        def get_grid():
            # type: () -> GridType
            time_coa_poly = Poly2DType(Coefs=time_coa_poly_coeffs)
            if collect_info.RadarMode.ModeType == 'SPOTLIGHT':
                time_coa_poly = Poly2DType(Coefs=[[float(time_coa_poly_coeffs[0, 0]), ], ])

            row_win = _stringify(hf['window_function_range'][()])
            if row_win == 'NONE':
                row_win = 'UNIFORM'
            row = DirParamType(
                SS=row_ss,
                Sgn=-1,
                KCtr=2*center_freq/speed_of_light,
                ImpRespBW=2*tx_bandwidth/speed_of_light,
                DeltaKCOAPoly=Poly2DType(Coefs=[[0,]]),
                WgtType=WgtTypeType(WindowName=row_win))
            col_win = _stringify(hf['window_function_azimuth'][()])
            if col_win == 'NONE':
                col_win = 'UNIFORM'
            col = DirParamType(
                SS=col_ss,
                Sgn=-1,
                KCtr=0,
                ImpRespBW=col_imp_res_bw,
                WgtType=WgtTypeType(WindowName=col_win),
                DeltaKCOAPoly=Poly2DType(Coefs=dop_centroid_poly_coeffs*ss_zd_s/col_ss))
            return GridType(
                Type='RGZERO',
                ImagePlane='SLANT',
                TimeCOAPoly=time_coa_poly,
                Row=row,
                Col=col)
Ejemplo n.º 2
0
        def update_inca_and_grid():
            t_sicd.RMA.INCA.R_CA_SCP = r_ca_sampled[t_sicd.ImageData.SCPPixel.Row]
            scp_ca_time = zd_time[t_sicd.ImageData.SCPPixel.Col]

            # compute DRateSFPoly
            # velocity at scp ca time
            vel_ca = t_sicd.Position.ARPPoly.derivative_eval(scp_ca_time, der_order=1)
            # squared magnitude
            vm_ca_sq = numpy.sum(vel_ca*vel_ca)
            # polynomial coefficient for function representing range as a function of range distance from SCP
            r_ca_poly = numpy.array([t_sicd.RMA.INCA.R_CA_SCP, 1], dtype=numpy.float64)
            # closest Doppler rate polynomial to SCP
            min_ind = numpy.argmin(numpy.absolute(grid_zd_time - scp_ca_time))
            # define range coordinate grid
            coords_rg_m = grid_r - t_sicd.RMA.INCA.R_CA_SCP
            # determine dop_rate_poly coordinates
            dop_rate_poly = polynomial.polyfit(coords_rg_m, -doprate_sampled[min_ind, :], 4)  # why fourth order?
            t_sicd.RMA.INCA.FreqZero = center_freq
            t_sicd.RMA.INCA.DRateSFPoly = Poly2DType(Coefs=numpy.reshape(
                -numpy.convolve(dop_rate_poly, r_ca_poly)*speed_of_light/(2*center_freq*vm_ca_sq), (-1, 1)))

            # update Grid.Col parameters
            t_sicd.Grid.Col.SS = numpy.sqrt(vm_ca_sq)*abs(ss_az_s)*t_sicd.RMA.INCA.DRateSFPoly.Coefs[0, 0]
            t_sicd.Grid.Col.ImpRespBW = min(abs(dop_bw*ss_az_s), 1)/t_sicd.Grid.Col.SS
            t_sicd.RMA.INCA.TimeCAPoly = [scp_ca_time, ss_az_s/t_sicd.Grid.Col.SS]

            #TimeCOAPoly/DopCentroidPoly/DeltaKCOAPoly
            coords_az_m = (grid_zd_time - scp_ca_time)*t_sicd.Grid.Col.SS/ss_az_s

            # cerate the 2d grids
            coords_rg_2d_t, coords_az_2d_t = numpy.meshgrid(coords_rg_m, coords_az_m, indexing='xy')

            coefs, residuals, rank, sing_values = two_dim_poly_fit(
                coords_rg_2d_t, coords_az_2d_t, dopcentroid_sampled,
                x_order=3, y_order=3, x_scale=1e-3, y_scale=1e-3, rcond=1e-40)
            logger.info(
                'The dop_centroid_poly fit details:\n\t'
                'root mean square residuals = {}\n\t'
                'rank = {}\n\t'
                'singular values = {}'.format(residuals, rank, sing_values))
            t_sicd.RMA.INCA.DopCentroidPoly = Poly2DType(Coefs=coefs)
            t_sicd.Grid.Col.DeltaKCOAPoly = Poly2DType(Coefs=coefs*ss_az_s/t_sicd.Grid.Col.SS)

            timeca_sampled = numpy.outer(grid_zd_time, numpy.ones((grid_r.size, )))
            time_coa_sampled = timeca_sampled + (dopcentroid_sampled/doprate_sampled)
            coefs, residuals, rank, sing_values = two_dim_poly_fit(
                coords_rg_2d_t, coords_az_2d_t, time_coa_sampled,
                x_order=3, y_order=3, x_scale=1e-3, y_scale=1e-3, rcond=1e-40)
            logger.info(
                'The time_coa_poly fit details:\n\t'
                'root mean square residuals = {}\n\t'
                'rank = {}\n\t'
                'singular values = {}'.format(residuals, rank, sing_values))
            t_sicd.Grid.TimeCOAPoly = Poly2DType(Coefs=coefs)

            return coords_rg_2d_t, coords_az_2d_t
Ejemplo n.º 3
0
            def get_poly(ds, name):
                array = ds[:]
                fill = ds.attrs['_FillValue']
                boolc = (array != fill)

                if numpy.any(boolc):
                    array = array[boolc]
                    if numpy.any(array != array[0]):
                        coefs, residuals, rank, sing_values = two_dim_poly_fit(
                            coords_rg_2d[boolc],
                            coords_az_2d[boolc],
                            array,
                            x_order=3,
                            y_order=3,
                            x_scale=1e-3,
                            y_scale=1e-3,
                            rcond=1e-40)
                        logging.info(
                            'The {} fit details:\nroot mean square residuals = {}\nrank = {}\nsingular values = {}'
                            .format(name, residuals, rank, sing_values))
                    else:
                        # it's constant, so just use a constant polynomial
                        coefs = [
                            [
                                array[0],
                            ],
                        ]
                        logging.info('The {} values are constant'.format(name))
                    return Poly2DType(Coefs=coefs)
                else:
                    logging.warning(
                        'No non-trivial values for {} provided.'.format(name))
                    return None
Ejemplo n.º 4
0
def fit_time_coa_polynomial(inca, image_data, grid, dop_rate_scaled_coeffs, poly_order=2):
    """

    Parameters
    ----------
    inca : sarpy.io.complex.sicd_elements.RMA.INCAType
    image_data : sarpy.io.complex.sicd_elements.ImageData.ImageDataType
    grid : sarpy.io.complex.sicd_elements.Grid.GridType
    dop_rate_scaled_coeffs : numpy.ndarray
        the dop rate polynomial relative to physical coordinates - the is a
        common construct in converting metadata for csk/sentinel/radarsat
    poly_order : int
        the degree of the polynomial to fit.
    Returns
    -------
    Poly2DType
    """

    grid_samples = poly_order + 8
    coords_az = get_im_physical_coords(
        numpy.linspace(0, image_data.NumCols - 1, grid_samples, dtype='float64'), grid, image_data, 'col')
    coords_rg = get_im_physical_coords(
        numpy.linspace(0, image_data.NumRows - 1, grid_samples, dtype='float64'), grid, image_data, 'row')
    coords_az_2d, coords_rg_2d = numpy.meshgrid(coords_az, coords_rg)
    time_ca_sampled = inca.TimeCAPoly(coords_az_2d)
    dop_centroid_sampled = inca.DopCentroidPoly(coords_rg_2d, coords_az_2d)
    doppler_rate_sampled = polynomial.polyval(coords_rg_2d, dop_rate_scaled_coeffs)
    time_coa_sampled = time_ca_sampled + dop_centroid_sampled / doppler_rate_sampled
    coefs, residuals, rank, sing_values = two_dim_poly_fit(
        coords_rg_2d, coords_az_2d, time_coa_sampled,
        x_order=poly_order, y_order=poly_order, x_scale=1e-3, y_scale=1e-3, rcond=1e-40)
    logging.info('The time_coa_fit details:\nroot mean square residuals = {}\nrank = {}\nsingular values = {}'.format(residuals, rank, sing_values))
    return Poly2DType(Coefs=coefs)
Ejemplo n.º 5
0
 def get_rma() -> RMAType:
     dop_centroid_poly = Poly2DType(Coefs=dop_centroid_poly_coeffs)
     dop_centroid_coa = True
     if collect_info.RadarMode.ModeType == 'SPOTLIGHT':
         dop_centroid_poly = None
         dop_centroid_coa = None
     # NB: DRateSFPoly is defined as a function of only range - reshape appropriately
     inca = INCAType(
         R_CA_SCP=r_ca_scp,
         FreqZero=center_freq,
         DRateSFPoly=Poly2DType(
             Coefs=numpy.reshape(drate_sf_poly_coefs, (-1, 1))),
         DopCentroidPoly=dop_centroid_poly,
         DopCentroidCOA=dop_centroid_coa,
         TimeCAPoly=Poly1DType(Coefs=time_ca_poly_coeffs))
     return RMAType(RMAlgoType='OMEGA_K', INCA=inca)
Ejemplo n.º 6
0
Archivo: csk.py Proyecto: LordHui/sarpy
 def get_grid():  # type: () -> GridType
     if h5_dict['Projection ID'] == 'SLANT RANGE/AZIMUTH':
         image_plane = 'SLANT'
         gr_type = 'RGZERO'
     else:
         image_plane = 'GROUND'
         gr_type = None
     # Row
     row_window_name = h5_dict['Range Focusing Weighting Function'].rstrip().upper()
     row_params = None
     if row_window_name == 'HAMMING':
         row_params = {'COEFFICIENT': '{0:15f}'.format(h5_dict['Range Focusing Weighting Coefficient'])}
     row = DirParamType(Sgn=-1,
                        KCtr=2*center_frequency/speed_of_light,
                        DeltaKCOAPoly=Poly2DType(Coefs=[[0, ], ]),
                        WgtType=WgtTypeType(WindowName=row_window_name, Parameters=row_params))
     # Col
     col_window_name = h5_dict['Azimuth Focusing Weighting Function'].rstrip().upper()
     col_params = None
     if col_window_name == 'HAMMING':
         col_params = {'COEFFICIENT': '{0:15f}'.format(h5_dict['Azimuth Focusing Weighting Coefficient'])}
     col = DirParamType(Sgn=-1,
                        KCtr=0,
                        WgtType=WgtTypeType(WindowName=col_window_name, Parameters=col_params))
     return GridType(ImagePlane=image_plane, Type=gr_type, Row=row, Col=col)
Ejemplo n.º 7
0
Archivo: csk.py Proyecto: LordHui/sarpy
 def update_rma_and_grid(sicd, band_name):
     # type: (SICDType, str) -> None
     rg_scp_time = rg_first_time + (ss_rg_s*sicd.ImageData.SCPPixel.Row)
     az_scp_time = az_first_time + (ss_az_s*sicd.ImageData.SCPPixel.Col)
     r_ca_scp = rg_scp_time*speed_of_light/2
     sicd.RMA.INCA.R_CA_SCP = r_ca_scp
     # compute DRateSFPoly
     scp_ca_time = az_scp_time + ref_time_offset
     vel_poly = sicd.Position.ARPPoly.derivative(der_order=1, return_poly=True)
     vel_ca_vec = vel_poly(scp_ca_time)
     vel_ca_sq = numpy.sum(vel_ca_vec*vel_ca_vec)
     vel_ca = numpy.sqrt(vel_ca_sq)
     r_ca = numpy.array([r_ca_scp, 1.], dtype=numpy.float64)
     dop_rate_poly_rg_shifted = dop_rate_poly_rg.shift(
         rg_ref_time-rg_scp_time, alpha=ss_rg_s/row_ss, return_poly=False)
     drate_sf_poly = -(polynomial.polymul(dop_rate_poly_rg_shifted, r_ca) *
                       speed_of_light/(2*center_frequency*vel_ca_sq))
     # update grid.row
     sicd.Grid.Row.SS = row_ss
     sicd.Grid.Row.ImpRespBW = row_bw
     sicd.Grid.Row.DeltaK1 = -0.5 * row_bw
     sicd.Grid.Row.DeltaK2 = 0.5 * row_bw
     # update grid.col
     col_ss = vel_ca*ss_az_s*drate_sf_poly[0]
     sicd.Grid.Col.SS = col_ss
     col_bw = min(band_dict[band_name]['Azimuth Focusing Bandwidth'] * abs(ss_az_s), 1) / col_ss
     sicd.Grid.Col.ImpRespBW = col_bw
     # update inca
     sicd.RMA.INCA.DRateSFPoly = Poly2DType(Coefs=numpy.reshape(drate_sf_poly, (-1, 1)))
     sicd.RMA.INCA.TimeCAPoly = Poly1DType(Coefs=[scp_ca_time, ss_az_s/col_ss])
     # compute DopCentroidPoly & DeltaKCOAPoly
     dop_centroid_poly = numpy.zeros((dop_poly_rg.order1+1, dop_poly_az.order1+1), dtype=numpy.float64)
     dop_centroid_poly[0, 0] = dop_poly_rg(rg_scp_time-rg_ref_time) + \
         dop_poly_az(az_scp_time-az_ref_time) - \
         0.5*(dop_poly_rg[0] + dop_poly_az[0])
     dop_poly_rg_shifted = dop_poly_rg.shift(rg_ref_time-rg_scp_time, alpha=ss_rg_s/row_ss)
     dop_poly_az_shifted = dop_poly_az.shift(az_ref_time-az_scp_time, alpha=ss_az_s/col_ss)
     dop_centroid_poly[1:, 0] = dop_poly_rg_shifted[1:]
     dop_centroid_poly[0, 1:] = dop_poly_az_shifted[1:]
     sicd.RMA.INCA.DopCentroidPoly = Poly2DType(Coefs=dop_centroid_poly)
     sicd.RMA.INCA.DopCentroidCOA = True
     sicd.Grid.Col.DeltaKCOAPoly = Poly2DType(Coefs=dop_centroid_poly*ss_az_s/col_ss)
     # fit TimeCOAPoly
     sicd.Grid.TimeCOAPoly = fit_time_coa_polynomial(
         sicd.RMA.INCA, sicd.ImageData, sicd.Grid, dop_rate_poly_rg_shifted, poly_order=2)
Ejemplo n.º 8
0
Archivo: csk.py Proyecto: LordHui/sarpy
 def update_radiometric(sicd, band_name):
     # type: (SICDType, str) -> None
     if h5_dict['Range Spreading Loss Compensation Geometry'] != 'NONE':
         slant_range = h5_dict['Reference Slant Range']
         exp = h5_dict['Reference Slant Range Exponent']
         sf = slant_range**(2*exp)
         if h5_dict['Calibration Constant Compensation Flag'] == 0:
             rsf = h5_dict['Rescaling Factor']
             cal = band_dict[band_name]['Calibration Constant']
             sf /= cal*(rsf**2)
         sicd.Radiometric = RadiometricType(BetaZeroSFPoly=Poly2DType(Coefs=[[sf, ], ]))
Ejemplo n.º 9
0
        def get_grid():  # type: () -> GridType
            def get_wgt_type(weight_name, coefficient, direction):
                if weight_name == 'GENERAL_COSINE':
                    # probably only for kompsat?
                    weight_name = 'HAMMING'
                    coefficient = 1 - coefficient
                if coefficient is None:
                    params = None
                else:
                    params = {'COEFFICIENT': '{0:0.17E}'.format(coefficient)}
                out = WgtTypeType(WindowName=weight_name, Parameters=params)
                if weight_name != 'HAMMING':
                    logger.warning(
                        'Got unexpected weight scheme {} for {}.\n\t'
                        'The weighting will not be properly populated.'.format(
                            weight_name, direction))
                return out

            if re.sub(
                    ' ', '',
                    h5_dict['Projection ID']).upper() == 'SLANTRANGE/AZIMUTH':
                image_plane = 'SLANT'
                gr_type = 'RGZERO'
            else:
                image_plane = 'GROUND'
                gr_type = 'PLANE'
            # Row
            row_window_name = h5_dict[
                'Range Focusing Weighting Function'].rstrip().upper()
            row_coefficient = h5_dict.get(
                'Range Focusing Weighting Coefficient', None)
            row_weight = get_wgt_type(row_window_name, row_coefficient, 'Row')
            row = DirParamType(Sgn=-1,
                               KCtr=2 * center_frequency / speed_of_light,
                               DeltaKCOAPoly=Poly2DType(Coefs=[
                                   [
                                       0,
                                   ],
                               ]),
                               WgtType=row_weight)
            # Col
            col_window_name = h5_dict[
                'Azimuth Focusing Weighting Function'].rstrip().upper()
            col_coefficient = h5_dict.get(
                'Azimuth Focusing Weighting Coefficient', None)
            col_weight = get_wgt_type(col_window_name, col_coefficient, 'Col')
            col = DirParamType(Sgn=-1, KCtr=0, WgtType=col_weight)
            return GridType(ImagePlane=image_plane,
                            Type=gr_type,
                            Row=row,
                            Col=col)
Ejemplo n.º 10
0
        def define_radiometric():
            def get_poly(ds, name):
                array = ds[:]
                fill = ds.attrs['_FillValue']
                boolc = (array != fill)

                if numpy.any(boolc):
                    array = array[boolc]
                    if numpy.any(array != array[0]):
                        coefs, residuals, rank, sing_values = two_dim_poly_fit(
                            coords_rg_2d[boolc], coords_az_2d[boolc], array,
                            x_order=3, y_order=3, x_scale=1e-3, y_scale=1e-3, rcond=1e-40)
                        logger.info(
                            'The {} fit details:\n\t'
                            'root mean square residuals = {}\n\t'
                            'rank = {}\n\t'
                            'singular values = {}'.format(name, residuals, rank, sing_values))
                    else:
                        # it's constant, so just use a constant polynomial
                        coefs = [[array[0], ], ]
                        logger.info('The {} values are constant'.format(name))
                    return Poly2DType(Coefs=coefs)
                else:
                    logger.warning('No non-trivial values for {} provided.'.format(name))
                    return None

            beta0_poly = get_poly(beta0, 'beta0')
            gamma0_poly = get_poly(gamma0, 'gamma0')
            sigma0_poly = get_poly(sigma0, 'sigma0')

            nesz = hf['/science/LSAR/SLC/metadata/calibrationInformation/frequency{}/{}/nes0'.format(freq_name,
                                                                                                     pol_name)][:]
            noise_samples = nesz - (10 * numpy.log10(sigma0_poly.Coefs[0, 0]))

            coefs, residuals, rank, sing_values = two_dim_poly_fit(
                coords_rg_2d, coords_az_2d, noise_samples,
                x_order=3, y_order=3, x_scale=1e-3, y_scale=1e-3, rcond=1e-40)
            logger.info(
                'The noise_poly fit details:\n\t'
                'root mean square residuals = {}\n\t'
                'rank = {}\n\t'
                'singular values = {}'.format(
                    residuals, rank, sing_values))
            t_sicd.Radiometric = RadiometricType(
                BetaZeroSFPoly=beta0_poly,
                GammaZeroSFPoly=gamma0_poly,
                SigmaZeroSFPoly=sigma0_poly,
                NoiseLevel=NoiseLevelType_(
                    NoiseLevelType='ABSOLUTE', NoisePoly=Poly2DType(Coefs=coefs)))
Ejemplo n.º 11
0
Archivo: csk.py Proyecto: Ryanzgy/sarpy
 def update_radiometric(sicd, band_name):
     # type: (SICDType, str) -> None
     if 'KMP' in self._satellite:
         # TODO: skipping for now - strange results for kompsat
         return
     if h5_dict['Range Spreading Loss Compensation Geometry'] != 'NONE':
         slant_range = h5_dict['Reference Slant Range']
         exp = h5_dict['Reference Slant Range Exponent']
         sf = slant_range**(2*exp)
         rsf = h5_dict['Rescaling Factor']
         sf /= rsf * rsf
         if h5_dict.get('Calibration Constant Compensation Flag', None) == 0:
             cal = band_dict[band_name]['Calibration Constant']
             sf /= cal
         sicd.Radiometric = RadiometricType(BetaZeroSFPoly=Poly2DType(Coefs=[[sf, ], ]))
Ejemplo n.º 12
0
    def _get_grid_row(self):
        """
        Gets the Grid.Row metadata.

        Returns
        -------
        DirParamType
        """

        center_freq = self._get_center_frequency()
        if self.generation == 'RS2':
            row_ss = float(
                self._find('./imageAttributes'
                           '/rasterAttributes'
                           '/sampledPixelSpacing').text)
        elif self.generation == 'RCM':
            row_ss = float(
                self._find('./imageReferenceAttributes'
                           '/rasterAttributes'
                           '/sampledPixelSpacing').text)
        else:
            raise ValueError('unhandled generation {}'.format(self.generation))

        row_irbw = 2 * float(
            self._find('./imageGenerationParameters'
                       '/sarProcessingInformation'
                       '/totalProcessedRangeBandwidth').text) / speed_of_light
        row_wgt_type = WgtTypeType(
            WindowName=self._find('./imageGenerationParameters'
                                  '/sarProcessingInformation'
                                  '/rangeWindow/windowName').text.upper())
        if row_wgt_type.WindowName == 'KAISER':
            row_wgt_type.Parameters = {
                'BETA':
                self._find('./imageGenerationParameters'
                           '/sarProcessingInformation'
                           '/rangeWindow/windowCoefficient').text
            }
        return DirParamType(SS=row_ss,
                            ImpRespBW=row_irbw,
                            Sgn=-1,
                            KCtr=2 * center_freq / speed_of_light,
                            DeltaKCOAPoly=Poly2DType(Coefs=((0, ), )),
                            WgtType=row_wgt_type)
Ejemplo n.º 13
0
 def update_radiometric(sicd: SICDType, band_name: str) -> None:
     if self.mission_id in ['KMPS', 'CSG']:
         # TODO: skipping for now - strange results for flag == 77. Awaiting gidance - see Wade.
         return
     if h5_dict['Range Spreading Loss Compensation Geometry'] != 'NONE':
         slant_range = h5_dict['Reference Slant Range']
         exp = h5_dict['Reference Slant Range Exponent']
         sf = slant_range**(2 * exp)
         rsf = h5_dict['Rescaling Factor']
         sf /= rsf * rsf
         if h5_dict.get('Calibration Constant Compensation Flag',
                        None) == 0:
             cal = band_dict[band_name]['Calibration Constant']
             sf /= cal
         sicd.Radiometric = RadiometricType(BetaZeroSFPoly=Poly2DType(
             Coefs=[
                 [
                     sf,
                 ],
             ]))
Ejemplo n.º 14
0
        def add_noise():
            if sicd.Radiometric is None:
                return

            nesz_raw = numpy.array(img['nesz_polynomial']['coefficients'],
                                   dtype='float64')
            test_value = polynomial.polyval(rma.INCA.R_CA_SCP, nesz_raw)
            if abs(test_value - img['nesz_peak']) > 100:
                # this polynomial reversed in early versions, so reverse if evaluated results are nonsense
                nesz_raw = nesz_raw[::-1]
            nesz_poly_raw = Poly2DType(Coefs=numpy.reshape(nesz_raw, (-1, 1)))
            noise_coeffs = nesz_poly_raw.shift(-rma.INCA.R_CA_SCP,
                                               1,
                                               0,
                                               1,
                                               return_poly=False)
            # this is in nesz units, so shift to absolute units
            noise_coeffs[0] -= 10 * numpy.log10(
                sicd.Radiometric.SigmaZeroSFPoly[0, 0])
            sicd.Radiometric.NoiseLevel = NoiseLevelType_(
                NoiseLevelType='ABSOLUTE', NoisePoly=noise_coeffs)
Ejemplo n.º 15
0
        def update_rma_and_grid(sicd: SICDType, band_name: str) -> None:
            rg_scp_time = rg_first_time + (ss_rg_s *
                                           sicd.ImageData.SCPPixel.Row)
            az_scp_time = az_first_time + (use_sign2 * ss_az_s *
                                           sicd.ImageData.SCPPixel.Col)
            r_ca_scp = rg_scp_time * speed_of_light / 2
            sicd.RMA.INCA.R_CA_SCP = r_ca_scp
            # compute DRateSFPoly
            scp_ca_time = az_scp_time + ref_time_offset
            vel_poly = sicd.Position.ARPPoly.derivative(der_order=1,
                                                        return_poly=True)
            vel_ca_vec = vel_poly(scp_ca_time)
            vel_ca_sq = numpy.sum(vel_ca_vec * vel_ca_vec)
            vel_ca = numpy.sqrt(vel_ca_sq)
            r_ca = numpy.array([r_ca_scp, 1.], dtype=numpy.float64)
            dop_rate_poly_rg_shifted = dop_rate_poly_rg.shift(
                rg_ref_time - rg_scp_time,
                alpha=ss_rg_s / row_ss,
                return_poly=False)
            drate_sf_poly = -(polynomial.polymul(dop_rate_poly_rg_shifted,
                                                 r_ca) * speed_of_light /
                              (2 * center_frequency * vel_ca_sq))
            # update grid.row
            sicd.Grid.Row.SS = row_ss
            sicd.Grid.Row.ImpRespBW = row_bw
            sicd.Grid.Row.DeltaK1 = -0.5 * row_bw
            sicd.Grid.Row.DeltaK2 = 0.5 * row_bw
            # update grid.col
            col_ss = abs(vel_ca * ss_az_s * drate_sf_poly[0])
            sicd.Grid.Col.SS = col_ss
            if self.mission_id == 'CSK':
                col_bw = min(
                    band_dict[band_name]
                    ['Azimuth Focusing Transition Bandwidth'] * ss_az_s,
                    1) / col_ss
            elif self.mission_id in ['CSG', 'KMPS']:
                col_bw = min(
                    band_dict[band_name]['Azimuth Focusing Bandwidth'] *
                    ss_az_s, 1) / col_ss
            else:
                raise ValueError('Got unhandled mission_id {}'.format(
                    self.mission_id))
            sicd.Grid.Col.ImpRespBW = col_bw
            # update inca
            sicd.RMA.INCA.DRateSFPoly = Poly2DType(
                Coefs=numpy.reshape(drate_sf_poly, (-1, 1)))
            sicd.RMA.INCA.TimeCAPoly = Poly1DType(
                Coefs=[scp_ca_time, use_sign2 * ss_az_s / col_ss])
            # compute DopCentroidPoly & DeltaKCOAPoly
            dop_centroid_poly = numpy.zeros(
                (dop_poly_rg.order1 + 1, dop_poly_az.order1 + 1),
                dtype=numpy.float64)
            dop_centroid_poly[0, 0] = dop_poly_rg(rg_scp_time-rg_ref_time) + \
                dop_poly_az(az_scp_time-az_ref_time) - \
                0.5*(dop_poly_rg[0] + dop_poly_az[0])
            dop_poly_rg_shifted = dop_poly_rg.shift(rg_ref_time - rg_scp_time,
                                                    alpha=ss_rg_s / row_ss)
            dop_poly_az_shifted = dop_poly_az.shift(az_ref_time - az_scp_time,
                                                    alpha=ss_az_s / col_ss)
            dop_centroid_poly[1:, 0] = dop_poly_rg_shifted[1:]
            dop_centroid_poly[0, 1:] = dop_poly_az_shifted[1:]
            sicd.RMA.INCA.DopCentroidPoly = Poly2DType(Coefs=dop_centroid_poly)
            sicd.RMA.INCA.DopCentroidCOA = True
            sicd.Grid.Col.DeltaKCOAPoly = Poly2DType(
                Coefs=use_sign * dop_centroid_poly * ss_az_s / col_ss)
            # fit TimeCOAPoly
            sicd.Grid.TimeCOAPoly = fit_time_coa_polynomial(
                sicd.RMA.INCA,
                sicd.ImageData,
                sicd.Grid,
                dop_rate_poly_rg_shifted,
                poly_order=2)

            if csk_addin is not None:
                csk_addin.check_sicd(sicd, self.mission_id, h5_dict)
Ejemplo n.º 16
0
    def _get_radiometric(self, image_data, grid):
        """
        Gets the Radiometric metadata.

        Parameters
        ----------
        image_data : ImageDataType
        grid : GridType

        Returns
        -------
        RadiometricType
        """
        def perform_radiometric_fit(component_file):
            comp_struct = _parse_xml(component_file,
                                     without_ns=(self.generation != 'RS2'))
            comp_values = numpy.array([
                float(entry)
                for entry in comp_struct.find('./gains').text.split()
            ],
                                      dtype=numpy.float64)
            comp_values = 1. / (comp_values * comp_values
                                )  # adjust for sicd convention
            if numpy.all(comp_values == comp_values[0]):
                return numpy.array([
                    [
                        comp_values[0],
                    ],
                ], dtype=numpy.float64)
            else:
                # fit a 1-d polynomial in range
                coords_rg = (numpy.arange(image_data.NumRows) -
                             image_data.SCPPixel.Row) * grid.Row.SS
                if self.generation == 'RCM':  # the rows are sub-sampled
                    start = int(comp_struct.find('./pixelFirstLutValue').text)
                    num_vs = int(comp_struct.find('./numberOfValues').text)
                    t_step = int(comp_struct.find('./stepSize').text)
                    if t_step > 0:
                        rng_indices = numpy.arange(start, num_vs, t_step)
                    else:
                        rng_indices = numpy.arange(start, -1, t_step)
                    coords_rg = coords_rg[rng_indices]
                return numpy.atleast_2d(
                    polynomial.polyfit(coords_rg, comp_values, 3))

        base_path = os.path.dirname(self.file_name)
        if self.generation == 'RS2':
            beta_file = os.path.join(
                base_path,
                self._find('./imageAttributes'
                           '/lookupTable'
                           '[@incidenceAngleCorrection="Beta Nought"]').text)
            sigma_file = os.path.join(
                base_path,
                self._find('./imageAttributes'
                           '/lookupTable'
                           '[@incidenceAngleCorrection="Sigma Nought"]').text)
            gamma_file = os.path.join(
                base_path,
                self._find('./imageAttributes'
                           '/lookupTable'
                           '[@incidenceAngleCorrection="Gamma"]').text)
        elif self.generation == 'RCM':
            beta_file = os.path.join(
                base_path, 'calibration',
                self._find('./imageReferenceAttributes'
                           '/lookupTableFileName'
                           '[@sarCalibrationType="Beta Nought"]').text)
            sigma_file = os.path.join(
                base_path, 'calibration',
                self._find('./imageReferenceAttributes'
                           '/lookupTableFileName'
                           '[@sarCalibrationType="Sigma Nought"]').text)
            gamma_file = os.path.join(
                base_path, 'calibration',
                self._find('./imageReferenceAttributes'
                           '/lookupTableFileName'
                           '[@sarCalibrationType="Gamma"]').text)
        else:
            raise ValueError('unhandled generation {}'.format(self.generation))

        if not os.path.isfile(beta_file):
            logging.error(
                msg="Beta calibration information should be located in file {}, "
                "which doesn't exist.".format(beta_file))
            return None

        # perform beta, sigma, gamma fit
        beta_zero_sf_poly = perform_radiometric_fit(beta_file)
        sigma_zero_sf_poly = perform_radiometric_fit(sigma_file)
        gamma_zero_sf_poly = perform_radiometric_fit(gamma_file)

        # construct noise poly
        noise_level = None
        if self.generation == 'RS2':
            # noise is in the main product.xml
            beta0_element = self._find(
                './sourceAttributes/radarParameters'
                '/referenceNoiseLevel[@incidenceAngleCorrection="Beta Nought"]'
            )
        elif self.generation == 'RCM':
            noise_file = os.path.join(
                base_path, 'calibration',
                self._find(
                    './imageReferenceAttributes/noiseLevelFileName').text)
            noise_root = _parse_xml(noise_file, without_ns=True)
            noise_levels = noise_root.findall('./referenceNoiseLevel')
            beta0s = [
                entry for entry in noise_levels
                if entry.find('sarCalibrationType').text.startswith('Beta')
            ]
            beta0_element = beta0s[0] if len(beta0s) > 0 else None
        else:
            raise ValueError('unhandled generation {}'.format(self.generation))

        if beta0_element is not None:
            noise_level = NoiseLevelType_(NoiseLevelType='ABSOLUTE')
            pfv = float(beta0_element.find('pixelFirstNoiseValue').text)
            step = float(beta0_element.find('stepSize').text)
            beta0s = numpy.array([
                float(x)
                for x in beta0_element.find('noiseLevelValues').text.split()
            ])
            range_coords = grid.Row.SS * (numpy.arange(len(beta0s)) * step +
                                          pfv - image_data.SCPPixel.Row)
            noise_poly = polynomial.polyfit(
                range_coords, beta0s - 10 * numpy.log10(
                    polynomial.polyval(range_coords, beta_zero_sf_poly[:, 0])),
                2)
            noise_level.NoisePoly = Poly2DType(
                Coefs=numpy.atleast_2d(noise_poly))

        return RadiometricType(BetaZeroSFPoly=beta_zero_sf_poly,
                               SigmaZeroSFPoly=sigma_zero_sf_poly,
                               GammaZeroSFPoly=gamma_zero_sf_poly,
                               NoiseLevel=noise_level)
Ejemplo n.º 17
0
    def _get_rma_adjust_grid(self, scpcoa, grid, image_data, position,
                             collection_info):
        """
        Gets the RMA metadata, and adjust the Grid.Col metadata.

        Parameters
        ----------
        scpcoa : SCPCOAType
        grid : GridType
        image_data : ImageDataType
        position : PositionType
        collection_info : CollectionInfoType

        Returns
        -------
        RMAType
        """

        look = scpcoa.look
        start_time = self._get_start_time()
        center_freq = self._get_center_frequency()
        doppler_bandwidth = float(
            self._find('./imageGenerationParameters'
                       '/sarProcessingInformation'
                       '/totalProcessedAzimuthBandwidth').text)
        zero_dop_last_line = parse_timestring(
            self._find('./imageGenerationParameters'
                       '/sarProcessingInformation'
                       '/zeroDopplerTimeLastLine').text)
        zero_dop_first_line = parse_timestring(
            self._find('./imageGenerationParameters'
                       '/sarProcessingInformation'
                       '/zeroDopplerTimeFirstLine').text)
        if look > 1:  # SideOfTrack == 'L'
            # we explicitly want negative time order
            if zero_dop_first_line < zero_dop_last_line:
                zero_dop_first_line, zero_dop_last_line = zero_dop_last_line, zero_dop_first_line
        else:
            # we explicitly want positive time order
            if zero_dop_first_line > zero_dop_last_line:
                zero_dop_first_line, zero_dop_last_line = zero_dop_last_line, zero_dop_first_line
        col_spacing_zd = get_seconds(zero_dop_last_line,
                                     zero_dop_first_line,
                                     precision='us') / (image_data.NumCols - 1)
        # zero doppler time of SCP relative to collect start
        time_scp_zd = get_seconds(zero_dop_first_line, start_time, precision='us') + \
            image_data.SCPPixel.Col*col_spacing_zd
        if self.generation == 'RS2':
            near_range = float(
                self._find('./imageGenerationParameters'
                           '/sarProcessingInformation'
                           '/slantRangeNearEdge').text)
        elif self.generation == 'RCM':
            near_range = float(
                self._find('./sceneAttributes'
                           '/imageAttributes'
                           '/slantRangeNearEdge').text)
        else:
            raise ValueError('unhandled generation {}'.format(self.generation))

        inca = INCAType(R_CA_SCP=near_range +
                        (image_data.SCPPixel.Row * grid.Row.SS),
                        FreqZero=center_freq)
        # doppler rate calculations
        velocity = position.ARPPoly.derivative_eval(time_scp_zd, 1)
        vel_ca_squared = numpy.sum(velocity * velocity)
        # polynomial representing range as a function of range distance from SCP
        r_ca = numpy.array([inca.R_CA_SCP, 1], dtype=numpy.float64)
        # doppler rate coefficients
        if self.generation == 'RS2':
            doppler_rate_coeffs = numpy.array([
                float(entry) for entry in self._find(
                    './imageGenerationParameters'
                    '/dopplerRateValues'
                    '/dopplerRateValuesCoefficients').text.split()
            ],
                                              dtype=numpy.float64)
            doppler_rate_ref_time = float(
                self._find('./imageGenerationParameters'
                           '/dopplerRateValues'
                           '/dopplerRateReferenceTime').text)
        elif self.generation == 'RCM':
            doppler_rate_coeffs = numpy.array([
                float(entry) for entry in self._find(
                    './dopplerRate'
                    '/dopplerRateEstimate'
                    '/dopplerRateCoefficients').text.split()
            ],
                                              dtype=numpy.float64)
            doppler_rate_ref_time = float(
                self._find('./dopplerRate'
                           '/dopplerRateEstimate'
                           '/dopplerRateReferenceTime').text)
        else:
            raise ValueError('unhandled generation {}'.format(self.generation))

        # the doppler_rate_coeffs represents a polynomial in time, relative to
        #   doppler_rate_ref_time.
        # to construct the doppler centroid polynomial, we need to change scales
        #   to a polynomial in space, relative to SCP.
        doppler_rate_poly = Poly1DType(Coefs=doppler_rate_coeffs)
        alpha = 2.0 / speed_of_light
        t_0 = doppler_rate_ref_time - alpha * inca.R_CA_SCP
        dop_rate_scaled_coeffs = doppler_rate_poly.shift(t_0,
                                                         alpha,
                                                         return_poly=False)
        # DRateSFPoly is then a scaled multiple of this scaled poly and r_ca above
        coeffs = -numpy.convolve(dop_rate_scaled_coeffs, r_ca) / (
            alpha * center_freq * vel_ca_squared)
        inca.DRateSFPoly = Poly2DType(
            Coefs=numpy.reshape(coeffs, (coeffs.size, 1)))

        # modify a few of the other fields
        ss_scale = numpy.sqrt(vel_ca_squared) * inca.DRateSFPoly[0, 0]
        grid.Col.SS = col_spacing_zd * ss_scale
        grid.Col.ImpRespBW = -look * doppler_bandwidth / ss_scale
        inca.TimeCAPoly = Poly1DType(Coefs=[time_scp_zd, 1. / ss_scale])

        # doppler centroid
        if self.generation == 'RS2':
            doppler_cent_coeffs = numpy.array([
                float(entry) for entry in self._find(
                    './imageGenerationParameters'
                    '/dopplerCentroid'
                    '/dopplerCentroidCoefficients').text.split()
            ],
                                              dtype=numpy.float64)
            doppler_cent_ref_time = float(
                self._find('./imageGenerationParameters'
                           '/dopplerCentroid'
                           '/dopplerCentroidReferenceTime').text)
            doppler_cent_time_est = parse_timestring(
                self._find('./imageGenerationParameters'
                           '/dopplerCentroid'
                           '/timeOfDopplerCentroidEstimate').text)
        elif self.generation == 'RCM':
            doppler_cent_coeffs = numpy.array([
                float(entry) for entry in self._find(
                    './dopplerCentroid'
                    '/dopplerCentroidEstimate'
                    '/dopplerCentroidCoefficients').text.split()
            ],
                                              dtype=numpy.float64)
            doppler_cent_ref_time = float(
                self._find('./dopplerCentroid'
                           '/dopplerCentroidEstimate'
                           '/dopplerCentroidReferenceTime').text)
            doppler_cent_time_est = parse_timestring(
                self._find('./dopplerCentroid'
                           '/dopplerCentroidEstimate'
                           '/timeOfDopplerCentroidEstimate').text)
        else:
            raise ValueError('unhandled generation {}'.format(self.generation))

        doppler_cent_poly = Poly1DType(Coefs=doppler_cent_coeffs)
        alpha = 2.0 / speed_of_light
        t_0 = doppler_cent_ref_time - alpha * inca.R_CA_SCP
        scaled_coeffs = doppler_cent_poly.shift(t_0, alpha, return_poly=False)
        inca.DopCentroidPoly = Poly2DType(
            Coefs=numpy.reshape(scaled_coeffs, (scaled_coeffs.size, 1)))
        # adjust doppler centroid for spotlight, we need to add a second
        # dimension to DopCentroidPoly
        if collection_info.RadarMode.ModeType == 'SPOTLIGHT':
            doppler_cent_est = get_seconds(doppler_cent_time_est,
                                           start_time,
                                           precision='us')
            doppler_cent_col = (doppler_cent_est -
                                time_scp_zd) / col_spacing_zd
            dop_poly = numpy.zeros((scaled_coeffs.shape[0], 2),
                                   dtype=numpy.float64)
            dop_poly[:, 0] = scaled_coeffs
            dop_poly[0, 1] = -look * center_freq * alpha * numpy.sqrt(
                vel_ca_squared) / inca.R_CA_SCP
            # dopplerCentroid in native metadata was defined at specific column,
            # which might not be our SCP column.  Adjust so that SCP column is correct.
            dop_poly[0, 0] = dop_poly[0, 0] - (dop_poly[0, 1] *
                                               doppler_cent_col * grid.Col.SS)
            inca.DopCentroidPoly = Poly2DType(Coefs=dop_poly)

        grid.Col.DeltaKCOAPoly = Poly2DType(
            Coefs=inca.DopCentroidPoly.get_array() * col_spacing_zd /
            grid.Col.SS)
        # compute grid.Col.DeltaK1/K2 from DeltaKCOAPoly
        coeffs = grid.Col.DeltaKCOAPoly.get_array()[:, 0]
        # get roots
        roots = polynomial.polyroots(coeffs)
        # construct range bounds (in meters)
        range_bounds = (
            numpy.array([0, image_data.NumRows - 1], dtype=numpy.float64) -
            image_data.SCPPixel.Row) * grid.Row.SS
        possible_ranges = numpy.copy(range_bounds)
        useful_roots = ((roots > numpy.min(range_bounds)) &
                        (roots < numpy.max(range_bounds)))
        if numpy.any(useful_roots):
            possible_ranges = numpy.concatenate(
                (possible_ranges, roots[useful_roots]), axis=0)
        azimuth_bounds = (
            numpy.array([0, (image_data.NumCols - 1)], dtype=numpy.float64) -
            image_data.SCPPixel.Col) * grid.Col.SS
        coords_az_2d, coords_rg_2d = numpy.meshgrid(azimuth_bounds,
                                                    possible_ranges)
        possible_bounds_deltak = grid.Col.DeltaKCOAPoly(
            coords_rg_2d, coords_az_2d)
        grid.Col.DeltaK1 = numpy.min(
            possible_bounds_deltak) - 0.5 * grid.Col.ImpRespBW
        grid.Col.DeltaK2 = numpy.max(
            possible_bounds_deltak) + 0.5 * grid.Col.ImpRespBW
        # Wrapped spectrum
        if (grid.Col.DeltaK1 < -0.5 / grid.Col.SS) or (grid.Col.DeltaK2 >
                                                       0.5 / grid.Col.SS):
            grid.Col.DeltaK1 = -0.5 / abs(grid.Col.SS)
            grid.Col.DeltaK2 = -grid.Col.DeltaK1
        time_coa_poly = fit_time_coa_polynomial(inca,
                                                image_data,
                                                grid,
                                                dop_rate_scaled_coeffs,
                                                poly_order=2)
        if collection_info.RadarMode.ModeType == 'SPOTLIGHT':
            # using above was convenience, but not really sensible in spotlight mode
            grid.TimeCOAPoly = Poly2DType(Coefs=[
                [
                    time_coa_poly.Coefs[0, 0],
                ],
            ])
            inca.DopCentroidPoly = None
        elif collection_info.RadarMode.ModeType == 'STRIPMAP':
            # fit TimeCOAPoly for grid
            grid.TimeCOAPoly = time_coa_poly
            inca.DopCentroidCOA = True
        else:
            raise ValueError('unhandled ModeType {}'.format(
                collection_info.RadarMode.ModeType))
        return RMAType(RMAlgoType='OMEGA_K', INCA=inca)