https://github.com/RadioAstronomySoftwareGroup/pyuvdata
Raw File
Tip revision: 0b1b091eeec941c6081327cfd1d65f689feafd8c authored by Paul La Plante on 08 August 2020, 00:16 UTC
Merge branch 'Smithsonian-submillimeter_array' into master
Tip revision: 0b1b091
telescopes.py
# -*- mode: python; coding: utf-8 -*-
# Copyright (c) 2018 Radio Astronomy Software Group
# Licensed under the 2-clause BSD License

"""Telescope information and known telescope list."""
import numpy as np
from astropy.coordinates import Angle

from . import uvbase
from . import parameter as uvp

__all__ = ["Telescope", "known_telescopes", "get_telescope"]


# center_xyz is the location of the telescope in ITRF (earth-centered frame)
KNOWN_TELESCOPES = {
    "PAPER": {
        "center_xyz": None,
        "latitude": Angle("-30d43m17.5s").radian,
        "longitude": Angle("21d25m41.9s").radian,
        "altitude": 1073.0,
        "citation": (
            "value taken from capo/cals/hsa7458_v000.py, "
            "comment reads KAT/SA  (GPS), altitude from elevationmap.net"
        ),
    },
    "HERA": {
        "center_xyz": None,
        "latitude": Angle("-30.72152612068925d").radian,
        "longitude": Angle("21.42830382686301d").radian,
        "altitude": 1051.69,
        "diameters": 14.0,
        "citation": (
            "value taken from hera_mc geo.py script "
            "(using hera_cm_db_updates under the hood.)"
        ),
    },
    "MWA": {
        "center_xyz": None,
        "latitude": Angle("-26d42m11.94986s").radian,
        "longitude": Angle("116d40m14.93485s").radian,
        "altitude": 377.827,
        "citation": "Tingay et al., 2013",
    },
    "SMA": {
        "center_xyz": None,
        "latitude": Angle("19d49m27.13895s").radian,
        "longitude": Angle("-155d28m39.08279s").radian,
        "altitude": 4083.948144,
        "citation": "Ho, P. T. P., Moran, J. M., & Lo, K. Y. 2004, ApJL, 616, L1",
    },
}


class Telescope(uvbase.UVBase):
    """
    A class for defining a telescope for use with UVData objects.

    Attributes
    ----------
    citation : str
        text giving source of telescope information
    telescope_name : UVParameter of str
        name of the telescope
    telescope_location : UVParameter of array_like
        telescope location xyz coordinates in ITRF (earth-centered frame).
    antenna_diameters : UVParameter of float
        Optional, antenna diameters in meters. Used by CASA to construct a
        default beam if no beam is supplied.
    """

    def __init__(self):
        """Create a new Telescope object."""
        # add the UVParameters to the class
        # use the same names as in UVData so they can be automatically set
        self.citation = None

        self._telescope_name = uvp.UVParameter(
            "telescope_name", description="name of telescope " "(string)", form="str"
        )
        desc = (
            "telescope location: xyz in ITRF (earth-centered frame). "
            "Can also be set using telescope_location_lat_lon_alt or "
            "telescope_location_lat_lon_alt_degrees properties"
        )
        self._telescope_location = uvp.LocationParameter(
            "telescope_location",
            description=desc,
            acceptable_range=(6.35e6, 6.39e6),
            tols=1e-3,
        )
        desc = (
            "Antenna diameters in meters. Used by CASA to "
            "construct a default beam if no beam is supplied."
        )
        self._antenna_diameters = uvp.UVParameter(
            "antenna_diameters",
            required=False,
            description=desc,
            expected_type=np.float,
            tols=1e-3,  # 1 mm
        )
        # possibly add in future versions:
        # Antenna positions (but what about reconfigurable/growing telescopes?)

        super(Telescope, self).__init__()


def known_telescopes():
    """
    Get list of known telescopes.

    Returns
    -------
    list of str
        List of known telescope names.
    """
    return list(KNOWN_TELESCOPES.keys())


def get_telescope(telescope_name, telescope_dict_in=None):
    """
    Get Telescope object for a telescope in telescope_dict.

    Parameters
    ----------
    telescope_name : str
        Name of a telescope
    telescope_dict_in: dict
        telescope info dict. Default is None, meaning use KNOWN_TELESCOPES
        (other values are only used for testing)

    Returns
    -------
    Telescope object
        The Telescope object associated with telescope_name.
    """
    if telescope_dict_in is None:
        telescope_dict_in = KNOWN_TELESCOPES

    telescope_list = list(telescope_dict_in.keys())
    uc_telescope_list = [item.upper() for item in telescope_list]
    if telescope_name.upper() in uc_telescope_list:
        telescope_index = uc_telescope_list.index(telescope_name.upper())
        telescope_dict = telescope_dict_in[telescope_list[telescope_index]]
        obj = Telescope()
        obj.citation = telescope_dict["citation"]
        obj.telescope_name = telescope_list[telescope_index]
        if telescope_dict["center_xyz"] is not None:
            obj.telescope_location = telescope_dict["center_xyz"]
        else:
            if (
                telescope_dict["latitude"] is None
                or telescope_dict["longitude"] is None
                or telescope_dict["altitude"] is None
            ):
                raise ValueError(
                    "either the center_xyz or the "
                    "latitude, longitude and altitude of the "
                    "telescope must be specified"
                )
            obj.telescope_location_lat_lon_alt = (
                telescope_dict["latitude"],
                telescope_dict["longitude"],
                telescope_dict["altitude"],
            )

            obj.check(run_check_acceptability=True)
        if "diameters" in telescope_dict.keys():
            obj.antenna_diameters = telescope_dict["diameters"]
    else:
        # no telescope matching this name
        return False

    return obj
back to top