static PyObject* auto_correlations(PyObject* self, PyObject* args) { oskar_VisBlock* h = 0; oskar_Mem* m = 0; PyObject *capsule = 0; PyArrayObject *array = 0; npy_intp dims[4]; if (!PyArg_ParseTuple(args, "O", &capsule)) return 0; if (!(h = (oskar_VisBlock*) get_handle(capsule, name))) return 0; /* Check that auto-correlations exist. */ if (!oskar_vis_block_has_auto_correlations(h)) { PyErr_SetString(PyExc_RuntimeError, "No auto-correlations in block."); return 0; } /* Return an array reference to Python. */ m = oskar_vis_block_auto_correlations(h); dims[0] = oskar_vis_block_num_times(h); dims[1] = oskar_vis_block_num_channels(h); dims[2] = oskar_vis_block_num_stations(h); dims[3] = oskar_vis_block_num_pols(h); array = (PyArrayObject*)PyArray_SimpleNewFromData(4, dims, (oskar_mem_is_double(m) ? NPY_CDOUBLE : NPY_CFLOAT), oskar_mem_void(m)); return Py_BuildValue("N", array); /* Don't increment refcount. */ }
static PyObject* num_channels(PyObject* self, PyObject* args) { oskar_VisBlock* h = 0; PyObject* capsule = 0; if (!PyArg_ParseTuple(args, "O", &capsule)) return 0; if (!(h = (oskar_VisBlock*) get_handle(capsule, name))) return 0; return Py_BuildValue("i", oskar_vis_block_num_channels(h)); }
static void sim_baselines(oskar_Simulator* h, DeviceData* d, oskar_Sky* sky, int channel_index_block, int time_index_block, int time_index_simulation, int* status) { int num_baselines, num_stations, num_src, num_times_block, num_channels; double dt_dump_days, t_start, t_dump, gast, frequency, ra0, dec0; const oskar_Mem *x, *y, *z; oskar_Mem* alias = 0; /* Get dimensions. */ num_baselines = oskar_telescope_num_baselines(d->tel); num_stations = oskar_telescope_num_stations(d->tel); num_src = oskar_sky_num_sources(sky); num_times_block = oskar_vis_block_num_times(d->vis_block); num_channels = oskar_vis_block_num_channels(d->vis_block); /* Return if there are no sources in the chunk, * or if block time index requested is outside the valid range. */ if (num_src == 0 || time_index_block >= num_times_block) return; /* Get the time and frequency of the visibility slice being simulated. */ dt_dump_days = h->time_inc_sec / 86400.0; t_start = h->time_start_mjd_utc; t_dump = t_start + dt_dump_days * (time_index_simulation + 0.5); gast = oskar_convert_mjd_to_gast_fast(t_dump); frequency = h->freq_start_hz + channel_index_block * h->freq_inc_hz; /* Scale source fluxes with spectral index and rotation measure. */ oskar_sky_scale_flux_with_frequency(sky, frequency, status); /* Evaluate station u,v,w coordinates. */ ra0 = oskar_telescope_phase_centre_ra_rad(d->tel); dec0 = oskar_telescope_phase_centre_dec_rad(d->tel); x = oskar_telescope_station_true_x_offset_ecef_metres_const(d->tel); y = oskar_telescope_station_true_y_offset_ecef_metres_const(d->tel); z = oskar_telescope_station_true_z_offset_ecef_metres_const(d->tel); oskar_convert_ecef_to_station_uvw(num_stations, x, y, z, ra0, dec0, gast, d->u, d->v, d->w, status); /* Set dimensions of Jones matrices. */ if (d->R) oskar_jones_set_size(d->R, num_stations, num_src, status); if (d->Z) oskar_jones_set_size(d->Z, num_stations, num_src, status); oskar_jones_set_size(d->J, num_stations, num_src, status); oskar_jones_set_size(d->E, num_stations, num_src, status); oskar_jones_set_size(d->K, num_stations, num_src, status); /* Evaluate station beam (Jones E: may be matrix). */ oskar_timer_resume(d->tmr_E); oskar_evaluate_jones_E(d->E, num_src, OSKAR_RELATIVE_DIRECTIONS, oskar_sky_l(sky), oskar_sky_m(sky), oskar_sky_n(sky), d->tel, gast, frequency, d->station_work, time_index_simulation, status); oskar_timer_pause(d->tmr_E); #if 0 /* Evaluate ionospheric phase (Jones Z: scalar) and join with Jones E. * NOTE this is currently only a CPU implementation. */ if (d->Z) { oskar_evaluate_jones_Z(d->Z, num_src, sky, d->tel, &settings->ionosphere, gast, frequency, &(d->workJonesZ), status); oskar_timer_resume(d->tmr_join); oskar_jones_join(d->E, d->Z, d->E, status); oskar_timer_pause(d->tmr_join); } #endif /* Evaluate parallactic angle (Jones R: matrix), and join with Jones Z*E. * TODO Move this into station beam evaluation instead. */ if (d->R) { oskar_timer_resume(d->tmr_E); oskar_evaluate_jones_R(d->R, num_src, oskar_sky_ra_rad_const(sky), oskar_sky_dec_rad_const(sky), d->tel, gast, status); oskar_timer_pause(d->tmr_E); oskar_timer_resume(d->tmr_join); oskar_jones_join(d->R, d->E, d->R, status); oskar_timer_pause(d->tmr_join); } /* Evaluate interferometer phase (Jones K: scalar). */ oskar_timer_resume(d->tmr_K); oskar_evaluate_jones_K(d->K, num_src, oskar_sky_l_const(sky), oskar_sky_m_const(sky), oskar_sky_n_const(sky), d->u, d->v, d->w, frequency, oskar_sky_I_const(sky), h->source_min_jy, h->source_max_jy, status); oskar_timer_pause(d->tmr_K); /* Join Jones K with Jones Z*E. */ oskar_timer_resume(d->tmr_join); oskar_jones_join(d->J, d->K, d->R ? d->R : d->E, status); oskar_timer_pause(d->tmr_join); /* Create alias for auto/cross-correlations. */ oskar_timer_resume(d->tmr_correlate); alias = oskar_mem_create_alias(0, 0, 0, status); /* Auto-correlate for this time and channel. */ if (oskar_vis_block_has_auto_correlations(d->vis_block)) { oskar_mem_set_alias(alias, oskar_vis_block_auto_correlations(d->vis_block), num_stations * (num_channels * time_index_block + channel_index_block), num_stations, status); oskar_auto_correlate(alias, num_src, d->J, sky, status); } /* Cross-correlate for this time and channel. */ if (oskar_vis_block_has_cross_correlations(d->vis_block)) { oskar_mem_set_alias(alias, oskar_vis_block_cross_correlations(d->vis_block), num_baselines * (num_channels * time_index_block + channel_index_block), num_baselines, status); oskar_cross_correlate(alias, num_src, d->J, sky, d->tel, d->u, d->v, d->w, gast, frequency, status); } /* Free alias for auto/cross-correlations. */ oskar_mem_free(alias, status); oskar_timer_pause(d->tmr_correlate); }
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); }