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); } }
TEST(element_weights_errors, test_apply) { int num_elements = 10000; int status = 0; double gain = 1.5; double gain_error = 0.2; double phase = 0.1 * M_PI; double phase_error = (5 / 180.0) * M_PI; double weight_gain = 1.0; double weight_phase = 0.5 * M_PI; double2 weight; weight.x = weight_gain * cos(weight_phase); weight.y = weight_gain * sin(weight_phase); oskar_Mem *d_gain, *d_gain_error, *d_phase, *d_phase_error, *d_errors; oskar_Mem *h_weights, *d_weights; d_errors = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_GPU, num_elements, &status); d_gain = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_gain_error = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_phase = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_phase_error = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); h_weights = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, num_elements, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_set_value_real(d_gain, gain, 0, 0, &status); oskar_mem_set_value_real(d_gain_error, gain_error, 0, 0, &status); oskar_mem_set_value_real(d_phase, phase, 0, 0, &status); oskar_mem_set_value_real(d_phase_error, phase_error, 0, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double2* h_weights_ = oskar_mem_double2(h_weights, &status); for (int i = 0; i < num_elements; ++i) { h_weights_[i].x = weight.x; h_weights_[i].y = weight.y; } d_weights = oskar_mem_create_copy(h_weights, OSKAR_GPU, &status); oskar_evaluate_element_weights_errors(num_elements, d_gain, d_gain_error, d_phase, d_phase_error, 0, 0, 0, d_errors, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_element_multiply(NULL, d_weights, d_errors, num_elements, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Write memory to file for inspection. const char* fname = "temp_test_weights.dat"; FILE* file = fopen(fname, "w"); oskar_mem_save_ascii(file, 7, num_elements, &status, d_gain, d_gain_error, d_phase, d_phase_error, d_errors, h_weights, d_weights); fclose(file); remove(fname); // Free memory. oskar_mem_free(d_gain, &status); oskar_mem_free(d_gain_error, &status); oskar_mem_free(d_phase, &status); oskar_mem_free(d_phase_error, &status); oskar_mem_free(d_errors, &status); oskar_mem_free(h_weights, &status); oskar_mem_free(d_weights, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); }