void oskar_station_override_element_feed_angle(oskar_Station* s,
        unsigned int seed, int x_pol, double alpha_error_rad,
        double beta_error_rad, double gamma_error_rad, int* status)
{
    int i;

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

    /* Check if there are child stations. */
    if (oskar_station_has_child(s))
    {
        /* Recursive call to find the last level (i.e. the element data). */
        for (i = 0; i < s->num_elements; ++i)
        {
            oskar_station_override_element_feed_angle(
                    oskar_station_child(s, i), seed, x_pol,
                    alpha_error_rad, beta_error_rad, gamma_error_rad, status);
        }
    }
    else
    {
        /* Override element data at last level. */
        int id;
        double *a, *b, *c, r[4];
        oskar_Mem *alpha, *beta, *gamma;

        /* Get pointer to the X or Y element orientation data. */
        alpha = x_pol ? s->element_x_alpha_cpu : s->element_y_alpha_cpu;
        beta  = x_pol ? s->element_x_beta_cpu : s->element_y_beta_cpu;
        gamma = x_pol ? s->element_x_gamma_cpu : s->element_y_gamma_cpu;
        a = oskar_mem_double(alpha, status);
        b = oskar_mem_double(beta, status);
        c = oskar_mem_double(gamma, status);
        id = oskar_station_unique_id(s);
        for (i = 0; i < s->num_elements; ++i)
        {
            /* Generate random numbers from Gaussian distribution. */
            oskar_random_gaussian4(seed, i, id, 0, 0, r);
            r[0] *= alpha_error_rad;
            r[1] *= beta_error_rad;
            r[2] *= gamma_error_rad;

            /* Set the new angle. */
            a[i] += r[0];
            b[i] += r[1];
            c[i] += r[2];
        }
    }
}
Пример #2
0
void oskar_evaluate_element_weights(oskar_Mem* weights,
        oskar_Mem* weights_error, double wavenumber,
        const oskar_Station* station, double x_beam, double y_beam,
        double z_beam, int time_index, int* status)
{
    int num_elements;

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

    /* Resize weights and weights error work arrays if required. */
    num_elements = oskar_station_num_elements(station);
    if ((int)oskar_mem_length(weights) < num_elements)
        oskar_mem_realloc(weights, num_elements, status);
    if ((int)oskar_mem_length(weights_error) < num_elements)
        oskar_mem_realloc(weights_error, num_elements, status);

    /* Generate DFT weights. */
    oskar_evaluate_element_weights_dft(weights, num_elements, wavenumber,
            oskar_station_element_measured_x_enu_metres_const(station),
            oskar_station_element_measured_y_enu_metres_const(station),
            oskar_station_element_measured_z_enu_metres_const(station),
            x_beam, y_beam, z_beam, status);

    /* Apply time-variable errors. */
    if (oskar_station_apply_element_errors(station))
    {
        /* Generate weights errors. */
        oskar_evaluate_element_weights_errors(num_elements,
                oskar_station_element_gain_const(station),
                oskar_station_element_gain_error_const(station),
                oskar_station_element_phase_offset_rad_const(station),
                oskar_station_element_phase_error_rad_const(station),
                oskar_station_seed_time_variable_errors(station), time_index,
                oskar_station_unique_id(station), weights_error, status);

        /* Modify the weights (complex multiply with error vector). */
        oskar_mem_element_multiply(0, weights, weights_error,
                num_elements, status);
    }

    /* Modify the weights using the provided apodisation values. */
    if (oskar_station_apply_element_weight(station))
    {
        oskar_mem_element_multiply(0, weights,
                oskar_station_element_weight_const(station), num_elements,
                status);
    }
}