Beispiel #1
0
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. */
}
Beispiel #2
0
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));
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}