static void compute_enu_directions(oskar_Mem* x, oskar_Mem* y, oskar_Mem* z,
        int np, const oskar_Mem* l, const oskar_Mem* m, const oskar_Mem* n,
        const oskar_Station* station, double GAST, int* status)
{
    double ha0, dec0;
    oskar_mem_ensure(x, np, status);
    oskar_mem_ensure(y, np, status);
    oskar_mem_ensure(z, np, status);
    if (*status) return;

    /* Obtain ra0, dec0 of phase centre */
    const double lat  = oskar_station_lat_rad(station);
    const int pointing_coord_type = oskar_station_beam_coord_type(station);
    if (pointing_coord_type == OSKAR_SPHERICAL_TYPE_EQUATORIAL)
    {
        const double ra0 = oskar_station_beam_lon_rad(station);
        ha0  = (GAST + oskar_station_lon_rad(station)) - ra0;
        dec0 = oskar_station_beam_lat_rad(station);
    }
    else if (pointing_coord_type == OSKAR_SPHERICAL_TYPE_AZEL)
    {
        /* TODO convert from az0, el0 to ha0, dec0 */
        ha0 = 0.0;
        dec0 = 0.0;
        *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE;
        return;
    }
    else
    {
        *status = OSKAR_ERR_SETTINGS_TELESCOPE;
        return;
    }
    oskar_convert_relative_directions_to_enu_directions(
            0, 0, 0, np, l, m, n, ha0, dec0, lat, 0, x, y, z, status);
}
Beispiel #2
0
static void compute_relative_directions(oskar_Mem* l, oskar_Mem* m,
        oskar_Mem* n, int np, const oskar_Mem* x, const oskar_Mem* y,
        const oskar_Mem* z, const oskar_Station* station, double GAST,
        int* status)
{
    double ha0, dec0, lat;
    int pointing_coord_type;

    if (*status) return;

    /* Resize work arrays if needed */
    if ((int)oskar_mem_length(l) < np) oskar_mem_realloc(l, np, status);
    if ((int)oskar_mem_length(m) < np) oskar_mem_realloc(m, np, status);
    if ((int)oskar_mem_length(n) < np) oskar_mem_realloc(n, np, status);
    if (*status) return;

    /* Obtain ra0, dec0 of phase centre */
    lat  = oskar_station_lat_rad(station);
    pointing_coord_type = oskar_station_beam_coord_type(station);
    if (pointing_coord_type == OSKAR_SPHERICAL_TYPE_EQUATORIAL)
    {
        double ra0;
        ra0  = oskar_station_beam_lon_rad(station);
        ha0  = (GAST + oskar_station_lon_rad(station)) - ra0;
        dec0 = oskar_station_beam_lat_rad(station);
    }
    else if (pointing_coord_type == OSKAR_SPHERICAL_TYPE_AZEL)
    {
        /* TODO convert from az0, el0 to ha0, dec0 */
        ha0 = 0.0;
        dec0 = 0.0;
        *status = OSKAR_FAIL;
        return;
    }
    else
    {
        *status = OSKAR_ERR_SETTINGS_TELESCOPE;
        return;
    }

    /* Convert from ENU to phase-centre-relative directions. */
    oskar_convert_enu_directions_to_relative_directions(
            l, m, n, np, x, y, z, ha0, dec0, lat, status);
}
void oskar_evaluate_beam_horizon_direction(double* x, double* y, double* z,
        const oskar_Station* station, const double gast, int* status)
{
    int beam_coord_type;
    double beam_lon, beam_lat;

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

    /* Get direction cosines in horizontal coordinates. */
    beam_coord_type = oskar_station_beam_coord_type(station);
    beam_lon = oskar_station_beam_lon_rad(station);
    beam_lat = oskar_station_beam_lat_rad(station);

    if (beam_coord_type == OSKAR_SPHERICAL_TYPE_EQUATORIAL)
    {
        double lon, lat, last;
        lon = oskar_station_lon_rad(station);
        lat = oskar_station_lat_rad(station);
        last = gast + lon; /* Local Apparent Sidereal Time, in radians. */
        oskar_convert_apparent_ra_dec_to_enu_directions_d(1, &beam_lon,
                &beam_lat, last, lat, x, y, z);
    }
    else if (beam_coord_type == OSKAR_SPHERICAL_TYPE_AZEL)
    {
        /* Convert AZEL to direction cosines. */
        double cos_lat;
        cos_lat = cos(beam_lat);
        *x = cos_lat * sin(beam_lon);
        *y = cos_lat * cos(beam_lon);
        *z = sin(beam_lat);
    }
    else
    {
        *status = OSKAR_ERR_INVALID_ARGUMENT;
    }

    /* Check if the beam direction needs to be one of a set of
     * allowed (az,el) directions. */
    if (oskar_station_num_permitted_beams(station) > 0)
    {
        int i, n, min_index = 0;
        double az, el, cos_el, min_dist = DBL_MAX;
        const double *p_az, *p_el;

        /* Convert current direction cosines to azimuth, elevation. */
        az = atan2(*x, *y);
        el = atan2(*z, sqrt(*x * *x + *y * *y));

        /* Get pointers to permitted beam data. */
        n = oskar_station_num_permitted_beams(station);
        p_az = oskar_mem_double_const(
                oskar_station_permitted_beam_az_rad_const(station),
                status);
        p_el = oskar_mem_double_const(
                oskar_station_permitted_beam_el_rad_const(station),
                status);

        /* Loop over permitted beams. */
        for (i = 0; i < n; ++i)
        {
            double dist;
            dist = oskar_angular_distance(p_az[i], az, p_el[i], el);
            if (dist < min_dist)
            {
                min_dist = dist;
                min_index = i;
            }
        }

        /* Select beam azimuth and elevation based on minimum distance. */
        az = p_az[min_index];
        el = p_el[min_index];

        /* Set new direction cosines. */
        cos_el = cos(el);
        *x = cos_el * sin(az);
        *y = cos_el * cos(az);
        *z = sin(el);
    }
}