void oskar_imager_update_plane_fft(oskar_Imager* h, int num_vis, const oskar_Mem* uu, const oskar_Mem* vv, const oskar_Mem* amps, const oskar_Mem* weight, oskar_Mem* plane, double* plane_norm, int* status) { int num_cells, num_skipped = 0; if (*status) return; num_cells = h->grid_size * h->grid_size; if (oskar_mem_precision(plane) != h->imager_prec) *status = OSKAR_ERR_TYPE_MISMATCH; if ((int)oskar_mem_length(plane) < num_cells) oskar_mem_realloc(plane, num_cells, status); if (*status) return; if (h->imager_prec == OSKAR_DOUBLE) oskar_grid_simple_d(h->support, h->oversample, oskar_mem_double_const(h->conv_func, status), num_vis, oskar_mem_double_const(uu, status), oskar_mem_double_const(vv, status), oskar_mem_double_const(amps, status), oskar_mem_double_const(weight, status), h->cellsize_rad, h->grid_size, &num_skipped, plane_norm, oskar_mem_double(plane, status)); else oskar_grid_simple_f(h->support, h->oversample, oskar_mem_double_const(h->conv_func, status), num_vis, oskar_mem_float_const(uu, status), oskar_mem_float_const(vv, status), oskar_mem_float_const(amps, status), oskar_mem_float_const(weight, status), h->cellsize_rad, h->grid_size, &num_skipped, plane_norm, oskar_mem_float(plane, status)); if (num_skipped > 0) printf("WARNING: Skipped %d visibility points.\n", num_skipped); }
static void evaluate_jones_Z_station(oskar_Mem* Z_station, double wavelength, const oskar_Mem* TEC, const oskar_Mem* hor_z, double min_elevation, int num_pp, int* status) { int i, type; double arg; /* Check if safe to proceed. */ if (*status) return; type = oskar_mem_type(Z_station); if (type == OSKAR_DOUBLE_COMPLEX) { double2* Z = oskar_mem_double2(Z_station, status); for (i = 0; i < num_pp; ++i) { /* Initialise as an unit scalar Z = (1 + 0i) i.e. no phase change */ Z[i].x = 1.0; Z[i].y = 0.0; /* If the pierce point is below the minimum specified elevation * don't evaluate a phase */ if (asin((oskar_mem_double_const(hor_z, status))[i]) < min_elevation) continue; arg = wavelength * 25. * oskar_mem_double_const(TEC, status)[i]; /* Z phase == exp(i * lambda * 25 * tec) */ Z[i].x = cos(arg); Z[i].y = sin(arg); } } else if (type == OSKAR_SINGLE_COMPLEX) { float2* Z = oskar_mem_float2(Z_station, status); for (i = 0; i < num_pp; ++i) { /* Initialise as an unit scalar Z = (1 + 0i) i.e. no phase change */ Z[i].x = 1.0; Z[i].y = 0.0; /* If the pierce point is below the minimum specified elevation * don't evaluate a phase */ if (asin((oskar_mem_float_const(hor_z, status))[i]) < min_elevation) continue; arg = wavelength * 25. * oskar_mem_float_const(TEC, status)[i]; /* Z phase == exp(i * lambda * 25 * tec) */ Z[i].x = cos(arg); Z[i].y = sin(arg); } } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } }
void oskar_convert_station_uvw_to_baseline_uvw(int num_stations, int offset_in, const oskar_Mem* u, const oskar_Mem* v, const oskar_Mem* w, int offset_out, oskar_Mem* uu, oskar_Mem* vv, oskar_Mem* ww, int* status) { if (*status) return; const int type = oskar_mem_type(u); const int location = oskar_mem_location(u); if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) convert_station_uvw_to_baseline_uvw_float(num_stations, offset_in, oskar_mem_float_const(u, status), oskar_mem_float_const(v, status), oskar_mem_float_const(w, status), offset_out, oskar_mem_float(uu, status), oskar_mem_float(vv, status), oskar_mem_float(ww, status)); else if (type == OSKAR_DOUBLE) convert_station_uvw_to_baseline_uvw_double(num_stations, offset_in, oskar_mem_double_const(u, status), oskar_mem_double_const(v, status), oskar_mem_double_const(w, status), offset_out, oskar_mem_double(uu, status), oskar_mem_double(vv, status), oskar_mem_double(ww, status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; } else { size_t local_size[] = {32, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; if (type == OSKAR_SINGLE) k = "convert_station_uvw_to_baseline_uvw_float"; else if (type == OSKAR_DOUBLE) k = "convert_station_uvw_to_baseline_uvw_double"; else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = num_stations * local_size[0]; const oskar_Arg args[] = { {INT_SZ, &num_stations}, {INT_SZ, &offset_in}, {PTR_SZ, oskar_mem_buffer_const(u)}, {PTR_SZ, oskar_mem_buffer_const(v)}, {PTR_SZ, oskar_mem_buffer_const(w)}, {INT_SZ, &offset_out}, {PTR_SZ, oskar_mem_buffer(uu)}, {PTR_SZ, oskar_mem_buffer(vv)}, {PTR_SZ, oskar_mem_buffer(ww)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
int oskar_find_closest_match(double value, const oskar_Mem* values, int* status) { int type, num_values, match_index = 0; /* Check if safe to proceed. */ if (*status) return 0; /* Check location. */ if (oskar_mem_location(values) != OSKAR_CPU) { *status = OSKAR_ERR_BAD_LOCATION; return 0; } /* Switch on type. */ type = oskar_mem_type(values); num_values = (int)oskar_mem_length(values); if (type == OSKAR_DOUBLE) { match_index = oskar_find_closest_match_d(value, num_values, oskar_mem_double_const(values, status)); } else if (type == OSKAR_SINGLE) { match_index = oskar_find_closest_match_f(value, num_values, oskar_mem_float_const(values, status)); } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } return match_index; }
void copy_vis_pol(oskar_Mem* amps, oskar_Mem* wt, int amps_offset, const oskar_Mem* vis, const oskar_Mem* weight, int vis_offset, int weight_offset, int num_baselines, int stride, int pol_offset, int* status) { int i; if (*status) return; if (oskar_mem_precision(amps) == OSKAR_SINGLE) { float* w_out; const float* w_in; w_out = oskar_mem_float(wt, status) + amps_offset; w_in = oskar_mem_float_const(weight, status); for (i = 0; i < num_baselines; ++i) w_out[i] = w_in[stride * (weight_offset + i) + pol_offset]; if (vis) { float2* a; const float2* v; a = oskar_mem_float2(amps, status) + amps_offset; v = oskar_mem_float2_const(vis, status); for (i = 0; i < num_baselines; ++i) a[i] = v[stride * (vis_offset + i) + pol_offset]; } } else { double* w_out; const double* w_in; w_out = oskar_mem_double(wt, status) + amps_offset; w_in = oskar_mem_double_const(weight, status); for (i = 0; i < num_baselines; ++i) w_out[i] = w_in[stride * (weight_offset + i) + pol_offset]; if (vis) { double2* a; const double2* v; a = oskar_mem_double2(amps, status) + amps_offset; v = oskar_mem_double2_const(vis, status); for (i = 0; i < num_baselines; ++i) a[i] = v[stride * (vis_offset + i) + pol_offset]; } } }
static void convert_complex(const oskar_Mem* input, oskar_Mem* output, int offset, int* status) { size_t i, num_elements; if (*status) return; num_elements = oskar_mem_length(input); if (oskar_mem_precision(input) == OSKAR_SINGLE) { const float *in; float *out; in = oskar_mem_float_const(input, status); out = oskar_mem_float(output, status); for (i = 0; i < num_elements; ++i) out[i] = in[2*i + offset]; } else { const double *in; double *out; in = oskar_mem_double_const(input, status); out = oskar_mem_double(output, status); for (i = 0; i < num_elements; ++i) out[i] = in[2*i + offset]; } }
void oskar_evaluate_element_weights_dft(int num_elements, const oskar_Mem* x, const oskar_Mem* y, const oskar_Mem* z, double wavenumber, double x_beam, double y_beam, double z_beam, oskar_Mem* weights, int* status) { if (*status) return; const int location = oskar_mem_location(weights); const int type = oskar_mem_type(weights); const int precision = oskar_mem_precision(weights); if (oskar_mem_location(x) != location || oskar_mem_location(y) != location || oskar_mem_location(z) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_type(x) != precision || oskar_mem_type(y) != precision || oskar_mem_type(z) != precision) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if ((int)oskar_mem_length(weights) < num_elements || (int)oskar_mem_length(x) < num_elements || (int)oskar_mem_length(y) < num_elements || (int)oskar_mem_length(z) < num_elements) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } if (location == OSKAR_CPU) { if (type == OSKAR_DOUBLE_COMPLEX) evaluate_element_weights_dft_d(num_elements, oskar_mem_double_const(x, status), oskar_mem_double_const(y, status), oskar_mem_double_const(z, status), wavenumber, x_beam, y_beam, z_beam, oskar_mem_double2(weights, status)); else if (type == OSKAR_SINGLE_COMPLEX) evaluate_element_weights_dft_f(num_elements, oskar_mem_float_const(x, status), oskar_mem_float_const(y, status), oskar_mem_float_const(z, status), wavenumber, x_beam, y_beam, z_beam, oskar_mem_float2(weights, status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; const int is_dbl = oskar_mem_is_double(weights); if (type == OSKAR_DOUBLE_COMPLEX) k = "evaluate_element_weights_dft_double"; else if (type == OSKAR_SINGLE_COMPLEX) k = "evaluate_element_weights_dft_float"; else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } const float w = (float) wavenumber; const float x1 = (float) x_beam; const float y1 = (float) y_beam; const float z1 = (float) z_beam; oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_elements, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &num_elements}, {PTR_SZ, oskar_mem_buffer_const(x)}, {PTR_SZ, oskar_mem_buffer_const(y)}, {PTR_SZ, oskar_mem_buffer_const(z)}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&wavenumber : (const void*)&w}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&x_beam : (const void*)&x1}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&y_beam : (const void*)&y1}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&z_beam : (const void*)&z1}, {PTR_SZ, oskar_mem_buffer(weights)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
void oskar_blank_below_horizon(int offset_mask, int num_sources, const oskar_Mem* mask, int offset_out, oskar_Mem* data, int* status) { if (*status) return; const int location = oskar_mem_location(data); if (oskar_mem_location(mask) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_type(mask) != oskar_mem_precision(data)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if ((int)oskar_mem_length(data) < num_sources) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } if (location == OSKAR_CPU) { switch (oskar_mem_type(data)) { case OSKAR_DOUBLE_COMPLEX_MATRIX: blank_below_horizon_matrix_d(offset_mask, num_sources, oskar_mem_double_const(mask, status), offset_out, oskar_mem_double4c(data, status)); break; case OSKAR_DOUBLE_COMPLEX: blank_below_horizon_scalar_d(offset_mask, num_sources, oskar_mem_double_const(mask, status), offset_out, oskar_mem_double2(data, status)); break; case OSKAR_SINGLE_COMPLEX_MATRIX: blank_below_horizon_matrix_f(offset_mask, num_sources, oskar_mem_float_const(mask, status), offset_out, oskar_mem_float4c(data, status)); break; case OSKAR_SINGLE_COMPLEX: blank_below_horizon_scalar_f(offset_mask, num_sources, oskar_mem_float_const(mask, status), offset_out, oskar_mem_float2(data, status)); break; default: *status = OSKAR_ERR_BAD_DATA_TYPE; break; } } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; switch (oskar_mem_type(data)) { case OSKAR_DOUBLE_COMPLEX_MATRIX: k = "blank_below_horizon_matrix_double"; break; case OSKAR_DOUBLE_COMPLEX: k = "blank_below_horizon_scalar_double"; break; case OSKAR_SINGLE_COMPLEX_MATRIX: k = "blank_below_horizon_matrix_float"; break; case OSKAR_SINGLE_COMPLEX: k = "blank_below_horizon_scalar_float"; break; default: *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_sources, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &offset_mask}, {INT_SZ, &num_sources}, {PTR_SZ, oskar_mem_buffer_const(mask)}, {INT_SZ, &offset_out}, {PTR_SZ, oskar_mem_buffer(data)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
void oskar_dftw( int normalise, int num_in, double wavenumber, const oskar_Mem* weights_in, const oskar_Mem* x_in, const oskar_Mem* y_in, const oskar_Mem* z_in, int offset_coord_out, int num_out, const oskar_Mem* x_out, const oskar_Mem* y_out, const oskar_Mem* z_out, const oskar_Mem* data, int offset_out, oskar_Mem* output, int* status) { if (*status) return; const int location = oskar_mem_location(output); const int type = oskar_mem_precision(output); const int is_dbl = oskar_mem_is_double(output); const int is_3d = (z_in != NULL && z_out != NULL); const int is_data = (data != NULL); const int is_matrix = oskar_mem_is_matrix(output); if (!oskar_mem_is_complex(output) || !oskar_mem_is_complex(weights_in) || oskar_mem_is_matrix(weights_in)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (oskar_mem_location(weights_in) != location || oskar_mem_location(x_in) != location || oskar_mem_location(y_in) != location || oskar_mem_location(x_out) != location || oskar_mem_location(y_out) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_precision(weights_in) != type || oskar_mem_type(x_in) != type || oskar_mem_type(y_in) != type || oskar_mem_type(x_out) != type || oskar_mem_type(y_out) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (is_data) { if (oskar_mem_location(data) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (!oskar_mem_is_complex(data) || oskar_mem_type(data) != oskar_mem_type(output) || oskar_mem_precision(data) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } } if (is_3d) { if (oskar_mem_location(z_in) != location || oskar_mem_location(z_out) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_type(z_in) != type || oskar_mem_type(z_out) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } } oskar_mem_ensure(output, (size_t) offset_out + num_out, status); if (*status) return; if (location == OSKAR_CPU) { if (is_data) { if (is_matrix) { if (is_3d) { if (is_dbl) dftw_m2m_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), oskar_mem_double4c_const(data, status), offset_out, oskar_mem_double4c(output, status), 0); else dftw_m2m_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), oskar_mem_float4c_const(data, status), offset_out, oskar_mem_float4c(output, status), 0); } else { if (is_dbl) dftw_m2m_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, oskar_mem_double4c_const(data, status), offset_out, oskar_mem_double4c(output, status), 0); else dftw_m2m_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, oskar_mem_float4c_const(data, status), offset_out, oskar_mem_float4c(output, status), 0); } } else { if (is_3d) { if (is_dbl) dftw_c2c_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), oskar_mem_double2_const(data, status), offset_out, oskar_mem_double2(output, status), 0); else dftw_c2c_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), oskar_mem_float2_const(data, status), offset_out, oskar_mem_float2(output, status), 0); } else { if (is_dbl) dftw_c2c_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, oskar_mem_double2_const(data, status), offset_out, oskar_mem_double2(output, status), 0); else dftw_c2c_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, oskar_mem_float2_const(data, status), offset_out, oskar_mem_float2(output, status), 0); } } } else { if (is_3d) { if (is_dbl) dftw_o2c_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), 0, offset_out, oskar_mem_double2(output, status), 0); else dftw_o2c_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), 0, offset_out, oskar_mem_float2(output, status), 0); } else { if (is_dbl) dftw_o2c_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, 0, offset_out, oskar_mem_double2(output, status), 0); else dftw_o2c_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, 0, offset_out, oskar_mem_float2(output, status), 0); } } } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const void* np = 0; const char* k = 0; int max_in_chunk; float wavenumber_f = (float) wavenumber; /* Select the kernel. */ switch (is_dbl * DBL | is_3d * D3 | is_data * DAT | is_matrix * MAT) { case D2 | FLT: k = "dftw_o2c_2d_float"; break; case D2 | DBL: k = "dftw_o2c_2d_double"; break; case D3 | FLT: k = "dftw_o2c_3d_float"; break; case D3 | DBL: k = "dftw_o2c_3d_double"; break; case D2 | FLT | DAT: k = "dftw_c2c_2d_float"; break; case D2 | DBL | DAT: k = "dftw_c2c_2d_double"; break; case D3 | FLT | DAT: k = "dftw_c2c_3d_float"; break; case D3 | DBL | DAT: k = "dftw_c2c_3d_double"; break; case D2 | FLT | DAT | MAT: k = "dftw_m2m_2d_float"; break; case D2 | DBL | DAT | MAT: k = "dftw_m2m_2d_double"; break; case D3 | FLT | DAT | MAT: k = "dftw_m2m_3d_float"; break; case D3 | DBL | DAT | MAT: k = "dftw_m2m_3d_double"; break; default: *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE; return; } if (oskar_device_is_nv(location)) local_size[0] = (size_t) get_block_size(num_out); oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_out, local_size[0]); /* max_in_chunk must be multiple of 16. */ max_in_chunk = is_3d ? (is_dbl ? 384 : 800) : (is_dbl ? 448 : 896); if (is_data && is_3d && !is_dbl) max_in_chunk = 768; const size_t element_size = is_dbl ? sizeof(double) : sizeof(float); const size_t local_mem_size = max_in_chunk * element_size; const size_t arg_size_local[] = { 2 * local_mem_size, 2 * local_mem_size, (is_3d ? local_mem_size : 0) }; /* Set kernel arguments. */ const oskar_Arg args[] = { {INT_SZ, &num_in}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (void*)&wavenumber : (void*)&wavenumber_f}, {PTR_SZ, oskar_mem_buffer_const(weights_in)}, {PTR_SZ, oskar_mem_buffer_const(x_in)}, {PTR_SZ, oskar_mem_buffer_const(y_in)}, {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_in) : &np}, {INT_SZ, &offset_coord_out}, {INT_SZ, &num_out}, {PTR_SZ, oskar_mem_buffer_const(x_out)}, {PTR_SZ, oskar_mem_buffer_const(y_out)}, {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_out) : &np}, {PTR_SZ, is_data ? oskar_mem_buffer_const(data) : &np}, {INT_SZ, &offset_out}, {PTR_SZ, oskar_mem_buffer(output)}, {INT_SZ, &max_in_chunk} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, sizeof(arg_size_local) / sizeof(size_t), arg_size_local, status); } if (normalise) oskar_mem_scale_real(output, 1. / num_in, offset_out, num_out, status); }
oskar_Sky* oskar_sky_from_image(int precision, const oskar_Mem* image, int image_width, int image_height, double image_ra_deg, double image_dec_deg, double image_cellsize_deg, double image_freq_hz, double spectral_index, int* status) { int i, type, x, y; double crval[2], crpix[2], cdelt[2], val; oskar_Sky* sky; /* Check if safe to proceed. */ if (*status) return 0; /* Check the image size is even. */ if ((image_width % 2) || (image_height % 2)) { *status = OSKAR_ERR_INVALID_ARGUMENT; return 0; } /* Get reference pixels and reference values in radians. */ crpix[0] = image_width / 2 + 1; crpix[1] = image_height / 2 + 1; crval[0] = image_ra_deg * M_PI / 180.0; crval[1] = image_dec_deg * M_PI / 180.0; /* Compute sine of pixel deltas for inverse orthographic projection. */ cdelt[0] = -sin(image_cellsize_deg * M_PI / 180.0); cdelt[1] = -cdelt[0]; /* Create a sky model. */ sky = oskar_sky_create(precision, OSKAR_CPU, 0, status); /* Store the image pixels. */ type = oskar_mem_precision(image); if (type == OSKAR_SINGLE) { const float *img = oskar_mem_float_const(image, status); for (y = 0, i = 0; y < image_height; ++y) { for (x = 0; x < image_width; ++x) { /* Check pixel value. */ val = (double) (img[image_width * y + x]); if (val == 0.0) continue; set_pixel(sky, i++, x, y, val, crval, crpix, cdelt, image_freq_hz, spectral_index, status); } } } else { const double *img = oskar_mem_double_const(image, status); for (y = 0, i = 0; y < image_height; ++y) { for (x = 0; x < image_width; ++x) { /* Check pixel value. */ val = img[image_width * y + x]; if (val == 0.0) continue; set_pixel(sky, i++, x, y, val, crval, crpix, cdelt, image_freq_hz, spectral_index, status); } } } /* Return the sky model. */ oskar_sky_resize(sky, i, status); return sky; }
/* Wrapper. */ void oskar_convert_ludwig3_to_theta_phi_components(oskar_Mem* vec, int offset, int stride, int num_points, const oskar_Mem* phi, int* status) { int type, location; /* Check if safe to proceed. */ if (*status) return; /* Check that the vector component data is in matrix form. */ if (!oskar_mem_is_matrix(vec)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* Get data type and location. */ type = oskar_mem_type(phi); location = oskar_mem_location(phi); /* Convert vector representation from Ludwig-3 to spherical. */ if (type == OSKAR_SINGLE) { float2 *h_theta, *v_phi; const float *phi_; h_theta = oskar_mem_float2(vec, status) + offset; v_phi = oskar_mem_float2(vec, status) + offset + 1; phi_ = oskar_mem_float_const(phi, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_convert_ludwig3_to_theta_phi_components_cuda_f(num_points, h_theta, v_phi, phi_, stride); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { oskar_convert_ludwig3_to_theta_phi_components_f(num_points, h_theta, v_phi, phi_, stride); } } else if (type == OSKAR_DOUBLE) { double2 *h_theta, *v_phi; const double *phi_; h_theta = oskar_mem_double2(vec, status) + offset; v_phi = oskar_mem_double2(vec, status) + offset + 1; phi_ = oskar_mem_double_const(phi, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_convert_ludwig3_to_theta_phi_components_cuda_d(num_points, h_theta, v_phi, phi_, stride); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { oskar_convert_ludwig3_to_theta_phi_components_d(num_points, h_theta, v_phi, phi_, stride); } } else *status = OSKAR_ERR_BAD_DATA_TYPE; }
} /* Check numbers are the same, to appropriate precision. */ if (prec_approx == OSKAR_SINGLE && prec_accurate == OSKAR_SINGLE) { const float *approx, *accurate; approx = oskar_mem_float_const(app_ptr, status); accurate = oskar_mem_float_const(acc_ptr, status); CHECK_ELEMENTS(1e-5) } else if (prec_approx == OSKAR_DOUBLE && prec_accurate == OSKAR_SINGLE) { const double *approx; const float *accurate; approx = oskar_mem_double_const(app_ptr, status); accurate = oskar_mem_float_const(acc_ptr, status); CHECK_ELEMENTS(1e-5); } else if (prec_approx == OSKAR_SINGLE && prec_accurate == OSKAR_DOUBLE) { const float *approx; const double *accurate; approx = oskar_mem_float_const(app_ptr, status); accurate = oskar_mem_double_const(acc_ptr, status); CHECK_ELEMENTS(1e-5); } else if (prec_approx == OSKAR_DOUBLE && prec_accurate == OSKAR_DOUBLE) { const double *approx, *accurate; approx = oskar_mem_double_const(app_ptr, status); accurate = oskar_mem_double_const(acc_ptr, status);
int main(int argc, char** argv) { // ===== Declare options ================================================== oskar::OptionParser opt("oskar_vis_to_ascii_table", oskar_version_string()); opt.set_description("Converts an OSKAR visibility binary file to an ASCII " "table format with the following columns:\n " "[1] index, [2] baseline-uu, [3] baseline-vv, [4] baseline-ww " "[5] Real, [6] Imag. " "The table is written out in baseline-time order where baseline " "is the fastest varying dimension"); opt.add_required("OSKAR vis file"); opt.add_optional("output file name"); opt.add_flag("-c", "Channel index to write to file. (default = 0)", 1, "0", false, "--channel"); opt.add_flag("-p", "Polarisation ID to write to file. (default = 0) " "(0=I, 1=Q, 2=U, 3=V, 4=XX, 5=XY, 6=YX, 7=YY)", 1, "0", false, "--polarisation"); opt.add_flag("-t", "Time index to write to file. (default = all)", 1, "", false, "--time"); opt.add_flag("-w", "Output baseline coordinates in wavelengths. " "(default = metres)", false, "--baseline_wavelengths"); opt.add_flag("-h", "Write a summary header in the ASCII table. "); opt.add_flag("-v", "Verbose mode."); opt.add_flag("--csv", "Write in CSV format"); opt.add_flag("-s", "Write output table to standard output instead of to file.", false, "--stdout"); if (!opt.check_options(argc, argv)) return EXIT_FAILURE; // ===== Read options ==================================================== const char* vis_file = opt.get_arg(0); std::string txt_file; if (opt.num_args() == 2) txt_file = std::string(opt.get_arg(1)); else { txt_file = std::string(vis_file) + ".txt"; } int c = 0, p = 0, t = -1; if (opt.is_set("-c")) c = opt.get_int("-c"); if (opt.is_set("-p")) p = opt.get_int("-p"); if (opt.is_set("-t")) t = opt.get_int("-t"); bool metres = !opt.is_set("-w"); bool write_header = opt.is_set("-h"); bool csv = opt.is_set("--csv"); bool verbose = opt.is_set("-v"); // ===== Write table ====================================================== int status = 0; oskar_Binary* h = oskar_binary_create(vis_file, 'r', &status); oskar_Vis* vis = oskar_vis_read(h, &status); if (status) { fprintf(stderr, "ERROR: Unable to read specified visibility file: %s\n", vis_file); oskar_vis_free(vis, &status); oskar_binary_free(h); return status; } oskar_binary_free(h); int num_chan = oskar_vis_num_channels(vis); int num_times = oskar_vis_num_times(vis); int num_baselines = oskar_vis_num_baselines(vis); int num_pol = oskar_vis_num_pols(vis); int num_stations = oskar_vis_num_stations(vis); int total_vis = num_chan * num_times * num_baselines * num_pol; double freq_start_hz = oskar_vis_freq_start_hz(vis); double freq_inc_hz = oskar_vis_freq_inc_hz(vis); double freq_hz = freq_start_hz + c * freq_inc_hz; double lambda_m = 299792458.0 / freq_hz; if (t != -1 && t > num_times-1) { fprintf(stderr, "ERROR: Time index out of range.\n"); return EXIT_FAILURE; } if (c > num_chan-1) { fprintf(stderr, "ERROR: Channel index out of range.\n"); return EXIT_FAILURE; } FILE* out; if (!opt.is_set("-s")) { out = fopen(txt_file.c_str(), "w"); if (out == NULL) return EXIT_FAILURE; } else { out = stdout; } const oskar_Mem* uu = oskar_vis_baseline_uu_metres_const(vis); const oskar_Mem* vv = oskar_vis_baseline_vv_metres_const(vis); const oskar_Mem* ww = oskar_vis_baseline_ww_metres_const(vis); const oskar_Mem* amp = oskar_vis_amplitude_const(vis); // amplitudes dims: channel x times x baselines x pol int amp_offset = c * num_times * num_baselines; if (t != -1) amp_offset += t * num_baselines; // baseline dims: times x baselines int baseline_offset = 0; if (t != -1) baseline_offset = t * num_baselines; int type = oskar_mem_type(uu); int num_vis_out = num_baselines; if (t == -1) num_vis_out *= num_times; if (verbose) { write_header_(stdout, total_vis, num_chan, num_times, num_baselines, num_pol, num_stations, num_vis_out, c, freq_hz, lambda_m, p, t, metres); #if 0 fprintf(stdout, "amp_offset = %i\n", amp_offset); fprintf(stdout, "baseline_offset = %i\n", baseline_offset); #endif } // Write header if specified if (write_header) { write_header_(out, total_vis, num_chan, num_times, num_baselines, num_pol, num_stations, num_vis_out, c, freq_hz, lambda_m, p, t, metres); char pre = '#'; fprintf(out, "%c\n", pre); fprintf(out, "%c %s %-14s %-15s %-15s %-23s %-15s\n", pre, "Idx", " uu", " vv", " ww", " Amp. Re.", " Amp. Im."); } if (type == OSKAR_DOUBLE) { const double* uu_ = oskar_mem_double_const(uu, &status); const double* vv_ = oskar_mem_double_const(vv, &status); const double* ww_ = oskar_mem_double_const(ww, &status); const double4c* amp_ = oskar_mem_double4c_const(amp, &status); int aIdx = amp_offset; int bIdx = baseline_offset; for (int i = 0; i < num_vis_out; ++i, ++bIdx, ++aIdx) { double2 a = getPolAmp_<double2, double4c>(amp_[aIdx], p); double buu = (metres)? uu_[bIdx] : uu_[bIdx]/lambda_m; double bvv = (metres)? vv_[bIdx] : vv_[bIdx]/lambda_m; double bww = (metres)? ww_[bIdx] : ww_[bIdx]/lambda_m; writeData_<double, double2>(i, buu, bvv, bww, a, csv, out); } } else // OSKAR_SINGLE { const float* uu_ = oskar_mem_float_const(uu, &status); const float* vv_ = oskar_mem_float_const(vv, &status); const float* ww_ = oskar_mem_float_const(ww, &status); const float4c* amp_ = oskar_mem_float4c_const(amp, &status); int aIdx = amp_offset; int bIdx = baseline_offset; for (int i = 0; i < num_vis_out; ++i, ++bIdx, ++aIdx) { float2 a = getPolAmp_<float2, float4c>(amp_[aIdx], p); float buu = (metres)? uu_[bIdx] : uu_[bIdx]/lambda_m; float bvv = (metres)? vv_[bIdx] : vv_[bIdx]/lambda_m; float bww = (metres)? ww_[bIdx] : ww_[bIdx]/lambda_m; writeData_<float, float2>(i, buu, bvv, bww, a, csv, out); } } fclose(out); oskar_vis_free(vis, &status); return status; }
void oskar_auto_correlate(oskar_Mem* vis, int n_sources, const oskar_Jones* J, const oskar_Sky* sky, int* status) { int jones_type, base_type, location, matrix_type, n_stations; /* Check if safe to proceed. */ if (*status) return; /* Get the data dimensions. */ n_stations = oskar_jones_num_stations(J); /* Check data locations. */ location = oskar_sky_mem_location(sky); if (oskar_jones_mem_location(J) != location || oskar_mem_location(vis) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Check for consistent data types. */ jones_type = oskar_jones_type(J); base_type = oskar_sky_precision(sky); matrix_type = oskar_type_is_matrix(jones_type) && oskar_mem_is_matrix(vis); if (oskar_mem_precision(vis) != base_type || oskar_type_precision(jones_type) != base_type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (oskar_mem_type(vis) != jones_type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* If neither single or double precision, return error. */ if (base_type != OSKAR_SINGLE && base_type != OSKAR_DOUBLE) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } /* Check the input dimensions. */ if (oskar_jones_num_sources(J) < n_sources) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Select kernel. */ if (base_type == OSKAR_DOUBLE) { const double *I_, *Q_, *U_, *V_; I_ = oskar_mem_double_const(oskar_sky_I_const(sky), status); Q_ = oskar_mem_double_const(oskar_sky_Q_const(sky), status); U_ = oskar_mem_double_const(oskar_sky_U_const(sky), status); V_ = oskar_mem_double_const(oskar_sky_V_const(sky), status); if (matrix_type) { double4c *vis_; const double4c *J_; vis_ = oskar_mem_double4c(vis, status); J_ = oskar_jones_double4c_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_cuda_d(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_omp_d(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); } } else /* Scalar version. */ { double2 *vis_; const double2 *J_; vis_ = oskar_mem_double2(vis, status); J_ = oskar_jones_double2_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_scalar_cuda_d(n_sources, n_stations, J_, I_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_scalar_omp_d(n_sources, n_stations, J_, I_, vis_); } } } else /* Single precision. */ { const float *I_, *Q_, *U_, *V_; I_ = oskar_mem_float_const(oskar_sky_I_const(sky), status); Q_ = oskar_mem_float_const(oskar_sky_Q_const(sky), status); U_ = oskar_mem_float_const(oskar_sky_U_const(sky), status); V_ = oskar_mem_float_const(oskar_sky_V_const(sky), status); if (matrix_type) { float4c *vis_; const float4c *J_; vis_ = oskar_mem_float4c(vis, status); J_ = oskar_jones_float4c_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_cuda_f(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_omp_f(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); } } else /* Scalar version. */ { float2 *vis_; const float2 *J_; vis_ = oskar_mem_float2(vis, status); J_ = oskar_jones_float2_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_scalar_cuda_f(n_sources, n_stations, J_, I_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_scalar_omp_f(n_sources, n_stations, J_, I_, vis_); } } } }
int main(int argc, char** argv) { int status = 0; oskar::OptionParser opt("oskar_evaulate_pierce_points", oskar_version_string()); opt.add_required("settings file"); if (!opt.check_options(argc, argv)) return EXIT_FAILURE; const char* settings_file = opt.get_arg(); // Create the log. oskar_Log* log = oskar_log_create(OSKAR_LOG_MESSAGE, OSKAR_LOG_STATUS); oskar_log_message(log, 'M', 0, "Running binary %s", argv[0]); // Enum values used in writing time-freq data binary files enum OSKAR_TIME_FREQ_TAGS { TIME_IDX = 0, FREQ_IDX = 1, TIME_MJD_UTC = 2, FREQ_HZ = 3, NUM_FIELDS = 4, NUM_FIELD_TAGS = 5, HEADER_OFFSET = 10, DATA = 0, DIMS = 1, LABEL = 2, UNITS = 3, GRP = OSKAR_TAG_GROUP_TIME_FREQ_DATA }; oskar_Settings_old settings; oskar_settings_old_load(&settings, log, settings_file, &status); oskar_log_set_keep_file(log, settings.sim.keep_log_file); if (status) return status; oskar_Telescope* tel = oskar_settings_to_telescope(&settings, log, &status); oskar_Sky* sky = oskar_settings_to_sky(&settings, log, &status); // FIXME remove this restriction ... (see evaluate Z) if (settings.ionosphere.num_TID_screens != 1) return OSKAR_ERR_SETUP_FAIL; int type = settings.sim.double_precision ? OSKAR_DOUBLE : OSKAR_SINGLE; int loc = OSKAR_CPU; int num_sources = oskar_sky_num_sources(sky); oskar_Mem *hor_x, *hor_y, *hor_z; hor_x = oskar_mem_create(type, loc, num_sources, &status); hor_y = oskar_mem_create(type, loc, num_sources, &status); hor_z = oskar_mem_create(type, loc, num_sources, &status); oskar_Mem *pp_lon, *pp_lat, *pp_rel_path; int num_stations = oskar_telescope_num_stations(tel); int num_pp = num_stations * num_sources; pp_lon = oskar_mem_create(type, loc, num_pp, &status); pp_lat = oskar_mem_create(type, loc, num_pp, &status); pp_rel_path = oskar_mem_create(type, loc, num_pp, &status); // Pierce points for one station (non-owned oskar_Mem pointers) oskar_Mem *pp_st_lon, *pp_st_lat, *pp_st_rel_path; pp_st_lon = oskar_mem_create_alias(0, 0, 0, &status); pp_st_lat = oskar_mem_create_alias(0, 0, 0, &status); pp_st_rel_path = oskar_mem_create_alias(0, 0, 0, &status); int num_times = settings.obs.num_time_steps; double obs_start_mjd_utc = settings.obs.start_mjd_utc; double dt_dump = settings.obs.dt_dump_days; // Binary file meta-data std::string label1 = "pp_lon"; std::string label2 = "pp_lat"; std::string label3 = "pp_path"; std::string units = "radians"; std::string units2 = ""; oskar_Mem *dims = oskar_mem_create(OSKAR_INT, loc, 2, &status); /* FIXME is this the correct dimension order ? * FIXME get the MATLAB reader to respect dimension ordering */ oskar_mem_int(dims, &status)[0] = num_sources; oskar_mem_int(dims, &status)[1] = num_stations; const char* filename = settings.ionosphere.pierce_points.filename; oskar_Binary* h = oskar_binary_create(filename, 'w', &status); double screen_height_m = settings.ionosphere.TID->height_km * 1000.0; // printf("Number of times = %i\n", num_times); // printf("Number of stations = %i\n", num_stations); void *x_, *y_, *z_; x_ = oskar_mem_void(oskar_telescope_station_true_x_offset_ecef_metres(tel)); y_ = oskar_mem_void(oskar_telescope_station_true_y_offset_ecef_metres(tel)); z_ = oskar_mem_void(oskar_telescope_station_true_z_offset_ecef_metres(tel)); for (int t = 0; t < num_times; ++t) { double t_dump = obs_start_mjd_utc + t * dt_dump; // MJD UTC double gast = oskar_convert_mjd_to_gast_fast(t_dump + dt_dump / 2.0); for (int i = 0; i < num_stations; ++i) { const oskar_Station* station = oskar_telescope_station_const(tel, i); double lon = oskar_station_lon_rad(station); double lat = oskar_station_lat_rad(station); double alt = oskar_station_alt_metres(station); double x_ecef, y_ecef, z_ecef, x_offset, y_offset, z_offset; if (type == OSKAR_DOUBLE) { x_offset = ((double*)x_)[i]; y_offset = ((double*)y_)[i]; z_offset = ((double*)z_)[i]; } else { x_offset = (double)((float*)x_)[i]; y_offset = (double)((float*)y_)[i]; z_offset = (double)((float*)z_)[i]; } oskar_convert_offset_ecef_to_ecef(1, &x_offset, &y_offset, &z_offset, lon, lat, alt, &x_ecef, &y_ecef, &z_ecef); double last = gast + lon; if (type == OSKAR_DOUBLE) { oskar_convert_apparent_ra_dec_to_enu_directions_d(num_sources, oskar_mem_double_const(oskar_sky_ra_rad_const(sky), &status), oskar_mem_double_const(oskar_sky_dec_rad_const(sky), &status), last, lat, oskar_mem_double(hor_x, &status), oskar_mem_double(hor_y, &status), oskar_mem_double(hor_z, &status)); } else { oskar_convert_apparent_ra_dec_to_enu_directions_f(num_sources, oskar_mem_float_const(oskar_sky_ra_rad_const(sky), &status), oskar_mem_float_const(oskar_sky_dec_rad_const(sky), &status), last, lat, oskar_mem_float(hor_x, &status), oskar_mem_float(hor_y, &status), oskar_mem_float(hor_z, &status)); } int offset = i * num_sources; oskar_mem_set_alias(pp_st_lon, pp_lon, offset, num_sources, &status); oskar_mem_set_alias(pp_st_lat, pp_lat, offset, num_sources, &status); oskar_mem_set_alias(pp_st_rel_path, pp_rel_path, offset, num_sources, &status); oskar_evaluate_pierce_points(pp_st_lon, pp_st_lat, pp_st_rel_path, x_ecef, y_ecef, z_ecef, screen_height_m, num_sources, hor_x, hor_y, hor_z, &status); } // Loop over stations. if (status != 0) continue; int index = t; // could be = (num_times * f) + t if we have frequency data int num_fields = 3; int num_field_tags = 4; double freq_hz = 0.0; int freq_idx = 0; // Write the header TAGS oskar_binary_write_int(h, GRP, TIME_IDX, index, t, &status); oskar_binary_write_double(h, GRP, FREQ_IDX, index, freq_idx, &status); oskar_binary_write_double(h, GRP, TIME_MJD_UTC, index, t_dump, &status); oskar_binary_write_double(h, GRP, FREQ_HZ, index, freq_hz, &status); oskar_binary_write_int(h, GRP, NUM_FIELDS, index, num_fields, &status); oskar_binary_write_int(h, GRP, NUM_FIELD_TAGS, index, num_field_tags, &status); // Write data TAGS (fields) int field, tagID; field = 0; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_lon, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label1.size()+1, label1.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units.size()+1, units.c_str(), &status); field = 1; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_lat, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label2.size()+1, label2.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units.size()+1, units.c_str(), &status); field = 2; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_rel_path, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label3.size()+1, label3.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units2.size()+1, units2.c_str(), &status); } // Loop over times // Close the OSKAR binary file. oskar_binary_free(h); // clean up memory oskar_mem_free(hor_x, &status); oskar_mem_free(hor_y, &status); oskar_mem_free(hor_z, &status); oskar_mem_free(pp_lon, &status); oskar_mem_free(pp_lat, &status); oskar_mem_free(pp_rel_path, &status); oskar_mem_free(pp_st_lon, &status); oskar_mem_free(pp_st_lat, &status); oskar_mem_free(pp_st_rel_path, &status); oskar_mem_free(dims, &status); oskar_telescope_free(tel, &status); oskar_sky_free(sky, &status); // Check for errors. if (status) oskar_log_error(log, "Run failed: %s.", oskar_get_error_string(status)); oskar_log_free(log); return status; }
/* Wrapper. */ void oskar_sky_scale_flux_with_frequency(oskar_Sky* sky, double frequency, int* status) { int type, location, num_sources; /* Check if safe to proceed. */ if (*status) return; /* Get the type, location and dimensions. */ type = oskar_sky_precision(sky); location = oskar_sky_mem_location(sky); num_sources = oskar_sky_num_sources(sky); /* Scale the flux values. */ if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) oskar_sky_scale_flux_with_frequency_f(num_sources, frequency, oskar_mem_float(oskar_sky_I(sky), status), oskar_mem_float(oskar_sky_Q(sky), status), oskar_mem_float(oskar_sky_U(sky), status), oskar_mem_float(oskar_sky_V(sky), status), oskar_mem_float(oskar_sky_reference_freq_hz(sky), status), oskar_mem_float_const( oskar_sky_spectral_index_const(sky), status), oskar_mem_float_const( oskar_sky_rotation_measure_rad_const(sky), status)); else if (type == OSKAR_DOUBLE) oskar_sky_scale_flux_with_frequency_d(num_sources, frequency, oskar_mem_double(oskar_sky_I(sky), status), oskar_mem_double(oskar_sky_Q(sky), status), oskar_mem_double(oskar_sky_U(sky), status), oskar_mem_double(oskar_sky_V(sky), status), oskar_mem_double(oskar_sky_reference_freq_hz(sky), status), oskar_mem_double_const( oskar_sky_spectral_index_const(sky), status), oskar_mem_double_const( oskar_sky_rotation_measure_rad_const(sky), status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; } else if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (type == OSKAR_SINGLE) oskar_sky_scale_flux_with_frequency_cuda_f(num_sources, frequency, oskar_mem_float(oskar_sky_I(sky), status), oskar_mem_float(oskar_sky_Q(sky), status), oskar_mem_float(oskar_sky_U(sky), status), oskar_mem_float(oskar_sky_V(sky), status), oskar_mem_float(oskar_sky_reference_freq_hz(sky), status), oskar_mem_float_const( oskar_sky_spectral_index_const(sky), status), oskar_mem_float_const( oskar_sky_rotation_measure_rad_const(sky), status)); else if (type == OSKAR_DOUBLE) oskar_sky_scale_flux_with_frequency_cuda_d(num_sources, frequency, oskar_mem_double(oskar_sky_I(sky), status), oskar_mem_double(oskar_sky_Q(sky), status), oskar_mem_double(oskar_sky_U(sky), status), oskar_mem_double(oskar_sky_V(sky), status), oskar_mem_double(oskar_sky_reference_freq_hz(sky), status), oskar_mem_double_const( oskar_sky_spectral_index_const(sky), status), oskar_mem_double_const( oskar_sky_rotation_measure_rad_const(sky), status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location & OSKAR_CL) { #ifdef OSKAR_HAVE_OPENCL cl_event event; cl_kernel k = 0; cl_int error, num; cl_uint arg = 0; size_t global_size, local_size; if (type == OSKAR_DOUBLE) k = oskar_cl_kernel("scale_flux_with_frequency_double"); else if (type == OSKAR_SINGLE) k = oskar_cl_kernel("scale_flux_with_frequency_float"); else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (!k) { *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE; return; } /* Set kernel arguments. */ num = (cl_int) num_sources; error = clSetKernelArg(k, arg++, sizeof(cl_int), &num); if (type == OSKAR_SINGLE) { const cl_float freq = (cl_float) frequency; error |= clSetKernelArg(k, arg++, sizeof(cl_float), &freq); } else if (type == OSKAR_DOUBLE) { const cl_double freq = (cl_double) frequency; error |= clSetKernelArg(k, arg++, sizeof(cl_double), &freq); } error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_I(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_Q(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_U(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_V(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_reference_freq_hz(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer_const(oskar_sky_spectral_index_const(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer_const(oskar_sky_rotation_measure_rad_const(sky), status)); if (error != CL_SUCCESS) { *status = OSKAR_ERR_INVALID_ARGUMENT; return; } /* Launch kernel on current command queue. */ local_size = oskar_cl_is_gpu() ? 256 : 128; global_size = ((num + local_size - 1) / local_size) * local_size; error = clEnqueueNDRangeKernel(oskar_cl_command_queue(), k, 1, NULL, &global_size, &local_size, 0, NULL, &event); if (error != CL_SUCCESS) *status = OSKAR_ERR_KERNEL_LAUNCH_FAILURE; #else *status = OSKAR_ERR_OPENCL_NOT_AVAILABLE; #endif } else *status = OSKAR_ERR_BAD_LOCATION; }
void oskar_gaussian_circular(int num_points, const oskar_Mem* l, const oskar_Mem* m, double std, oskar_Mem* out, int* status) { if (*status) return; const int location = oskar_mem_location(out); const double inv_2_var = 1.0 / (2.0 * std * std); const float inv_2_var_f = (float)inv_2_var; if (oskar_mem_precision(out) != oskar_mem_type(l) || oskar_mem_precision(out) != oskar_mem_type(m)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (location != oskar_mem_location(l) || location != oskar_mem_location(m)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if ((int)oskar_mem_length(l) < num_points || (int)oskar_mem_length(m) < num_points) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } oskar_mem_ensure(out, num_points, status); if (*status) return; if (location == OSKAR_CPU) { switch (oskar_mem_type(out)) { case OSKAR_SINGLE_COMPLEX: gaussian_circular_complex_f(num_points, oskar_mem_float_const(l, status), oskar_mem_float_const(m, status), inv_2_var_f, oskar_mem_float2(out, status)); break; case OSKAR_DOUBLE_COMPLEX: gaussian_circular_complex_d(num_points, oskar_mem_double_const(l, status), oskar_mem_double_const(m, status), inv_2_var, oskar_mem_double2(out, status)); break; case OSKAR_SINGLE_COMPLEX_MATRIX: gaussian_circular_matrix_f(num_points, oskar_mem_float_const(l, status), oskar_mem_float_const(m, status), inv_2_var_f, oskar_mem_float4c(out, status)); break; case OSKAR_DOUBLE_COMPLEX_MATRIX: gaussian_circular_matrix_d(num_points, oskar_mem_double_const(l, status), oskar_mem_double_const(m, status), inv_2_var, oskar_mem_double4c(out, status)); break; default: *status = OSKAR_ERR_BAD_DATA_TYPE; break; } } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; const int is_dbl = oskar_mem_is_double(out); switch (oskar_mem_type(out)) { case OSKAR_SINGLE_COMPLEX: k = "gaussian_circular_complex_float"; break; case OSKAR_DOUBLE_COMPLEX: k = "gaussian_circular_complex_double"; break; case OSKAR_SINGLE_COMPLEX_MATRIX: k = "gaussian_circular_matrix_float"; break; case OSKAR_DOUBLE_COMPLEX_MATRIX: k = "gaussian_circular_matrix_double"; break; default: *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_points, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &num_points}, {PTR_SZ, oskar_mem_buffer_const(l)}, {PTR_SZ, oskar_mem_buffer_const(m)}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&inv_2_var : (const void*)&inv_2_var_f}, {PTR_SZ, oskar_mem_buffer(out)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
/* Wrapper. */ void oskar_convert_ecef_to_station_uvw(int num_stations, const oskar_Mem* x, const oskar_Mem* y, const oskar_Mem* z, double ra0_rad, double dec0_rad, double gast, oskar_Mem* u, oskar_Mem* v, oskar_Mem* w, int* status) { int type, location; double ha0_rad; /* Check if safe to proceed. */ if (*status) return; /* Get data type and location of the input coordinates. */ type = oskar_mem_type(x); location = oskar_mem_location(x); /* Check that the memory is allocated. */ if (!oskar_mem_allocated(u) || !oskar_mem_allocated(v) || !oskar_mem_allocated(w) || !oskar_mem_allocated(x) || !oskar_mem_allocated(y) || !oskar_mem_allocated(z)) { *status = OSKAR_ERR_MEMORY_NOT_ALLOCATED; return; } /* Check that the data dimensions are OK. */ if ((int)oskar_mem_length(u) < num_stations || (int)oskar_mem_length(v) < num_stations || (int)oskar_mem_length(w) < num_stations || (int)oskar_mem_length(x) < num_stations || (int)oskar_mem_length(y) < num_stations || (int)oskar_mem_length(z) < num_stations) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Check that the data are in the right location. */ if (oskar_mem_location(y) != location || oskar_mem_location(z) != location || oskar_mem_location(u) != location || oskar_mem_location(v) != location || oskar_mem_location(w) != location) { *status = OSKAR_ERR_BAD_LOCATION; return; } /* Check that the data is of the right type. */ if (oskar_mem_type(y) != type || oskar_mem_type(z) != type || oskar_mem_type(u) != type || oskar_mem_type(v) != type || oskar_mem_type(w) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* Evaluate Greenwich Hour Angle of phase centre. */ ha0_rad = gast - ra0_rad; /* Evaluate station u,v,w coordinates. */ if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (type == OSKAR_SINGLE) { oskar_convert_ecef_to_station_uvw_cuda_f(num_stations, oskar_mem_float_const(x, status), oskar_mem_float_const(y, status), oskar_mem_float_const(z, status), (float)ha0_rad, (float)dec0_rad, oskar_mem_float(u, status), oskar_mem_float(v, status), oskar_mem_float(w, status)); } else if (type == OSKAR_DOUBLE) { oskar_convert_ecef_to_station_uvw_cuda_d(num_stations, oskar_mem_double_const(x, status), oskar_mem_double_const(y, status), oskar_mem_double_const(z, status), ha0_rad, dec0_rad, oskar_mem_double(u, status), oskar_mem_double(v, status), oskar_mem_double(w, status)); } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) { oskar_convert_ecef_to_station_uvw_f(num_stations, oskar_mem_float_const(x, status), oskar_mem_float_const(y, status), oskar_mem_float_const(z, status), (float)ha0_rad, (float)dec0_rad, oskar_mem_float(u, status), oskar_mem_float(v, status), oskar_mem_float(w, status)); } else if (type == OSKAR_DOUBLE) { oskar_convert_ecef_to_station_uvw_d(num_stations, oskar_mem_double_const(x, status), oskar_mem_double_const(y, status), oskar_mem_double_const(z, status), ha0_rad, dec0_rad, oskar_mem_double(u, status), oskar_mem_double(v, status), oskar_mem_double(w, status)); } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } } else { *status = OSKAR_ERR_BAD_LOCATION; } }
/* Wrapper. */ void oskar_convert_enu_directions_to_theta_phi(int num_points, const oskar_Mem* x, const oskar_Mem* y, const oskar_Mem* z, double delta_phi, oskar_Mem* theta, oskar_Mem* phi, int* status) { int type, location; /* Check if safe to proceed. */ if (*status) return; /* Get data type and location. */ type = oskar_mem_type(theta); location = oskar_mem_location(theta); /* Compute modified theta and phi coordinates. */ if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (type == OSKAR_SINGLE) { oskar_convert_enu_directions_to_theta_phi_cuda_f(num_points, oskar_mem_float_const(x, status), oskar_mem_float_const(y, status), oskar_mem_float_const(z, status), (float)delta_phi, oskar_mem_float(theta, status), oskar_mem_float(phi, status)); oskar_device_check_error(status); } else if (type == OSKAR_DOUBLE) { oskar_convert_enu_directions_to_theta_phi_cuda_d(num_points, oskar_mem_double_const(x, status), oskar_mem_double_const(y, status), oskar_mem_double_const(z, status), delta_phi, oskar_mem_double(theta, status), oskar_mem_double(phi, status)); oskar_device_check_error(status); } else *status = OSKAR_ERR_BAD_DATA_TYPE; #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) { oskar_convert_enu_directions_to_theta_phi_f(num_points, oskar_mem_float_const(x, status), oskar_mem_float_const(y, status), oskar_mem_float_const(z, status), (float)delta_phi, oskar_mem_float(theta, status), oskar_mem_float(phi, status)); } else if (type == OSKAR_DOUBLE) { oskar_convert_enu_directions_to_theta_phi_d(num_points, oskar_mem_double_const(x, status), oskar_mem_double_const(y, status), oskar_mem_double_const(z, status), delta_phi, oskar_mem_double(theta, status), oskar_mem_double(phi, status)); } else *status = OSKAR_ERR_BAD_DATA_TYPE; } }
void oskar_sky_append_to_set(int* set_size, oskar_Sky*** set_ptr, int max_sources_per_model, const oskar_Sky* model, int* status) { int free_space, space_required, num_extra_models, number_to_copy; int i, j, type, location, from_offset; oskar_Sky **set; size_t new_size; /* Check if safe to proceed. */ if (*status) return; /* Get type and location. */ type = oskar_sky_precision(model); location = oskar_sky_mem_location(model); if (location != OSKAR_CPU) { *status = OSKAR_ERR_BAD_LOCATION; return; } /* Work out if the set needs to be resized, and if so by how much. */ free_space = (*set_size == 0) ? 0 : max_sources_per_model - (*set_ptr)[*set_size - 1]->num_sources; space_required = model->num_sources - free_space; num_extra_models = (space_required + max_sources_per_model - 1) / max_sources_per_model; /* Sanity check. */ if (num_extra_models < 0) { *status = OSKAR_ERR_INVALID_ARGUMENT; return; } /* Resize the array of sky model handles. */ new_size = (*set_size + num_extra_models) * sizeof(oskar_Sky*); *set_ptr = realloc((*set_ptr), new_size); set = *set_ptr; for (i = *set_size; i < *set_size + num_extra_models; ++i) { set[i] = oskar_sky_create(type, location, max_sources_per_model, status); /* TODO Please clarify this statement and explain why it's needed. */ /* Set the number sources to zero as this is the number currently * allocated in the model. */ set[i]->num_sources = 0; } if (*status) return; /* Copy sources from the model into the set. */ /* Loop over set entries with free space and copy sources into them. */ number_to_copy = model->num_sources; from_offset = 0; for (i = (*set_size-1 > 0) ? *set_size-1 : 0; i < *set_size + num_extra_models; ++i) { int n_copy, offset_dst; offset_dst = oskar_sky_num_sources(set[i]); free_space = max_sources_per_model - offset_dst; n_copy = MIN(free_space, number_to_copy); oskar_sky_copy_contents(set[i], model, offset_dst, from_offset, n_copy, status); if (*status) break; set[i]->num_sources = n_copy + offset_dst; number_to_copy -= n_copy; from_offset += n_copy; } if (*status) return; /* Set the use extended flag if needed. */ for (j = (*set_size-1 > 0) ? *set_size-1 : 0; j < *set_size + num_extra_models; ++j) { oskar_Sky* sky = set[j]; const oskar_Mem *major, *minor; /* If any source in the model is extended, set the flag. */ major = oskar_sky_fwhm_major_rad_const(sky); minor = oskar_sky_fwhm_minor_rad_const(sky); if (type == OSKAR_DOUBLE) { const double *maj_, *min_; maj_ = oskar_mem_double_const(major, status); min_ = oskar_mem_double_const(minor, status); for (i = 0; i < sky->num_sources; ++i) { if (maj_[i] > 0.0 || min_[i] > 0.0) { sky->use_extended = OSKAR_TRUE; break; } } } else { const float *maj_, *min_; maj_ = oskar_mem_float_const(major, status); min_ = oskar_mem_float_const(minor, status); for (i = 0; i < sky->num_sources; ++i) { if (maj_[i] > 0.0 || min_[i] > 0.0) { sky->use_extended = OSKAR_TRUE; break; } } } } /* Update the set size */ *set_size += num_extra_models; }
void oskar_mem_evaluate_relative_error(const oskar_Mem* val_approx, const oskar_Mem* val_accurate, double* min_rel_error, double* max_rel_error, double* avg_rel_error, double* std_rel_error, int* status) { int prec_approx, prec_accurate; size_t i, n; const oskar_Mem *app_ptr, *acc_ptr; oskar_Mem *approx_temp = 0, *accurate_temp = 0; double old_m = 0.0, new_m = 0.0, old_s = 0.0, new_s = 0.0; /* Check if safe to proceed. */ if (*status) return; /* Initialise outputs. */ if (max_rel_error) *max_rel_error = -DBL_MAX; if (min_rel_error) *min_rel_error = DBL_MAX; if (avg_rel_error) *avg_rel_error = DBL_MAX; if (std_rel_error) *std_rel_error = DBL_MAX; /* Type and dimension check. */ if (oskar_mem_is_matrix(val_approx) && !oskar_mem_is_matrix(val_accurate)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (oskar_mem_is_complex(val_approx) && !oskar_mem_is_complex(val_accurate)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* Get and check base types. */ prec_approx = oskar_mem_precision(val_approx); prec_accurate = oskar_mem_precision(val_accurate); if (prec_approx != OSKAR_SINGLE && prec_approx != OSKAR_DOUBLE) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (prec_accurate != OSKAR_SINGLE && prec_accurate != OSKAR_DOUBLE) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } /* Get number of elements to check. */ n = oskar_mem_length(val_approx) < oskar_mem_length(val_accurate) ? oskar_mem_length(val_approx) : oskar_mem_length(val_accurate); if (oskar_mem_is_matrix(val_approx)) n *= 4; /* Copy input data to temporary CPU arrays if required. */ app_ptr = val_approx; acc_ptr = val_accurate; if (oskar_mem_location(val_approx) != OSKAR_CPU) { approx_temp = oskar_mem_create_copy(val_approx, OSKAR_CPU, status); if (*status) { oskar_mem_free(approx_temp, status); return; } app_ptr = approx_temp; } if (oskar_mem_location(val_accurate) != OSKAR_CPU) { accurate_temp = oskar_mem_create_copy(val_accurate, OSKAR_CPU, status); if (*status) { oskar_mem_free(accurate_temp, status); return; } acc_ptr = accurate_temp; } /* Check numbers are the same, to appropriate precision. */ if (prec_approx == OSKAR_SINGLE && prec_accurate == OSKAR_SINGLE) { const float *approx, *accurate; approx = oskar_mem_float_const(app_ptr, status); accurate = oskar_mem_float_const(acc_ptr, status); CHECK_ELEMENTS(1e-5) } else if (prec_approx == OSKAR_DOUBLE && prec_accurate == OSKAR_SINGLE)
/* Wrapper. */ void oskar_evaluate_jones_K(oskar_Jones* K, int num_sources, const oskar_Mem* l, const oskar_Mem* m, const oskar_Mem* n, const oskar_Mem* u, const oskar_Mem* v, const oskar_Mem* w, double frequency_hz, const oskar_Mem* source_filter, double source_filter_min, double source_filter_max, int* status) { int num_stations, jones_type, base_type, location; double wavenumber; /* Check if safe to proceed. */ if (*status) return; /* Get the Jones matrix block meta-data. */ jones_type = oskar_jones_type(K); base_type = oskar_type_precision(jones_type); location = oskar_jones_mem_location(K); num_stations = oskar_jones_num_stations(K); wavenumber = 2.0 * M_PI * frequency_hz / 299792458.0; /* Check that the data is in the right location. */ if (oskar_mem_location(l) != location || oskar_mem_location(m) != location || oskar_mem_location(n) != location || oskar_mem_location(source_filter) != location || oskar_mem_location(u) != location || oskar_mem_location(v) != location || oskar_mem_location(w) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Check that the data are of the right type. */ if (!oskar_type_is_complex(jones_type) || oskar_type_is_matrix(jones_type)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (base_type != oskar_mem_type(l) || base_type != oskar_mem_type(m) || base_type != oskar_mem_type(n) || base_type != oskar_mem_type(u) || base_type != oskar_mem_type(v) || base_type != oskar_mem_type(w) || base_type != oskar_mem_type(source_filter)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* Evaluate Jones matrices. */ if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (jones_type == OSKAR_SINGLE_COMPLEX) { oskar_evaluate_jones_K_cuda_f(oskar_jones_float2(K, status), num_sources, oskar_mem_float_const(l, status), oskar_mem_float_const(m, status), oskar_mem_float_const(n, status), num_stations, oskar_mem_float_const(u, status), oskar_mem_float_const(v, status), oskar_mem_float_const(w, status), wavenumber, oskar_mem_float_const(source_filter, status), source_filter_min, source_filter_max); } else if (jones_type == OSKAR_DOUBLE_COMPLEX) { oskar_evaluate_jones_K_cuda_d(oskar_jones_double2(K, status), num_sources, oskar_mem_double_const(l, status), oskar_mem_double_const(m, status), oskar_mem_double_const(n, status), num_stations, oskar_mem_double_const(u, status), oskar_mem_double_const(v, status), oskar_mem_double_const(w, status), wavenumber, oskar_mem_double_const(source_filter, status), source_filter_min, source_filter_max); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { if (jones_type == OSKAR_SINGLE_COMPLEX) { oskar_evaluate_jones_K_f(oskar_jones_float2(K, status), num_sources, oskar_mem_float_const(l, status), oskar_mem_float_const(m, status), oskar_mem_float_const(n, status), num_stations, oskar_mem_float_const(u, status), oskar_mem_float_const(v, status), oskar_mem_float_const(w, status), wavenumber, oskar_mem_float_const(source_filter, status), source_filter_min, source_filter_max); } else if (jones_type == OSKAR_DOUBLE_COMPLEX) { oskar_evaluate_jones_K_d(oskar_jones_double2(K, status), num_sources, oskar_mem_double_const(l, status), oskar_mem_double_const(m, status), oskar_mem_double_const(n, status), num_stations, oskar_mem_double_const(u, status), oskar_mem_double_const(v, status), oskar_mem_double_const(w, status), wavenumber, oskar_mem_double_const(source_filter, status), source_filter_min, source_filter_max); } } }
void oskar_imager_update_plane_wproj(oskar_Imager* h, size_t num_vis, const oskar_Mem* uu, const oskar_Mem* vv, const oskar_Mem* ww, const oskar_Mem* amps, const oskar_Mem* weight, oskar_Mem* plane, double* plane_norm, size_t* num_skipped, int* status) { int grid_size; size_t num_cells; if (*status) return; grid_size = oskar_imager_plane_size(h); num_cells = grid_size * grid_size; if (oskar_mem_precision(plane) != h->imager_prec) *status = OSKAR_ERR_TYPE_MISMATCH; if (oskar_mem_length(plane) < num_cells) oskar_mem_realloc(plane, num_cells, status); if (*status) return; if (h->imager_prec == OSKAR_DOUBLE) oskar_grid_wproj_d(h->num_w_planes, oskar_mem_int_const(h->w_support, status), h->oversample, h->conv_size_half, oskar_mem_double_const(h->w_kernels, status), num_vis, oskar_mem_double_const(uu, status), oskar_mem_double_const(vv, status), oskar_mem_double_const(ww, status), oskar_mem_double_const(amps, status), oskar_mem_double_const(weight, status), h->cellsize_rad, h->w_scale, grid_size, num_skipped, plane_norm, oskar_mem_double(plane, status)); else { char *fname = 0; #if SAVE_INPUT_DAT || SAVE_OUTPUT_DAT || SAVE_GRID fname = (char*) calloc(20 + h->input_root ? strlen(h->input_root) : 0, 1); #endif #if SAVE_INPUT_DAT { const float cellsize_rad_tmp = (const float) (h->cellsize_rad); const float w_scale_tmp = (const float) (h->w_scale); const size_t num_w_planes = (size_t) (h->num_w_planes); FILE* f; sprintf(fname, "%s_INPUT.dat", h->input_root); f = fopen(fname, "wb"); fwrite(&num_w_planes, sizeof(size_t), 1, f); fwrite(oskar_mem_void_const(h->w_support), sizeof(int), num_w_planes, f); fwrite(&h->oversample, sizeof(int), 1, f); fwrite(&h->conv_size_half, sizeof(int), 1, f); fwrite(oskar_mem_void_const(h->w_kernels), 2 * sizeof(float), h->num_w_planes * h->conv_size_half * h->conv_size_half, f); fwrite(&num_vis, sizeof(size_t), 1, f); fwrite(oskar_mem_void_const(uu), sizeof(float), num_vis, f); fwrite(oskar_mem_void_const(vv), sizeof(float), num_vis, f); fwrite(oskar_mem_void_const(ww), sizeof(float), num_vis, f); fwrite(oskar_mem_void_const(amps), 2 * sizeof(float), num_vis, f); fwrite(oskar_mem_void_const(weight), sizeof(float), num_vis, f); fwrite(&cellsize_rad_tmp, sizeof(float), 1, f); fwrite(&w_scale_tmp, sizeof(float), 1, f); fwrite(&grid_size, sizeof(int), 1, f); fclose(f); } #endif oskar_grid_wproj_f(h->num_w_planes, oskar_mem_int_const(h->w_support, status), h->oversample, h->conv_size_half, oskar_mem_float_const(h->w_kernels, status), num_vis, oskar_mem_float_const(uu, status), oskar_mem_float_const(vv, status), oskar_mem_float_const(ww, status), oskar_mem_float_const(amps, status), oskar_mem_float_const(weight, status), (float) (h->cellsize_rad), (float) (h->w_scale), grid_size, num_skipped, plane_norm, oskar_mem_float(plane, status)); #if SAVE_OUTPUT_DAT { FILE* f; sprintf(fname, "%s_OUTPUT.dat", h->input_root); f = fopen(fname, "wb"); fwrite(num_skipped, sizeof(size_t), 1, f); fwrite(plane_norm, sizeof(double), 1, f); fwrite(&grid_size, sizeof(int), 1, f); fwrite(oskar_mem_void_const(plane), 2 * sizeof(float), num_cells, f); fclose(f); } #endif #if SAVE_GRID sprintf(fname, "%s_GRID", h->input_root); oskar_mem_write_fits_cube(plane, fname, grid_size, grid_size, 1, 0, status); #endif free(fname); } }
void oskar_splines_evaluate(const oskar_Splines* spline, int num_points, const oskar_Mem* x, const oskar_Mem* y, int stride_out, int offset_out, oskar_Mem* output, int* status) { if (*status) return; const int type = oskar_splines_precision(spline); const int location = oskar_splines_mem_location(spline); const int nx = oskar_splines_num_knots_x_theta(spline); const int ny = oskar_splines_num_knots_y_phi(spline); const oskar_Mem* tx = oskar_splines_knots_x_theta_const(spline); const oskar_Mem* ty = oskar_splines_knots_y_phi_const(spline); const oskar_Mem* coeff = oskar_splines_coeff_const(spline); if (type != oskar_mem_type(x) || type != oskar_mem_type(y)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (location != oskar_mem_location(output) || location != oskar_mem_location(x) || location != oskar_mem_location(y)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (location == OSKAR_CPU) { int i; if (type == OSKAR_SINGLE) { const float *tx_, *ty_, *coeff_, *x_, *y_; float *out; tx_ = oskar_mem_float_const(tx, status); ty_ = oskar_mem_float_const(ty, status); coeff_ = oskar_mem_float_const(coeff, status); x_ = oskar_mem_float_const(x, status); y_ = oskar_mem_float_const(y, status); out = oskar_mem_float(output, status) + offset_out; if (nx == 0 || ny == 0 || !tx_ || !ty_ || !coeff_) for (i = 0; i < num_points; ++i) out[i * stride_out] = 0.0f; else { float x1, y1, wrk[8]; int iwrk1[2], kwrk1 = 2, lwrk = 8, err = 0; for (i = 0; i < num_points; ++i) { x1 = x_[i]; y1 = y_[i]; oskar_dierckx_bispev_f(tx_, nx, ty_, ny, coeff_, 3, 3, &x1, 1, &y1, 1, &out[i * stride_out], wrk, lwrk, iwrk1, kwrk1, &err); if (err != 0) { *status = OSKAR_ERR_SPLINE_EVAL_FAIL; return; } } } } else if (type == OSKAR_DOUBLE) { const double *tx_, *ty_, *coeff_, *x_, *y_; double *out; tx_ = oskar_mem_double_const(tx, status); ty_ = oskar_mem_double_const(ty, status); coeff_ = oskar_mem_double_const(coeff, status); x_ = oskar_mem_double_const(x, status); y_ = oskar_mem_double_const(y, status); out = oskar_mem_double(output, status) + offset_out; if (nx == 0 || ny == 0 || !tx_ || !ty_ || !coeff_) for (i = 0; i < num_points; ++i) out[i * stride_out] = 0.0; else { double x1, y1, wrk[8]; int iwrk1[2], kwrk1 = 2, lwrk = 8, err = 0; for (i = 0; i < num_points; ++i) { x1 = x_[i]; y1 = y_[i]; oskar_dierckx_bispev_d(tx_, nx, ty_, ny, coeff_, 3, 3, &x1, 1, &y1, 1, &out[i * stride_out], wrk, lwrk, iwrk1, kwrk1, &err); if (err != 0) { *status = OSKAR_ERR_SPLINE_EVAL_FAIL; return; } } } } else *status = OSKAR_ERR_BAD_DATA_TYPE; } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; if (nx == 0 || ny == 0) { if (type == OSKAR_DOUBLE) k = "set_zeros_stride_double"; else if (type == OSKAR_SINGLE) k = "set_zeros_stride_float"; else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_points, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &num_points}, {INT_SZ, &stride_out}, {INT_SZ, &offset_out}, {PTR_SZ, oskar_mem_buffer(output)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } else { if (type == OSKAR_DOUBLE) k = "dierckx_bispev_bicubic_double"; else if (type == OSKAR_SINGLE) k = "dierckx_bispev_bicubic_float"; else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_points, local_size[0]); const oskar_Arg args[] = { {PTR_SZ, oskar_mem_buffer_const(tx)}, {INT_SZ, &nx}, {PTR_SZ, oskar_mem_buffer_const(ty)}, {INT_SZ, &ny}, {PTR_SZ, oskar_mem_buffer_const(coeff)}, {INT_SZ, &num_points}, {PTR_SZ, oskar_mem_buffer_const(x)}, {PTR_SZ, oskar_mem_buffer_const(y)}, {INT_SZ, &stride_out}, {INT_SZ, &offset_out}, {PTR_SZ, oskar_mem_buffer(output)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } } }
void oskar_evaluate_vla_beam_pbcor(oskar_Mem* beam, int num_sources, const oskar_Mem* l, const oskar_Mem* m, double frequency_hz, int* status) { int index, precision, type, location; double f, p1, p2, p3; /* Check if safe to proceed. */ if (*status) return; /* Check type and location. */ precision = oskar_mem_precision(beam); type = oskar_mem_type(beam); location = oskar_mem_location(beam); if (precision != oskar_mem_type(l) || precision != oskar_mem_type(m)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (location != oskar_mem_location(l) || location != oskar_mem_location(m)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Find the nearest frequency at which data exists. */ index = oskar_find_closest_match_d(frequency_hz / 1.0e9, sizeof(freqs_ghz) / sizeof(double), freqs_ghz); f = frequency_hz / 1.0e9; p1 = p1s[index]; p2 = p2s[index]; p3 = p3s[index]; /* Switch on precision. */ if (precision == OSKAR_SINGLE) { const float *l_, *m_; l_ = oskar_mem_float_const(l, status); m_ = oskar_mem_float_const(m, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (type == OSKAR_SINGLE) { oskar_evaluate_vla_beam_pbcor_cuda_f( oskar_mem_float(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_SINGLE_COMPLEX) { oskar_evaluate_vla_beam_pbcor_complex_cuda_f( oskar_mem_float2(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_SINGLE_COMPLEX_MATRIX) { oskar_evaluate_vla_beam_pbcor_matrix_cuda_f( oskar_mem_float4c(beam, status), num_sources, l_, m_, f, p1, p2, p3); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) { oskar_evaluate_vla_beam_pbcor_f( oskar_mem_float(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_SINGLE_COMPLEX) { oskar_evaluate_vla_beam_pbcor_complex_f( oskar_mem_float2(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_SINGLE_COMPLEX_MATRIX) { oskar_evaluate_vla_beam_pbcor_matrix_f( oskar_mem_float4c(beam, status), num_sources, l_, m_, f, p1, p2, p3); } } } else if (precision == OSKAR_DOUBLE) { const double *l_, *m_; l_ = oskar_mem_double_const(l, status); m_ = oskar_mem_double_const(m, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (type == OSKAR_DOUBLE) { oskar_evaluate_vla_beam_pbcor_cuda_d( oskar_mem_double(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_DOUBLE_COMPLEX) { oskar_evaluate_vla_beam_pbcor_complex_cuda_d( oskar_mem_double2(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_DOUBLE_COMPLEX_MATRIX) { oskar_evaluate_vla_beam_pbcor_matrix_cuda_d( oskar_mem_double4c(beam, status), num_sources, l_, m_, f, p1, p2, p3); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { if (type == OSKAR_DOUBLE) { oskar_evaluate_vla_beam_pbcor_d( oskar_mem_double(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_DOUBLE_COMPLEX) { oskar_evaluate_vla_beam_pbcor_complex_d( oskar_mem_double2(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_DOUBLE_COMPLEX_MATRIX) { oskar_evaluate_vla_beam_pbcor_matrix_d( oskar_mem_double4c(beam, status), num_sources, l_, m_, f, p1, p2, p3); } } } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } }
void oskar_evaluate_tec_tid(oskar_Mem* tec, int num_directions, const oskar_Mem* lon, const oskar_Mem* lat, const oskar_Mem* rel_path_length, double TEC0, oskar_SettingsTIDscreen* TID, double gast) { int i, j, type; double pp_lon, pp_lat; double pp_sec; double pp_tec; double amp, w, th, v; /* TID parameters */ double time; double earth_radius = 6365.0; /* km -- FIXME */ int status = 0; /* TODO check types, dimensions etc of memory */ type = oskar_mem_type(tec); oskar_mem_set_value_real(tec, 0.0, 0, 0, &status); /* Loop over TIDs */ for (i = 0; i < TID->num_components; ++i) { amp = TID->amp[i]; /* convert from km to rads */ w = TID->wavelength[i] / (earth_radius + TID->height_km); th = TID->theta[i] * M_PI/180.; /* convert from km/h to rad/s */ v = (TID->speed[i]/(earth_radius + TID->height_km)) / 3600; time = gast * 86400.0; /* days->sec */ /* Loop over directions */ for (j = 0; j < num_directions; ++j) { if (type == OSKAR_DOUBLE) { pp_lon = oskar_mem_double_const(lon, &status)[j]; pp_lat = oskar_mem_double_const(lat, &status)[j]; pp_sec = oskar_mem_double_const(rel_path_length, &status)[j]; pp_tec = pp_sec * amp * TEC0 * ( cos( (2.0*M_PI/w) * (cos(th)*pp_lon - v*time) ) + cos( (2.0*M_PI/w) * (sin(th)*pp_lat - v*time) ) ); pp_tec += TEC0; oskar_mem_double(tec, &status)[j] += pp_tec; } else { pp_lon = (double)oskar_mem_float_const(lon, &status)[j]; pp_lat = (double)oskar_mem_float_const(lat, &status)[j]; pp_sec = (double)oskar_mem_float_const(rel_path_length, &status)[j]; pp_tec = pp_sec * amp * TEC0 * ( cos( (2.0*M_PI/w) * (cos(th)*pp_lon - v*time) ) + cos( (2.0*M_PI/w) * (sin(th)*pp_lat - v*time) ) ); pp_tec += TEC0; oskar_mem_float(tec, &status)[j] += (float)pp_tec; } } /* loop over directions */ } /* loop over components. */ }
void oskar_sky_evaluate_gaussian_source_parameters(oskar_Sky* sky, int zero_failed_sources, double ra0, double dec0, int* num_failed, int* status) { int i, j, num_sources; int type; /* Check if safe to proceed. */ if (*status) return; /* Return if memory is not on the CPU. */ if (oskar_sky_mem_location(sky) != OSKAR_CPU) { *status = OSKAR_ERR_BAD_LOCATION; return; } /* Get data type and number of sources. */ type = oskar_sky_precision(sky); num_sources = oskar_sky_num_sources(sky); /* Switch on type. */ if (type == OSKAR_DOUBLE) { /* Double precision. */ const double *ra_, *dec_, *maj_, *min_, *pa_; double *I_, *Q_, *U_, *V_, *a_, *b_, *c_; double cos_pa_2, sin_pa_2, sin_2pa, inv_std_min_2, inv_std_maj_2; double ellipse_a, ellipse_b, maj, min, pa, cos_pa, sin_pa, t; double l[ELLIPSE_PTS], m[ELLIPSE_PTS]; double work1[5 * ELLIPSE_PTS], work2[5 * ELLIPSE_PTS]; double lon[ELLIPSE_PTS], lat[ELLIPSE_PTS]; double x[ELLIPSE_PTS], y[ELLIPSE_PTS], z[ELLIPSE_PTS]; ra_ = oskar_mem_double_const(oskar_sky_ra_rad_const(sky), status); dec_ = oskar_mem_double_const(oskar_sky_dec_rad_const(sky), status); maj_ = oskar_mem_double_const(oskar_sky_fwhm_major_rad_const(sky), status); min_ = oskar_mem_double_const(oskar_sky_fwhm_minor_rad_const(sky), status); pa_ = oskar_mem_double_const(oskar_sky_position_angle_rad_const(sky), status); I_ = oskar_mem_double(oskar_sky_I(sky), status); Q_ = oskar_mem_double(oskar_sky_Q(sky), status); U_ = oskar_mem_double(oskar_sky_U(sky), status); V_ = oskar_mem_double(oskar_sky_V(sky), status); a_ = oskar_mem_double(oskar_sky_gaussian_a(sky), status); b_ = oskar_mem_double(oskar_sky_gaussian_b(sky), status); c_ = oskar_mem_double(oskar_sky_gaussian_c(sky), status); for (i = 0; i < num_sources; ++i) { /* Note: could do something different from the projection below * in the case of a line (i.e. maj or min = 0), as in this case * there is no ellipse to project, only two points. * -- This continue could then be a if() .. else() instead. */ if (maj_[i] == 0.0 && min_[i] == 0.0) continue; /* Evaluate shape of ellipse on the l,m plane. */ ellipse_a = maj_[i]/2.0; ellipse_b = min_[i]/2.0; cos_pa = cos(pa_[i]); sin_pa = sin(pa_[i]); for (j = 0; j < ELLIPSE_PTS; ++j) { t = j * 60.0 * M_PI / 180.0; l[j] = ellipse_a*cos(t)*sin_pa + ellipse_b*sin(t)*cos_pa; m[j] = ellipse_a*cos(t)*cos_pa - ellipse_b*sin(t)*sin_pa; } oskar_convert_relative_directions_to_lon_lat_2d_d(ELLIPSE_PTS, l, m, 0.0, 0.0, lon, lat); /* Rotate on the sphere. */ oskar_convert_lon_lat_to_xyz_d(ELLIPSE_PTS, lon, lat, x, y, z); oskar_rotate_sph_d(ELLIPSE_PTS, x, y, z, ra_[i], dec_[i]); oskar_convert_xyz_to_lon_lat_d(ELLIPSE_PTS, x, y, z, lon, lat); oskar_convert_lon_lat_to_relative_directions_2d_d( ELLIPSE_PTS, lon, lat, ra0, dec0, l, m); /* Get new major and minor axes and position angle. */ oskar_fit_ellipse_d(&maj, &min, &pa, ELLIPSE_PTS, l, m, work1, work2, status); /* Check if fitting failed. */ if (*status == OSKAR_ERR_ELLIPSE_FIT_FAILED) { if (zero_failed_sources) { I_[i] = 0.0; Q_[i] = 0.0; U_[i] = 0.0; V_[i] = 0.0; } ++(*num_failed); *status = 0; continue; } else if (*status) break; /* Evaluate ellipse parameters. */ inv_std_maj_2 = 0.5 * (maj * maj) * M_PI_2_2_LN_2; inv_std_min_2 = 0.5 * (min * min) * M_PI_2_2_LN_2; cos_pa_2 = cos(pa) * cos(pa); sin_pa_2 = sin(pa) * sin(pa); sin_2pa = sin(2.0 * pa); a_[i] = cos_pa_2*inv_std_min_2 + sin_pa_2*inv_std_maj_2; b_[i] = -sin_2pa*inv_std_min_2*0.5 + sin_2pa *inv_std_maj_2*0.5; c_[i] = sin_pa_2*inv_std_min_2 + cos_pa_2*inv_std_maj_2; } } else { /* Single precision. */ const float *ra_, *dec_, *maj_, *min_, *pa_; float *I_, *Q_, *U_, *V_, *a_, *b_, *c_; float cos_pa_2, sin_pa_2, sin_2pa, inv_std_min_2, inv_std_maj_2; float ellipse_a, ellipse_b, maj, min, pa, cos_pa, sin_pa, t; float l[ELLIPSE_PTS], m[ELLIPSE_PTS]; float work1[5 * ELLIPSE_PTS], work2[5 * ELLIPSE_PTS]; float lon[ELLIPSE_PTS], lat[ELLIPSE_PTS]; float x[ELLIPSE_PTS], y[ELLIPSE_PTS], z[ELLIPSE_PTS]; ra_ = oskar_mem_float_const(oskar_sky_ra_rad_const(sky), status); dec_ = oskar_mem_float_const(oskar_sky_dec_rad_const(sky), status); maj_ = oskar_mem_float_const(oskar_sky_fwhm_major_rad_const(sky), status); min_ = oskar_mem_float_const(oskar_sky_fwhm_minor_rad_const(sky), status); pa_ = oskar_mem_float_const(oskar_sky_position_angle_rad_const(sky), status); I_ = oskar_mem_float(oskar_sky_I(sky), status); Q_ = oskar_mem_float(oskar_sky_Q(sky), status); U_ = oskar_mem_float(oskar_sky_U(sky), status); V_ = oskar_mem_float(oskar_sky_V(sky), status); a_ = oskar_mem_float(oskar_sky_gaussian_a(sky), status); b_ = oskar_mem_float(oskar_sky_gaussian_b(sky), status); c_ = oskar_mem_float(oskar_sky_gaussian_c(sky), status); for (i = 0; i < num_sources; ++i) { /* Note: could do something different from the projection below * in the case of a line (i.e. maj or min = 0), as in this case * there is no ellipse to project, only two points. * -- This continue could then be a if() .. else() instead. */ if (maj_[i] == 0.0 && min_[i] == 0.0) continue; /* Evaluate shape of ellipse on the l,m plane. */ ellipse_a = maj_[i]/2.0; ellipse_b = min_[i]/2.0; cos_pa = cos(pa_[i]); sin_pa = sin(pa_[i]); for (j = 0; j < ELLIPSE_PTS; ++j) { t = j * 60.0 * M_PI / 180.0; l[j] = ellipse_a*cos(t)*sin_pa + ellipse_b*sin(t)*cos_pa; m[j] = ellipse_a*cos(t)*cos_pa - ellipse_b*sin(t)*sin_pa; } oskar_convert_relative_directions_to_lon_lat_2d_f(ELLIPSE_PTS, l, m, 0.0, 0.0, lon, lat); /* Rotate on the sphere. */ oskar_convert_lon_lat_to_xyz_f(ELLIPSE_PTS, lon, lat, x, y, z); oskar_rotate_sph_f(ELLIPSE_PTS, x, y, z, ra_[i], dec_[i]); oskar_convert_xyz_to_lon_lat_f(ELLIPSE_PTS, x, y, z, lon, lat); oskar_convert_lon_lat_to_relative_directions_2d_f( ELLIPSE_PTS, lon, lat, (float)ra0, (float)dec0, l, m); /* Get new major and minor axes and position angle. */ oskar_fit_ellipse_f(&maj, &min, &pa, ELLIPSE_PTS, l, m, work1, work2, status); /* Check if fitting failed. */ if (*status == OSKAR_ERR_ELLIPSE_FIT_FAILED) { if (zero_failed_sources) { I_[i] = 0.0; Q_[i] = 0.0; U_[i] = 0.0; V_[i] = 0.0; } ++(*num_failed); *status = 0; continue; } else if (*status) break; /* Evaluate ellipse parameters. */ inv_std_maj_2 = 0.5 * (maj * maj) * M_PI_2_2_LN_2; inv_std_min_2 = 0.5 * (min * min) * M_PI_2_2_LN_2; cos_pa_2 = cos(pa) * cos(pa); sin_pa_2 = sin(pa) * sin(pa); sin_2pa = sin(2.0 * pa); a_[i] = cos_pa_2*inv_std_min_2 + sin_pa_2*inv_std_maj_2; b_[i] = -sin_2pa*inv_std_min_2*0.5 + sin_2pa *inv_std_maj_2*0.5; c_[i] = sin_pa_2*inv_std_min_2 + cos_pa_2*inv_std_maj_2; } } }
void oskar_convert_ludwig3_to_theta_phi_components( int num_points, const oskar_Mem* phi, int stride, int offset, oskar_Mem* vec, int* status) { if (*status) return; const int type = oskar_mem_type(phi); const int location = oskar_mem_location(phi); const int off_h = offset, off_v = offset + 1; if (!oskar_mem_is_matrix(vec)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) convert_ludwig3_to_theta_phi_float( num_points, oskar_mem_float_const(phi, status), stride, off_h, off_v, oskar_mem_float2(vec, status), oskar_mem_float2(vec, status)); else if (type == OSKAR_DOUBLE) convert_ludwig3_to_theta_phi_double( num_points, oskar_mem_double_const(phi, status), stride, off_h, off_v, oskar_mem_double2(vec, status), oskar_mem_double2(vec, status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; if (type == OSKAR_SINGLE) k = "convert_ludwig3_to_theta_phi_float"; else if (type == OSKAR_DOUBLE) k = "convert_ludwig3_to_theta_phi_double"; else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_points, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &num_points}, {PTR_SZ, oskar_mem_buffer_const(phi)}, {INT_SZ, &stride}, {INT_SZ, &off_h}, {INT_SZ, &off_v}, {PTR_SZ, oskar_mem_buffer(vec)}, {PTR_SZ, oskar_mem_buffer(vec)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
void oskar_evaluate_station_beam_gaussian(oskar_Mem* beam, int num_points, const oskar_Mem* l, const oskar_Mem* m, const oskar_Mem* horizon_mask, double fwhm_rad, int* status) { int type, location; double fwhm_lm, std; /* Check if safe to proceed. */ if (*status) return; /* Get type and check consistency. */ type = oskar_mem_precision(beam); if (type != oskar_mem_type(l) || type != oskar_mem_type(m)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (type != OSKAR_SINGLE && type != OSKAR_DOUBLE) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (!oskar_mem_is_complex(beam)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (fwhm_rad == 0.0) { *status = OSKAR_ERR_SETTINGS_TELESCOPE; return; } /* Get location and check consistency. */ location = oskar_mem_location(beam); if (location != oskar_mem_location(l) || location != oskar_mem_location(m)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Check that length of input arrays are consistent. */ if ((int)oskar_mem_length(l) < num_points || (int)oskar_mem_length(m) < num_points) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Resize output array if needed. */ if ((int)oskar_mem_length(beam) < num_points) oskar_mem_realloc(beam, num_points, status); /* Check if safe to proceed. */ if (*status) return; /* Compute Gaussian standard deviation from FWHM. */ fwhm_lm = sin(fwhm_rad); std = fwhm_lm / (2.0 * sqrt(2.0 * log(2.0))); if (type == OSKAR_DOUBLE) { const double *l_, *m_; l_ = oskar_mem_double_const(l, status); m_ = oskar_mem_double_const(m, status); if (location == OSKAR_CPU) { if (oskar_mem_is_scalar(beam)) { oskar_gaussian_d(oskar_mem_double2(beam, status), num_points, l_, m_, std); } else { oskar_gaussian_md(oskar_mem_double4c(beam, status), num_points, l_, m_, std); } } else { #ifdef OSKAR_HAVE_CUDA if (oskar_mem_is_scalar(beam)) { oskar_gaussian_cuda_d(oskar_mem_double2(beam, status), num_points, l_, m_, std); } else { oskar_gaussian_cuda_md(oskar_mem_double4c(beam, status), num_points, l_, m_, std); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } } else /* type == OSKAR_SINGLE */ { const float *l_, *m_; l_ = oskar_mem_float_const(l, status); m_ = oskar_mem_float_const(m, status); if (location == OSKAR_CPU) { if (oskar_mem_is_scalar(beam)) { oskar_gaussian_f(oskar_mem_float2(beam, status), num_points, l_, m_, (float)std); } else { oskar_gaussian_mf(oskar_mem_float4c(beam, status), num_points, l_, m_, (float)std); } } else { #ifdef OSKAR_HAVE_CUDA if (oskar_mem_is_scalar(beam)) { oskar_gaussian_cuda_f(oskar_mem_float2(beam, status), num_points, l_, m_, (float)std); } else { oskar_gaussian_cuda_mf(oskar_mem_float4c(beam, status), num_points, l_, m_, (float)std); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } } /* Blank (zero) sources below the horizon. */ oskar_blank_below_horizon(beam, horizon_mask, num_points, status); }
void oskar_vis_block_write_ms(const oskar_VisBlock* blk, const oskar_VisHeader* header, oskar_MeasurementSet* ms, int* status) { const oskar_Mem *in_acorr, *in_xcorr, *in_uu, *in_vv, *in_ww; oskar_Mem *temp_vis = 0, *temp_uu = 0, *temp_vv = 0, *temp_ww = 0; double exposure_sec, interval_sec, t_start_mjd, t_start_sec; double ra_rad, dec_rad, ref_freq_hz; unsigned int a1, a2, num_baseln_in, num_baseln_out, num_channels; unsigned int num_pols_in, num_pols_out, num_stations, num_times, b, c, t; unsigned int i, i_out, prec, start_time_index, start_chan_index; unsigned int have_autocorr, have_crosscorr; const void *xcorr, *acorr; void* out; /* Check if safe to proceed. */ if (*status) return; /* Pull data from visibility structures. */ num_pols_out = oskar_ms_num_pols(ms); num_pols_in = oskar_vis_block_num_pols(blk); num_stations = oskar_vis_block_num_stations(blk); num_baseln_in = oskar_vis_block_num_baselines(blk); num_channels = oskar_vis_block_num_channels(blk); num_times = oskar_vis_block_num_times(blk); in_acorr = oskar_vis_block_auto_correlations_const(blk); in_xcorr = oskar_vis_block_cross_correlations_const(blk); in_uu = oskar_vis_block_baseline_uu_metres_const(blk); in_vv = oskar_vis_block_baseline_vv_metres_const(blk); in_ww = oskar_vis_block_baseline_ww_metres_const(blk); have_autocorr = oskar_vis_block_has_auto_correlations(blk); have_crosscorr = oskar_vis_block_has_cross_correlations(blk); start_time_index = oskar_vis_block_start_time_index(blk); start_chan_index = oskar_vis_block_start_channel_index(blk); ra_rad = oskar_vis_header_phase_centre_ra_deg(header) * D2R; dec_rad = oskar_vis_header_phase_centre_dec_deg(header) * D2R; exposure_sec = oskar_vis_header_time_average_sec(header); interval_sec = oskar_vis_header_time_inc_sec(header); t_start_mjd = oskar_vis_header_time_start_mjd_utc(header); ref_freq_hz = oskar_vis_header_freq_start_hz(header); prec = oskar_mem_precision(in_xcorr); t_start_sec = t_start_mjd * 86400.0 + interval_sec * (start_time_index + 0.5); /* Check that there is something to write. */ if (!have_autocorr && !have_crosscorr) return; /* Get number of output baselines. */ num_baseln_out = num_baseln_in; if (have_autocorr) num_baseln_out += num_stations; /* Check polarisation dimension consistency: * num_pols_in can be less than num_pols_out, but not vice-versa. */ if (num_pols_in > num_pols_out) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Check the dimensions match. */ if (oskar_ms_num_pols(ms) != num_pols_out || oskar_ms_num_stations(ms) != num_stations) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Check the reference frequencies match. */ if (fabs(oskar_ms_ref_freq_hz(ms) - ref_freq_hz) > 1e-10) { *status = OSKAR_ERR_VALUE_MISMATCH; return; } /* Check the phase centres are the same. */ if (fabs(oskar_ms_phase_centre_ra_rad(ms) - ra_rad) > 1e-10 || fabs(oskar_ms_phase_centre_dec_rad(ms) - dec_rad) > 1e-10) { *status = OSKAR_ERR_VALUE_MISMATCH; return; } /* Add visibilities and u,v,w coordinates. */ temp_vis = oskar_mem_create(prec | OSKAR_COMPLEX, OSKAR_CPU, num_baseln_out * num_channels * num_pols_out, status); temp_uu = oskar_mem_create(prec, OSKAR_CPU, num_baseln_out, status); temp_vv = oskar_mem_create(prec, OSKAR_CPU, num_baseln_out, status); temp_ww = oskar_mem_create(prec, OSKAR_CPU, num_baseln_out, status); xcorr = oskar_mem_void_const(in_xcorr); acorr = oskar_mem_void_const(in_acorr); out = oskar_mem_void(temp_vis); if (prec == OSKAR_DOUBLE) { const double *uu_in, *vv_in, *ww_in; double *uu_out, *vv_out, *ww_out; uu_in = oskar_mem_double_const(in_uu, status); vv_in = oskar_mem_double_const(in_vv, status); ww_in = oskar_mem_double_const(in_ww, status); uu_out = oskar_mem_double(temp_uu, status); vv_out = oskar_mem_double(temp_vv, status); ww_out = oskar_mem_double(temp_ww, status); for (t = 0; t < num_times; ++t) { /* Construct the baseline coordinates for the given time. */ int start_row = (start_time_index + t) * num_baseln_out; for (a1 = 0, b = 0, i_out = 0; a1 < num_stations; ++a1) { if (have_autocorr) { uu_out[i_out] = 0.0; vv_out[i_out] = 0.0; ww_out[i_out] = 0.0; ++i_out; } if (have_crosscorr) { for (a2 = a1 + 1; a2 < num_stations; ++a2, ++b, ++i_out) { i = num_baseln_in * t + b; uu_out[i_out] = uu_in[i]; vv_out[i_out] = vv_in[i]; ww_out[i_out] = ww_in[i]; } } } for (c = 0, i_out = 0; c < num_channels; ++c) { /* Construct amplitude data for the given time and channel. */ if (num_pols_in == 4) { for (a1 = 0, b = 0; a1 < num_stations; ++a1) { if (have_autocorr) { i = num_stations * (t * num_channels + c) + a1; ((double4c*)out)[i_out++] = ((const double4c*)acorr)[i]; } if (have_crosscorr) { for (a2 = a1 + 1; a2 < num_stations; ++b, ++a2) { i = num_baseln_in * (t * num_channels + c) + b; ((double4c*)out)[i_out++] = ((const double4c*)xcorr)[i]; } } } } else if (num_pols_in == 1 && num_pols_out == 1) { for (a1 = 0, b = 0; a1 < num_stations; ++a1) { if (have_autocorr) { i = num_stations * (t * num_channels + c) + a1; ((double2*)out)[i_out++] = ((const double2*)acorr)[i]; } if (have_crosscorr) { for (a2 = a1 + 1; a2 < num_stations; ++b, ++a2) { i = num_baseln_in * (t * num_channels + c) + b; ((double2*)out)[i_out++] = ((const double2*)xcorr)[i]; } } } } else { double2 vis_amp, *out_; out_ = (double2*)out; for (a1 = 0, b = 0; a1 < num_stations; ++a1) { if (have_autocorr) { i = num_stations * (t * num_channels + c) + a1; vis_amp = ((const double2*)acorr)[i]; out_[i_out + 0] = vis_amp; /* XX */ out_[i_out + 1].x = 0.0; /* XY */ out_[i_out + 1].y = 0.0; /* XY */ out_[i_out + 2].x = 0.0; /* YX */ out_[i_out + 2].y = 0.0; /* YX */ out_[i_out + 3] = vis_amp; /* YY */ i_out += 4; } if (have_crosscorr) { for (a2 = a1 + 1; a2 < num_stations; ++b, ++a2) { i = num_baseln_in * (t * num_channels + c) + b; vis_amp = ((const double2*)xcorr)[i]; out_[i_out + 0] = vis_amp; /* XX */ out_[i_out + 1].x = 0.0; /* XY */ out_[i_out + 1].y = 0.0; /* XY */ out_[i_out + 2].x = 0.0; /* YX */ out_[i_out + 2].y = 0.0; /* YX */ out_[i_out + 3] = vis_amp; /* YY */ i_out += 4; } } } } } oskar_ms_write_coords_d(ms, start_row, num_baseln_out, uu_out, vv_out, ww_out, exposure_sec, interval_sec, t_start_sec + (t * interval_sec)); oskar_ms_write_vis_d(ms, start_row, start_chan_index, num_channels, num_baseln_out, (const double*)out); } } else if (prec == OSKAR_SINGLE) { const float *uu_in, *vv_in, *ww_in; float *uu_out, *vv_out, *ww_out; uu_in = oskar_mem_float_const(in_uu, status); vv_in = oskar_mem_float_const(in_vv, status); ww_in = oskar_mem_float_const(in_ww, status); uu_out = oskar_mem_float(temp_uu, status); vv_out = oskar_mem_float(temp_vv, status); ww_out = oskar_mem_float(temp_ww, status); for (t = 0; t < num_times; ++t) { /* Construct the baseline coordinates for the given time. */ int start_row = (start_time_index + t) * num_baseln_out; for (a1 = 0, b = 0, i_out = 0; a1 < num_stations; ++a1) { if (have_autocorr) { uu_out[i_out] = 0.0; vv_out[i_out] = 0.0; ww_out[i_out] = 0.0; ++i_out; } if (have_crosscorr) { for (a2 = a1 + 1; a2 < num_stations; ++a2, ++b, ++i_out) { i = num_baseln_in * t + b; uu_out[i_out] = uu_in[i]; vv_out[i_out] = vv_in[i]; ww_out[i_out] = ww_in[i]; } } } for (c = 0, i_out = 0; c < num_channels; ++c) { /* Construct amplitude data for the given time and channel. */ if (num_pols_in == 4) { for (a1 = 0, b = 0; a1 < num_stations; ++a1) { if (have_autocorr) { i = num_stations * (t * num_channels + c) + a1; ((float4c*)out)[i_out++] = ((const float4c*)acorr)[i]; } if (have_crosscorr) { for (a2 = a1 + 1; a2 < num_stations; ++b, ++a2) { i = num_baseln_in * (t * num_channels + c) + b; ((float4c*)out)[i_out++] = ((const float4c*)xcorr)[i]; } } } } else if (num_pols_in == 1 && num_pols_out == 1) { for (a1 = 0, b = 0; a1 < num_stations; ++a1) { if (have_autocorr) { i = num_stations * (t * num_channels + c) + a1; ((float2*)out)[i_out++] = ((const float2*)acorr)[i]; } if (have_crosscorr) { for (a2 = a1 + 1; a2 < num_stations; ++b, ++a2) { i = num_baseln_in * (t * num_channels + c) + b; ((float2*)out)[i_out++] = ((const float2*)xcorr)[i]; } } } } else { float2 vis_amp, *out_; out_ = (float2*)out; for (a1 = 0, b = 0; a1 < num_stations; ++a1) { if (have_autocorr) { i = num_stations * (t * num_channels + c) + a1; vis_amp = ((const float2*)acorr)[i]; out_[i_out + 0] = vis_amp; /* XX */ out_[i_out + 1].x = 0.0; /* XY */ out_[i_out + 1].y = 0.0; /* XY */ out_[i_out + 2].x = 0.0; /* YX */ out_[i_out + 2].y = 0.0; /* YX */ out_[i_out + 3] = vis_amp; /* YY */ i_out += 4; } if (have_crosscorr) { for (a2 = a1 + 1; a2 < num_stations; ++b, ++a2) { i = num_baseln_in * (t * num_channels + c) + b; vis_amp = ((const float2*)xcorr)[i]; out_[i_out + 0] = vis_amp; /* XX */ out_[i_out + 1].x = 0.0; /* XY */ out_[i_out + 1].y = 0.0; /* XY */ out_[i_out + 2].x = 0.0; /* YX */ out_[i_out + 2].y = 0.0; /* YX */ out_[i_out + 3] = vis_amp; /* YY */ i_out += 4; } } } } } oskar_ms_write_coords_f(ms, start_row, num_baseln_out, uu_out, vv_out, ww_out, exposure_sec, interval_sec, t_start_sec + (t * interval_sec)); oskar_ms_write_vis_f(ms, start_row, start_chan_index, num_channels, num_baseln_out, (const float*)out); } } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } /* Cleanup. */ oskar_mem_free(temp_vis, status); oskar_mem_free(temp_uu, status); oskar_mem_free(temp_vv, status); oskar_mem_free(temp_ww, status); }