oskar_Telescope* oskar_telescope_create_copy(const oskar_Telescope* src,
        int location, int* status)
{
    int i = 0;
    oskar_Telescope* telescope;

    /* Create a new, empty model. */
    telescope = oskar_telescope_create(oskar_telescope_precision(src),
            location, 0, status);

    /* Copy private meta-data. */
    telescope->precision = src->precision;
    telescope->mem_location = location;

    /* Copy the meta-data. */
    telescope->pol_mode = src->pol_mode;
    telescope->num_stations = src->num_stations;
    telescope->max_station_size = src->max_station_size;
    telescope->max_station_depth = src->max_station_depth;
    telescope->identical_stations = src->identical_stations;
    telescope->allow_station_beam_duplication = src->allow_station_beam_duplication;
    telescope->enable_numerical_patterns = src->enable_numerical_patterns;
    telescope->lon_rad = src->lon_rad;
    telescope->lat_rad = src->lat_rad;
    telescope->alt_metres = src->alt_metres;
    telescope->pm_x_rad = src->pm_x_rad;
    telescope->pm_y_rad = src->pm_y_rad;
    telescope->phase_centre_coord_type = src->phase_centre_coord_type;
    telescope->phase_centre_ra_rad = src->phase_centre_ra_rad;
    telescope->phase_centre_dec_rad = src->phase_centre_dec_rad;
    telescope->channel_bandwidth_hz = src->channel_bandwidth_hz;
    telescope->time_average_sec = src->time_average_sec;
    telescope->uv_filter_min = src->uv_filter_min;
    telescope->uv_filter_max = src->uv_filter_max;
    telescope->uv_filter_units = src->uv_filter_units;
    telescope->noise_enabled = src->noise_enabled;
    telescope->noise_seed = src->noise_seed;

    /* Copy the coordinates. */
    oskar_mem_copy(telescope->station_true_x_offset_ecef_metres,
            src->station_true_x_offset_ecef_metres, status);
    oskar_mem_copy(telescope->station_true_y_offset_ecef_metres,
            src->station_true_y_offset_ecef_metres, status);
    oskar_mem_copy(telescope->station_true_z_offset_ecef_metres,
            src->station_true_z_offset_ecef_metres, status);
    oskar_mem_copy(telescope->station_true_x_enu_metres,
            src->station_true_x_enu_metres, status);
    oskar_mem_copy(telescope->station_true_y_enu_metres,
            src->station_true_y_enu_metres, status);
    oskar_mem_copy(telescope->station_true_z_enu_metres,
            src->station_true_z_enu_metres, status);
    oskar_mem_copy(telescope->station_measured_x_offset_ecef_metres,
            src->station_measured_x_offset_ecef_metres, status);
    oskar_mem_copy(telescope->station_measured_y_offset_ecef_metres,
            src->station_measured_y_offset_ecef_metres, status);
    oskar_mem_copy(telescope->station_measured_z_offset_ecef_metres,
            src->station_measured_z_offset_ecef_metres, status);
    oskar_mem_copy(telescope->station_measured_x_enu_metres,
            src->station_measured_x_enu_metres, status);
    oskar_mem_copy(telescope->station_measured_y_enu_metres,
            src->station_measured_y_enu_metres, status);
    oskar_mem_copy(telescope->station_measured_z_enu_metres,
            src->station_measured_z_enu_metres, status);

    /* Copy each station. */
    telescope->station = malloc(src->num_stations * sizeof(oskar_Station*));
    for (i = 0; i < src->num_stations; ++i)
    {
        telescope->station[i] = oskar_station_create_copy(
                oskar_telescope_station_const(src, i), location, status);
    }

    /* Return pointer to data structure. */
    return telescope;
}
Example #2
0
void oskar_evaluate_jones_Z(oskar_Jones* Z, const oskar_Sky* sky,
        const oskar_Telescope* telescope,
        const oskar_SettingsIonosphere* settings, double gast,
        double frequency_hz, oskar_WorkJonesZ* work, int* status)
{
    int i, num_sources, num_stations;
    /* Station position in ECEF frame */
    double station_x, station_y, station_z, wavelength;
    oskar_Mem *Z_station;
    int type;
    oskar_Sky* sky_cpu; /* Copy of the sky model on the CPU */

    /* Check if safe to proceed. */
    if (*status) return;

    /* Check data types. */
    type = oskar_sky_precision(sky);
    if (oskar_telescope_precision(telescope) != type ||
            oskar_jones_type(Z) != (type | OSKAR_COMPLEX) ||
            oskar_work_jones_z_type(work) != type)
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return;
    }

    /* For now, this function requires data is on the CPU .. check this. */

    /* Resize the work array (if needed) */
    num_stations = oskar_telescope_num_stations(telescope);
    num_sources = oskar_sky_num_sources(sky);
    oskar_work_jones_z_resize(work, num_sources, status);

    /* Copy the sky model to the CPU. */
    sky_cpu = oskar_sky_create_copy(sky, OSKAR_CPU, status);

    Z_station = oskar_mem_create_alias(0, 0, 0, status);
    wavelength = 299792458.0 / frequency_hz;

    /* Evaluate the ionospheric phase screen for each station at each
     * source pierce point. */
    for (i = 0; i < num_stations; ++i)
    {
        double last, lon, lat;
        const oskar_Station* station;
        station = oskar_telescope_station_const(telescope, i);
        lon = oskar_station_lon_rad(station);
        lat = oskar_station_lat_rad(station);
        last = gast + lon;

        /* Evaluate horizontal x,y,z source positions (for which to evaluate
         * pierce points) */
        oskar_convert_relative_directions_to_enu_directions(
                work->hor_x, work->hor_y, work->hor_z, num_sources,
                oskar_sky_l_const(sky_cpu), oskar_sky_m_const(sky_cpu),
                oskar_sky_n_const(sky_cpu), last - oskar_sky_reference_ra_rad(sky_cpu),
                oskar_sky_reference_dec_rad(sky_cpu), lat, status);

        /* Obtain station coordinates in the ECEF frame. */
        evaluate_station_ECEF_coords(&station_x, &station_y, &station_z, i,
                telescope);

        /* Obtain the pierce points. */
        /* FIXME(BM) this is current hard-coded to TID height screen 0
         * this fix is only needed to support multiple screen heights. */
        oskar_evaluate_pierce_points(work->pp_lon, work->pp_lat,
                work->pp_rel_path, station_x, station_y,
                station_z, settings->TID[0].height_km * 1000., num_sources,
                work->hor_x, work->hor_y, work->hor_z, status);

        /* Evaluate TEC values for the pierce points */
        oskar_evaluate_TEC(work, num_sources, settings, gast, status);

        /* Get a pointer to the Jones matrices for the station */
        oskar_jones_get_station_pointer(Z_station, Z, i, status);

        /* Populate the Jones matrix with ionospheric phase */
        evaluate_jones_Z_station(Z_station, wavelength,
                work->total_TEC, work->hor_z, settings->min_elevation,
                num_sources, status);
    }

    oskar_sky_free(sky_cpu, status);
    oskar_mem_free(Z_station, status);
}