Пример #1
0
def cirs_to_observed(cirs_coo, observed_frame):
    if (np.any(observed_frame.location != cirs_coo.location) or
            np.any(cirs_coo.obstime != observed_frame.obstime)):
        cirs_coo = cirs_coo.transform_to(CIRS(obstime=observed_frame.obstime,
                                              location=observed_frame.location))

    # if the data are UnitSphericalRepresentation, we can skip the distance calculations
    is_unitspherical = (isinstance(cirs_coo.data, UnitSphericalRepresentation) or
                        cirs_coo.cartesian.x.unit == u.one)

    # We used to do "astrometric" corrections here, but these are no longer necesssary
    # CIRS has proper topocentric behaviour
    usrepr = cirs_coo.represent_as(UnitSphericalRepresentation)
    cirs_ra = usrepr.lon.to_value(u.radian)
    cirs_dec = usrepr.lat.to_value(u.radian)
    # first set up the astrometry context for CIRS<->observed
    astrom = erfa_astrom.get().apio(observed_frame)

    if isinstance(observed_frame, AltAz):
        lon, zen, _, _, _ = erfa.atioq(cirs_ra, cirs_dec, astrom)
        lat = PIOVER2 - zen
    else:
        _, _, lon, lat, _ = erfa.atioq(cirs_ra, cirs_dec, astrom)

    if is_unitspherical:
        rep = UnitSphericalRepresentation(lat=u.Quantity(lat, u.radian, copy=False),
                                          lon=u.Quantity(lon, u.radian, copy=False),
                                          copy=False)
    else:
        # since we've transformed to CIRS at the observatory location, just use CIRS distance
        rep = SphericalRepresentation(lat=u.Quantity(lat, u.radian, copy=False),
                                      lon=u.Quantity(lon, u.radian, copy=False),
                                      distance=cirs_coo.distance,
                                      copy=False)
    return observed_frame.realize_frame(rep)
Пример #2
0
def icrs_to_altaz(icrs_coo, altaz_frame):
    # if the data are UnitSphericalRepresentation, we can skip the distance calculations
    is_unitspherical = (isinstance(icrs_coo.data, UnitSphericalRepresentation)
                        or icrs_coo.cartesian.x.unit == u.one)
    # first set up the astrometry context for ICRS<->AltAz
    astrom = erfa_astrom.get().apco(altaz_frame)

    # correct for parallax to find BCRS direction from observer (as in erfa.pmpx)
    if is_unitspherical:
        srepr = icrs_coo.spherical
    else:
        observer_icrs = CartesianRepresentation(astrom['eb'],
                                                unit=u.au,
                                                xyz_axis=-1,
                                                copy=False)
        srepr = (icrs_coo.cartesian -
                 observer_icrs).represent_as(SphericalRepresentation)

    # convert to topocentric CIRS
    cirs_ra, cirs_dec = atciqz(srepr, astrom)

    # now perform AltAz conversion
    az, zen, ha, odec, ora = erfa.atioq(cirs_ra, cirs_dec, astrom)
    alt = PIOVER2 - zen
    if is_unitspherical:
        aa_srepr = UnitSphericalRepresentation(az << u.radian,
                                               alt << u.radian,
                                               copy=False)
    else:
        aa_srepr = SphericalRepresentation(az << u.radian,
                                           alt << u.radian,
                                           srepr.distance,
                                           copy=False)
    return altaz_frame.realize_frame(aa_srepr)
Пример #3
0
def cirs_to_altaz(cirs_coo, altaz_frame):
    if np.any(cirs_coo.obstime != altaz_frame.obstime):
        # the only frame attribute for the current CIRS is the obstime, but this
        # would need to be updated if a future change allowed specifying an
        # Earth location algorithm or something
        cirs_coo = cirs_coo.transform_to(CIRS(obstime=altaz_frame.obstime))

    # we use the same obstime everywhere now that we know they're the same
    obstime = cirs_coo.obstime

    # if the data are UnitSphericalRepresentation, we can skip the distance calculations
    is_unitspherical = (isinstance(cirs_coo.data, UnitSphericalRepresentation)
                        or cirs_coo.cartesian.x.unit == u.one)

    if is_unitspherical:
        usrepr = cirs_coo.represent_as(UnitSphericalRepresentation)
        cirs_ra = usrepr.lon.to_value(u.radian)
        cirs_dec = usrepr.lat.to_value(u.radian)
    else:
        # compute an "astrometric" ra/dec -i.e., the direction of the
        # displacement vector from the observer to the target in CIRS
        loccirs = altaz_frame.location.get_itrs(
            cirs_coo.obstime).transform_to(cirs_coo)
        diffrepr = (
            cirs_coo.cartesian -
            loccirs.cartesian).represent_as(UnitSphericalRepresentation)

        cirs_ra = diffrepr.lon.to_value(u.radian)
        cirs_dec = diffrepr.lat.to_value(u.radian)

    # first set up the astrometry context for CIRS<->AltAz
    astrom = erfa_astrom.get().apio13(altaz_frame)

    az, zen, _, _, _ = erfa.atioq(cirs_ra, cirs_dec, astrom)

    if is_unitspherical:
        rep = UnitSphericalRepresentation(lat=u.Quantity(PIOVER2 - zen,
                                                         u.radian,
                                                         copy=False),
                                          lon=u.Quantity(az,
                                                         u.radian,
                                                         copy=False),
                                          copy=False)
    else:
        # now we get the distance as the cartesian distance from the earth
        # location to the coordinate location
        locitrs = altaz_frame.location.get_itrs(obstime)
        distance = locitrs.separation_3d(cirs_coo)
        rep = SphericalRepresentation(lat=u.Quantity(PIOVER2 - zen,
                                                     u.radian,
                                                     copy=False),
                                      lon=u.Quantity(az, u.radian, copy=False),
                                      distance=distance,
                                      copy=False)
    return altaz_frame.realize_frame(rep)
Пример #4
0
def _erfa_check(ira, idec, astrom):
    """
    This function does the same thing the astropy layer is supposed to do, but
    all in erfa
    """
    cra, cdec = erfa.atciq(ira, idec, 0, 0, 0, 0, astrom)
    az, zen, ha, odec, ora = erfa.atioq(cra, cdec, astrom)
    alt = np.pi / 2 - zen
    cra2, cdec2 = erfa.atoiq('A', az, zen, astrom)
    ira2, idec2 = erfa.aticq(cra2, cdec2, astrom)

    dct = locals()
    del dct['astrom']
    return dct
Пример #5
0
def cirs_to_altaz(cirs_coo, altaz_frame):
    if np.any(cirs_coo.obstime != altaz_frame.obstime):
        # the only frame attribute for the current CIRS is the obstime, but this
        # would need to be updated if a future change allowed specifying an
        # Earth location algorithm or something
        cirs_coo = cirs_coo.transform_to(CIRS(obstime=altaz_frame.obstime))

    # we use the same obstime everywhere now that we know they're the same
    obstime = cirs_coo.obstime

    # if the data are UnitSphericalRepresentation, we can skip the distance calculations
    is_unitspherical = (isinstance(cirs_coo.data, UnitSphericalRepresentation)
                        or cirs_coo.cartesian.x.unit == u.one)

    if is_unitspherical:
        usrepr = cirs_coo.represent_as(UnitSphericalRepresentation)
        cirs_ra = usrepr.lon.to_value(u.radian)
        cirs_dec = usrepr.lat.to_value(u.radian)
    else:
        # compute an "astrometric" ra/dec -i.e., the direction of the
        # displacement vector from the observer to the target in CIRS
        loccirs = altaz_frame.location.get_itrs(
            cirs_coo.obstime).transform_to(cirs_coo)
        diffrepr = (
            cirs_coo.cartesian -
            loccirs.cartesian).represent_as(UnitSphericalRepresentation)

        cirs_ra = diffrepr.lon.to_value(u.radian)
        cirs_dec = diffrepr.lat.to_value(u.radian)

    lon, lat, height = altaz_frame.location.to_geodetic('WGS84')
    xp, yp = get_polar_motion(obstime)

    # first set up the astrometry context for CIRS<->AltAz
    jd1, jd2 = get_jd12(obstime, 'utc')
    astrom = erfa.apio13(
        jd1,
        jd2,
        get_dut1utc(obstime),
        lon.to_value(u.radian),
        lat.to_value(u.radian),
        height.to_value(u.m),
        xp,
        yp,  # polar motion
        # all below are already in correct units because they are QuantityFrameAttribues
        altaz_frame.pressure.value,
        altaz_frame.temperature.value,
        altaz_frame.relative_humidity.value,
        altaz_frame.obswl.value)

    az, zen, _, _, _ = erfa.atioq(cirs_ra, cirs_dec, astrom)

    if is_unitspherical:
        rep = UnitSphericalRepresentation(lat=u.Quantity(PIOVER2 - zen,
                                                         u.radian,
                                                         copy=False),
                                          lon=u.Quantity(az,
                                                         u.radian,
                                                         copy=False),
                                          copy=False)
    else:
        # now we get the distance as the cartesian distance from the earth
        # location to the coordinate location
        locitrs = altaz_frame.location.get_itrs(obstime)
        distance = locitrs.separation_3d(cirs_coo)
        rep = SphericalRepresentation(lat=u.Quantity(PIOVER2 - zen,
                                                     u.radian,
                                                     copy=False),
                                      lon=u.Quantity(az, u.radian, copy=False),
                                      distance=distance,
                                      copy=False)
    return altaz_frame.realize_frame(rep)