def computeImpGeoloc(in_productType, in_objPixc, in_indices, in_height):
    """
    Refines geolocation for in_objPixc pixels corresponding to indices in_indices (in in_objPix)
        
    :param in_productType: type of product among "SP"=LakeSP and "TILE"=LakeTile
    :type in_productType: string
    :param in_objPixc: pixel cloud from which to compute improved geolocation
    :type in_objPixc: proc_pixc.PixelCloud or proc_pixc_sp.PixelCloudSP object
    :param in_indices: indices of pixels related to the same object
    :type in_indices: 1D-array of int
    :param in_height: new height of each point used for improved geoloc
    :type in_height: 1D-array of float
        
    :return out_lon_corr: improved longitude of pixels of in_indices
    :rtype: 1D-array of float
    :return out_lat_corr: improved latitude of pixels of in_indices
    :rtype: 1D-array of float
    :return out_lat_corr: improved latitude of pixels of in_indices
    :rtype: 1D-array of float
    """
    logger = logging.getLogger("proc_pixc_vec")
    nb_pix = in_indices.size
    logger.debug("> %d PixC to deal with", nb_pix)
        
    # 1 - Prepare data for Damien's algo
    # 1.1 - Convert geodetic coordinates (lat, lon, height) to cartesian coordinates (x, y, z)
    x, y, z = my_geoloc.convert_llh2ecef(in_objPixc.latitude[in_indices], in_objPixc.longitude[in_indices], in_objPixc.height[in_indices], my_var.GEN_RAD_EARTH_EQ, my_var.GEN_RAD_EARTH_POLE)
    # 1.2 - Get position of associated along-track pixels (in cartesian coordinates)
    nadir_x = in_objPixc.nadir_x[in_indices]
    nadir_y = in_objPixc.nadir_y[in_indices]
    nadir_z = in_objPixc.nadir_z[in_indices]
    # 1.3 - Get velocity of associated along-track pixels (in cartesian coordinates)
    nadir_vx = in_objPixc.nadir_vx[in_indices]
    nadir_vy = in_objPixc.nadir_vy[in_indices]
    nadir_vz = in_objPixc.nadir_vz[in_indices]
    # 1.4 - Get distance from satellite to target point
    ri = in_objPixc.near_range + in_objPixc.range_index[in_indices] * my_var.GEN_RANGE_SPACING
    
    # 2 - Use Damien's algo
    # 2.1 - Init output vectors
    out_lat_corr = np.zeros(nb_pix)  # Improved latitudes
    out_lon_corr = np.zeros(nb_pix)  # Improved longitudes
    out_height_corr = np.zeros(nb_pix)  # Improved heights
    # 2.2 - Improve geolocation
    p_final, p_final_llh, h_mu, (iter_grad,nfev_minimize_scalar) = my_geoloc.pointcloud_height_geoloc_vect(np.transpose(np.array([x, y, z])), in_objPixc.height[in_indices],
                                                                                                           np.transpose(np.array([nadir_x, nadir_y, nadir_z])),
                                                                                                           np.transpose(np.array([nadir_vx, nadir_vy, nadir_vz])),
                                                                                                           ri, in_height, 
                                                                                                           recompute_Doppler=True, recompute_R=True, verbose=False, 
                                                                                                           max_iter_grad=1, height_goal=1.e-3, safe_flag=True)
    # 2.3 - Save output variables
    out_lat_corr, out_lon_corr, out_height_corr = np.transpose(p_final_llh)
    
    # 2.4 - Return output between 0 and 360 degrees (pixel cloud format)
    return my_tools.convert_to_0_360(out_lon_corr), out_lat_corr, out_height_corr
    def taylor_improved_geoloc(self):
        """
        Improve the height of noisy point (in object sensor)
        """

        nb_pix = self.pixcvec.height.size
        # Convert geodetic coordinates (lat, lon, height) to cartesian coordinates (x, y, z)
        x, y, z = geoloc.convert_llh2ecef(self.pixcvec.latitude,
                                          self.pixcvec.longitude,
                                          self.pixcvec.height,
                                          GEN_RAD_EARTH_EQ, GEN_RAD_EARTH_POLE)

        # Get position of associated along-track pixels (in cartesian coordinates)
        nadir_x = self.sensor.nadir_x
        nadir_y = self.sensor.nadir_y
        nadir_z = self.sensor.nadir_z

        # Get velocity of associated along-track pixels (in cartesian coordinates)
        nadir_vx = self.sensor.nadir_vx
        nadir_vy = self.sensor.nadir_vy
        nadir_vz = self.sensor.nadir_vz

        # Get distance from satellite to target point
        ri = self.pixcvec.near_range + self.pixcvec.range_idx * self.pixcvec.range_spacing

        # Init output vectors
        self.out_lat_corr = np.zeros(nb_pix)  # Improved latitudes
        self.out_lon_corr = np.zeros(nb_pix)  # Improved longitudes
        self.out_height_corr = np.zeros(nb_pix)  # Improved heights

        # need to remap illumnation time to nearest sensor index
        # TODO replace this by a call to a get_sensor_index or equivalent function
        # that either interpolates the sensor or does something more efficient
        f = interpolate.interp1d(self.sensor.time,
                                 range(len(self.sensor.time)))
        sensor_s = (np.rint(f(self.pixc.illumination_time))).astype(int)

        # Loop over each pixel (could be vectorized)
        # vectorisation
        h_noisy = self.pixcvec.height
        nadir_x_vect = np.zeros(nb_pix)
        nadir_y_vect = np.zeros(nb_pix)
        nadir_z_vect = np.zeros(nb_pix)
        nadir_vx_vect = np.zeros(nb_pix)
        nadir_vy_vect = np.zeros(nb_pix)
        nadir_vz_vect = np.zeros(nb_pix)

        for i in np.arange(nb_pix):
            ind_sensor = sensor_s[i]
            nadir_x_vect[i] = nadir_x[ind_sensor]
            nadir_y_vect[i] = nadir_y[ind_sensor]
            nadir_z_vect[i] = nadir_z[ind_sensor]
            nadir_vx_vect[i] = nadir_vx[ind_sensor]
            nadir_vy_vect[i] = nadir_vy[ind_sensor]
            nadir_vz_vect[i] = nadir_vz[ind_sensor]

        # improuve height with vectorised pixel
        p_final, p_final_llh, h_mu, (
            iter_grad,
            nfev_minimize_scalar) = geoloc.pointcloud_height_geoloc_vect(
                np.transpose(np.array([x, y, z])),
                h_noisy,
                np.transpose(
                    np.array([nadir_x_vect, nadir_y_vect, nadir_z_vect])),
                np.transpose(
                    np.array([nadir_vx_vect, nadir_vy_vect, nadir_vz_vect])),
                ri,
                self.new_height,
                recompute_doppler=True,
                recompute_range=True,
                verbose=False,
                max_iter_grad=1,
                height_goal=1.e-3)

        self.out_lat_corr, self.out_lon_corr, self.out_height_corr = np.transpose(
            p_final_llh)
)
vs = np.load(
    '/work/ALT/swot/swotdev/desrochesd/swot-sds/swotCNES/src/cnes/modules/geoloc/scripts/data_test/vs.save.npy'
)
R_target = np.load(
    '/work/ALT/swot/swotdev/desrochesd/swot-sds/swotCNES/src/cnes/modules/geoloc/scripts/data_test/r.save.npy'
)
h_target = np.load(
    '/work/ALT/swot/swotdev/desrochesd/swot-sds/swotCNES/src/cnes/modules/geoloc/scripts/data_test/h_target.save.npy'
)

p_corr = geoloc.pointcloud_height_geoloc_vect(p,
                                              h_noisy,
                                              s,
                                              vs,
                                              R_target,
                                              h_target,
                                              recompute_Doppler=True,
                                              recompute_R=True,
                                              verbose=False,
                                              max_iter_grad=1,
                                              height_goal=1.e-3,
                                              safe_flag=True)

np.save(
    '/work/ALT/swot/swotdev/desrochesd/swot-sds/swotCNES/src/cnes/modules/geoloc/scripts/data_test/p_corr.save',
    p_corr[0])
np.save(
    '/work/ALT/swot/swotdev/desrochesd/swot-sds/swotCNES/src/cnes/modules/geoloc/scripts/data_test/p_corr_llh.save',
    p_corr[1])
Example #4
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('pixel_cloud_file', type=str)
    parser.add_argument('output_final_pixel_cloud', default=None, type=str)
    parser.add_argument('rdf', default=None, type=str)

    args = vars(parser.parse_args())
    shutil.copyfile(abspath(args['pixel_cloud_file']),
                    abspath(args['output_final_pixel_cloud']))

    rdf = my_rdf.myRdfReader(args['rdf'])
    parameters = rdf.parameters

    pixc = Dataset(abspath(args['pixel_cloud_file']), 'r')
    final_pixc = Dataset(abspath(args['output_final_pixel_cloud']), 'a')

    az = pixc.groups['pixel_cloud'].variables['azimuth_index'][:]
    col = pixc.groups['pixel_cloud'].variables['range_index'][:]
    lat = pixc.groups['pixel_cloud'].variables['latitude'][:]
    lon = pixc.groups['pixel_cloud'].variables['longitude'][:]
    height = pixc.groups['pixel_cloud'].variables['height'][:]
    pixel_cloud_time = pixc.groups['pixel_cloud'].variables[
        'illumination_time'][:].filled()
    cross_track = pixc.groups['pixel_cloud'].variables['cross_track'][:]

    orbit_time = pixc.groups['tvp'].variables['time'][:].filled()

    cycle_number = pixc.getncattr('cycle_number')
    pass_number = pixc.getncattr('pass_number')
    swath_side = pixc.getncattr('swath_side')
    if swath_side == 'L':
        swath_side = 'Left'
    if swath_side == 'R':
        swath_side = 'Right'

    near_range = pixc.getncattr('near_range')
    nominal_slant_range_spacing = pixc.getncattr('nominal_slant_range_spacing')

    ri = near_range + nominal_slant_range_spacing * col

    delta_h = 0.

    tropo = Tropo_module(parameters['Tropo model'], min(col), max(col), min(az), max(az), \
    float(parameters['Tropo error stdv']), float(parameters['Tropo error mean']), float(parameters['Tropo error correlation']), \
    parameters['Tropo error map file'])

    tropo.generate_tropo_field_over_pass(min(lat))

    tropo.apply_tropo_error_on_pixels(az, col)
    tropo_2d_field = tropo.tropo_2d_field
    delta_h += tropo_2d_field

    if parameters['roll_repository_name'] != None:

        print("Applying roll residual error")

        roll = Roll_module(parameters['roll_repository_name'])
        roll.get_roll_file_associated_to_orbit_and_cycle(
            pass_number, cycle_number, delta_time=-1541.907908)

        roll.interpolate_roll_on_sensor_grid(orbit_time)

        # Apply roll for each pixel
        roll.interpolate_roll_on_pixelcloud(orbit_time, pixel_cloud_time,
                                            cross_track)
        delta_h_roll = (roll.roll1_err_cloud)
        delta_h += delta_h_roll

    else:
        print("No roll error applied")

    IN_attributes = orbitAttributes()

    IN_attributes.lat = pixc.groups['tvp'].variables['latitude'][:] * DEG2RAD
    IN_attributes.lon = pixc.groups['tvp'].variables['longitude'][:] * DEG2RAD
    IN_attributes.heading_init = pixc.groups['tvp'].variables[
        'velocity_heading'][:] * DEG2RAD
    IN_attributes.alt = pixc.groups['tvp'].variables['altitude'][:]

    IN_attributes.vx = pixc.groups['tvp'].variables['vx'][:]
    IN_attributes.vy = pixc.groups['tvp'].variables['vy'][:]
    IN_attributes.vz = pixc.groups['tvp'].variables['vz'][:]

    if parameters['noisy_geoloc']:

        coordinates_sensor = np.dstack(
            (IN_attributes.lat[az] * RAD2DEG, IN_attributes.lon[az] * RAD2DEG,
             IN_attributes.alt[az]))[0]

        xyz_sensor = project_array(coordinates_sensor,
                                   srcp='latlon',
                                   dstp='geocent')
        coordinates_pixc = np.dstack((lat, lon, height))[0]
        xyz_pixc = project_array(coordinates_pixc,
                                 srcp='latlon',
                                 dstp='geocent')
        vxyz_sensor = np.dstack((IN_attributes.vx[az], IN_attributes.vy[az],
                                 IN_attributes.vz[az]))[0]

        ri = np.sqrt((xyz_sensor[:, 0] - xyz_pixc[:, 0])**2 +
                     (xyz_sensor[:, 1] - xyz_pixc[:, 1])**2 +
                     (xyz_sensor[:, 2] - xyz_pixc[:, 2])**2)

        p_final, p_final_llh, h_mu, (
            iter_grad,
            nfev_minimize_scalar) = my_geoloc.pointcloud_height_geoloc_vect(
                xyz_pixc,
                height,
                xyz_sensor,
                vxyz_sensor,
                ri,
                height + delta_h,
                recompute_doppler=True,
                recompute_range=True,
                verbose=False,
                max_iter_grad=1,
                height_goal=1.e-3)

        final_pixc.groups['pixel_cloud'].variables[
            'latitude'][:] = p_final_llh[:, 0]
        final_pixc.groups['pixel_cloud'].variables[
            'longitude'][:] = p_final_llh[:, 1]
        final_pixc.groups['pixel_cloud'].variables[
            'height'][:] = p_final_llh[:, 2]

    else:
        final_pixc.groups['pixel_cloud'].variables[
            'height'][:] = height + delta_h

    pixc.close()
    final_pixc.close()
    def taylor_improved_geoloc(self):
        """ Improve the height of noisy point (in object sensor) """
        LOGGER.info("doing taylor improved geolocation")

        nb_pix = self.pixc['pixel_cloud']['height'].size
        # Convert geodetic coordinates (lat, lon, height) to cartesian coordinates (x, y, z)
        x, y, z = geoloc.convert_llh2ecef(self.pixc['pixel_cloud']['latitude'],
                                          self.pixc['pixel_cloud']['longitude'],
                                          self.pixc['pixel_cloud']['height'],
                                          GEN_RAD_EARTH_EQ, GEN_RAD_EARTH_POLE)

        # Get position of associated along-track pixels (in cartesian coordinates)
        nadir_x = self.pixc['tvp']['x']
        nadir_y = self.pixc['tvp']['y']
        nadir_z = self.pixc['tvp']['z']

        # Get velocity of associated along-track pixels (in cartesian coordinates)
        nadir_vx = self.pixc['tvp']['vx']
        nadir_vy = self.pixc['tvp']['vy']
        nadir_vz = self.pixc['tvp']['vz']

        # Get distance from satellite to target point
        ri = self.pixc.near_range + (self.pixc['pixel_cloud']['range_index']
                                     * self.pixc.nominal_slant_range_spacing)

        # Init output vectors
        self.out_lat_corr = np.zeros(nb_pix)  # Improved latitudes
        self.out_lon_corr = np.zeros(nb_pix)  # Improved longitudes
        self.out_height_corr = np.zeros(nb_pix)  # Improved heights

        # Remap illumnation time to nearest sensor index
        sensor_s = ag.get_sensor_index(self.pixc)

        # Loop over each pixel (could be vectorized)
        h_noisy = self.pixc['pixel_cloud']['height']
        nadir_x_vect = np.zeros(nb_pix)
        nadir_y_vect = np.zeros(nb_pix)
        nadir_z_vect = np.zeros(nb_pix)
        nadir_vx_vect = np.zeros(nb_pix)
        nadir_vy_vect = np.zeros(nb_pix)
        nadir_vz_vect = np.zeros(nb_pix)

        for i in np.arange(nb_pix):
            ind_sensor = sensor_s[i]
            nadir_x_vect[i] = nadir_x[ind_sensor]
            nadir_y_vect[i] = nadir_y[ind_sensor]
            nadir_z_vect[i] = nadir_z[ind_sensor]
            nadir_vx_vect[i] = nadir_vx[ind_sensor]
            nadir_vy_vect[i] = nadir_vy[ind_sensor]
            nadir_vz_vect[i] = nadir_vz[ind_sensor]

        # improve height with vectorised pixel
        p_final, p_final_llh, h_mu, (iter_grad, nfev_minimize_scalar) = \
            geoloc.pointcloud_height_geoloc_vect(np.transpose(np.array([x, y, z])),
                                                 h_noisy,
                                                 np.transpose(np.array(
                                                     [nadir_x_vect, nadir_y_vect,
                                                      nadir_z_vect])),
                                                 np.transpose(np.array(
                                                     [nadir_vx_vect, nadir_vy_vect,
                                                      nadir_vz_vect])),
                                                 ri, self.new_height,
                                                 recompute_doppler=True,
                                                 recompute_range=True, verbose=False,
                                                 max_iter_grad=1, height_goal=1.e-3)

        self.out_lat_corr, self.out_lon_corr, self.out_height_corr = np.transpose(
            p_final_llh)