Beispiel #1
0
    def get_ants_installed_since(self,
                                 query_date,
                                 station_types_to_check='all'):
        """
        Get list of antennas installed since query_date.

        Parameters
        ----------
        query_date : astropy Time
            Date to get limit check for installation.
        station_types_to_check : str or list of str
            Stations types to limit check.

        """
        import cartopy.crs as ccrs
        station_types_to_check = self.parse_station_types_to_check(
            station_types_to_check)
        dt = query_date.gps
        latlon_p = ccrs.Geodetic()
        utm_p = ccrs.UTM(self.hera_zone[0])
        lat_corr = self.lat_corr[self.hera_zone[1]]
        found_stations = []
        for a in self.session.query(geo_location.GeoLocation).filter(
                geo_location.GeoLocation.created_gpstime >= dt):
            if a.station_type_name.lower() in station_types_to_check:
                a.gps2Time()
                a.desc = self.station_types[a.station_type_name]['Description']
                a.lon, a.lat = latlon_p.transform_point(
                    a.easting, a.northing - lat_corr, utm_p)
                a.X, a.Y, a.Z = uvutils.XYZ_from_LatLonAlt(
                    radians(a.lat), radians(a.lon), a.elevation)
                found_stations.append(copy.copy(a))
                if self.fp_out is not None and not self.testing:  # pragma: no cover
                    self.fp_out.write('{}\n'.format(self._loc_line(a)))
        return found_stations
Beispiel #2
0
def parse_telescope_params(tele_params):
    """
    Parse the "telescope" section of a healvis obsparam.

    Args:
        tele_params: Dictionary of telescope parameters

    Returns:
        dict of array properties:
            |  Nants_data: Number of antennas
            |  Nants_telescope: Number of antennas
            |  antenna_names: list of antenna names
            |  antenna_numbers: corresponding list of antenna numbers
            |  antenna_positions: Array of ECEF antenna positions
            |  telescope_location: ECEF array center location
            |  telescope_config_file: Path to configuration yaml file
            |  antenna_location_file: Path to csv layout file
            |  telescope_name: observatory name
    """
    layout_csv = tele_params["array_layout"]
    if not os.path.exists(layout_csv):
        if not os.path.exists(layout_csv):
            raise ValueError(
                "layout_csv file from yaml does not exist: {}".format(
                    layout_csv))

    ant_layout = _parse_layout_csv(layout_csv)
    if isinstance(tele_params["telescope_location"], str):
        tloc = tele_params["telescope_location"][1:-1]  # drop parens
        tloc = list(map(float, tloc.split(",")))
    else:
        tloc = list(tele_params["telescope_location"])
    tloc[0] *= np.pi / 180.0
    tloc[1] *= np.pi / 180.0  # Convert to radians
    tloc_xyz = uvutils.XYZ_from_LatLonAlt(*tloc)

    E, N, U = ant_layout["e"], ant_layout["n"], ant_layout["u"]
    antnames = ant_layout["name"]
    return_dict = {}

    return_dict["Nants_data"] = antnames.size
    return_dict["Nants_telescope"] = antnames.size
    return_dict["antenna_names"] = np.array(antnames.tolist())
    return_dict["antenna_numbers"] = np.array(ant_layout["number"])
    antpos_enu = np.vstack((E, N, U)).T
    return_dict["antenna_positions"] = (
        uvutils.ECEF_from_ENU(antpos_enu, *tloc) - tloc_xyz)
    return_dict["array_layout"] = layout_csv
    return_dict["telescope_location"] = tloc_xyz
    return_dict["telescope_name"] = tele_params["telescope_name"]

    return return_dict
Beispiel #3
0
def get_telescope_location_ecef(lat, lon, alt):
    """
    Compute the telescope location in ECEF coordinates from lat/lon/alt.

    Args:
      lat (float) -- telescope latitude, in radians
      lon (float) -- telescope longitude, in radians
      alt (float) -- telescope altitude, in meters

    Returns:
       ecef -- len(3) array of x,y,z values of telescope location in ECEF
           coordinates, in meters.
    """
    import pyuvdata.utils as uvutils
    return uvutils.XYZ_from_LatLonAlt(lat, lon, alt)
Beispiel #4
0
def test_XYZ_from_LatLonAlt():
    """Test conversion from lat/lon/alt to ECEF xyz with reference values."""
    out_xyz = uvutils.XYZ_from_LatLonAlt(ref_latlonalt[0], ref_latlonalt[1],
                                         ref_latlonalt[2])
    # Got reference by forcing http://www.oc.nps.edu/oc2902w/coord/llhxyz.htm
    # to give additional precision.
    assert np.allclose(ref_xyz, out_xyz, rtol=0, atol=1e-3)

    # test error checking
    pytest.raises(ValueError, uvutils.XYZ_from_LatLonAlt, ref_latlonalt[0],
                  ref_latlonalt[1],
                  np.array([ref_latlonalt[2], ref_latlonalt[2]]))
    pytest.raises(ValueError, uvutils.XYZ_from_LatLonAlt, ref_latlonalt[0],
                  np.array([ref_latlonalt[1], ref_latlonalt[1]]),
                  ref_latlonalt[2])
Beispiel #5
0
    def get_location(self, to_find_list, query_date):
        """
        Get GeoLocation objects for a list of station_names.

        Parameters
        ----------
        to_find_list :  list of str
            station names to find
        query_date : string, int, Time, datetime
            Date to get information for, anything that can be parsed by `get_astropytime`.

        Returns
        -------
        list of GeoLocation objects
            GeoLocation objects corresponding to station names.

        """
        import cartopy.crs as ccrs
        latlon_p = ccrs.Geodetic()
        utm_p = ccrs.UTM(self.hera_zone[0])
        lat_corr = self.lat_corr[self.hera_zone[1]]
        locations = []
        self.query_date = cm_utils.get_astropytime(query_date)
        for station_name in to_find_list:
            for a in self.session.query(geo_location.GeoLocation).filter(
                (func.upper(geo_location.GeoLocation.station_name) ==
                 station_name.upper())
                    & (geo_location.GeoLocation.created_gpstime <
                       self.query_date.gps)):
                a.gps2Time()
                a.desc = self.station_types[a.station_type_name]['Description']
                a.lon, a.lat = latlon_p.transform_point(
                    a.easting, a.northing - lat_corr, utm_p)
                a.X, a.Y, a.Z = uvutils.XYZ_from_LatLonAlt(
                    radians(a.lat), radians(a.lon), a.elevation)
                locations.append(copy.copy(a))
                if self.fp_out is not None and not self.testing:  # pragma: no cover
                    self.fp_out.write('{}\n'.format(self._loc_line(a)))
        return locations
Beispiel #6
0
            fnd_list = geo.get_location([stn[0]],
                                        t,
                                        station_types=geo.station_types)
            fnd = fnd_list[0]
            lat = fnd.lat
            lon = fnd.lon
            alt = fnd.elevation

            ant_nums.append(ant_number)
            longitudes.append(lon)
            latitudes.append(lat)
            elevations.append(alt)

# convert to ecef (in meters)
ecef_positions = uvutils.XYZ_from_LatLonAlt(
    np.array(latitudes) * np.pi / 180.,
    np.array(longitudes) * np.pi / 180., elevations)
rotecef_positions = uvutils.rotECEF_from_ECEF(ecef_positions.T,
                                              cofa_loc.lon * np.pi / 180.)

# make an array of antenna positions in the form miriad is expecting
c_ns = const.c.to('m/ns').value
nants = max(ant_nums) + 1
antpos = np.zeros([nants, 3])
for i, ant in enumerate(ant_nums):
    antpos[ant, :] = rotecef_positions[i, :] / c_ns

# make an aa object
freqs = np.array([0.15])
beam = aipy.phs.Beam(freqs)
ants = [aipy.phs.Antenna(a[0], a[1], a[2], beam) for a in antpos]
Beispiel #7
0
    def get_cminfo_correlator(self, hookup_type=None):
        """
        Return a dict with info needed by the correlator.

        Note: This method requires pyuvdata

        Parameters
        ----------
        hookup_type : str or None
            Type of hookup to use (current observing system is 'parts_hera').
            If 'None' it will determine which system it thinks it is based on
            the part-type.  The order in which it checks is specified in cm_sysdef.
            Only change if you know you want a different system (like 'parts_paper').
            Default is None.

        Returns
        -------
        dict
            cm info formatted for the correlator.
            Dict keys are:
                'antenna_numbers': Antenna numbers (list of integers)
                'antenna_names': Station names (we use antenna_names because that's
                    what they're called in data files) (list of strings)
                'correlator_inputs': Correlator input strings for x/y (e/n)
                    polarizations (list of 2 element tuples of strings)
                'antenna_positions': Antenna positions in relative ECEF coordinates
                    (list of 3-element vectors of floats)
                'cm_version': CM git hash (string)
                'cofa_lat': latitude of the center-of-array in degrees
                'cofa_lon': longitude of the center-of-array in degrees
                'cofa_alt': altitude of center-of-array in meters
        """
        from pyuvdata import utils as uvutils
        from . import cm_handling

        cm_h = cm_handling.Handling(session=self.session)
        cm_version = cm_h.get_cm_version()
        cofa_loc = self.geo.cofa()[0]
        cofa_xyz = uvutils.XYZ_from_LatLonAlt(cofa_loc.lat * np.pi / 180.,
                                              cofa_loc.lon * np.pi / 180.,
                                              cofa_loc.elevation)
        stations_conn = self.get_connected_stations(at_date='now', hookup_type=hookup_type)
        stn_arrays = SystemInfo()
        for stn in stations_conn:
            stn_arrays.update_arrays(stn)
        # latitudes, longitudes output by get_connected_stations are in degrees
        # XYZ_from_LatLonAlt wants radians
        ecef_positions = uvutils.XYZ_from_LatLonAlt(np.array(stn_arrays.lat) * np.pi / 180.,
                                                    np.array(stn_arrays.lon) * np.pi / 180.,
                                                    stn_arrays.elevation)

        rel_ecef_positions = ecef_positions - cofa_xyz
        return {'antenna_numbers': stn_arrays.antenna_number,
                # This is actually station names, not antenna names,
                # but antenna_names is what it's called in pyuvdata
                'antenna_names': stn_arrays.station_name,
                # this is a tuple giving the f-engine names for x, y
                'correlator_inputs': stn_arrays.correlator_input,
                'antenna_positions': rel_ecef_positions.tolist(),
                'cm_version': cm_version,
                'cofa_lat': cofa_loc.lat,
                'cofa_lon': cofa_loc.lon,
                'cofa_alt': cofa_loc.elevation}
# Convert UTM to Lat/Lon
# LatLon to ECEF using pyuvdata.utils
#
# Finally convert ECEF to ENU using
# coordinates of the center of the array (cofa)
# ENU coordinates are wrt center of the array

antpos_ENU = {}

# Extract cminfo from redis for cofa coordinates
cminfo = redis_cm.read_cminfo_from_redis(return_as='dict')
cofa_lat = cminfo['cofa_lat'] * np.pi / 180.
cofa_lon = cminfo['cofa_lon'] * np.pi / 180.
cofa_alt = cminfo['cofa_alt']

for ant, loc in ants.items():

    lon, lat = latlon.transform_point(loc['E'], loc['N'] - lat_corr, utm)

    # Convert the latitute-longitude to ECEF
    ecef = uvutils.XYZ_from_LatLonAlt(lat * np.pi / 180, lon * np.pi / 180,
                                      loc['elevation'])

    # Convert ECEF to ENU
    enu = uvutils.ENU_from_ECEF(ecef, cofa_lat, cofa_lon, cofa_alt)
    antpos_ENU[ant] = enu.tolist()

with open('HERA_350_ENU.json', 'w') as fp:
    json.dump(antpos_ENU, fp)
Beispiel #9
0
def test_ENU_tofrom_ECEF():
    center_lat = -30.7215261207 * np.pi / 180.0
    center_lon = 21.4283038269 * np.pi / 180.0
    center_alt = 1051.7
    lats = np.array([
        -30.72218216, -30.72138101, -30.7212785, -30.7210011, -30.72159853,
        -30.72206199, -30.72174614, -30.72188775, -30.72183915, -30.72100138
    ]) * np.pi / 180.0
    lons = np.array([
        21.42728211, 21.42811727, 21.42814544, 21.42795736, 21.42686739,
        21.42918772, 21.42785662, 21.4286408, 21.42750933, 21.42896567
    ]) * np.pi / 180.0
    alts = np.array([
        1052.25, 1051.35, 1051.2, 1051., 1051.45, 1052.04, 1051.68, 1051.87,
        1051.77, 1051.06
    ])

    # used pymap3d, which implements matlab code, as a reference.
    x = [
        5109327.46674067, 5109339.76407785, 5109344.06370947, 5109365.11297147,
        5109372.115673, 5109266.94314734, 5109329.89620962, 5109295.13656657,
        5109337.21810468, 5109329.85680612
    ]

    y = [
        2005130.57953031, 2005221.35184577, 2005225.93775268, 2005214.8436201,
        2005105.42364036, 2005302.93158317, 2005190.65566222, 2005257.71335575,
        2005157.78980089, 2005304.7729239
    ]

    z = [
        -3239991.24516348, -3239914.4185286, -3239904.57048431,
        -3239878.02656316, -3239935.20415493, -3239979.68381865,
        -3239949.39266985, -3239962.98805772, -3239958.30386264,
        -3239878.08403833
    ]

    east = [
        -97.87631659, -17.87126443, -15.17316938, -33.19049252, -137.60520964,
        84.67346748, -42.84049408, 32.28083937, -76.1094745, 63.40285935
    ]
    north = [
        -72.7437482, 16.09066646, 27.45724573, 58.21544651, -8.02964511,
        -59.41961437, -24.39698388, -40.09891961, -34.70965816, 58.18410876
    ]
    up = [
        0.54883333, -0.35004539, -0.50007736, -0.70035299, -0.25148791,
        0.33916067, -0.02019057, 0.16979185, 0.06945155, -0.64058124
    ]

    xyz = uvutils.XYZ_from_LatLonAlt(lats, lons, alts)
    assert np.allclose(np.stack((x, y, z), axis=1), xyz, atol=1e-3)

    enu = uvutils.ENU_from_ECEF(xyz, center_lat, center_lon, center_alt)
    assert np.allclose(np.stack((east, north, up), axis=1), enu, atol=1e-3)
    # check warning if array transposed
    uvtest.checkWarnings(uvutils.ENU_from_ECEF,
                         [xyz.T, center_lat, center_lon, center_alt],
                         message='The expected shape of ECEF xyz array',
                         category=DeprecationWarning)
    # check warning if  3 x 3 array
    uvtest.checkWarnings(uvutils.ENU_from_ECEF,
                         [xyz[0:3], center_lat, center_lon, center_alt],
                         message='The xyz array in ENU_from_ECEF is',
                         category=DeprecationWarning)
    # check error if only 2 coordinates
    pytest.raises(ValueError, uvutils.ENU_from_ECEF, xyz[:, 0:2], center_lat,
                  center_lon, center_alt)

    # check that a round trip gives the original value.
    xyz_from_enu = uvutils.ECEF_from_ENU(enu, center_lat, center_lon,
                                         center_alt)
    assert np.allclose(xyz, xyz_from_enu, atol=1e-3)
    # check warning if array transposed
    uvtest.checkWarnings(uvutils.ECEF_from_ENU,
                         [enu.T, center_lat, center_lon, center_alt],
                         message='The expected shape the ENU array',
                         category=DeprecationWarning)
    # check warning if  3 x 3 array
    uvtest.checkWarnings(uvutils.ECEF_from_ENU,
                         [enu[0:3], center_lat, center_lon, center_alt],
                         message='The enu array in ECEF_from_ENU is',
                         category=DeprecationWarning)
    # check error if only 2 coordinates
    pytest.raises(ValueError, uvutils.ENU_from_ECEF, enu[:, 0:2], center_lat,
                  center_lon, center_alt)

    # check passing a single value
    enu_single = uvutils.ENU_from_ECEF(xyz[0, :], center_lat, center_lon,
                                       center_alt)
    assert np.allclose(np.array((east[0], north[0], up[0])),
                       enu[0, :],
                       atol=1e-3)

    xyz_from_enu = uvutils.ECEF_from_ENU(enu_single, center_lat, center_lon,
                                         center_alt)
    assert np.allclose(xyz[0, :], xyz_from_enu, atol=1e-3)

    # error checking
    pytest.raises(ValueError, uvutils.ENU_from_ECEF, xyz[:, 0:1], center_lat,
                  center_lon, center_alt)
    pytest.raises(ValueError, uvutils.ECEF_from_ENU, enu[:, 0:1], center_lat,
                  center_lon, center_alt)
    pytest.raises(ValueError, uvutils.ENU_from_ECEF, xyz / 2., center_lat,
                  center_lon, center_alt)
import numpy as np
from astropy import constants, coordinates, units
from astropy.time import Time
from astropy.coordinates import SkyCoord, EarthLocation, FK5

from pyuvdata import utils as uvutils
from hera_mc import geo_handling

# get cofa information
handling = geo_handling.Handling()
cofa = handling.cofa()[0]
cofa_lat = cofa.lat * np.pi / 180.0
cofa_lon = cofa.lon * np.pi / 180.0
cofa_alt = cofa.elevation

cofa_xyz = uvutils.XYZ_from_LatLonAlt(cofa_lat, cofa_lon, cofa_alt)
cofa_enu = uvutils.ENU_from_ECEF(cofa_xyz, cofa_lat, cofa_lon, cofa_alt)

# get antennas
telescope_location = EarthLocation.from_geocentric(*cofa_xyz, unit=units.m)
jd = int(Time.now().jd)
if True:
    time0 = Time.now()
    time0.location = telescope_location
else:
    time0 = Time(jd, format="jd", location=telescope_location)
print("time0: ", time0.jd)
ants = handling.get_active_stations(time0, "all")
# sort the list by antenna name
ants = sorted(ants, key=lambda x: int(x.station_name[2:]))
Beispiel #11
0
            data.ant_1_array = np.asarray(
                [str(a)[2:-1] for a in data.ant_1_array]).astype(int)
            data.ant_2_array = np.asarray(
                [str(a)[2:-1] for a in data.ant_2_array]).astype(int)

            # Get antenna locations from hera_mc database
            mh = Handling()
            info = mh.get_cminfo_correlator()
            #with open('cminfo.cp','r') as fp:
            #    info = cp.load(fp)

            #set telescope data
            lla = (np.radians(info['cofa_lat']), np.radians(info['cofa_lon']),
                   info['cofa_alt'])
            data.telescope_location = utils.XYZ_from_LatLonAlt(
                lla[0], lla[1], lla[2])

            data.antenna_positions = info['antenna_positions']
            data.antenna_numbers = np.array(
                info['antenna_numbers']).astype(int)
            data.antenna_names = np.asarray(
                [str(a) for a in info['antenna_names']])
            data.Nants_telescope = len(data.antenna_numbers)
            data.Nants_data = 3

            # Write times
            jds = Time(times, format='unix')
            data.time_array = jds.jd
            data.set_lsts_from_time_array()

            # Set ra,dec of zenith during observation