void oskar_imager_finalise(oskar_Imager* h, int num_output_images, oskar_Mem** output_images, int num_output_grids, oskar_Mem** output_grids, int* status) { int t, c, p, i; if (*status || !h->planes) return; /* Adjust normalisation if required. */ if (h->scale_norm_with_num_input_files) { for (i = 0; i < h->num_planes; ++i) h->plane_norm[i] /= h->num_files; } /* Copy grids to output grid planes if given. */ for (i = 0; (i < h->num_planes) && (i < num_output_grids); ++i) { oskar_mem_copy(output_grids[i], h->planes[i], status); oskar_mem_scale_real(output_grids[i], 1.0 / h->plane_norm[i], status); } /* Check if images are required. */ if (h->fits_file[0] || output_images) { /* Finalise all the planes. */ for (i = 0; i < h->num_planes; ++i) { oskar_imager_finalise_plane(h, h->planes[i], h->plane_norm[i], status); oskar_imager_trim_image(h->planes[i], h->grid_size, h->image_size, status); } /* Copy images to output image planes if given. */ for (i = 0; (i < h->num_planes) && (i < num_output_images); ++i) { memcpy(oskar_mem_void(output_images[i]), oskar_mem_void_const(h->planes[i]), h->image_size * h->image_size * oskar_mem_element_size(h->imager_prec)); } /* Write to files if required. */ for (t = 0, i = 0; t < h->im_num_times; ++t) for (c = 0; c < h->im_num_channels; ++c) for (p = 0; p < h->im_num_pols; ++p, ++i) write_plane(h, h->planes[i], t, c, p, status); } /* Reset imager memory. */ oskar_imager_reset_cache(h, status); }
static void evaluate_station_ECEF_coords( double* station_x, double* station_y, double* station_z, int stationID, const oskar_Telescope* telescope) { double st_x, st_y, st_z; double lon, lat, alt; const oskar_Station* station; const void *x_, *y_, *z_; x_ = oskar_mem_void_const( oskar_telescope_station_true_x_offset_ecef_metres_const(telescope)); y_ = oskar_mem_void_const( oskar_telescope_station_true_y_offset_ecef_metres_const(telescope)); z_ = oskar_mem_void_const( oskar_telescope_station_true_z_offset_ecef_metres_const(telescope)); station = oskar_telescope_station_const(telescope, stationID); lon = oskar_station_lon_rad(station); lat = oskar_station_lat_rad(station); alt = oskar_station_alt_metres(station); if (oskar_mem_type( oskar_telescope_station_true_x_offset_ecef_metres_const(telescope)) == OSKAR_DOUBLE) { st_x = ((const double*)x_)[stationID]; st_y = ((const double*)y_)[stationID]; st_z = ((const double*)z_)[stationID]; } else { st_x = (double)((const float*)x_)[stationID]; st_y = (double)((const float*)y_)[stationID]; st_z = (double)((const float*)z_)[stationID]; } oskar_convert_offset_ecef_to_ecef(1, &st_x, &st_y, &st_z, lon, lat, alt, station_x, station_y, station_z); }
void oskar_imager_rotate_vis(size_t num_vis, const oskar_Mem* uu, const oskar_Mem* vv, const oskar_Mem* ww, oskar_Mem* amps, const double delta_l, const double delta_m, const double delta_n) { size_t i; if (oskar_mem_precision(amps) == OSKAR_DOUBLE) { const double *u, *v, *w; double2* a; u = (const double*)oskar_mem_void_const(uu); v = (const double*)oskar_mem_void_const(vv); w = (const double*)oskar_mem_void_const(ww); a = (double2*)oskar_mem_void(amps); for (i = 0; i < num_vis; ++i) { double arg, phase_re, phase_im, re, im; arg = 2.0*M_PI * (u[i] * delta_l + v[i] * delta_m + w[i] * delta_n); phase_re = cos(arg); phase_im = sin(arg); re = a[i].x * phase_re - a[i].y * phase_im; im = a[i].x * phase_im + a[i].y * phase_re; a[i].x = re; a[i].y = im; } } else { const float *u, *v, *w; float2* a; u = (const float*)oskar_mem_void_const(uu); v = (const float*)oskar_mem_void_const(vv); w = (const float*)oskar_mem_void_const(ww); a = (float2*)oskar_mem_void(amps); for (i = 0; i < num_vis; ++i) { float arg, phase_re, phase_im, re, im; arg = 2.0*M_PI * (u[i] * delta_l + v[i] * delta_m + w[i] * delta_n); phase_re = cos(arg); phase_im = sin(arg); re = a[i].x * phase_re - a[i].y * phase_im; im = a[i].x * phase_im + a[i].y * phase_re; a[i].x = re; a[i].y = im; } } }
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_mem_save_ascii(FILE* file, size_t num_mem, size_t offset, size_t num_elements, int* status, ...) { int type; size_t i, j; va_list args; oskar_Mem** handles; /* Array of oskar_Mem pointers in CPU memory. */ /* Check if safe to proceed. */ if (*status) return; /* Check there are at least the number of specified elements in * each array. */ va_start(args, status); for (i = 0; i < num_mem; ++i) { const oskar_Mem* mem; mem = va_arg(args, const oskar_Mem*); if (oskar_mem_length(mem) < num_elements) *status = OSKAR_ERR_DIMENSION_MISMATCH; } va_end(args); /* Check if safe to proceed. */ if (*status) return; /* Allocate and set up the handle array. */ handles = (oskar_Mem**) malloc(num_mem * sizeof(oskar_Mem*)); va_start(args, status); for (i = 0; i < num_mem; ++i) { oskar_Mem* mem; mem = va_arg(args, oskar_Mem*); if (oskar_mem_location(mem) != OSKAR_CPU) { handles[i] = oskar_mem_create_copy(mem, OSKAR_CPU, status); } else { handles[i] = mem; } } va_end(args); for (j = 0; j < num_elements; ++j) { /* Break if error. */ if (*status) break; for (i = 0; i < num_mem; ++i) { const void* data; data = oskar_mem_void_const(handles[i]); type = oskar_mem_type(handles[i]); switch (type) { case OSKAR_SINGLE: { fprintf(file, SDF, ((const float*)data)[j + offset]); continue; } case OSKAR_DOUBLE: { fprintf(file, SDD, ((const double*)data)[j + offset]); continue; } case OSKAR_SINGLE_COMPLEX: { float2 d; d = ((const float2*)data)[j + offset]; fprintf(file, SDF SDF, d.x, d.y); continue; } case OSKAR_DOUBLE_COMPLEX: { double2 d; d = ((const double2*)data)[j + offset]; fprintf(file, SDD SDD, d.x, d.y); continue; } case OSKAR_SINGLE_COMPLEX_MATRIX: { float4c d; d = ((const float4c*)data)[j + offset]; fprintf(file, SDF SDF SDF SDF SDF SDF SDF SDF, d.a.x, d.a.y, d.b.x, d.b.y, d.c.x, d.c.y, d.d.x, d.d.y); continue; } case OSKAR_DOUBLE_COMPLEX_MATRIX: { double4c d; d = ((const double4c*)data)[j + offset]; fprintf(file, SDD SDD SDD SDD SDD SDD SDD SDD, d.a.x, d.a.y, d.b.x, d.b.y, d.c.x, d.c.y, d.d.x, d.d.y); continue; } case OSKAR_CHAR: { putc(((const char*)data)[j + offset], file); continue; } case OSKAR_INT: { fprintf(file, "%5d ", ((const int*)data)[j + offset]); continue; } default: { *status = OSKAR_ERR_BAD_DATA_TYPE; continue; } } } putc('\n', file); } /* Free any temporary memory used by this function. */ va_start(args, status); for (i = 0; i < num_mem; ++i) { const oskar_Mem* mem; mem = va_arg(args, const oskar_Mem*); if (oskar_mem_location(mem) != OSKAR_CPU) { oskar_mem_free(handles[i], status); } } va_end(args); /* Free the handle array. */ free(handles); }
const int* oskar_station_element_types_cpu_const(const oskar_Station* model) { return (const int*) oskar_mem_void_const(model->element_types_cpu); }
double oskar_station_element_y_gamma_rad(const oskar_Station* model, int index) { return ((const double*) oskar_mem_void_const(model->element_y_gamma_cpu))[index]; }
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); }