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]; } } }
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); } }