Esempio n. 1
0
oskar_VisBlock* oskar_simulator_finalise_block(oskar_Simulator* h,
        int block_index, int* status)
{
    int i, i_active;
    oskar_VisBlock *b0 = 0, *b = 0;
    if (*status) return 0;

    /* The visibilities must be copied back
     * at the end of the block simulation. */

    /* Combine all vis blocks into the first one. */
    i_active = (block_index + 1) % 2;
    b0 = h->d[0].vis_block_cpu[!i_active];
    if (!h->coords_only)
    {
        oskar_Mem *xc0 = 0, *ac0 = 0;
        xc0 = oskar_vis_block_cross_correlations(b0);
        ac0 = oskar_vis_block_auto_correlations(b0);
        for (i = 1; i < h->num_devices; ++i)
        {
            b = h->d[i].vis_block_cpu[!i_active];
            if (oskar_vis_block_has_cross_correlations(b))
                oskar_mem_add(xc0, xc0, oskar_vis_block_cross_correlations(b),
                        oskar_mem_length(xc0), status);
            if (oskar_vis_block_has_auto_correlations(b))
                oskar_mem_add(ac0, ac0, oskar_vis_block_auto_correlations(b),
                        oskar_mem_length(ac0), status);
        }
    }

    /* Calculate baseline uvw coordinates for the block. */
    if (oskar_vis_block_has_cross_correlations(b0))
    {
        const oskar_Mem *x, *y, *z;
        x = oskar_telescope_station_measured_x_offset_ecef_metres_const(h->tel);
        y = oskar_telescope_station_measured_y_offset_ecef_metres_const(h->tel);
        z = oskar_telescope_station_measured_z_offset_ecef_metres_const(h->tel);
        oskar_convert_ecef_to_baseline_uvw(
                oskar_telescope_num_stations(h->tel), x, y, z,
                oskar_telescope_phase_centre_ra_rad(h->tel),
                oskar_telescope_phase_centre_dec_rad(h->tel),
                oskar_vis_block_num_times(b0),
                oskar_vis_header_time_start_mjd_utc(h->header),
                oskar_vis_header_time_inc_sec(h->header) / 86400.0,
                oskar_vis_block_start_time_index(b0),
                oskar_vis_block_baseline_uu_metres(b0),
                oskar_vis_block_baseline_vv_metres(b0),
                oskar_vis_block_baseline_ww_metres(b0), h->temp, status);
    }

    /* Add uncorrelated system noise to the combined visibilities. */
    if (!h->coords_only)
    {
        oskar_vis_block_add_system_noise(b0, h->header, h->tel,
                block_index, h->temp, status);
    }

    /* Return a pointer to the block. */
    return b0;
}
Esempio n. 2
0
void oskar_beam_pattern_set_telescope_model(oskar_BeamPattern* h,
        const oskar_Telescope* model, int* status)
{
    if (*status) return;

    /* Check the model is not empty. */
    if (oskar_telescope_num_stations(model) == 0)
    {
        oskar_log_error(h->log, "Telescope model is empty.");
        *status = OSKAR_ERR_SETTINGS_TELESCOPE;
        return;
    }

    /* Remove any existing telescope model, and copy the new one. */
    oskar_telescope_free(h->tel, status);
    h->tel = oskar_telescope_create_copy(model, OSKAR_CPU, status);
    h->pol_mode = oskar_telescope_pol_mode(h->tel);
    h->phase_centre_deg[0] = oskar_telescope_phase_centre_ra_rad(h->tel) *
            180.0 / M_PI;
    h->phase_centre_deg[1] = oskar_telescope_phase_centre_dec_rad(h->tel) *
            180.0 / M_PI;

    /* Analyse the telescope model. */
    oskar_telescope_analyse(h->tel, status);
    if (h->log)
        oskar_telescope_log_summary(h->tel, h->log, status);
}
Esempio n. 3
0
void oskar_simulator_check_init(oskar_Simulator* h, int* status)
{
    if (*status) return;

    /* Check that the telescope model has been set. */
    if (!h->tel)
    {
        oskar_log_error(h->log, "Telescope model not set.");
        *status = OSKAR_ERR_SETTINGS_TELESCOPE;
        return;
    }

    /* Create the visibility header if required. */
    if (!h->header)
        set_up_vis_header(h, status);

    /* Calculate source parameters if required. */
    if (!h->init_sky)
    {
        int i, num_failed = 0;
        double ra0, dec0;

        /* Compute source direction cosines relative to phase centre. */
        ra0 = oskar_telescope_phase_centre_ra_rad(h->tel);
        dec0 = oskar_telescope_phase_centre_dec_rad(h->tel);
        for (i = 0; i < h->num_sky_chunks; ++i)
        {
            oskar_sky_evaluate_relative_directions(h->sky_chunks[i],
                    ra0, dec0, status);

            /* Evaluate extended source parameters. */
            oskar_sky_evaluate_gaussian_source_parameters(h->sky_chunks[i],
                    h->zero_failed_gaussians, ra0, dec0, &num_failed, status);
        }
        if (num_failed > 0)
        {
            if (h->zero_failed_gaussians)
                oskar_log_warning(h->log, "Gaussian ellipse solution failed "
                        "for %i sources. These will have their fluxes "
                        "set to zero.", num_failed);
            else
                oskar_log_warning(h->log, "Gaussian ellipse solution failed "
                        "for %i sources. These will be simulated "
                        "as point sources.", num_failed);
        }
        h->init_sky = 1;
    }

    /* Check that each compute device has been set up. */
    set_up_device_data(h, status);
}
Esempio n. 4
0
static void sim_baselines(oskar_Simulator* h, DeviceData* d, oskar_Sky* sky,
        int channel_index_block, int time_index_block,
        int time_index_simulation, int* status)
{
    int num_baselines, num_stations, num_src, num_times_block, num_channels;
    double dt_dump_days, t_start, t_dump, gast, frequency, ra0, dec0;
    const oskar_Mem *x, *y, *z;
    oskar_Mem* alias = 0;

    /* Get dimensions. */
    num_baselines   = oskar_telescope_num_baselines(d->tel);
    num_stations    = oskar_telescope_num_stations(d->tel);
    num_src         = oskar_sky_num_sources(sky);
    num_times_block = oskar_vis_block_num_times(d->vis_block);
    num_channels    = oskar_vis_block_num_channels(d->vis_block);

    /* Return if there are no sources in the chunk,
     * or if block time index requested is outside the valid range. */
    if (num_src == 0 || time_index_block >= num_times_block) return;

    /* Get the time and frequency of the visibility slice being simulated. */
    dt_dump_days = h->time_inc_sec / 86400.0;
    t_start = h->time_start_mjd_utc;
    t_dump = t_start + dt_dump_days * (time_index_simulation + 0.5);
    gast = oskar_convert_mjd_to_gast_fast(t_dump);
    frequency = h->freq_start_hz + channel_index_block * h->freq_inc_hz;

    /* Scale source fluxes with spectral index and rotation measure. */
    oskar_sky_scale_flux_with_frequency(sky, frequency, status);

    /* Evaluate station u,v,w coordinates. */
    ra0 = oskar_telescope_phase_centre_ra_rad(d->tel);
    dec0 = oskar_telescope_phase_centre_dec_rad(d->tel);
    x = oskar_telescope_station_true_x_offset_ecef_metres_const(d->tel);
    y = oskar_telescope_station_true_y_offset_ecef_metres_const(d->tel);
    z = oskar_telescope_station_true_z_offset_ecef_metres_const(d->tel);
    oskar_convert_ecef_to_station_uvw(num_stations, x, y, z, ra0, dec0, gast,
            d->u, d->v, d->w, status);

    /* Set dimensions of Jones matrices. */
    if (d->R)
        oskar_jones_set_size(d->R, num_stations, num_src, status);
    if (d->Z)
        oskar_jones_set_size(d->Z, num_stations, num_src, status);
    oskar_jones_set_size(d->J, num_stations, num_src, status);
    oskar_jones_set_size(d->E, num_stations, num_src, status);
    oskar_jones_set_size(d->K, num_stations, num_src, status);

    /* Evaluate station beam (Jones E: may be matrix). */
    oskar_timer_resume(d->tmr_E);
    oskar_evaluate_jones_E(d->E, num_src, OSKAR_RELATIVE_DIRECTIONS,
            oskar_sky_l(sky), oskar_sky_m(sky), oskar_sky_n(sky), d->tel,
            gast, frequency, d->station_work, time_index_simulation, status);
    oskar_timer_pause(d->tmr_E);

#if 0
    /* Evaluate ionospheric phase (Jones Z: scalar) and join with Jones E.
     * NOTE this is currently only a CPU implementation. */
    if (d->Z)
    {
        oskar_evaluate_jones_Z(d->Z, num_src, sky, d->tel,
                &settings->ionosphere, gast, frequency, &(d->workJonesZ),
                status);
        oskar_timer_resume(d->tmr_join);
        oskar_jones_join(d->E, d->Z, d->E, status);
        oskar_timer_pause(d->tmr_join);
    }
#endif

    /* Evaluate parallactic angle (Jones R: matrix), and join with Jones Z*E.
     * TODO Move this into station beam evaluation instead. */
    if (d->R)
    {
        oskar_timer_resume(d->tmr_E);
        oskar_evaluate_jones_R(d->R, num_src, oskar_sky_ra_rad_const(sky),
                oskar_sky_dec_rad_const(sky), d->tel, gast, status);
        oskar_timer_pause(d->tmr_E);
        oskar_timer_resume(d->tmr_join);
        oskar_jones_join(d->R, d->E, d->R, status);
        oskar_timer_pause(d->tmr_join);
    }

    /* Evaluate interferometer phase (Jones K: scalar). */
    oskar_timer_resume(d->tmr_K);
    oskar_evaluate_jones_K(d->K, num_src, oskar_sky_l_const(sky),
            oskar_sky_m_const(sky), oskar_sky_n_const(sky), d->u, d->v, d->w,
            frequency, oskar_sky_I_const(sky),
            h->source_min_jy, h->source_max_jy, status);
    oskar_timer_pause(d->tmr_K);

    /* Join Jones K with Jones Z*E. */
    oskar_timer_resume(d->tmr_join);
    oskar_jones_join(d->J, d->K, d->R ? d->R : d->E, status);
    oskar_timer_pause(d->tmr_join);

    /* Create alias for auto/cross-correlations. */
    oskar_timer_resume(d->tmr_correlate);
    alias = oskar_mem_create_alias(0, 0, 0, status);

    /* Auto-correlate for this time and channel. */
    if (oskar_vis_block_has_auto_correlations(d->vis_block))
    {
        oskar_mem_set_alias(alias,
                oskar_vis_block_auto_correlations(d->vis_block),
                num_stations *
                (num_channels * time_index_block + channel_index_block),
                num_stations, status);
        oskar_auto_correlate(alias, num_src, d->J, sky, status);
    }

    /* Cross-correlate for this time and channel. */
    if (oskar_vis_block_has_cross_correlations(d->vis_block))
    {
        oskar_mem_set_alias(alias,
                oskar_vis_block_cross_correlations(d->vis_block),
                num_baselines *
                (num_channels * time_index_block + channel_index_block),
                num_baselines, status);
        oskar_cross_correlate(alias, num_src, d->J, sky, d->tel,
                d->u, d->v, d->w, gast, frequency, status);
    }

    /* Free alias for auto/cross-correlations. */
    oskar_mem_free(alias, status);
    oskar_timer_pause(d->tmr_correlate);
}
Esempio n. 5
0
static void set_up_vis_header(oskar_Simulator* h, int* status)
{
    int num_stations, vis_type;
    const double rad2deg = 180.0/M_PI;
    int write_autocorr = 0, write_crosscorr = 0;
    if (*status) return;

    /* Check type of correlations to produce. */
    if (h->correlation_type == 'C')
        write_crosscorr = 1;
    else if (h->correlation_type == 'A')
        write_autocorr = 1;
    else if (h->correlation_type == 'B')
    {
        write_autocorr = 1;
        write_crosscorr = 1;
    }

    /* Create visibility header. */
    num_stations = oskar_telescope_num_stations(h->tel);
    vis_type = h->prec | OSKAR_COMPLEX;
    if (oskar_telescope_pol_mode(h->tel) == OSKAR_POL_MODE_FULL)
        vis_type |= OSKAR_MATRIX;
    h->header = oskar_vis_header_create(vis_type, h->prec,
            h->max_times_per_block, h->num_time_steps, h->num_channels,
            h->num_channels, num_stations, write_autocorr, write_crosscorr,
            status);

    /* Add metadata from settings. */
    oskar_vis_header_set_freq_start_hz(h->header, h->freq_start_hz);
    oskar_vis_header_set_freq_inc_hz(h->header, h->freq_inc_hz);
    oskar_vis_header_set_time_start_mjd_utc(h->header, h->time_start_mjd_utc);
    oskar_vis_header_set_time_inc_sec(h->header, h->time_inc_sec);

    /* Add settings file contents if defined. */
    if (h->settings_path)
    {
        oskar_Mem* temp;
        temp = oskar_mem_read_binary_raw(h->settings_path,
                OSKAR_CHAR, OSKAR_CPU, status);
        oskar_mem_copy(oskar_vis_header_settings(h->header), temp, status);
        oskar_mem_free(temp, status);
    }

    /* Copy other metadata from telescope model. */
    oskar_vis_header_set_time_average_sec(h->header,
            oskar_telescope_time_average_sec(h->tel));
    oskar_vis_header_set_channel_bandwidth_hz(h->header,
            oskar_telescope_channel_bandwidth_hz(h->tel));
    oskar_vis_header_set_phase_centre(h->header, 0,
            oskar_telescope_phase_centre_ra_rad(h->tel) * rad2deg,
            oskar_telescope_phase_centre_dec_rad(h->tel) * rad2deg);
    oskar_vis_header_set_telescope_centre(h->header,
            oskar_telescope_lon_rad(h->tel) * rad2deg,
            oskar_telescope_lat_rad(h->tel) * rad2deg,
            oskar_telescope_alt_metres(h->tel));
    oskar_mem_copy(oskar_vis_header_station_x_offset_ecef_metres(h->header),
            oskar_telescope_station_true_x_offset_ecef_metres_const(h->tel),
            status);
    oskar_mem_copy(oskar_vis_header_station_y_offset_ecef_metres(h->header),
            oskar_telescope_station_true_y_offset_ecef_metres_const(h->tel),
            status);
    oskar_mem_copy(oskar_vis_header_station_z_offset_ecef_metres(h->header),
            oskar_telescope_station_true_z_offset_ecef_metres_const(h->tel),
            status);
}
Esempio n. 6
0
void oskar_beam_pattern_generate_coordinates(oskar_BeamPattern* h,
        int beam_coord_type, int* status)
{
    size_t num_pixels = 0;
    int nside = 0;

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

    /* If memory is already allocated, do nothing. */
    if (h->x) return;

    /* Calculate number of pixels if possible. */
    if (h->coord_grid_type == 'B') /* Beam image */
    {
        num_pixels = h->width * h->height;
    }
    else if (h->coord_grid_type == 'H') /* Healpix */
    {
        nside = h->nside;
        num_pixels = 12 * nside * nside;
    }
    else if (h->coord_grid_type == 'S') /* Sky model */
        num_pixels = 0;
    else
    {
        *status = OSKAR_ERR_INVALID_ARGUMENT;
        return;
    }

    /* Create output arrays. */
    h->x = oskar_mem_create(h->prec, OSKAR_CPU, num_pixels, status);
    h->y = oskar_mem_create(h->prec, OSKAR_CPU, num_pixels, status);
    h->z = oskar_mem_create(h->prec, OSKAR_CPU, num_pixels, status);

    /* Get equatorial or horizon coordinates. */
    if (h->coord_frame_type == 'E')
    {
        /*
         * Equatorial coordinates.
         */
        switch (h->coord_grid_type)
        {
        case 'B': /* Beam image */
        {
            oskar_evaluate_image_lmn_grid(h->width, h->height,
                    h->fov_deg[0]*(M_PI/180.0), h->fov_deg[1]*(M_PI/180.0), 1,
                    h->x, h->y, h->z, status);
            break;
        }
        case 'H': /* Healpix */
        {
            int num_points, type, i;
            double ra0 = 0.0, dec0 = 0.0;
            oskar_Mem *theta, *phi;

            /* Generate theta and phi from nside. */
            num_points = 12 * nside * nside;
            type = oskar_mem_type(h->x);
            theta = oskar_mem_create(type, OSKAR_CPU, num_points, status);
            phi = oskar_mem_create(type, OSKAR_CPU, num_points, status);
            oskar_convert_healpix_ring_to_theta_phi(nside, theta, phi, status);

            /* Convert theta from polar angle to elevation. */
            if (type == OSKAR_DOUBLE)
            {
                double* theta_ = oskar_mem_double(theta, status);
                for (i = 0; i < num_points; ++i)
                    theta_[i] = 90.0 - theta_[i];
            }
            else if (type == OSKAR_SINGLE)
            {
                float* theta_ = oskar_mem_float(theta, status);
                for (i = 0; i < num_points; ++i)
                    theta_[i] = 90.0f - theta_[i];
            }
            else
            {
                *status = OSKAR_ERR_BAD_DATA_TYPE;
            }

            /* Evaluate beam phase centre coordinates in equatorial frame. */
            if (beam_coord_type == OSKAR_SPHERICAL_TYPE_EQUATORIAL)
            {
                ra0 = oskar_telescope_phase_centre_ra_rad(h->tel);
                dec0 = oskar_telescope_phase_centre_dec_rad(h->tel);
            }
            else if (beam_coord_type == OSKAR_SPHERICAL_TYPE_AZEL)
            {
                /* TODO convert from az0, el0 to ra0, dec0 */
                *status = OSKAR_FAIL;
            }
            else
            {
                *status = OSKAR_ERR_INVALID_ARGUMENT;
            }

            /* Convert equatorial angles to direction cosines in the frame
             * of the beam phase centre. */
            oskar_convert_lon_lat_to_relative_directions(num_points,
                    phi, theta, ra0, dec0, h->x, h->y, h->z, status);

            /* Free memory. */
            oskar_mem_free(theta, status);
            oskar_mem_free(phi, status);
            break;
        }
        case 'S': /* Sky model */
        {
            oskar_Mem *ra, *dec;
            int type = 0, num_points = 0;
            type = oskar_mem_type(h->x);
            ra = oskar_mem_create(type, OSKAR_CPU, 0, status);
            dec = oskar_mem_create(type, OSKAR_CPU, 0, status);
            load_coords(ra, dec, h->sky_model_file, status);
            num_points = oskar_mem_length(ra);
            oskar_mem_realloc(h->x, num_points, status);
            oskar_mem_realloc(h->y, num_points, status);
            oskar_mem_realloc(h->z, num_points, status);
            oskar_convert_lon_lat_to_relative_directions(
                    num_points, ra, dec,
                    oskar_telescope_phase_centre_ra_rad(h->tel),
                    oskar_telescope_phase_centre_dec_rad(h->tel),
                    h->x, h->y, h->z, status);
            oskar_mem_free(ra, status);
            oskar_mem_free(dec, status);
            break;
        }
        default:
            *status = OSKAR_ERR_INVALID_ARGUMENT;
            break;
        };

        /* Set the return values. */
        h->coord_type = OSKAR_RELATIVE_DIRECTIONS;
        h->lon0 = oskar_telescope_phase_centre_ra_rad(h->tel);
        h->lat0 = oskar_telescope_phase_centre_dec_rad(h->tel);
    }
    else if (h->coord_frame_type == 'H')
    {
        /*
         * Horizon coordinates.
         */
        switch (h->coord_grid_type)
        {
        case 'B': /* Beam image */
        {
            /* NOTE: This is for an all-sky image centred on the zenith. */
            oskar_evaluate_image_lmn_grid(h->width, h->height,
                    M_PI, M_PI, 1, h->x, h->y, h->z, status);
            break;
        }
        case 'H': /* Healpix */
        {
            int num_points, type;
            oskar_Mem *theta, *phi;
            num_points = 12 * nside * nside;
            type = oskar_mem_type(h->x);
            theta = oskar_mem_create(type, OSKAR_CPU, num_points, status);
            phi = oskar_mem_create(type, OSKAR_CPU, num_points, status);
            oskar_convert_healpix_ring_to_theta_phi(nside, theta, phi, status);
            oskar_convert_theta_phi_to_enu_directions(num_points,
                    theta, phi, h->x, h->y, h->z, status);
            oskar_mem_free(theta, status);
            oskar_mem_free(phi, status);
            break;
        }
        default:
            *status = OSKAR_ERR_INVALID_ARGUMENT;
            break;
        };

        /* Set the return values. */
        h->coord_type = OSKAR_ENU_DIRECTIONS;
        h->lon0 = 0.0;
        h->lat0 = M_PI / 2.0;
    }
    else
    {
        *status = OSKAR_ERR_INVALID_ARGUMENT;
    }

    /* Set the number of pixels. */
    h->num_pixels = oskar_mem_length(h->x);
}