void oskar_sky_set_spectral_index(oskar_Sky* sky, int index,
        double ref_frequency, double spectral_index, int* status)
{
    if (*status) return;

    oskar_mem_set_element_real(sky->reference_freq_hz, index,
            ref_frequency, status);
    oskar_mem_set_element_real(sky->spectral_index, index,
            spectral_index, status);
}
Beispiel #2
0
void oskar_evaluate_station_beam(oskar_Mem* beam_pattern, int num_points,
        int coord_type, oskar_Mem* x, oskar_Mem* y, oskar_Mem* z,
        double norm_ra_rad, double norm_dec_rad, const oskar_Station* station,
        oskar_StationWork* work, int time_index, double frequency_hz,
        double GAST, int* status)
{
    int normalise_final_beam;
    oskar_Mem* out;

    /* Check if safe to proceed. */
    if (*status) return;

    /* Set default output beam array. */
    out = beam_pattern;

    /* Check that the arrays have enough space to add an extra source at the
     * end (for normalisation). We don't want to reallocate here, since that
     * will be slow to do each time: must simply ensure that we pass input
     * arrays that are large enough.
     * The normalisation doesn't need to happen if the station has an
     * isotropic beam. */
    normalise_final_beam = oskar_station_normalise_final_beam(station) &&
            (oskar_station_type(station) != OSKAR_STATION_TYPE_ISOTROPIC);
    if (normalise_final_beam)
    {
        double c_x = 0.0, c_y = 0.0, c_z = 1.0;

        /* Increment number of points. */
        num_points++;

        /* Check the input arrays are big enough to hold the new source. */
        if ((int)oskar_mem_length(x) < num_points ||
                (int)oskar_mem_length(y) < num_points ||
                (int)oskar_mem_length(z) < num_points)
        {
            *status = OSKAR_ERR_DIMENSION_MISMATCH;
            return;
        }

        /* Set output beam array to work buffer. */
        out = oskar_station_work_normalised_beam(work, beam_pattern, status);

        /* Get the beam direction in the appropriate coordinate system. */
        /* (Direction cosines are already set to the interferometer phase
         * centre for relative directions.) */
        if (coord_type == OSKAR_ENU_DIRECTIONS)
        {
            double t_x, t_y, t_z, ha0;
            ha0 = (GAST + oskar_station_lon_rad(station)) - norm_ra_rad;
            oskar_convert_relative_directions_to_enu_directions_d(
                    &t_x, &t_y, &t_z, 1, &c_x, &c_y, &c_z, ha0, norm_dec_rad,
                    oskar_station_lat_rad(station));
            c_x = t_x;
            c_y = t_y;
            c_z = t_z;
        }

        /* Add the extra normalisation source to the end of the arrays. */
        oskar_mem_set_element_real(x, num_points-1, c_x, status);
        oskar_mem_set_element_real(y, num_points-1, c_y, status);
        oskar_mem_set_element_real(z, num_points-1, c_z, status);
    }

    /* Evaluate the station beam for the given directions. */
    if (coord_type == OSKAR_ENU_DIRECTIONS)
    {
        evaluate_station_beam_enu_directions(out, num_points, x, y, z,
                station, work, time_index, frequency_hz, GAST, status);
    }
    else if (coord_type == OSKAR_RELATIVE_DIRECTIONS)
    {
        evaluate_station_beam_relative_directions(out, num_points, x, y, z,
                station, work, time_index, frequency_hz, GAST, status);
    }
    else
    {
        *status = OSKAR_ERR_INVALID_ARGUMENT;
    }

    /* Scale beam pattern by value of the last source if required. */
    if (normalise_final_beam)
    {
        double amp = 0.0;

        /* Get the last element of the vector and convert to amplitude. */
        if (oskar_mem_is_matrix(out))
        {
            double4c val;
            val = oskar_mem_get_element_matrix(out, num_points-1, status);

            /*
             * Scale by square root of "Stokes I" autocorrelation:
             * sqrt(0.5 * [sum of resultant diagonal]).
             *
             * We have
             * [ Xa  Xb ] [ Xa*  Xc* ] = [ Xa Xa* + Xb Xb*    (don't care)   ]
             * [ Xc  Xd ] [ Xb*  Xd* ]   [  (don't care)     Xc Xc* + Xd Xd* ]
             *
             * Stokes I is completely real, so need only evaluate the real
             * part of all the multiplies. Because of the conjugate terms,
             * these become re*re + im*im.
             *
             * Need the square root because we only want the normalised value
             * for the beam itself (in isolation), not its actual
             * autocorrelation!
             */
            amp = val.a.x * val.a.x + val.a.y * val.a.y +
                    val.b.x * val.b.x + val.b.y * val.b.y +
                    val.c.x * val.c.x + val.c.y * val.c.y +
                    val.d.x * val.d.x + val.d.y * val.d.y;
            amp = sqrt(0.5 * amp);
        }
        else
        {
            double2 val;
            val = oskar_mem_get_element_complex(out, num_points-1, status);

            /* Scale by voltage. */
            amp = sqrt(val.x * val.x + val.y * val.y);
        }

        /* Scale beam array by normalisation value. */
        oskar_mem_scale_real(out, 1.0/amp, status);

        /* Copy output beam data. */
        oskar_mem_copy_contents(beam_pattern, out, 0, 0, num_points-1, status);
    }
}
void oskar_station_set_element_weight(oskar_Station* dst,
        int index, double re, double im, int* status)
{
    oskar_mem_set_element_real(dst->element_weight, 2*index + 0, re, status);
    oskar_mem_set_element_real(dst->element_weight, 2*index + 1, im, status);
}
void oskar_telescope_set_station_coords(oskar_Telescope* dst, int index,
        const double measured_offset_ecef[3], const double true_offset_ecef[3],
        const double measured_enu[3], const double true_enu[3], int* status)
{
    oskar_mem_set_element_real(dst->station_measured_x_offset_ecef_metres,
            index, measured_offset_ecef[0], status);
    oskar_mem_set_element_real(dst->station_measured_y_offset_ecef_metres,
            index, measured_offset_ecef[1], status);
    oskar_mem_set_element_real(dst->station_measured_z_offset_ecef_metres,
            index, measured_offset_ecef[2], status);
    oskar_mem_set_element_real(dst->station_true_x_offset_ecef_metres,
            index, true_offset_ecef[0], status);
    oskar_mem_set_element_real(dst->station_true_y_offset_ecef_metres,
            index, true_offset_ecef[1], status);
    oskar_mem_set_element_real(dst->station_true_z_offset_ecef_metres,
            index, true_offset_ecef[2], status);
    oskar_mem_set_element_real(dst->station_measured_x_enu_metres,
            index, measured_enu[0], status);
    oskar_mem_set_element_real(dst->station_measured_y_enu_metres,
            index, measured_enu[1], status);
    oskar_mem_set_element_real(dst->station_measured_z_enu_metres,
            index, measured_enu[2], status);
    oskar_mem_set_element_real(dst->station_true_x_enu_metres,
            index, true_enu[0], status);
    oskar_mem_set_element_real(dst->station_true_y_enu_metres,
            index, true_enu[1], status);
    oskar_mem_set_element_real(dst->station_true_z_enu_metres,
            index, true_enu[2], status);
}