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); }
void oskar_imager_read_coords_vis(oskar_Imager* h, const char* filename, int i_file, int num_files, int* percent_done, int* percent_next, int* status) { oskar_Binary* vis_file; oskar_VisHeader* header; oskar_Mem *uu, *vv, *ww, *weight, *time_centroid, *time_slice; int coord_prec, max_times_per_block, tags_per_block, i_block, num_blocks; int num_times_total, num_stations, num_baselines, num_pols; double time_start_mjd, time_inc_sec; if (*status) return; /* Read the header. */ vis_file = oskar_binary_create(filename, 'r', status); header = oskar_vis_header_read(vis_file, status); if (*status) { oskar_vis_header_free(header, status); oskar_binary_free(vis_file); return; } coord_prec = oskar_vis_header_coord_precision(header); max_times_per_block = oskar_vis_header_max_times_per_block(header); tags_per_block = oskar_vis_header_num_tags_per_block(header); num_times_total = oskar_vis_header_num_times_total(header); num_stations = oskar_vis_header_num_stations(header); num_baselines = num_stations * (num_stations - 1) / 2; num_pols = oskar_type_is_matrix(oskar_vis_header_amp_type(header)) ? 4 : 1; num_blocks = (num_times_total + max_times_per_block - 1) / max_times_per_block; time_start_mjd = oskar_vis_header_time_start_mjd_utc(header) * 86400.0; time_inc_sec = oskar_vis_header_time_inc_sec(header); /* Set visibility meta-data. */ oskar_imager_set_vis_frequency(h, oskar_vis_header_freq_start_hz(header), oskar_vis_header_freq_inc_hz(header), oskar_vis_header_num_channels_total(header)); oskar_imager_set_vis_phase_centre(h, oskar_vis_header_phase_centre_ra_deg(header), oskar_vis_header_phase_centre_dec_deg(header)); /* Create scratch arrays. Weights are all 1. */ uu = oskar_mem_create(coord_prec, OSKAR_CPU, 0, status); vv = oskar_mem_create(coord_prec, OSKAR_CPU, 0, status); ww = oskar_mem_create(coord_prec, OSKAR_CPU, 0, status); time_centroid = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, num_baselines * max_times_per_block, status); time_slice = oskar_mem_create_alias(0, 0, 0, status); weight = oskar_mem_create(h->imager_prec, OSKAR_CPU, num_baselines * num_pols * max_times_per_block, status); oskar_mem_set_value_real(weight, 1.0, 0, 0, status); /* Loop over visibility blocks. */ for (i_block = 0; i_block < num_blocks; ++i_block) { int t, num_times, num_channels, start_time, start_chan, end_chan; int dim_start_and_size[6]; size_t num_rows; if (*status) break; /* Read block metadata. */ oskar_timer_resume(h->tmr_read); oskar_binary_set_query_search_start(vis_file, i_block * tags_per_block, status); oskar_binary_read(vis_file, OSKAR_INT, OSKAR_TAG_GROUP_VIS_BLOCK, OSKAR_VIS_BLOCK_TAG_DIM_START_AND_SIZE, i_block, sizeof(dim_start_and_size), dim_start_and_size, status); start_time = dim_start_and_size[0]; start_chan = dim_start_and_size[1]; num_times = dim_start_and_size[2]; num_channels = dim_start_and_size[3]; num_rows = num_times * num_baselines; end_chan = start_chan + num_channels - 1; /* Fill in the time centroid values. */ for (t = 0; t < num_times; ++t) { oskar_mem_set_alias(time_slice, time_centroid, t * num_baselines, num_baselines, status); oskar_mem_set_value_real(time_slice, time_start_mjd + (start_time + t + 0.5) * time_inc_sec, 0, num_baselines, status); } /* Read the baseline coordinates. */ oskar_binary_read_mem(vis_file, uu, OSKAR_TAG_GROUP_VIS_BLOCK, OSKAR_VIS_BLOCK_TAG_BASELINE_UU, i_block, status); oskar_binary_read_mem(vis_file, vv, OSKAR_TAG_GROUP_VIS_BLOCK, OSKAR_VIS_BLOCK_TAG_BASELINE_VV, i_block, status); oskar_binary_read_mem(vis_file, ww, OSKAR_TAG_GROUP_VIS_BLOCK, OSKAR_VIS_BLOCK_TAG_BASELINE_WW, i_block, status); /* Update the imager with the data. */ oskar_timer_pause(h->tmr_read); oskar_imager_update(h, num_rows, start_chan, end_chan, num_pols, uu, vv, ww, 0, weight, time_centroid, status); *percent_done = (int) round(100.0 * ( (i_block + 1) / (double)(num_blocks * num_files) + i_file / (double)num_files)); if (h->log && percent_next && *percent_done >= *percent_next) { oskar_log_message(h->log, 'S', -2, "%3d%% ...", *percent_done); *percent_next = 10 + 10 * (*percent_done / 10); } } oskar_mem_free(uu, status); oskar_mem_free(vv, status); oskar_mem_free(ww, status); oskar_mem_free(weight, status); oskar_mem_free(time_centroid, status); oskar_mem_free(time_slice, status); oskar_vis_header_free(header, status); oskar_binary_free(vis_file); }
/* * Translation layer from new file format to old structure. * This will be deleted when the old oskar_Vis structure is fully retired. */ oskar_Vis* oskar_vis_read_new(oskar_Binary* h, int* status) { oskar_VisHeader* hdr = 0; oskar_VisBlock* blk = 0; oskar_Vis* vis = 0; oskar_Mem* amp = 0; const oskar_Mem* xcorr = 0; int amp_type, max_times_per_block, num_channels, num_stations, num_times; int i, num_blocks; double freq_ref_hz, freq_inc_hz, time_ref_mjd_utc, time_inc_sec; /* Try to read the new header. */ hdr = oskar_vis_header_read(h, status); if (*status) { oskar_vis_header_free(hdr, status); return 0; } /* Create the old vis structure. */ amp_type = oskar_vis_header_amp_type(hdr); max_times_per_block = oskar_vis_header_max_times_per_block(hdr); num_channels = oskar_vis_header_num_channels_total(hdr); num_stations = oskar_vis_header_num_stations(hdr); num_times = oskar_vis_header_num_times_total(hdr); vis = oskar_vis_create(amp_type, OSKAR_CPU, num_channels, num_times, num_stations, status); if (*status) { oskar_vis_header_free(hdr, status); oskar_vis_free(vis, status); return 0; } /* Copy station coordinates and metadata. */ freq_ref_hz = oskar_vis_header_freq_start_hz(hdr); freq_inc_hz = oskar_vis_header_freq_inc_hz(hdr); time_ref_mjd_utc = oskar_vis_header_time_start_mjd_utc(hdr); time_inc_sec = oskar_vis_header_time_inc_sec(hdr); oskar_mem_copy(oskar_vis_station_x_offset_ecef_metres(vis), oskar_vis_header_station_x_offset_ecef_metres_const(hdr), status); oskar_mem_copy(oskar_vis_station_y_offset_ecef_metres(vis), oskar_vis_header_station_y_offset_ecef_metres_const(hdr), status); oskar_mem_copy(oskar_vis_station_z_offset_ecef_metres(vis), oskar_vis_header_station_z_offset_ecef_metres_const(hdr), status); oskar_mem_copy(oskar_vis_settings(vis), oskar_vis_header_settings_const(hdr), status); oskar_mem_copy(oskar_vis_telescope_path(vis), oskar_vis_header_telescope_path_const(hdr), status); oskar_vis_set_channel_bandwidth_hz(vis, oskar_vis_header_channel_bandwidth_hz(hdr)); oskar_vis_set_freq_inc_hz(vis, freq_inc_hz); oskar_vis_set_freq_start_hz(vis, freq_ref_hz); oskar_vis_set_phase_centre(vis, oskar_vis_header_phase_centre_ra_deg(hdr), oskar_vis_header_phase_centre_dec_deg(hdr)); oskar_vis_set_telescope_position(vis, oskar_vis_header_telescope_lon_deg(hdr), oskar_vis_header_telescope_lat_deg(hdr), oskar_vis_header_telescope_alt_metres(hdr)); oskar_vis_set_time_average_sec(vis, oskar_vis_header_time_average_sec(hdr)); oskar_vis_set_time_inc_sec(vis, time_inc_sec); oskar_vis_set_time_start_mjd_utc(vis, time_ref_mjd_utc); /* Create a visibility block to read into. */ blk = oskar_vis_block_create_from_header(OSKAR_CPU, hdr, status); amp = oskar_vis_amplitude(vis); xcorr = oskar_vis_block_cross_correlations_const(blk); /* Work out the number of blocks. */ num_blocks = (num_times + max_times_per_block - 1) / max_times_per_block; for (i = 0; i < num_blocks; ++i) { int block_length, num_baselines, time_offset, total_baselines, t, c; /* Read the block. */ oskar_vis_block_read(blk, hdr, h, i, status); num_baselines = oskar_vis_block_num_baselines(blk); block_length = oskar_vis_block_num_times(blk); /* Copy the baseline coordinate data. */ time_offset = i * max_times_per_block * num_baselines; total_baselines = num_baselines * block_length; oskar_mem_copy_contents(oskar_vis_baseline_uu_metres(vis), oskar_vis_block_baseline_uu_metres_const(blk), time_offset, 0, total_baselines, status); oskar_mem_copy_contents(oskar_vis_baseline_vv_metres(vis), oskar_vis_block_baseline_vv_metres_const(blk), time_offset, 0, total_baselines, status); oskar_mem_copy_contents(oskar_vis_baseline_ww_metres(vis), oskar_vis_block_baseline_ww_metres_const(blk), time_offset, 0, total_baselines, status); /* Fill the array in the old dimension order. */ for (t = 0; t < block_length; ++t) { for (c = 0; c < num_channels; ++c) { oskar_mem_copy_contents(amp, xcorr, num_baselines * (c * num_times + i * max_times_per_block + t), num_baselines * (t * num_channels + c), num_baselines, status); } } } /* Clean up and return. */ oskar_vis_block_free(blk, status); oskar_vis_header_free(hdr, status); return vis; }